[med-svn] [beast2-mcmc] 02/08: Imported Upstream version 2.4.0pre+dfsg

Andreas Tille tille at debian.org
Wed May 4 08:01:40 UTC 2016


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

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

commit e8824d3d6b97eb6c820939742af2bf6eecd19ea0
Author: Andreas Tille <tille at debian.org>
Date:   Tue Mar 8 16:08:37 2016 +0100

    Imported Upstream version 2.4.0pre+dfsg
---
 build.xml                                          |   25 +-
 doc/tutorials/EBSP/Makefile                        |   16 +
 doc/tutorials/EBSP/ebsp2-tut.bib                   |   51 +
 doc/tutorials/EBSP/ebsp2-tut.tex                   |  376 ++++
 doc/tutorials/EBSP/figures/clock_model.png         |  Bin 0 -> 16792 bytes
 doc/tutorials/EBSP/figures/clock_model2.png        |  Bin 0 -> 12830 bytes
 doc/tutorials/EBSP/figures/clock_model3.png        |  Bin 0 -> 12619 bytes
 doc/tutorials/EBSP/figures/clock_model4.png        |  Bin 0 -> 12816 bytes
 doc/tutorials/EBSP/figures/clockrate_prior.png     |  Bin 0 -> 32789 bytes
 doc/tutorials/EBSP/figures/import_alignment.png    |  Bin 0 -> 18962 bytes
 doc/tutorials/EBSP/figures/import_alignment2.png   |  Bin 0 -> 28831 bytes
 doc/tutorials/EBSP/figures/mcmc_panel.png          |  Bin 0 -> 24809 bytes
 doc/tutorials/EBSP/figures/mystery1.pdf            |  Bin 0 -> 6323 bytes
 doc/tutorials/EBSP/figures/mystery2.pdf            |  Bin 0 -> 5929 bytes
 doc/tutorials/EBSP/figures/mystery3.pdf            |  Bin 0 -> 41201 bytes
 doc/tutorials/EBSP/figures/mysteryTimesHist.pdf    |  Bin 0 -> 5382 bytes
 doc/tutorials/EBSP/figures/operators.png           |  Bin 0 -> 68075 bytes
 doc/tutorials/EBSP/figures/ploidy.png              |  Bin 0 -> 66371 bytes
 doc/tutorials/EBSP/figures/popmean.png             |  Bin 0 -> 30859 bytes
 doc/tutorials/EBSP/figures/site_model.png          |  Bin 0 -> 29547 bytes
 doc/tutorials/EBSP/figures/tracer1.png             |  Bin 0 -> 70580 bytes
 doc/tutorials/EBSP/figures/tracer2.png             |  Bin 0 -> 52951 bytes
 doc/tutorials/EBSP/figures/tree_prior.png          |  Bin 0 -> 47827 bytes
 doc/tutorials/EBSP/figures/view_operators.png      |  Bin 0 -> 34745 bytes
 doc/tutorials/EBSP/mystery-mammal/X.nex.nex        |   40 +
 doc/tutorials/EBSP/mystery-mammal/mt.nex.nex       |   40 +
 doc/tutorials/EBSP/mystery-mammal/nuclear.nex.nex  |   40 +
 doc/tutorials/EBSP/scripts/plotEBSP.R              |  224 +++
 examples/testHKY.json                              |   14 +-
 examples/testTipDates.xml                          |    2 +-
 examples/testUCLNclock.json                        |  135 ++
 packages.xml                                       |   71 -
 release/Linux/bin/beast                            |    2 +-
 release/common/VERSION HISTORY.txt                 |    2 +-
 release/common/tools/DensiTree_launch4j.xml        |    2 +-
 src/beast/app/BEASTVersion.java                    |   21 +-
 src/beast/app/BeastMCMC.java                       |  121 +-
 src/beast/app/DocMaker.java                        |  213 ++-
 src/beast/app/ModelBuilder.java                    |   15 +-
 src/beast/app/beastapp/BeastDialog.java            |   45 +-
 src/beast/app/beastapp/BeastLauncher.java          |   91 +-
 src/beast/app/beastapp/BeastMain.java              |  116 +-
 src/beast/app/beastapp/WholeNumberField.java       |   43 +-
 src/beast/app/beauti/AlignmentListInputEditor.java |  494 ++---
 src/beast/app/beauti/AlignmentViewer.java          |  140 +-
 src/beast/app/beauti/Beauti.java                   |  357 ++--
 src/beast/app/beauti/BeautiAlignmentProvider.java  |  145 +-
 src/beast/app/beauti/BeautiConfig.java             |  195 +-
 src/beast/app/beauti/BeautiConnector.java          |  178 +-
 src/beast/app/beauti/BeautiDoc.java                | 1298 ++++++-------
 src/beast/app/beauti/BeautiLauncher.java           |    5 +-
 src/beast/app/beauti/BeautiPanel.java              |  150 +-
 src/beast/app/beauti/BeautiPanelConfig.java        |  254 +--
 src/beast/app/beauti/BeautiSubTemplate.java        |  224 +--
 .../app/beauti/ClockModelListInputEditor.java      |   42 +-
 src/beast/app/beauti/ClonePartitionPanel.java      |   30 +-
 src/beast/app/beauti/Fragment.java                 |    6 +-
 src/beast/app/beauti/FrequenciesInputEditor.java   |   40 +-
 ...eTreeForSpeciesTreeDistributionInputEditor.java |   70 +-
 src/beast/app/beauti/GuessPatternDialog.java       |  224 ++-
 src/beast/app/beauti/JPackageDialog.java           |  399 ++--
 src/beast/app/beauti/JPackageRepositoryDialog.java |  155 +-
 src/beast/app/beauti/LoggerListInputEditor.java    |   17 +-
 src/beast/app/beauti/MRCAPriorInputEditor.java     |   89 +-
 src/beast/app/beauti/OperatorListInputEditor.java  |   46 +-
 .../beauti/ParametricDistributionInputEditor.java  |  167 +-
 src/beast/app/beauti/PartitionContext.java         |   25 +-
 src/beast/app/beauti/PriorInputEditor.java         |   49 +-
 src/beast/app/beauti/PriorListInputEditor.java     |   89 +-
 src/beast/app/beauti/SiteModelInputEditor.java     |   59 +-
 .../app/beauti/SpeciesTreePriorInputEditor.java    |   10 +-
 src/beast/app/beauti/StateNodeListInputEditor.java |    7 +-
 src/beast/app/beauti/TaxonSetDialog.java           |   79 +-
 src/beast/app/beauti/TaxonSetInputEditor.java      |  199 +-
 src/beast/app/beauti/TipDatesInputEditor.java      |  274 ++-
 .../app/beauti/TreeDistributionInputEditor.java    |   75 +-
 .../app/beauti/guiutil/S11InitialSelection.java    |   40 +-
 src/beast/app/draw/Arrow.java                      |   43 +-
 src/beast/app/draw/BEASTObjectDialog.java          |   74 +-
 src/beast/app/draw/BEASTObjectInputEditor.java     |  464 +++--
 src/beast/app/draw/BEASTObjectPanel.java           |  298 +--
 src/beast/app/draw/BEASTObjectSet.java             |    8 +-
 src/beast/app/draw/BEASTObjectShape.java           |  102 +-
 src/beast/app/draw/BooleanInputEditor.java         |   24 +-
 src/beast/app/draw/Document.java                   |  941 +++++-----
 src/beast/app/draw/DoubleListInputEditor.java      |  127 +-
 src/beast/app/draw/EnumInputEditor.java            |   38 +-
 src/beast/app/draw/ExtensionFileFilter.java        |   11 +-
 src/beast/app/draw/HelpBrowser.java                |   48 +-
 src/beast/app/draw/InputEditor.java                |  126 +-
 src/beast/app/draw/InputEditorFactory.java         |  202 +-
 src/beast/app/draw/InputShape.java                 |   75 +-
 src/beast/app/draw/IntegerListInputEditor.java     |  157 +-
 src/beast/app/draw/ListInputEditor.java            |  209 ++-
 src/beast/app/draw/ModelBuilder.java               |  657 ++++---
 src/beast/app/draw/MyAction.java                   |   25 +-
 src/beast/app/draw/ParameterInputEditor.java       |  110 +-
 src/beast/app/draw/Selection.java                  |   74 +-
 src/beast/app/draw/Shape.java                      |  197 +-
 src/beast/app/draw/SmallButton.java                |   15 +-
 src/beast/app/draw/SmallButtonOld.java             |    7 +-
 src/beast/app/draw/SmallLabel.java                 |    7 +-
 src/beast/app/draw/TrackPoint.java                 |    8 +-
 src/beast/app/seqgen/MergeDataWith.java            |   34 +-
 src/beast/app/seqgen/SequenceSimulator.java        |   89 +-
 src/beast/app/seqgen/SimulatedAlignment.java       |   57 +-
 src/beast/app/tools/AppStore.java                  |  110 +-
 src/beast/app/tools/AppStoreLauncher.java          |   12 +-
 src/beast/app/tools/EBSPAnalyser.java              |  136 +-
 src/beast/app/tools/LogCombiner.java               |  254 +--
 src/beast/app/tools/LogCombinerDialog.java         |  111 +-
 src/beast/app/tools/LogCombinerLauncher.java       |    6 +-
 src/beast/app/tools/TableEditorStopper.java        |    7 +-
 src/beast/app/treeannotator/CladeSystem.java       |    9 +-
 src/beast/app/treeannotator/ContourAttrib.java     |    1 +
 src/beast/app/treeannotator/ContourGenerator.java  |   53 +-
 src/beast/app/treeannotator/ContourPath.java       |    1 +
 src/beast/app/treeannotator/ContourWithSynder.java |    9 +-
 src/beast/app/treeannotator/FileDrop.java          |   35 +-
 .../treeannotator/KernelDensityEstimator2D.java    |    9 +-
 src/beast/app/treeannotator/RealNumberField.java   |   35 +-
 src/beast/app/treeannotator/SnyderContour.java     |   10 +-
 src/beast/app/treeannotator/TreeAnnotator.java     |  200 +-
 .../app/treeannotator/TreeAnnotatorDialog.java     |   54 +-
 .../app/treeannotator/TreeAnnotatorLauncher.java   |    5 +-
 src/beast/app/treeannotator/TreeSetParser.java     |  329 ++--
 src/beast/app/util/Arguments.java                  |    5 +-
 src/beast/app/util/ErrorLogHandler.java            |    9 +-
 src/beast/app/util/FileDrop.java                   |   48 +-
 src/beast/app/util/MessageLogHandler.java          |   13 +-
 src/beast/app/util/Utils.java                      |   69 +-
 src/beast/app/util/Utils6.java                     |   21 +-
 src/beast/app/util/Version.java                    |   10 +-
 src/beast/app/util/WholeNumberField.java           |   42 +-
 src/beast/core/BEASTInterface.java                 |  262 +--
 src/beast/core/BEASTObject.java                    |   41 +-
 src/beast/core/BEASTObjectAnnotation.java          |   12 -
 src/beast/core/CalculationNode.java                |   16 +-
 src/beast/core/Citation.java                       |    6 +-
 src/beast/core/Distribution.java                   |   17 +-
 src/beast/core/Function.java                       |   23 +-
 src/beast/core/Input.java                          |  266 +--
 src/beast/core/InputForAnnotatedConstructor.java   |  277 +++
 src/beast/core/Loggable.java                       |    7 +-
 src/beast/core/Logger.java                         |  230 +--
 src/beast/core/MCMC.java                           |  244 ++-
 src/beast/core/Operator.java                       |  127 +-
 src/beast/core/OperatorSchedule.java               |   76 +-
 src/beast/core/Param.java                          |   40 +-
 src/beast/core/Runnable.java                       |   12 +-
 src/beast/core/State.java                          |  236 +--
 src/beast/core/StateNode.java                      |   24 +-
 src/beast/core/StateNodeInitialiser.java           |    6 +-
 src/beast/core/parameter/BooleanParameter.java     |   37 +-
 src/beast/core/parameter/BooleanParameterList.java |    4 +-
 src/beast/core/parameter/CompoundValuable.java     |   38 +-
 src/beast/core/parameter/GeneralParameterList.java |   76 +-
 src/beast/core/parameter/IntegerParameter.java     |   59 +-
 src/beast/core/parameter/IntegerParameterList.java |    7 +-
 src/beast/core/parameter/Map.java                  |   40 +-
 src/beast/core/parameter/Parameter.java            |  172 +-
 src/beast/core/parameter/RealParameter.java        |   48 +-
 src/beast/core/parameter/RealParameterList.java    |    7 +-
 src/beast/core/util/CompoundDistribution.java      |   50 +-
 src/beast/core/util/ESS.java                       |  223 ++-
 src/beast/core/util/Log.java                       |   13 +
 src/beast/core/util/Sum.java                       |   26 +-
 src/beast/evolution/alignment/Alignment.java       |  267 +--
 .../evolution/alignment/AscertainedAlignment.java  |   56 +-
 .../evolution/alignment/FilteredAlignment.java     |   24 +-
 src/beast/evolution/alignment/Sequence.java        |   30 +-
 src/beast/evolution/alignment/Taxon.java           |   18 +-
 src/beast/evolution/alignment/TaxonSet.java        |   28 +-
 .../evolution/alignment/distance/Distance.java     |    6 +-
 .../alignment/distance/HammingDistance.java        |    6 +-
 .../evolution/branchratemodel/BranchRateModel.java |    2 +-
 .../branchratemodel/RandomLocalClockModel.java     |   33 +-
 .../evolution/branchratemodel/RateStatistic.java   |   34 +-
 .../branchratemodel/StrictClockModel.java          |    4 +-
 .../branchratemodel/UCRelaxedClockModel.java       |   48 +-
 src/beast/evolution/datatype/DataType.java         |   56 +-
 src/beast/evolution/datatype/StandardData.java     |   32 +-
 src/beast/evolution/datatype/UserDataType.java     |   42 +-
 .../evolution/likelihood/BeagleTreeLikelihood.java |  149 +-
 .../evolution/likelihood/BeerLikelihoodCore.java   |  448 ++---
 .../evolution/likelihood/BeerLikelihoodCore4.java  |  271 +--
 .../likelihood/GenericTreeLikelihood.java          |   10 +-
 src/beast/evolution/likelihood/LikelihoodCore.java |   81 +-
 .../likelihood/ThreadedBeerLikelihoodCore.java     |  984 ++++++++++
 .../likelihood/ThreadedBeerLikelihoodCore4.java    |  293 +++
 .../likelihood/ThreadedLikelihoodCore.java         |  152 ++
 .../likelihood/ThreadedTreeLikelihood.java         |  363 ++++
 src/beast/evolution/likelihood/TreeLikelihood.java |  123 +-
 src/beast/evolution/operators/BitFlipOperator.java |    9 +-
 .../operators/CompoundParameterHelper.java         |   40 +-
 .../evolution/operators/DeltaExchangeOperator.java |  111 +-
 src/beast/evolution/operators/Exchange.java        |   90 +-
 .../evolution/operators/IntRandomWalkOperator.java |   13 +-
 .../evolution/operators/IntUniformOperator.java    |   10 +-
 src/beast/evolution/operators/JointOperator.java   |   18 +-
 src/beast/evolution/operators/NodeReheight.java    |  204 +--
 .../operators/RealRandomWalkOperator.java          |   27 +-
 src/beast/evolution/operators/ScaleOperator.java   |   90 +-
 src/beast/evolution/operators/SliceOperator.java   |   37 +-
 src/beast/evolution/operators/SubtreeSlide.java    |  100 +-
 src/beast/evolution/operators/SwapOperator.java    |   16 +-
 .../evolution/operators/TipDatesRandomWalker.java  |   44 +-
 src/beast/evolution/operators/TipDatesScaler.java  |   52 +-
 src/beast/evolution/operators/TreeOperator.java    |    6 +-
 src/beast/evolution/operators/Uniform.java         |   12 +-
 src/beast/evolution/operators/UniformOperator.java |   28 +-
 src/beast/evolution/operators/UpDownOperator.java  |   39 +-
 src/beast/evolution/operators/WilsonBalding.java   |   70 +-
 src/beast/evolution/sitemodel/SiteModel.java       |   54 +-
 .../evolution/sitemodel/SiteModelInterface.java    |   22 +-
 .../speciation/BirthDeathGernhard08Model.java      |   37 +-
 .../speciation/CalibratedBirthDeathModel.java      |  217 +--
 .../speciation/CalibratedYuleInitialTree.java      |   25 +-
 .../evolution/speciation/CalibratedYuleModel.java  |  193 +-
 .../speciation/CalibrationLineagesIterator.java    |   70 +-
 .../evolution/speciation/CalibrationPoint.java     |   13 +-
 .../GeneTreeForSpeciesTreeDistribution.java        |  223 +--
 src/beast/evolution/speciation/RandomGeneTree.java |    8 +-
 .../speciation/SpeciesTreeDistribution.java        |    1 -
 .../evolution/speciation/SpeciesTreeLogger.java    |   24 +-
 .../evolution/speciation/SpeciesTreePrior.java     |   84 +-
 .../evolution/speciation/StarBeastStartState.java  |  151 +-
 src/beast/evolution/speciation/TreeTopFinder.java  |   17 +-
 src/beast/evolution/speciation/YuleModel.java      |   18 +-
 .../substitutionmodel/BinaryCovarion.java          |   63 +-
 .../evolution/substitutionmodel/Blosum62.java      |   10 +-
 src/beast/evolution/substitutionmodel/CPREV.java   |   10 +-
 src/beast/evolution/substitutionmodel/Dayhoff.java |   10 +-
 .../substitutionmodel/DefaultEigenSystem.java      |    8 +-
 .../EmpiricalSubstitutionModel.java                |   73 +-
 .../evolution/substitutionmodel/Frequencies.java   |   87 +-
 src/beast/evolution/substitutionmodel/GTR.java     |   29 +-
 .../GeneralSubstitutionModel.java                  |   50 +-
 src/beast/evolution/substitutionmodel/HKY.java     |   14 +-
 src/beast/evolution/substitutionmodel/JTT.java     |   10 +-
 .../evolution/substitutionmodel/JukesCantor.java   |   18 +-
 src/beast/evolution/substitutionmodel/MTREV.java   |   10 +-
 .../substitutionmodel/MutationDeathModel.java      |   16 +-
 src/beast/evolution/substitutionmodel/SYM.java     |   27 +-
 .../substitutionmodel/SubstitutionModel.java       |   16 +-
 src/beast/evolution/substitutionmodel/TIM.java     |   25 +-
 src/beast/evolution/substitutionmodel/TN93.java    |   14 +-
 src/beast/evolution/substitutionmodel/TVM.java     |   27 +-
 src/beast/evolution/substitutionmodel/WAG.java     |   12 +-
 src/beast/evolution/tree/CladeSet.java             |   12 +-
 src/beast/evolution/tree/Node.java                 |  173 +-
 src/beast/evolution/tree/RandomTree.java           |  265 +--
 src/beast/evolution/tree/TraitSet.java             |   88 +-
 src/beast/evolution/tree/Tree.java                 |  253 +--
 src/beast/evolution/tree/TreeDistribution.java     |    6 +-
 src/beast/evolution/tree/TreeHeightLogger.java     |   10 +-
 src/beast/evolution/tree/TreeInterface.java        |    5 +-
 src/beast/evolution/tree/TreeTraceAnalysis.java    |   23 +-
 src/beast/evolution/tree/TreeUtils.java            |   30 +-
 .../evolution/tree/TreeWithMetaDataLogger.java     |   26 +-
 .../evolution/tree/coalescent/BayesianSkyline.java |   30 +-
 .../evolution/tree/coalescent/Coalescent.java      |   10 +-
 .../coalescent/CompoundPopulationFunction.java     |   63 +-
 .../tree/coalescent/ConstantPopulation.java        |   14 +-
 .../tree/coalescent/ExponentialGrowth.java         |   19 +-
 .../evolution/tree/coalescent/IntervalType.java    |    3 +-
 .../tree/coalescent/PopulationFunction.java        |   26 +-
 .../evolution/tree/coalescent/SampleOffValues.java |   21 +-
 .../tree/coalescent/ScaledPopulationFunction.java  |   23 +-
 .../evolution/tree/coalescent/TreeIntervals.java   |   37 +-
 src/beast/math/Binomial.java                       |    2 +-
 src/beast/math/distributions/Beta.java             |   27 +-
 src/beast/math/distributions/ChiSquare.java        |   17 +-
 src/beast/math/distributions/Dirichlet.java        |   30 +-
 src/beast/math/distributions/Exponential.java      |   22 +-
 src/beast/math/distributions/Gamma.java            |   29 +-
 src/beast/math/distributions/InverseGamma.java     |   45 +-
 .../math/distributions/LaplaceDistribution.java    |   21 +-
 .../distributions/LogNormalDistributionModel.java  |   57 +-
 src/beast/math/distributions/MRCAPrior.java        |  197 +-
 .../distributions/MarkovChainDistribution.java     |   21 +-
 src/beast/math/distributions/Normal.java           |   27 +-
 .../math/distributions/ParametricDistribution.java |   35 +-
 src/beast/math/distributions/Poisson.java          |   14 +-
 src/beast/math/distributions/Prior.java            |   15 +-
 src/beast/math/distributions/Uniform.java          |    8 +-
 src/beast/math/statistic/DiscreteStatistics.java   |   12 +-
 src/beast/math/statistic/RPNcalculator.java        |   51 +-
 .../math/statistic/RPNexpressionCalculator.java    |    2 +-
 src/beast/util/AddOnManager.java                   | 1019 +++++++----
 src/beast/util/ClusterTree.java                    |  486 ++---
 src/beast/util/CollectionUtils.java                |    4 +-
 src/beast/util/CredibleSet.java                    |    2 +-
 src/beast/util/FrequencySet.java                   |   18 +-
 src/beast/util/InputType.java                      |   66 +
 src/beast/util/JSONParser.java                     | 1258 ++++++++-----
 src/beast/util/JSONParserException.java            |   48 +-
 src/beast/util/JSONProducer.java                   |  407 ++---
 src/beast/util/LogAnalyser.java                    |  340 ++--
 src/beast/util/LogComparator.java                  |   26 +-
 src/beast/util/MersenneTwisterFast.java            |   56 +-
 src/beast/util/NexusParser.java                    |  658 +++----
 src/beast/util/OutputUtils.java                    |   28 +-
 src/beast/util/Package.java                        |  238 ++-
 src/beast/util/PackageDependency.java              |   61 +-
 src/beast/util/PackageVersion.java                 |  128 ++
 src/beast/util/Randomizer.java                     |    6 +-
 src/beast/util/TreeParser.java                     |  138 +-
 src/beast/util/XMLParser.java                      |  960 ++++++----
 src/beast/util/XMLParserException.java             |   72 +-
 src/beast/util/XMLParserUtils.java                 |  252 ++-
 src/beast/util/XMLProducer.java                    |  596 +++---
 src/beast/util/treeparser/Newick.g4                |    2 +-
 src/beast/util/treeparser/NewickBaseVisitor.java   |    2 +-
 src/beast/util/treeparser/NewickLexer.java         |   48 +-
 src/beast/util/treeparser/NewickParser.java        |    2 +-
 src/beast/util/treeparser/NewickVisitor.java       |    2 +-
 .../commons/math/ConvergingAlgorithmImpl.java      |   30 +-
 .../math/MaxEvaluationsExceededException.java      |    2 -
 .../math/MaxIterationsExceededException.java       |    2 -
 .../commons/math/analysis/BinaryFunction.java      |    3 +-
 .../commons/math/analysis/ComposableFunction.java  |    6 +-
 .../analysis/integration/RombergIntegrator.java    |    6 +-
 .../analysis/integration/TrapezoidIntegrator.java  |    6 +-
 .../integration/UnivariateRealIntegratorImpl.java  |   14 +-
 .../math/analysis/solvers/BisectionSolver.java     |   12 +-
 .../commons/math/analysis/solvers/BrentSolver.java |   14 +-
 .../math/analysis/solvers/MullerSolver.java        |   12 +-
 .../math/analysis/solvers/NewtonSolver.java        |   12 +-
 .../math/analysis/solvers/RiddersSolver.java       |   12 +-
 .../math/analysis/solvers/SecantSolver.java        |   12 +-
 .../analysis/solvers/UnivariateRealSolverImpl.java |   15 +-
 .../solvers/UnivariateRealSolverUtils.java         |    2 +-
 .../AbstractContinuousDistribution.java            |   10 +-
 .../math/distribution/AbstractDistribution.java    |    3 +-
 .../distribution/AbstractIntegerDistribution.java  |   15 +-
 .../math/distribution/BetaDistribution.java        |    2 +-
 .../math/distribution/BetaDistributionImpl.java    |   24 +-
 .../distribution/BinomialDistributionImpl.java     |   15 +-
 .../math/distribution/CauchyDistributionImpl.java  |   15 +-
 .../math/distribution/ChiSquaredDistribution.java  |    2 +-
 .../distribution/ChiSquaredDistributionImpl.java   |   16 +-
 .../math/distribution/ExponentialDistribution.java |    2 +-
 .../distribution/ExponentialDistributionImpl.java  |   13 +-
 .../math/distribution/FDistributionImpl.java       |   15 +-
 .../math/distribution/GammaDistribution.java       |    2 +-
 .../math/distribution/GammaDistributionImpl.java   |   19 +-
 .../commons/math/distribution/HasDensity.java      |    1 +
 .../HypergeometricDistributionImpl.java            |   21 +-
 .../math/distribution/NormalDistribution.java      |    2 +-
 .../math/distribution/NormalDistributionImpl.java  |   19 +-
 .../math/distribution/PascalDistributionImpl.java  |   15 +-
 .../math/distribution/PoissonDistributionImpl.java |   15 +-
 .../math/distribution/TDistributionImpl.java       |   15 +-
 .../math/distribution/WeibullDistributionImpl.java |   15 +-
 .../math/distribution/ZipfDistributionImpl.java    |   15 +-
 src/org/json/CDL.java                              |  279 ---
 src/org/json/Cookie.java                           |  169 --
 src/org/json/CookieList.java                       |   90 -
 src/org/json/HTTP.java                             |  163 --
 src/org/json/HTTPTokener.java                      |   77 -
 src/org/json/JSON.java                             |  117 ++
 src/org/json/JSONArray.java                        | 1170 +++++-------
 src/org/json/JSONException.java                    |   74 +-
 src/org/json/JSONML.java                           |  467 -----
 src/org/json/JSONObject.java                       | 1922 ++++++--------------
 src/org/json/JSONString.java                       |   18 -
 src/org/json/JSONStringer.java                     |  510 +++++-
 src/org/json/JSONTokener.java                      |  849 +++++----
 src/org/json/JSONWriter.java                       |  327 ----
 src/org/json/Kim.java                              |  373 ----
 src/org/json/Property.java                         |   74 -
 src/org/json/README                                |   68 -
 src/org/json/XML.java                              |  508 ------
 src/org/json/XMLTokener.java                       |  365 ----
 src/org/json/zip/BitInputStream.java               |  169 --
 src/org/json/zip/BitOutputStream.java              |  154 --
 src/org/json/zip/BitReader.java                    |   41 -
 src/org/json/zip/BitWriter.java                    |   51 -
 src/org/json/zip/Compressor.java                   |  575 ------
 src/org/json/zip/Decompressor.java                 |  325 ----
 src/org/json/zip/Huff.java                         |  406 -----
 src/org/json/zip/JSONzip.java                      |  281 ---
 src/org/json/zip/Keep.java                         |   84 -
 src/org/json/zip/MapKeep.java                      |  160 --
 src/org/json/zip/None.java                         |   15 -
 src/org/json/zip/PostMortem.java                   |   47 -
 src/org/json/zip/README                            |    2 -
 src/org/json/zip/TrieKeep.java                     |  396 ----
 src/test/beast/BEASTTestCase.java                  |    3 +-
 src/test/beast/app/BeautiSubTemplateTest.java      |  184 +-
 src/test/beast/app/BeautiTest.java                 |   32 +-
 src/test/beast/app/beauti/BeautiBase.java          |   22 +-
 .../app/beauti/BeautiDivergenceDatingTest.java     |   43 +-
 .../beast/app/beauti/BeautiRateTutorialTest.java   |   22 +-
 src/test/beast/app/beauti/BeautiSimpleTest.java    |   16 +-
 src/test/beast/app/beauti/BeautiStarBeastTest.java |    5 +-
 src/test/beast/app/beauti/CloneTest.java           |    1 -
 src/test/beast/app/beauti/FixedMeanRateTest.java   |   24 +-
 src/test/beast/app/beauti/LinkUnlinkTest.java      |    2 +-
 src/test/beast/beast2vs1/ClockModelTest.java       |    3 +-
 src/test/beast/beast2vs1/StarBEASTTest.java        |    3 +-
 .../beast/beast2vs1/SubstitutionModelTest.java     |    3 +-
 src/test/beast/beast2vs1/TaxonOrderTest.java       |    3 +-
 src/test/beast/beast2vs1/TestFramework.java        |   26 +-
 src/test/beast/beast2vs1/TipTimeTest.java          |    3 +-
 src/test/beast/beast2vs1/TreePriorTest.java        |    3 +-
 src/test/beast/beast2vs1/TreeTest.java             |    3 +-
 .../beast/beast2vs1/trace/DiscreteStatistics.java  |   13 +-
 src/test/beast/beast2vs1/trace/Expectation.java    |   13 +-
 src/test/beast/beast2vs1/trace/LogAnalyser.java    |   25 +-
 src/test/beast/beast2vs1/trace/LogFileTraces.java  |    4 +
 .../beast/beast2vs1/trace/NumberFormatter.java     |    2 +-
 src/test/beast/beast2vs1/trace/TraceException.java |    4 +-
 .../beast/beast2vs1/trace/TraceStatistics.java     |    4 +-
 src/test/beast/beast2vs1/trace/TraceType.java      |    9 +-
 src/test/beast/beast2vs1/trace/TrimLineReader.java |    3 +-
 src/test/beast/core/BEASTInterfaceTest.java        |   36 +-
 src/test/beast/core/StateNodeInitialiserTest.java  |    5 +-
 .../core/parameter/BooleanParameterListTest.java   |   18 +-
 .../core/parameter/IntegerParameterListTest.java   |   18 +-
 src/test/beast/core/parameter/ParameterTest.java   |    2 -
 .../core/parameter/RealParameterListTest.java      |   18 +-
 .../evolution/alignment/FilteredAlignmentTest.java |   17 +-
 .../alignment/UncertainAlignmentTest.java          |    8 +-
 .../alignment/UnorderedAlignmentsTest.java         |   13 +-
 .../evolution/likelihood/TreeLikelihoodTest.java   |  159 +-
 .../evolution/operator/ExchangeOperatorTest.java   |    2 -
 .../operator/IntRandomWalkOperatorTest.java        |    4 +-
 .../operator/UniformIntegerOperatorTest.java       |    4 +-
 .../speciation/BirthDeathGernhard08ModelTest.java  |   24 +-
 src/test/beast/evolution/substmodel/GTRTest.java   |   60 +-
 src/test/beast/evolution/substmodel/HKYTest.java   |   37 +-
 src/test/beast/evolution/tree/RandomTreeTest.java  |    8 +-
 .../beast/evolution/tree/TreeAnnotatorTest.java    |   13 +-
 .../tree/coalescent/BayesianSkylineTest.java       |    2 +-
 src/test/beast/integration/DocumentationTest.java  |   63 +-
 .../beast/integration/ExampleJSONParsingTest.java  |   46 +-
 .../beast/integration/ExampleXmlParsingTest.java   |   46 +-
 src/test/beast/integration/InputTypeTest.java      |  172 +-
 src/test/beast/integration/ResumeTest.java         |    7 +-
 src/test/beast/integration/XMLElementNameTest.java |   81 +-
 src/test/beast/integration/XMLProducerTest.java    |   33 +-
 .../LogNormalDistributionModelTest.java            |    7 +-
 .../beast/math/distributions/MRCAPriorTest.java    |   35 +-
 .../MeanOfParametricDistributionTest.java          |   11 +-
 .../beast/util/AnnotatedRunnableTestClass.java     |   97 +
 src/test/beast/util/JSONTest.java                  |  109 +-
 src/test/beast/util/NexusParserTest.java           |   54 +-
 src/test/beast/util/TreeParserTest.java            |   43 +-
 src/test/beast/util/XMLTest.java                   |   43 +
 templates/Standard.xml                             |    4 +-
 templates/StarBeast.xml                            |    7 +-
 templates/TreePriors.xml                           |    2 +-
 version.xml                                        |    1 +
 455 files changed, 21656 insertions(+), 21730 deletions(-)

diff --git a/build.xml b/build.xml
index a20c428..821d599 100644
--- a/build.xml
+++ b/build.xml
@@ -89,6 +89,7 @@
         <delete file="${build}/beast/app/tools/LogCombinerLauncher.class" />
         <delete file="${build}/beast/app/treeannotator/TreeAnnotatorLauncher.class" />
         <delete file="${build}/beast/app/util/Utils6.class" />
+        <delete file="${build}/beast/app/BEASTVersion.class" />
         <javac source="1.6"
                target="1.6"
                bootclasspath='/opt/jdk1.6.0_45/jre/lib/rt.jar'
@@ -101,6 +102,7 @@
                includeAntRuntime='false'>
             <include name="beast/**/*Launcher.java" />
             <include name="beast/**/Utils6.java" />
+            <include name="beast/**/BEASTVersion.java" />
         </javac>
         <copy todir="${build}">
             <fileset dir="${src}" includes="**/*.properties" />
@@ -137,6 +139,7 @@
             <fileset dir="${build}">
                 <include name="beast/**/*Launcher.class" />
                 <include name="beast/**/Utils6*.class" />
+                <include name="beast/**/BEASTVersion.class" />
                 <include name="beast/app/draw/icons/beauti.png"/>
             </fileset>
         </jar>
@@ -149,7 +152,23 @@
                 <include name="beast/**/*.xsl" />
             </fileset>
         </jar>
-    </target>
+
+        <!-- create BEAST package -->
+        <mkdir dir="${release_dir}/package/" />
+        <mkdir dir="${release_dir}/package/lib" />
+        <copy file="${dist}/beast.src.jar" todir="${release_dir}/package/"/>
+        <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">
+            <fileset dir="${release_dir}/package">
+                <include name="version.xml" />
+                <include name="lib/beast.jar" />
+                <include name="beast.src.jar" />
+            </fileset>
+        </jar>
+
+</target>
 
     <!-- run beast.jar -->
     <target name="run_BEAST">
@@ -215,8 +234,8 @@
 
 
     <!-- Release -->
-    <property name="version" value="2.3.2" />
-    <property name="version_number" value="2.3.2" />
+    <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" />
 
diff --git a/doc/tutorials/EBSP/Makefile b/doc/tutorials/EBSP/Makefile
new file mode 100644
index 0000000..bc44fab
--- /dev/null
+++ b/doc/tutorials/EBSP/Makefile
@@ -0,0 +1,16 @@
+all: ebsp2-tut
+
+ebsp2-tut: ebsp2-tut.pdf
+	mkdir ebsp2-tut
+	cp -R ebsp2-tut.pdf scripts mystery-mammal ebsp2-tut
+	zip -r ebsp2-tut.zip ebsp2-tut
+	rm -rf ebsp2-tut
+
+ebsp2-tut.pdf: ebsp2-tut.tex
+	pdflatex ebsp2-tut
+	bibtex ebsp2-tut
+	pdflatex ebsp2-tut
+	pdflatex ebsp2-tut
+
+clean:
+	rm -f ebsp2-tut.aux ebsp2-tut.bbl ebsp2-tut.blg ebsp2-tut.log ebsp2-tut.pdf ebsp2-tut.zip
diff --git a/doc/tutorials/EBSP/ebsp2-tut.bib b/doc/tutorials/EBSP/ebsp2-tut.bib
new file mode 100644
index 0000000..10824d6
--- /dev/null
+++ b/doc/tutorials/EBSP/ebsp2-tut.bib
@@ -0,0 +1,51 @@
+% This file was created with JabRef 2.10.
+% Encoding: ISO8859_1
+
+
+ at Article{Bouckaert2014,
+  Title                    = {{BEAST 2}: a software platform for {B}ayesian evolutionary analysis.},
+  Author                   = {Bouckaert, Remco and Heled, Joseph and K{\"{u}}hnert, Denise and Vaughan, Tim and Wu, Chieh-Hsi and Xie, Dong and Suchard, Marc A. and Rambaut, Andrew and Drummond, Alexei J.},
+  Journal                  = {PLoS Comput Biol},
+  Year                     = {2014},
+
+  Month                    = {Apr},
+  Number                   = {4},
+  Pages                    = {e1003537},
+  Volume                   = {10},
+
+  Abstract                 = {We present a new open source, extensible and flexible software platform for Bayesian evolutionary analysis called BEAST 2. This software platform is a re-design of the popular BEAST 1 platform to correct structural deficiencies that became evident as the BEAST 1 software evolved. Key among those deficiencies was the lack of post-deployment extensibility. BEAST 2 now has a fully developed package management system that allows third party developers to write a [...]
+  Doi                      = {10.1371/journal.pcbi.1003537},
+  Institution              = {Computational Evolution Group, Department of Computer Science, University of Auckland, Auckland, New Zealand; Allan Wilson Centre for Molecular Ecology and Evolution, University of Auckland, Auckland, New Zealand.},
+  Keywords                 = {Bayes Theorem; Biological Evolution; Programming Languages; Software},
+  Language                 = {eng},
+  Medline-pst              = {epublish},
+  Owner                    = {tvaughan},
+  Pii                      = {PCOMPBIOL-D-13-02115},
+  Pmid                     = {24722319},
+  Timestamp                = {2015.05.07},
+  Url                      = {http://dx.doi.org/10.1371/journal.pcbi.1003537}
+}
+
+ at Article{Heled2008,
+  Title                    = {Bayesian inference of population size history from multiple loci.},
+  Author                   = {Heled, Joseph and Drummond, Alexei J.},
+  Journal                  = {BMC Evol Biol},
+  Year                     = {2008},
+  Pages                    = {289},
+  Volume                   = {8},
+
+  __markedentry            = {[tim:]},
+  Abstract                 = {Effective population size (Ne) is related to genetic variability and is a basic parameter in many models of population genetics. A number of methods for inferring current and past population sizes from genetic data have been developed since JFC Kingman introduced the n-coalescent in 1982. Here we present the Extended Bayesian Skyline Plot, a non-parametric Bayesian Markov chain Monte Carlo algorithm that extends a previous coalescent-based method in several  [...]
+  Doi                      = {10.1186/1471-2148-8-289},
+  File                     = {:2008_Heled_Drummond.pdf:PDF},
+  Institution              = {Department of Computer Science, University of Auckland, Auckland, New Zealand. jheled at gmail.com},
+  Keywords                 = {Algorithms; Animals; Bayes Theorem; Drosophila, genetics; Hepacivirus, genetics; Models, Genetic; Models, Statistical},
+  Language                 = {eng},
+  Medline-pst              = {epublish},
+  Owner                    = {tim},
+  Pii                      = {1471-2148-8-289},
+  Pmid                     = {18947398},
+  Timestamp                = {2016.01.11},
+  Url                      = {http://dx.doi.org/10.1186/1471-2148-8-289}
+}
+
diff --git a/doc/tutorials/EBSP/ebsp2-tut.tex b/doc/tutorials/EBSP/ebsp2-tut.tex
new file mode 100644
index 0000000..361f95a
--- /dev/null
+++ b/doc/tutorials/EBSP/ebsp2-tut.tex
@@ -0,0 +1,376 @@
+\documentclass[a4paper,11pt]{article}
+
+\usepackage{graphicx}
+\usepackage{natbib}
+
+\title{Extended Bayesian Skyline Plot tutorial\\for BEAST 2}
+
+\author{Joseph Heled\\(updated for BEAST 2 by Tim Vaughan)}
+\date{}
+
+\setlength{\parindent}{0em}
+\setlength{\parskip}{1em}
+
+\begin{document}
+
+\maketitle
+
+This short practical explains how to set up an Extended Bayesian Skyline Plot
+(EBSP) analysis in BEAST 2 \citep{Bouckaert2014}, and how to generate some EBSP
+plots.
+
+To make the most of this tutorial you should follow the steps described here on
+your system. Reading the article \citep{Heled2008} first is not a bad idea
+either. Use your own data if you are comfortable with BEAST, otherwise use the
+provided examples.  The next section uses the data in the `mystery-mammal'
+directory, three genes from a small mammal: one nuclear, one mitochondrial, and
+one from the X chromosome.
+
+This tutorial is based on BEAST version 2.3.2. Before proceeding any further,
+visit \texttt{www.beast2.org} and ensure you are running the latest version.
+
+My sincere apologies for any harm done by the figures to your aesthetic
+sensibilities. Nobody, the Java team included, cares much for my preferred
+platform, Linux.
+
+\section{Setting up the analysis}
+
+\subsection{Loading the data}
+
+The EBSP is a multi-locus method, so the step first involves loading all
+loci/genes into BEAUti. The simplest way to do so is to prepare one NEXUS file
+for each alignment. Taxa names in each alignment have to be unique, but
+duplicates across alignments are fine.
+
+Start BEAUti, open the File menu and select `Import Alignment`.  Navigate to
+the data directory, select all the files you wish included in the analysis and
+click `Open' (Figure~\ref{fig:importAlignment}).
+
+\begin{figure}[h!]
+    \centering
+    \hspace{-0.5cm}\begin{minipage}[b]{0.4\textwidth}
+        \begin{center}
+            \includegraphics[width=\textwidth]{figures/import_alignment.png}
+            (a)
+        \end{center}
+    \end{minipage}\hspace{0.5cm}\begin{minipage}[b]{0.6\textwidth}
+        \begin{center}
+            \includegraphics[width=\textwidth]{figures/import_alignment2.png}
+            (b)
+        \end{center}
+    \end{minipage}
+    \caption{Loading multiple alignments into BEAUti.}
+\label{fig:importAlignment}
+\end{figure}
+
+\subsection{Site model}
+
+Open the \textsc{Site Model} pane. Here we choose, for every gene, the
+evolutionary models specifying how characters evolve at each site (one aligned
+position). Do not automatically choose the most general models possible (GTR,
+Gamma + Invariant Sites, Partitioned Codon positions etc.). Please remember
+that the more general models have more parameters, and this may result in
+longer runs and slower mixing. This is the time to display your superior
+knowledge of the data! Sometimes performing an exploratory run(s) on a single
+loci can help, especially when the simpler model is a special case of a general
+one. Sometimes the simpler model is represented by particular parameter values,
+and checking if the credible interval(s) contain those specific values can be a
+factor in the decision.
+
+In this particular case we'll use the HKY substitution model, but will change
+the `Frequencies' to Empirical, as shown in the following figure:
+
+    \includegraphics[width=\textwidth]{figures/site_model.png}
+
+Repeat for each loci. Please note that I know absolutely nothing about
+this particular data, and it is entirely possible using the GTR or partitioning
+is the better choice.
+
+\subsection{Clock model}
+
+Now move to the \textsc{Clock Model} pane. Here you choose the molecular clock
+model for each gene. The same considerations as in the site model apply: stay
+with the strict clock unless you know otherwise.
+
+You may have noticed that exactly two of the three genes are marked as
+`Estimate'. In general we can't infer the absolute rate from contemporaneous
+data (all samples collected at the same time), but we can infer relative rates.
+The unmarked loci is the reference rate, which is by default set to one. Other
+rates will be relative to the reference: a rate of 2 (with the reference being
+1) means `evolving twice as fast as the reference'.
+
+In general it is best to pick the most stable reference. Here this would be the
+mtDNA, since it evolves faster, and so the sequences in that loci will be more
+divergent and contain more information. Ensure that the rate of `mt.nex' is
+unchecked and the other two are checked. To do this, you'll first need to open
+the `Mode' menu and deselect `Automatic set clock rate', as shown below:
+
+\includegraphics[width=\textwidth]{figures/clock_model.png}
+
+Then, select each of the loci names in turn from the list on the left hand side
+of the screen, making sure that `estimate' is checked for X and nuclear but
+unchecked for mt, as shown in figures below:
+
+\begin{center}
+    \includegraphics[width=0.8\textwidth]{figures/clock_model2.png}
+\end{center}
+
+\begin{center}
+\includegraphics[width=0.8\textwidth]{figures/clock_model3.png}
+\end{center}
+
+\begin{center}
+\includegraphics[width=0.8\textwidth]{figures/clock_model4.png}
+\end{center}
+
+The units of the time axis for the trees and population size is the same as the
+reference rate. When it equals 1, time is measured in substitutions. When we
+have an estimate of the reference, it may be more convenient to plug it in and
+have time in years. Since this is a mammal, I will arbitrarily pick a rate of
+0.05 per million years. Double-Click on the 1.0 rate for the mt locus and enter
+0.05 – and times from the analysis will be in millions of years.
+
+To make a smoother start you should change the other starting rates – say to
+0.005.  Note that we set the reference rate to a known fixed value, but that
+can be relaxed too. It is possible to let the rate vary (by checking it's
+`Estimate' box as well), and place a prior on the rate parameter in the priors
+section (which is clockRate.c:mt in this specific case). You have to realize
+that the rate will not be estimated---there is no data here to make that
+possible---it will simply follow the prior. But the uncertainty regarding the
+exact value will be reflected in all other estimates.
+
+\subsection{Priors}
+
+Now, switch to the \textsc{Priors} pane. The first thing we need to do here is
+set the prior for each of the gene trees to `Coalescent Extended Bayesian
+Skyline`.  Do this by selecting this option from the drop-down menu to the
+right of `Tree.t:X', `Tree.t:mt' and `Tree.t:nuclear', as shown below:
+
+\includegraphics[width=\textwidth]{figures/tree_prior.png}
+
+Once this is complete, click the arrow to the left of Tree.t:X, then click the
+pencil icon to the right of the `PopulationModel' text that appears. As shown
+in the following figure, this will bring up a dialog containing a text
+field that allows you to edit the scale factor for the population size applied
+to this particular gene tree:
+
+\includegraphics[width=\textwidth]{figures/ploidy.png}
+
+This allows us to account for the ploidy of each locus. Since this gene is on
+the X chromosome, we apply a scale factor of 1.5 as each member of the
+population has 1.5 copies of this gene on average.
+
+Perform these same steps to set the scale factors for the mtDNA and nuclear
+genes to 0.5 and 2 respectively. (We use 0.5 for mtDNA because only the female
+mtDNA contributes to the effective population size.)
+
+Next, we replace the improper uniform priors on the two estimated clock rates
+with proper uniform priors by setting a finite upper bound of 1.0 for each.  Do
+this by clicking the arrows to the left of clockRate.c:X and
+clockRate.c:nuclear and replacing `infinity' with 1.0, as shown in
+the following figure:
+
+\includegraphics[width=\textwidth]{figures/clockrate_prior.png}
+
+This should be well above any likely value for the
+clock rates, but improves mixing by preventing the inference algorithm from
+exploring implausible values.
+
+Finally, we modify the hyper-prior on the mean of the population size
+distribution. By default this an improper $1/x$ prior which is in general a
+sensible option. Unfortunately though, this can lead to poor mixing and
+necessitate runs much longer than we have time for in a tutorial such as this.
+Thus, to improve the rate of convergence, we replace this with a tight Gaussian
+prior centred on 1.0 with a standard deviation of 0.1. Set this by selecting
+`Normal' from the drop-down menu next to populationMean.alltrees and adjusting
+the parameter values as shown in the following figure:
+
+\includegraphics[width=\textwidth]{figures/popmean.png}
+
+\subsection{Operator weights}
+
+The MCMC algorithm used by BEAST explores the state space defined by the set of
+objects (including the parameters and trees) to be inferred by applying
+stochastic functions called `operators' to modify these objects. How frequently
+each operator is used is defined by its `weight'. While almost any combination of (non-zero) weights will produce the same result in the end, the efficiency with which the algorithm produces effectively independent samples from the posterior can be dramatically influenced by specific choices.
+
+To view the list of operators BEAST will use for this analysis and their
+weights, select `Show operators panel' from the View menu:
+
+\includegraphics[width=\textwidth]{figures/view_operators.png}
+
+The first change we make is to increase the weights of the operators affecting
+the $\kappa$ parameter from theHKY substitution models from 0.1 to 3, as shown
+by the three red arrows at the top of the following figure:
+
+\includegraphics[width=\textwidth]{figures/operators.png}
+
+Secondly, looking at the operators that modify each tree we see that the sum of
+their weights is about 70. The sum of the default weights for the operators
+affecting the population function is roughly the same at 60. Given that there
+are 3 gene trees, modifications to the trees will be proposed about 3 times
+more frequently than modifications to the population function.  We therefore
+increase the existing population function operator weights by a factor of 3 to
+even this out a bit.  To do this, modify the weights shown by the bottom three
+red arrows in the previous figure.
+
+\subsection{MCMC settings}
+
+Finally, open the \textsc{MCMC} pane. Click the arrow to the left of `tracelog'
+and change the output file name to `mystery.log', as shown in the figure below.
+Similarly, click the arrow to the left of `EBSPLogger' and ensure the EBSP
+output file name is `EBSP.log'.
+
+    \includegraphics[width=\textwidth]{figures/mcmc_panel.png}
+
+For this tutorial we will retain the default chain length of $10^7$ steps, but
+you should note that this is almost certainly too short for a real analysis.
+
+
+Once the output file names are set, create a new directory in the tutorial
+folder named `mystery-run' using whatever method is appropriate under your
+operating system.  Then open the BEAUti File menu and select Save, to save the
+BEAST XML file representing the analysis in this new directory, using the file
+name `mystery.xml'.
+
+\section{Running, Inspecting and Plotting}
+
+Run the chain using BEAST.\@ This takes around 5 minutes on a computer with an
+Intel i5 processor, but your mileage may vary. This will generate a number of
+output files that are analyzed in the following sections.
+
+\subsection{Tracer inspection}
+
+Start up Tracer and load the `mystery.log' file generated by the analysis.  I
+suggest you browse a little on your own before reading further.
+
+You probably looked at the posterior ESS (Effective Sample Size) first.
+Selecting this and viewing its trace should reveal something similar to what is
+shown below:
+
+\includegraphics[width=\textwidth]{figures/tracer1.png}
+
+The calculated value is 102, but from a visual inspection of the trace it looks
+as though the true number of effectively independent samples may be even lower.
+This is fine, as we knew a chain of 10 million would be too short.
+
+The next stop for an EBSP analysis is to look at the number of population
+changes. To do this, scroll to the very bottom of the table on the left-hand
+side of the screen and select `sum(indicators.alltrees)'.  You should see
+something similar to the following:
+
+\includegraphics[width=\textwidth]{figures/tracer2.png}
+
+This indicates that we can confidently reject a constant population since the
+95\% HPD excludes 0.
+
+Lastly, you should see that the nuclear and X clock rates come out to
+approximately $8\times 10^{-3}$ and $2\times 10^{-3}$, respectively, which seem
+reasonable.  The kappa values look fine, although there value for X has a very
+wide credible interval indicating perhaps that there were too few substitutions
+to enable a good estimate.
+
+\subsection{Plotting}
+
+The EBSP analysis generated a log file named `EBSP.log'.  (Remember that we set
+this filename in a previous step.)  This can be used in conjunction with the
+EBSPAnalyzer tool to produce a file that can be loaded into R or some other
+plotting package for visualizing the demographic history posterior.
+
+In this tutorial however, we will use an R script to produce the visualizations
+directly. To do this, launch R from the `mystery-run' folder containing the
+BEAST output files. (If you are using RStudio or some other graphical front-end
+to R, you'll probably find a menu option to set the current working directory.)
+Then execute the following from the R command line:
+\begin{verbatim}
+    >source("../scripts/plotEBSP.R")
+    >plotEBSP("EBSP.log", useHPD=FALSE, log="y")
+\end{verbatim}
+
+The first line loads the functions defined in the R script (which is located in
+the `scripts' directory in the tutorial folder). The second produces a visual
+representation of the EBSP posterior samples contained in the file `EBSP.log`.
+The `useHPD=FALSE' option causes plotEBSP to display 95\% Central Posterior
+Density (CPD) intervals instead of HPD intervals, while the `log="y"' option
+causes the y axis to be displayed using a log scale.  A figure similar to the
+following will be produced:\\
+\includegraphics[width=\textwidth]{figures/mystery1.pdf}
+
+The function accepts all of the standard R plot options allowing us to, for
+instance, alter the bounds of the plot or change the axis labels or add a title
+and thus is quite capable of producing publication-quality output.  For
+instance, to generate a close-up with a linear vertical scale we can use
+\begin{verbatim}
+    >plotEBSP("EBSP.log", useHPD=FALSE, xlim=c(0, 0.03))
+\end{verbatim}
+which produces\\
+\includegraphics[width=\textwidth]{figures/mystery2.pdf}
+
+This displays a ten-fold increase over the past 20000 years (remember our times
+are in Myears). If we assume a generation time of 1 year we get a current
+effective population size of around 1 million\footnote{If generation time was
+    10 years, 1M years would be $10^5$ generations and so an $N_e$ of 1 would
+    be $10^5$ individuals}. This is a very large number, but remember this is
+for illustration purposes only. The actual numbers depend on choice of mutation
+rate and generation time. Ignoring this objection, let us explore the result a
+little more.
+
+First note the wide credible intervals. Three genes will rarely give tight
+bounds when dealing with population sizes. The need for more genes when
+estimating effective population size can not be overemphasized. Especially when
+considering that I used only 32 sequences out of a about 128. For the purpose
+of this analysis the effort in sequencing this large number is wasted:
+sequencing more genes, if possible, would greatly improve the results.
+
+Secondly, recall that the EBSP prior allows the population (or rather its
+slope in the case of the linear variety) to change only at points which
+correspond to events on one of the gene trees.  Because these points are
+generated by something akin to a coalescent process, they are not at all evenly
+distributed through time.  To get an idea of their distribution, we can use
+another function which is provided by the plotEBSP.R script:
+\begin{verbatim}
+    >plotEBSPTimesHist("EBSP.log")
+\end{verbatim}
+which produces the following figure:
+
+\includegraphics[width=\textwidth]{figures/mysteryTimesHist.pdf}
+
+The spike in the histogram at time 0 is caused by the populations always having
+a ``change'' point at this time.
+
+Note the horizontal axis extends only to 0.12, in contrast with the original
+skyline figure where it extended to over 0.4.  The histogram is constructed to
+include 95\% of the tree event times. This figure therefore implies that there
+are almost no events informing the population dynamics beyond a time of 0.1.
+Thus, the apparently constant population size beyond this time is due almost
+exclusively to the prior rather than the data.  One possible explanation is
+that those mammals experienced a bottleneck at this point, perhaps severe
+enough so that no amount of genes will let us see beyond it.
+
+Finally, lets consider the first skyline figure. The grey area represents an
+interval which includes 95\% of all population histories in the sampled
+posterior.  It can be useful to look more closely at this distribution, as this
+approach to summarizing the posterior can sometimes be misleading.  The
+following command replaces the uniform grey shading with faint renderings of
+individual population trajectories:
+
+\begin{verbatim}
+    >plotEBSP("EBSP.log", useHPD=FALSE, plotPopFunctions=TRUE, log="y")
+\end{verbatim}
+
+Note that the transparency of the population function lines can be adjusted
+using the `popFunctionAlpha' parameter.
+
+This produces the following figure, which is a full view of the posterior --
+all of the samples that are summarized by the median and credible interval
+lines.
+
+\includegraphics[width=\textwidth]{figures/mystery3.pdf}
+
+In this case, the figure confirms that the 95\% confidence intervals are a good
+representation of the actual sampled population function distribution.
+
+\bibliography{ebsp2-tut}
+\bibliographystyle{plainnat}
+
+\end{document}
diff --git a/doc/tutorials/EBSP/figures/clock_model.png b/doc/tutorials/EBSP/figures/clock_model.png
new file mode 100644
index 0000000..8839cda
Binary files /dev/null and b/doc/tutorials/EBSP/figures/clock_model.png differ
diff --git a/doc/tutorials/EBSP/figures/clock_model2.png b/doc/tutorials/EBSP/figures/clock_model2.png
new file mode 100644
index 0000000..e666821
Binary files /dev/null and b/doc/tutorials/EBSP/figures/clock_model2.png differ
diff --git a/doc/tutorials/EBSP/figures/clock_model3.png b/doc/tutorials/EBSP/figures/clock_model3.png
new file mode 100644
index 0000000..97dd770
Binary files /dev/null and b/doc/tutorials/EBSP/figures/clock_model3.png differ
diff --git a/doc/tutorials/EBSP/figures/clock_model4.png b/doc/tutorials/EBSP/figures/clock_model4.png
new file mode 100644
index 0000000..270b142
Binary files /dev/null and b/doc/tutorials/EBSP/figures/clock_model4.png differ
diff --git a/doc/tutorials/EBSP/figures/clockrate_prior.png b/doc/tutorials/EBSP/figures/clockrate_prior.png
new file mode 100644
index 0000000..a624ab0
Binary files /dev/null and b/doc/tutorials/EBSP/figures/clockrate_prior.png differ
diff --git a/doc/tutorials/EBSP/figures/import_alignment.png b/doc/tutorials/EBSP/figures/import_alignment.png
new file mode 100644
index 0000000..82041b9
Binary files /dev/null and b/doc/tutorials/EBSP/figures/import_alignment.png differ
diff --git a/doc/tutorials/EBSP/figures/import_alignment2.png b/doc/tutorials/EBSP/figures/import_alignment2.png
new file mode 100644
index 0000000..46964cf
Binary files /dev/null and b/doc/tutorials/EBSP/figures/import_alignment2.png differ
diff --git a/doc/tutorials/EBSP/figures/mcmc_panel.png b/doc/tutorials/EBSP/figures/mcmc_panel.png
new file mode 100644
index 0000000..2498678
Binary files /dev/null and b/doc/tutorials/EBSP/figures/mcmc_panel.png differ
diff --git a/doc/tutorials/EBSP/figures/mystery1.pdf b/doc/tutorials/EBSP/figures/mystery1.pdf
new file mode 100644
index 0000000..44c036a
Binary files /dev/null and b/doc/tutorials/EBSP/figures/mystery1.pdf differ
diff --git a/doc/tutorials/EBSP/figures/mystery2.pdf b/doc/tutorials/EBSP/figures/mystery2.pdf
new file mode 100644
index 0000000..3559497
Binary files /dev/null and b/doc/tutorials/EBSP/figures/mystery2.pdf differ
diff --git a/doc/tutorials/EBSP/figures/mystery3.pdf b/doc/tutorials/EBSP/figures/mystery3.pdf
new file mode 100644
index 0000000..df7f26d
Binary files /dev/null and b/doc/tutorials/EBSP/figures/mystery3.pdf differ
diff --git a/doc/tutorials/EBSP/figures/mysteryTimesHist.pdf b/doc/tutorials/EBSP/figures/mysteryTimesHist.pdf
new file mode 100644
index 0000000..3674998
Binary files /dev/null and b/doc/tutorials/EBSP/figures/mysteryTimesHist.pdf differ
diff --git a/doc/tutorials/EBSP/figures/operators.png b/doc/tutorials/EBSP/figures/operators.png
new file mode 100644
index 0000000..96676aa
Binary files /dev/null and b/doc/tutorials/EBSP/figures/operators.png differ
diff --git a/doc/tutorials/EBSP/figures/ploidy.png b/doc/tutorials/EBSP/figures/ploidy.png
new file mode 100644
index 0000000..a536ee1
Binary files /dev/null and b/doc/tutorials/EBSP/figures/ploidy.png differ
diff --git a/doc/tutorials/EBSP/figures/popmean.png b/doc/tutorials/EBSP/figures/popmean.png
new file mode 100644
index 0000000..4eabb26
Binary files /dev/null and b/doc/tutorials/EBSP/figures/popmean.png differ
diff --git a/doc/tutorials/EBSP/figures/site_model.png b/doc/tutorials/EBSP/figures/site_model.png
new file mode 100644
index 0000000..fe2c037
Binary files /dev/null and b/doc/tutorials/EBSP/figures/site_model.png differ
diff --git a/doc/tutorials/EBSP/figures/tracer1.png b/doc/tutorials/EBSP/figures/tracer1.png
new file mode 100644
index 0000000..5ef9b2b
Binary files /dev/null and b/doc/tutorials/EBSP/figures/tracer1.png differ
diff --git a/doc/tutorials/EBSP/figures/tracer2.png b/doc/tutorials/EBSP/figures/tracer2.png
new file mode 100644
index 0000000..74e6fdb
Binary files /dev/null and b/doc/tutorials/EBSP/figures/tracer2.png differ
diff --git a/doc/tutorials/EBSP/figures/tree_prior.png b/doc/tutorials/EBSP/figures/tree_prior.png
new file mode 100644
index 0000000..506e999
Binary files /dev/null and b/doc/tutorials/EBSP/figures/tree_prior.png differ
diff --git a/doc/tutorials/EBSP/figures/view_operators.png b/doc/tutorials/EBSP/figures/view_operators.png
new file mode 100644
index 0000000..16d90bc
Binary files /dev/null and b/doc/tutorials/EBSP/figures/view_operators.png differ
diff --git a/doc/tutorials/EBSP/mystery-mammal/X.nex.nex b/doc/tutorials/EBSP/mystery-mammal/X.nex.nex
new file mode 100644
index 0000000..39703f2
--- /dev/null
+++ b/doc/tutorials/EBSP/mystery-mammal/X.nex.nex
@@ -0,0 +1,40 @@
+#NEXUS
+
+Begin data;
+	Dimensions ntax=32 nchar=1037;
+	Format datatype=dna gap=-;
+	Matrix
+taxa_4 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATGGT [...]
+taxa_258 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_109 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_332 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_155 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGAATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_235 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_286 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_8 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATGGT [...]
+taxa_2 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATGGT [...]
+taxa_290 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_198 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGAATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_116 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_243 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_174 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_46 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATGG [...]
+taxa_236 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_66 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATGG [...]
+taxa_288 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_317 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_18 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATGG [...]
+taxa_200 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_245 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_22 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATGG [...]
+taxa_285 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_82 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATGG [...]
+taxa_34 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATGG [...]
+taxa_148 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_278 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_165 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_5 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATGGT [...]
+taxa_264 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+taxa_319 	GGACAGCCCCTAAACTTCCTTGTTAGGGCTGTCCTGGCCTGGAATGCTCCAGCACGTACCCGTACCCCCACCCCCCACTTTGCAGGAAGTAGTTCCTCCTGAAGAAAGAGCCCTGGACTCAGATCCGGCTCTCAGTTATCGTCACTAACCACCCATGGGATCTTGGGCAAATCTTTCCCCACCTCTGGGCCTCTGTTTCCTCATCCATGGCATGAGGGAGTCAACCAAGAGGATCACTAAAGGCCCTTCCAGCTGCTTGGGATGGAGGGCTTCCTGGGGGCACACCCATAAGGCAGTGAGAACGTGAGAGTGGCCTCAAACTCCAGACACCTCTCTTCCCAACCAGAGGCTGGAACCGGATCATTGTGGAAAAGCCCTTCGGGAAGGACCTACAGAGCTCCGACAAGCTGTCCAACCACATCTCTTCGCTTTTCCATGAGGACCAAATCTACCGGATTGATCACTACCTGGGCAAGGAGATG [...]
+	;
+End;
diff --git a/doc/tutorials/EBSP/mystery-mammal/mt.nex.nex b/doc/tutorials/EBSP/mystery-mammal/mt.nex.nex
new file mode 100644
index 0000000..8907457
--- /dev/null
+++ b/doc/tutorials/EBSP/mystery-mammal/mt.nex.nex
@@ -0,0 +1,40 @@
+#NEXUS
+
+Begin data;
+	Dimensions ntax=32 nchar=600;
+	Format datatype=dna gap=-;
+	Matrix
+taxa_13 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATTC [...]
+taxa_320 	CTGCCAACACCATCCAACATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAGATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTCATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTTGCATT [...]
+taxa_182 	CTGCCAACACCATCCAACATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_318 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_144 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_223 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCTTAACCCGATTTTTCGCATT [...]
+taxa_63 	CTGCCAACACCATCCAACATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTCATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATTC [...]
+taxa_324 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAGTATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_161 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATATCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_59 	CTGCCAACACCATCCAACATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAGATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTCATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACTCGATTTTTTGCATTC [...]
+taxa_313 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAACTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_35 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAAACGGATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATTC [...]
+taxa_111 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATGTGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_145 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_178 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATATCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_24 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATCCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATTC [...]
+taxa_184 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_176 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATATCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_56 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATTC [...]
+taxa_284 	CTGCCAACACCATCCAACATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGGATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_16 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATTC [...]
+taxa_270 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_60 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAACTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATTC [...]
+taxa_170 	CTGCCAACACCATCCAACATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_38 	CTGCCAACACCATCCAACATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAGATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTCATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACTCGATTTTTTGCATTC [...]
+taxa_300 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCgTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_295 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_86 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATTC [...]
+taxa_110 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCggtTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCaTGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTacTACGGATCATATCTTTACaAAGAAaCaTGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTtGAGGCGCAACAgTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCtCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_291 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+taxa_267 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCggtTCACTATTAGGAATATGCCTAATCATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATAtTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAgTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAaCCCGATTTTTCGCATT [...]
+taxa_167 	CTGCCAACACCATCCAATATCTCAGCTTGATGGAATTTCGGTTCACTATTAGGAATATGCCTAATTATCCAAATCCTAACAGGCTTATTCTTAGCAATACATTACACATCAGACACACTAACCGCATTCTCATCAGTAGCCCATATTTGCCGAGATGTAAACTACGGATGACTTATCCGAAATATTCATGCCAACGGAGCATCTATATTCTTTATATGCCTTTTCCTCCATGTAGGACGAGGAATCTACTACGGATCATATCTTTACAAAGAAACATGAAACATTGGAGTTATTCTACTATTAACAGTTATAGCCACTGCATTCGTGGGCTACGTACTACCTTGAGGACAAATATCATTTTGAGGCGCAACAGTTATTACTAACCTATTATCTGCTATCCCCTATATCGGAAATACATTAGTAGAATGAATTTGAGGAGGATTCTCCGTTGACAAAGCCACCCTAACCCGATTTTTCGCATT [...]
+	;
+End;
diff --git a/doc/tutorials/EBSP/mystery-mammal/nuclear.nex.nex b/doc/tutorials/EBSP/mystery-mammal/nuclear.nex.nex
new file mode 100644
index 0000000..b9fd688
--- /dev/null
+++ b/doc/tutorials/EBSP/mystery-mammal/nuclear.nex.nex
@@ -0,0 +1,40 @@
+#NEXUS
+
+Begin data;
+	Dimensions ntax=32 nchar=537;
+	Format datatype=dna gap=-;
+	Matrix
+taxa_135 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_247 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_292 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_26 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGA [...]
+taxa_102 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATCAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_143 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATCAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_329 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_10 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGA [...]
+taxa_298 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_69 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATCAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGA [...]
+taxa_54 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGA [...]
+taxa_191 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_49 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGA [...]
+taxa_157 	??????ACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_265 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_210 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_21 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGA [...]
+taxa_7 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGAT [...]
+taxa_311 	?????????????????????????????????????????????????????????????TGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATCAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_159 	?????????????????????????????????????????????????????????????TGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_234 	?????????????????????????????????????????????????????????????TGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_90 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGA [...]
+taxa_197 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_244 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATCAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_50 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGA [...]
+taxa_101 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATCAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_279 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_113 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_42 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATCAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGA [...]
+taxa_294 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCACAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAAATAAAATAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGG [...]
+taxa_79 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGA [...]
+taxa_12 	CTGTTTACTCAAATCTGAAGTTACCCTGAAAAAAGAAATATTAGGAGTTAATAATAATATATGAGTTCTATCAATGACACATATTAAATAGAAATCATAGGGGCAGCTGGGTAGCTTAGTGGATGAGAACCAGGCTTAGAGAAGGGAAGTCCTAGGTTCAAATGTGACCTCAGACACTTCCCAGCTGTGTGACCCTGGACAAGTCACTTGATCTCCATTGCCTACCCTTACCACTCTTCTGCCTTGGAGCCAATACACAGTATTGATTTCCAGACGGAAGGTAAGGGTTTAAAAAAAAAA-CTAACTAAATTAAATAAATAAATAGAAATCATAGGGAAGAAGGAAAATTCTGTGTTCATTTACAGAACTATTTAGGTTATGGGAAAACTGAATGCAAGAATGGGATTATCGGAGAGACCAGAATGGTTCATTCATTATGGGAATACCTTCTTGAAGTATCAGAAACCTACGCTTCCGAAGGA [...]
+	;
+End;
diff --git a/doc/tutorials/EBSP/scripts/plotEBSP.R b/doc/tutorials/EBSP/scripts/plotEBSP.R
new file mode 100644
index 0000000..4545c25
--- /dev/null
+++ b/doc/tutorials/EBSP/scripts/plotEBSP.R
@@ -0,0 +1,224 @@
+getPopSize <- function(t, changeTimes, changePops, isLinear) {
+
+    i <- findInterval(t, changeTimes)
+
+    if (isLinear) {
+        if (i>=length(changeTimes))
+            return (changePops[length(changePops)])
+
+        if (i<1)
+            return (changePops[1])
+
+        return (changePops[i] + (t-changeTimes[i])/(changeTimes[i+1]-changeTimes[i])*(changePops[i+1]-changePops[i]))
+    } else {
+        return (changePops[min(length(changePops), max(0, i))])
+    }
+}
+
+# Adds a population function to an existing plot
+plotPopFunction <- function(changeTimes, changePops, isLinear, maxTime=NA, ...) {
+    if (isLinear) {
+        lines(changeTimes, changePops, ...)
+    } else {
+        lines(changeTimes, changePops, 's', ...)
+    }
+
+    if (!is.na(maxTime) && maxTime>changeTimes[length(changeTimes)])
+        lines(c(changeTimes[length(changeTimes)], maxTime), rep(changePops[length(changePops)],2), ...)
+}
+
+# This is an approximation that assumes HPD is a single interval
+computeHPD <- function(x, alpha=0.95, sorted=FALSE) {
+    if (sorted)
+        y <- x
+    else
+        y <- sort(x)
+
+    n <- length(y)
+    m <- round(alpha*n)
+
+    i <- 1
+    delta <- y[n] - y[1]
+    lower <- y[1]
+    upper <- y[n]
+
+    while (i+m <= n) {
+        thisDelta <- y[i+m] - y[i]
+        if (thisDelta < delta) {
+            delta <- thisDelta
+            lower <- y[i]
+            upper <- y[i+m]
+        }
+
+        i <- i + 1
+    }
+
+    res <- list()
+    res$lower <- lower
+    res$upper <- upper
+
+    return(res)
+}
+
+# Compute all relevant statistics from EBSP data.
+processEBSPdata <- function(df, isLinear) {
+
+    frameLen <- dim(df)[1]
+    nTimes <- dim(df)[2] - 2
+
+    allTimes <- rep(0, nTimes)
+
+    changeTimes <- list()
+    changePops <- list()
+
+    Nmedian <- rep(0, nTimes)
+    NupperHPD <- rep(0, nTimes)
+    NlowerHPD <- rep(0, nTimes)
+    NupperCPD <- rep(0, nTimes)
+    NlowerCPD <- rep(0, nTimes)
+
+    for (i in 1:frameLen) {
+        theseChangeTimes <- NULL
+        theseChangePops <- NULL
+        p <- 0
+        for (j in 1:nTimes) {
+            pair = strsplit(as.character(df[i,1+j]), ":")[[1]]
+            time <- as.double(pair[1])
+            allTimes[j] <- allTimes[j] + time
+
+            if (length(pair)>1) {
+                p <- p + 1
+                theseChangeTimes[p] <- time
+                theseChangePops[p] <- as.double(pair[2])
+            }
+        }
+
+        changeTimes[[i]] <- theseChangeTimes
+        changePops[[i]] <- theseChangePops
+    }
+
+    allTimes <- allTimes/frameLen
+
+    for (i in 1:nTimes) {
+        thisN <- rep(0, frameLen)
+        for (j in 1:frameLen) {
+            thisN[j] <- getPopSize(allTimes[i], changeTimes[[j]], changePops[[j]], isLinear)
+        }
+        Nmedian[i] <- median(thisN)
+
+        # Compute confidence intervals
+
+        hpd <- computeHPD(thisN, alpha=0.95)
+        NlowerHPD[i] <- hpd$lower
+        NupperHPD[i] <- hpd$upper
+
+        NlowerCPD[i] <- quantile(thisN, probs=0.025)
+        NupperCPD[i] <- quantile(thisN, probs=0.975)
+    }
+
+    res <- list()
+    res$allTimes <- allTimes
+    res$changeTimes <- changeTimes
+    res$changePops <- changePops
+    res$Nmedian <- Nmedian
+    res$NlowerHPD <- NlowerHPD
+    res$NupperHPD <- NupperHPD
+    res$NlowerCPD <- NlowerCPD
+    res$NupperCPD <- NupperCPD
+
+    return(res)
+}
+
+getTimes <- function(df) {
+
+    frameLen <- dim(df)[1]
+    nTimes <- dim(df)[2] - 2
+
+    times <- rep(0, frameLen*nTimes)
+    k <- 1
+
+    for (i in 1:frameLen) {
+        for (j in 1:nTimes) {
+            times[k] <- as.double(strsplit(df[i,1+j], ":")[[1]][1])
+            k <- k + 1
+        }
+
+    }
+
+    return(times)
+}
+removeBurnin <- function(df, burnin=0.1) {
+    frameLen <- dim(df)[1]
+    return(df[-(1:ceiling(burnin*frameLen)),])
+}
+
+plotEBSP <- function(fileName, burnin=0.1, isLinear=TRUE, useHPD=TRUE, showLegend=TRUE, plotPopFunctions=FALSE, popFunctionAlpha=0.05, ...) {
+
+    df <- removeBurnin(read.table(fileName, header=T, sep='\t', as.is=T), burnin)
+    res <- processEBSPdata(df, isLinear)
+
+    ellipsis <- list(...)
+
+    if (length(ellipsis$xlab) == 0)
+        ellipsis$xlab = "Time"
+
+    if (length(ellipsis$ylab) == 0)
+        ellipsis$ylab = "Population"
+
+    if (length(ellipsis$ylim) == 0) {
+        if (useHPD)
+            ellipsis$ylim = c(0.9*min(res$NlowerHPD), 1.1*max(res$NupperHPD))
+        else
+            ellipsis$ylim = c(0.9*min(res$NlowerCPD), 1.1*max(res$NupperCPD))
+    }
+
+    args <- c(list(res$allTimes, res$Nmedian, 'l'), ellipsis)
+
+    do.call(plot, args)
+
+    if (!plotPopFunctions) {
+        if (useHPD)
+            polygon(c(res$allTimes, rev(res$allTimes)), c(res$NlowerHPD, rev(res$NupperHPD)),
+                    col="grey", border=NA)
+        else
+            polygon(c(res$allTimes, rev(res$allTimes)), c(res$NlowerCPD, rev(res$NupperCPD)),
+                    col="grey", border=NA)
+    } else {
+        maxTime <- max(res$allTimes)
+        for (i in 1:length(res$changeTimes)) {
+            plotPopFunction(res$changeTimes[[i]], res$changePops[[i]], isLinear, maxTime=maxTime, col=rgb(0, 0.5, 0, popFunctionAlpha))
+        }
+    }
+
+    if (useHPD) {
+        lines(res$allTimes, res$NupperHPD, lwd=1)
+        lines(res$allTimes, res$NlowerHPD, lwd=1)
+    } else {
+        lines(res$allTimes, res$NupperCPD, lwd=1)
+        lines(res$allTimes, res$NlowerCPD, lwd=1)
+    }
+
+    lines(res$allTimes, res$Nmedian, lty=2, lwd=2)
+
+    if (showLegend) {
+        if (useHPD)
+            CIlabel <- "95% HPD"
+        else
+            CIlabel <- "95% CPD"
+
+        legend('topright', inset=0.05, c("Median", CIlabel), lty=c(2, 1), lwd=c(2, 1))
+    }
+}
+
+plotEBSPTimesHist <- function(fileName, burnin=0.1, alpha=0.95, ...) {
+
+    df <- removeBurnin(read.table(fileName, header=T, sep='\t', as.is=T), burnin)
+    times <- getTimes(df)
+
+    xmax <- quantile(times, alpha)
+
+    hist(times, breaks=c(seq(0, xmax, length.out=100), max(times)), xlim=c(0, xmax),
+         xlab="Time", prob=T, main="Histogram of tree event times in log")
+
+}
+
diff --git a/examples/testHKY.json b/examples/testHKY.json
index 64e8189..57f6114 100644
--- a/examples/testHKY.json
+++ b/examples/testHKY.json
@@ -1,7 +1,15 @@
-{version: "2.0",
+{version: "2.3",
 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",
 
-analysis: [
+// this is a comment, which is non-standard JSON
+// only commenst after double slashes are supported
+// but /* bla */ comments are not
+
+map: [
+	{name: "stateNode", value: "parameter.RealParameter"}
+],
+
+beast: [
 	{id: "alignment.org",
 	 spec: "Alignment",
 	 bonobo    :"AGAAATATGTCTGATAAAAGAATTACTTTGATAGAGTAAATAATAGGAGTTTAAATCCCCTTATTTCTACTAGGACTATGAGAGTCGAACCCATCCCTGAGAATCCAAAATTCTCCGTGCCACCTATCACACCCCATCCTAAGTAAGGTCAGCTAAATAAGCTATCGGGCCCATACCCCGAAAATGTTGGTTATACCCTTCCCGTACTAAGAAATTTAGGTTAAACACAGACCAAGAGCCTTCAAAGCTCTCAGTAAGTTA-CAATACTTAATTTCTGTAAGGACTGCAAAACCCCACTCTGCATCAACTGAACGCAAATCAGCCACTTTAATTAAGCTAAGCCCTTCTAGATTAATGGGACTTAAACCCACAAACATTTAGTTAACAGCTAAACACCCTAATCAGC-TGGCTTCAATCTAAAGCCCCGGCAGG-TTTGAAGCTGCTTCTTTGAATTTGCAATTCAATATGAAAA-TC [...]
@@ -16,7 +24,7 @@ analysis: [
 	 spec: "MCMC", chainLength: 10000000,
 	 state: { storeEvery: 100000,
 		 stateNode: [
-			 {id: "hky.kappa", spec: "parameter.RealParameter", lower: 0.0, value: [ 1.0 ] },
+			 {id: "hky.kappa", lower: 0.0, value: [ 1.0 ] },
 			 {id: "tree", spec: "beast.evolution.tree.Tree" }
 		  ]
 		},
diff --git a/examples/testTipDates.xml b/examples/testTipDates.xml
index 2418c74..d2f9d05 100644
--- a/examples/testTipDates.xml
+++ b/examples/testTipDates.xml
@@ -151,7 +151,7 @@
 				<input name='tree' idref="tree"/>
 				<input name='siteModel' idref="siteModel"/>
                 <branchRateModel id="StrictClockModel" spec="beast.evolution.branchratemodel.StrictClockModel">
-                    <parameter dimension="1" estimate="false" id="clockRate" name="clock.rate" value="1.0"/>
+                    <parameter dimension="1" estimate="true" id="clockRate" name="clock.rate" value="1.0"/>
                 </branchRateModel>
 		    </distribution>
 		</distribution>
diff --git a/examples/testUCLNclock.json b/examples/testUCLNclock.json
new file mode 100644
index 0000000..7f90251
--- /dev/null
+++ b/examples/testUCLNclock.json
@@ -0,0 +1,135 @@
+{version: "2.3",
+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: [
+	{id: "dna",
+	 spec: "Alignment",
+	 Carp    :"ATGGCACACCCAACGCAACTAGGTTTCAAGGACGCGGCCATACCCGTTATAGAGGAACTTCTTCACTTCCACGACCACGCATTAATAATTGTGCTCCTAATTAGCACTTTAGTTTTATATATTATTACTGCAATGGTATCAACTAAACTTACTAATAAATATATTCTAGACTCCCAAGAAATCGAAATCGTATGAACCATTCTACCAGCCGTCATTTTAGTACTAATCGCCCTGCCCTCCCTACGCATCCTGTACCTTATAGACGAAATTAACGACCCTCACCTGACAATTAAAGCAATAGGACACCAATGATACTGAAGTTACGAGTATACAGACTATGAAAATCTAGGATTCGACTCCTATATAGTACCAACCCAAGACCTTGCCCCCGGACAATTCCGACTTCTGGAAACAGACCACCGAATAGTTGTTCCAATAGAATCCCCAGTCCGTGTCCTAGTATCTGCTGAAGACGTGCTA [...]
+	 Chicken :"ATGGCCAACCACTCCCAACTAGGCTTTCAAGACGCCTCATCCCCCATCATAGAAGAGCTCGTTGAATTCCACGACCACGCCCTGATAGTCGCACTAGCAATTTGCAGCTTAGTACTCTACCTTCTAACTCTTATACTTATAGAAAAACTATCA---TCAAACACCGTAGATGCCCAAGAAGTTGAACTAATCTGAACCATCCTACCCGCTATTGTCCTAGTCCTGCTTGCCCTCCCCTCCCTCCAAATCCTCTACATAATAGACGAAATCGACGAACCTGATCTCACCCTAAAAGCCATCGGACACCAATGATACTGAACCTATGAATACACAGACTTCAAGGACCTCTCATTTGACTCCTACATAACCCCAACAACAGACCTCCCCCTAGGCCACTTCCGCCTACTAGAAGTCGACCATCGCATTGTAATCCCCATAGAATCCCCCATTCGAGTAATCATCACCGCTGATGACGTCCTC [...]
+	 Cow     :"ATGGCATATCCCATACAACTAGGATTCCAAGATGCAACATCACCAATCATAGAAGAACTACTTCACTTTCATGACCACACGCTAATAATTGTCTTCTTAATTAGCTCATTAGTACTTTACATTATTTCACTAATACTAACGACAAAGCTGACCCATACAAGCACGATAGATGCACAAGAAGTAGAGACAATCTGAACCATTCTGCCCGCCATCATCTTAATTCTAATTGCTCTTCCTTCTTTACGAATTCTATACATAATAGATGAAATCAATAACCCATCTCTTACAGTAAAAACCATAGGACATCAGTGATACTGAAGCTATGAGTATACAGATTATGAGGACTTAAGCTTCGACTCCTACATAATTCCAACATCAGAATTAAAGCCAGGGGAGCTACGACTATTAGAAGTCGATAATCGAGTTGTACTACCAATAGAAATAACAATCCGAATGTTAGTCTCCTCTGAAGACGTATTA [...]
+	 Frog    :"ATGGCACACCCATCACAATTAGGTTTTCAAGACGCAGCCTCTCCAATTATAGAAGAATTACTTCACTTCCACGACCATACCCTCATAGCCGTTTTTCTTATTAGTACGCTAGTTCTTTACATTATTACTATTATAATAACTACTAAACTAACTAATACAAACCTAATGGACGCACAAGAGATCGAAATAGTGTGAACTATTATACCAGCTATTAGCCTCATCATAATTGCCCTTCCATCCCTTCGTATCCTATATTTAATAGATGAAGTTAATGATCCACACTTAACAATTAAAGCAATCGGCCACCAATGATACTGAAGCTACGAATATACTAACTATGAGGATCTCTCATTTGACTCTTATATAATTCCAACTAATGACCTTACCCCTGGACAATTCCGGCTGCTAGAAGTTGATAATCGAATAGTAGTCCCAATAGAATCTCCAACCCGACTTTTAGTTACAGCCGAAGACGTCCTC [...]
+	 Human   :"ATGGCACATGCAGCGCAAGTAGGTCTACAAGACGCTACTTCCCCTATCATAGAAGAGCTTATCACCTTTCATGATCACGCCCTCATAATCATTTTCCTTATCTGCTTCCTAGTCCTGTATGCCCTTTTCCTAACACTCACAACAAAACTAACTAATACTAACATCTCAGACGCTCAGGAAATAGAAACCGTCTGAACTATCCTGCCCGCCATCATCCTAGTCCTCATCGCCCTCCCATCCCTACGCATCCTTTACATAACAGACGAGGTCAACGATCCCTCCCTTACCATCAAATCAATTGGCCACCAATGGTACTGAACCTACGAGTACACCGACTACGGCGGACTAATCTTCAACTCCTACATACTTCCCCCATTATTCCTAGAACCAGGCGACCTGCGACTCCTTGACGTTGACAATCGAGTAGTACTCCCGATTGAAGCCCCCATTCGTATAATAATTACATCACAAGACGTCTTG [...]
+	 Loach   :"ATGGCACATCCCACACAATTAGGATTCCAAGACGCGGCCTCACCCGTAATAGAAGAACTTCTTCACTTCCATGACCATGCCCTAATAATTGTATTTTTGATTAGCGCCCTAGTACTTTATGTTATTATTACAACCGTCTCAACAAAACTCACTAACATATATATTTTGGACTCACAAGAAATTGAAATCGTATGAACTGTGCTCCCTGCCCTAATCCTCATTTTAATCGCCCTCCCCTCACTACGAATTCTATATCTTATAGACGAGATTAATGACCCCCACCTAACAATTAAGGCCATGGGGCACCAATGATACTGAAGCTACGAGTATACTGATTATGAAAACTTAAGTTTTGACTCCTACATAATCCCCACCCAGGACCTAACCCCTGGACAATTCCGGCTACTAGAGACAGACCACCGAATGGTTGTTCCCATAGAATCCCCTATTCGCATTCTTGTTTCCGCCGAAGATGTACTA [...]
+	 Mouse   :"ATGGCCTACCCATTCCAACTTGGTCTACAAGACGCCACATCCCCTATTATAGAAGAGCTAATAAATTTCCATGATCACACACTAATAATTGTTTTCCTAATTAGCTCCTTAGTCCTCTATATCATCTCGCTAATATTAACAACAAAACTAACACATACAAGCACAATAGATGCACAAGAAGTTGAAACCATTTGAACTATTCTACCAGCTGTAATCCTTATCATAATTGCTCTCCCCTCTCTACGCATTCTATATATAATAGACGAAATCAACAACCCCGTATTAACCGTTAAAACCATAGGGCACCAATGATACTGAAGCTACGAATATACTGACTATGAAGACCTATGCTTTGATTCATATATAATCCCAACAAACGACCTAAAACCTGGTGAACTACGACTGCTAGAAGTTGATAACCGAGTCGTTCTGCCAATAGAACTTCCAATCCGTATATTAATTTCATCTGAAGACGTCCTC [...]
+	 Rat     :"ATGGCTTACCCATTTCAACTTGGCTTACAAGACGCTACATCACCTATCATAGAAGAACTTACAAACTTTCATGACCACACCCTAATAATTGTATTCCTCATCAGCTCCCTAGTACTTTATATTATTTCACTAATACTAACAACAAAACTAACACACACAAGCACAATAGACGCCCAAGAAGTAGAAACAATTTGAACAATTCTCCCAGCTGTCATTCTTATTCTAATTGCCCTTCCCTCCCTACGAATTCTATACATAATAGACGAGATTAATAACCCAGTTCTAACAGTAAAAACTATAGGACACCAATGATACTGAAGCTATGAATATACTGACTATGAAGACCTATGCTTTGACTCCTACATAATCCCAACCAATGACCTAAAACCAGGTGAACTTCGTCTATTAGAAGTTGATAATCGGGTAGTCTTACCAATAGAACTTCCAATTCGTATACTAATCTCATCCGAAGACGTCCTG [...]
+	 Seal    :"ATGGCATACCCCCTACAAATAGGCCTACAAGATGCAACCTCTCCCATTATAGAGGAGTTACTACACTTCCATGACCACACATTAATAATTGTGTTCCTAATTAGCTCATTAGTACTCTACATTATCTCACTTATACTAACCACGAAACTCACCCACACAAGTACAATAGACGCACAAGAAGTGGAAACGGTGTGAACGATCCTACCCGCTATCATTTTAATTCTCATTGCCCTACCATCATTACGAATCCTCTACATAATGGACGAGATCAATAACCCTTCCTTGACCGTAAAAACTATAGGACATCAGTGATACTGAAGCTATGAGTACACAGACTACGAAGACCTGAACTTTGACTCATATATGATCCCCACACAAGAACTAAAGCCCGGAGAACTACGACTGCTAGAAGTAGACAATCGAGTAGTCCTCCCAATAGAAATAACAATCCGCATACTAATCTCATCAGAAGATGTACTC [...]
+	 Whale   :"ATGGCATATCCATTCCAACTAGGTTTCCAAGATGCAGCATCACCCATCATAGAAGAGCTCCTACACTTTCACGATCATACACTAATAATCGTTTTTCTAATTAGCTCTTTAGTTCTCTACATTATTACCCTAATGCTTACAACCAAATTAACACATACTAGTACAATAGACGCCCAAGAAGTAGAAACTGTCTGAACTATCCTCCCAGCCATTATCTTAATTTTAATTGCCTTGCCTTCATTACGGATCCTTTACATAATAGACGAAGTCAATAACCCCTCCCTCACTGTAAAAACAATAGGTCACCAATGATATTGAAGCTATGAGTATACCGACTACGAAGACCTAAGCTTCGACTCCTATATAATCCCAACATCAGACCTAAAGCCAGGAGAACTACGATTATTAGAAGTAGATAACCGAGTTGTCTTACCTATAGAAATAACAATCCGAATATTAGTCTCATCAGAAGACGTACTC [...]
+	},
+
+	{id: "mcmc",
+	 spec: "MCMC", chainLength: 10000000,
+	 state: {id: "state", storeEvery: 5000,
+		 stateNode: [
+			{id: "Tree.t:dna",
+			 spec: "beast.evolution.tree.Tree",
+				 taxonset: {id: "TaxonSet.dna", alignment: "@dna" }
+			},
+			 {id: "birthRate.t:dna", spec: "parameter.RealParameter", value: [ 1.0 ] },
+			 {id: "kappa.s:dna", spec: "parameter.RealParameter", lower: 0.0, value: [ 2.0 ] },
+			 {id: "ucldStdev.c:dna", spec: "parameter.RealParameter", lower: 0.0, value: [ 0.1 ] },
+			 {id: "rateCategories.c:dna", spec: "parameter.IntegerParameter", dimension: 18, value: [ 1 ] },
+			 {id: "freqParameter.s:dna", spec: "parameter.RealParameter", lower: 0.0, upper: 1.0, dimension: 4, value: [ 0.25 ] }
+		  ]
+		},
+	 init: [
+		{id: "RandomTree.t:dna",
+		 spec: "beast.evolution.tree.RandomTree", taxa: "@dna", initial: "@Tree.t:dna", estimate: false,
+			 populationModel: {id: "ConstantPopulation0.t:dna", spec: "ConstantPopulation", popSize: "1.0" }
+		}
+	  ],
+	 distribution: {id: "posterior",
+		 spec: "util.CompoundDistribution",
+		 distribution: [
+			{id: "prior",
+			 spec: "util.CompoundDistribution",
+			 distribution: [
+				 {id: "YuleModel.t:dna", spec: "beast.evolution.speciation.YuleModel", birthDiffRate: "@birthRate.t:dna", tree: "@Tree.t:dna" },
+				{id: "YuleBirthRatePrior.t:dna",
+				 spec: "beast.math.distributions.Prior", x: "@birthRate.t:dna",
+					 distr: {id: "Uniform.0", spec: "beast.math.distributions.Uniform", upper: Infinity }
+				},
+				{id: "KappaPrior.s:dna",
+				 spec: "beast.math.distributions.Prior", x: "@kappa.s:dna",
+					 distr: {id: "LogNormalDistributionModel.0", spec: "beast.math.distributions.LogNormalDistributionModel", M: "1.0", S: "1.25" }
+				},
+				{id: "ucldStdevPrior.c:dna",
+				 spec: "beast.math.distributions.Prior", x: "@ucldStdev.c:dna",
+					 distr: {id: "Gamma.0", spec: "beast.math.distributions.Gamma", alpha: "0.5396", beta: "0.3819" }
+				}
+			  ]
+			},
+			{id: "likelihood",
+			 spec: "util.CompoundDistribution",
+			 distribution: [
+				{id: "treeLikelihood.dna",
+				 spec: "TreeLikelihood", data: "@dna", tree: "@Tree.t:dna",
+				 siteModel: {id: "SiteModel.s:dna",
+					 spec: "SiteModel", mutationRate: "1.0", shape: "1.0", proportionInvariant: "0.0",
+					 substModel: {id: "hky.s:dna",
+						 spec: "HKY", kappa: "@kappa.s:dna",
+							 frequencies: {id: "estimatedFreqs.s:dna", frequencies: "@freqParameter.s:dna" }
+						}
+					},
+				 branchRateModel: {id: "RelaxedClock.c:dna",
+					 spec: "beast.evolution.branchratemodel.UCRelaxedClockModel", rateCategories: "@rateCategories.c:dna", tree: "@Tree.t:dna", clock.rate: "1.0",
+						 distr: {id: "LogNormalDistributionModel.c:dna", spec: "beast.math.distributions.LogNormalDistributionModel", M: "1.0", S: "@ucldStdev.c:dna", meanInRealSpace: true }
+					}
+				}
+			  ]
+			}
+		  ]
+		},
+	 operator: [
+		 {id: "YuleBirthRateScaler.t:dna", spec: "ScaleOperator", parameter: "@birthRate.t:dna", scaleFactor: 0.75, weight: 3.0 },
+		 {id: "YuleModelTreeScaler.t:dna", spec: "ScaleOperator", tree: "@Tree.t:dna", scaleFactor: 0.5, weight: 3.0 },
+		 {id: "YuleModelTreeRootScaler.t:dna", spec: "ScaleOperator", tree: "@Tree.t:dna", scaleFactor: 0.5, rootOnly: true, weight: 3.0 },
+		 {id: "YuleModelUniformOperator.t:dna", spec: "Uniform", tree: "@Tree.t:dna", weight: 30.0 },
+		 {id: "YuleModelSubtreeSlide.t:dna", spec: "SubtreeSlide", tree: "@Tree.t:dna", weight: 15.0 },
+		 {id: "YuleModelNarrow.t:dna", spec: "Exchange", tree: "@Tree.t:dna", weight: 15.0 },
+		 {id: "YuleModelWide.t:dna", spec: "Exchange", isNarrow: false, tree: "@Tree.t:dna", weight: 3.0 },
+		 {id: "YuleModelWilsonBalding.t:dna", spec: "WilsonBalding", tree: "@Tree.t:dna", weight: 3.0 },
+		 {id: "KappaScaler.s:dna", spec: "ScaleOperator", parameter: "@kappa.s:dna", scaleFactor: 0.5, weight: 0.1 },
+		 {id: "ucldStdevScaler.c:dna", spec: "ScaleOperator", parameter: "@ucldStdev.c:dna", scaleFactor: 0.5, weight: 3.0 },
+		 {id: "CategoriesRandomWalk.c:dna", spec: "IntRandomWalkOperator", windowSize: 1, parameter: "@rateCategories.c:dna", weight: 10.0 },
+		 {id: "CategoriesSwapOperator.c:dna", spec: "SwapOperator", intparameter: "@rateCategories.c:dna", weight: 10.0 },
+		 {id: "CategoriesUniform.c:dna", spec: "UniformOperator", parameter: "@rateCategories.c:dna", weight: 10.0 },
+		{id: "FrequenciesExchanger.s:dna",
+		 spec: "DeltaExchangeOperator", delta: 0.01, weight: 0.1,
+		 parameter: [
+			 {idref: "freqParameter.s:dna" }
+		  ]
+		}
+	  ],
+	 logger: [
+		{id: "tracelog", fileName: "dna.log", logEvery: 1000, model: "@posterior", sort: "smart", sanitiseHeaders: true,
+		 log: [
+			 {idref: "posterior" },
+			 {idref: "likelihood" },
+			 {idref: "prior" },
+			 {idref: "treeLikelihood.dna" },
+			 {id: "TreeHeight.t:dna", spec: "beast.evolution.tree.TreeHeightLogger", tree: "@Tree.t:dna" },
+			 {idref: "YuleModel.t:dna" },
+			 {idref: "birthRate.t:dna" },
+			 {idref: "kappa.s:dna" },
+			 {idref: "ucldStdev.c:dna" },
+			 {id: "rate.c:dna", spec: "beast.evolution.branchratemodel.RateStatistic", branchratemodel: "@RelaxedClock.c:dna", tree: "@Tree.t:dna" },
+			 {idref: "freqParameter.s:dna" }
+		  ]
+		},
+		{id: "screenlog", logEvery: 1000,
+		 log: [
+			 {idref: "posterior" },
+			 {id: "ESS.0", spec: "util.ESS", arg: "@posterior" },
+			 {idref: "likelihood" },
+			 {idref: "prior" }
+		  ]
+		},
+		{id: "treelog.t:dna", fileName: "$(tree).trees", logEvery: 1000, mode: "tree",
+		 log: [
+			 {id: "TreeWithMetaDataLogger.t:dna", spec: "beast.evolution.tree.TreeWithMetaDataLogger", tree: "@Tree.t:dna", branchratemodel: "@RelaxedClock.c:dna" }
+		  ]
+		}
+	  ]
+	}
+]
+}
diff --git a/packages.xml b/packages.xml
deleted file mode 100644
index 15e46e8..0000000
--- a/packages.xml
+++ /dev/null
@@ -1,71 +0,0 @@
-<packages>
-    <!--names in alphabetic order-->
-
-    <package name='BDSKY' version='1.1.0'
-           url="http://bdssm-beast2.googlecode.com/files/BDSKY.addon.v1.1.0.zip"
-           description="birth death skyline -- handles serially sampled tips">
-        <depends on='beast2' atleast='2.1.0'/>
-    </package>
-
-    <package name='BEASTii' version='1.1.0'
-           url="http://beastii.googlecode.com/files/BEASTii.addon.v1.1.0.zip"
-           description="BEAST utilities, such as multi threaded treeliklihood">
-        <depends on='beast2' atleast='2.1.0'/>
-    </package>
-
-    <package name='BEAST_CLASSIC' version='1.1.2'
-           url="https://www.cs.auckland.ac.nz/~remco/BEASTBook/BEAST_CLASSIC.addon.v1.1.2.zip"
-           description="BEAST classes ported from BEAST 1 in wrappers" >
-        <depends on='beast2' atleast='2.1.0'/>
-        <depends on='BEASTii' atleast='1.1.0'/>
-    </package>
-
-    <package name='CA' version='1.0.0'
-           url="http://beastii.googlecode.com/files/CA.addon.v1.0.0.zip"
-           description="CladeAge package for fossil calibrations">
-        <depends on='beast2' atleast='2.1.0'/>
-    </package>
-
-    <package name='DISSECT' version='1.0.0'
-           url="http://www.indriid.com/2014/DISSECT.addon.v1.0.0.zip"
-           description="species delimitation with *BEAST">
-        <depends on='beast2' atleast='2.1.0'/>
-    </package>
-
-    <package name='phylodynamics' version='1.0.0'
-           url="http://bdssm-beast2.googlecode.com/files/phylodynamics.addon.zip"
-           description="birth death skyline model" >
-        <depends on='beast2' atleast='2.1.0'/>
-    </package>
-
-    <package name='MASTER' version='1.4.1'
-           url="https://github.com/CompEvol/MASTER/releases/download/v1.4.1/MASTER.addon.v1.4.1.zip"
-           description="stochastic simulation" >
-        <depends on='beast2' atleast='2.1.0'/>
-    </package>
-
-    <package name='RBS' version='1.1.0'
-           url="http://rb-beast.googlecode.com/files/RBS.addon.v1.1.0.zip"
-           description="Reversible-jump Based substitution model" >
-        <depends on='beast2' atleast='2.1.0'/>
-    </package>
-
-    <package name='SA' version='1.0.0'
-           url="http://beastii.googlecode.com/files/SA.addon.v1.0.0.zip"
-           description="Sampled ancestor trees" >
-        <depends on='beast2' atleast='2.1.0'/>
-    </package>
-
-    <package name='SNAPP' version='1.1.4'
-           url="https://www.cs.auckland.ac.nz/~remco/BEASTBook/SNAPP.addon.v1.1.4.zip"
-           description="SNP and AFLP Phylogenies" >
-        <depends on='beast2' atleast='2.1.0'/>
-    </package>
-
-    <package name='SubstBMA' version='1.1.0'
-           url="http://www.cs.auckland.ac.nz/~remco/BEASTBook/SubstBMA.addon.v1.1.0.zip"
-           description="Substitution Bayesian Model Averaging" >
-        <depends on='beast2' atleast='2.1.0'/>
-    </package>
-
-</packages>
diff --git a/release/Linux/bin/beast b/release/Linux/bin/beast
index 5ed9bef..c6ee8c9 100755
--- a/release/Linux/bin/beast
+++ b/release/Linux/bin/beast
@@ -29,4 +29,4 @@ if [ -z "$JAVA_HOME" ]; then
 else
   JAVA=$JAVA_HOME/bin/java
 fi
-$JAVA -Xms64m -Xmx4g -Djava.library.path="$BEAST_LIB:/usr/local/lib" -cp "$BEAST_LIB/launcher.jar" beast.app.beastapp.BeastLauncher $*
+$JAVA -Xms64m -Xmx4g -cp "$BEAST_LIB/launcher.jar" beast.app.beastapp.BeastLauncher $*
diff --git a/release/common/VERSION HISTORY.txt b/release/common/VERSION HISTORY.txt
index 586abd6..d5399e0 100644
--- a/release/common/VERSION HISTORY.txt	
+++ b/release/common/VERSION HISTORY.txt	
@@ -8,7 +8,7 @@ All issues can be viewed at https://github.com/CompEvol/beast2/issues
 Version 2.3.2 December 2015
 	BEAUti
 		path corrected so Standard and StarBeast templates are visible under templates menu
-		import of traits from file when partions are split fixed
+		import of traits from file when partitions are split fixed
 		cloning of scripts with partition information fixed
 		set up weights of FixedMeanRate operator when ascertainment correction is applied
 		allows ParameterInputEditor to edit Parameter inputs
diff --git a/release/common/tools/DensiTree_launch4j.xml b/release/common/tools/DensiTree_launch4j.xml
index 2c08552..d88882f 100644
--- a/release/common/tools/DensiTree_launch4j.xml
+++ b/release/common/tools/DensiTree_launch4j.xml
@@ -2,7 +2,7 @@
   <headerType>gui</headerType>
   <icon>./DensiTree.ico</icon>  
   <jre>
-    <minVersion>1.6.0</minVersion>
+    <minVersion>1.8.0</minVersion>
     <initialHeapSize>256</initialHeapSize>
     <maxHeapSize>4096</maxHeapSize>
   </jre>    
diff --git a/src/beast/app/BEASTVersion.java b/src/beast/app/BEASTVersion.java
index e9fd538..239cefa 100644
--- a/src/beast/app/BEASTVersion.java
+++ b/src/beast/app/BEASTVersion.java
@@ -5,7 +5,7 @@ import beast.app.util.Version;
 /**
  * This class provides a mechanism for returning the version number of the
  * dr software. It relies on the administrator of the dr source using the
- * module tagging system in CVS. The method getVersionString() will return
+ * module tagging system in CVS. The method getVersion() will return
  * the version of dr under the following condition: <BR>
  * 1. the dr source has been checked out *by tag* before being packaged for
  * distribution.
@@ -29,19 +29,23 @@ public class BEASTVersion extends Version {
     
     private static final String BEAST2_SOURCE = "http://github.com/CompEvol/beast2";
 
-    public String getVersion() {
+    @Override
+	public String getVersion() {
         return VERSION;
     }
 
-    public String getVersionString() {
+    @Override
+	public String getVersionString() {
         return "v" + VERSION + (IS_PRERELEASE ? " Prerelease" : "");
     }
 
-    public String getDateString() {
+    @Override
+	public String getDateString() {
         return DATE_STRING;
     }
 
-    public String[] getCredits() {
+    @Override
+	public String[] getCredits() {
         return new String[]{
                 "Designed and developed by",
                 "Remco Bouckaert, Alexei J. Drummond, Andrew Rambaut & Marc A. Suchard",
@@ -76,7 +80,8 @@ public class BEASTVersion extends Version {
                 "Roald Forsberg, Beth Shapiro and Korbinian Strimmer"};
     }
 
-    public String getHTMLCredits() {
+    @Override
+	public String getHTMLCredits() {
         return
                 "<p>Designed and developed by<br>" +
                         "Remco Bouckaert, Alexei J. Drummond, Andrew Rambaut and Marc A. Suchard</p>" +
@@ -116,9 +121,9 @@ public class BEASTVersion extends Version {
      * 2.x.1 -> 2.0001
      * @return
      */
-    public double parseVersion(String sVersion) {
+    public double parseVersion(String versionString) {
         // is of the form 1.2.3
-        String [] strs = sVersion.split("\\.");
+        String [] strs = versionString.split("\\.");
         double version = 0;
         double divider = 1.0;
         for (int i = 0; i < strs.length; i++) {
diff --git a/src/beast/app/BeastMCMC.java b/src/beast/app/BeastMCMC.java
index 1ce13a4..a87e3ba 100644
--- a/src/beast/app/BeastMCMC.java
+++ b/src/beast/app/BeastMCMC.java
@@ -25,14 +25,11 @@
 package beast.app;
 
 
-import jam.util.IconUtils;
-
 import java.awt.BorderLayout;
 import java.awt.Component;
 import java.awt.Dimension;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.io.File;
+import java.io.IOException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -52,8 +49,14 @@ import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JOptionPane;
 import javax.swing.JTextField;
+import javax.swing.SwingConstants;
+import javax.swing.WindowConstants;
 import javax.swing.border.EtchedBorder;
 import javax.swing.filechooser.FileFilter;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.json.JSONException;
+import org.xml.sax.SAXException;
 
 import beagle.BeagleFlag;
 import beast.app.beastapp.BeastDialog;
@@ -62,14 +65,15 @@ import beast.app.beauti.Beauti;
 import beast.app.draw.ExtensionFileFilter;
 import beast.app.util.Version;
 import beast.core.Logger;
-import beast.core.Logger.LogFileMode;
 import beast.core.Runnable;
-
+import beast.core.util.Log;
 import beast.util.AddOnManager;
 import beast.util.JSONParser;
+import beast.util.JSONParserException;
 import beast.util.Randomizer;
 import beast.util.XMLParser;
 import beast.util.XMLParserException;
+import jam.util.IconUtils;
 
 /**
  * Main application for performing MCMC runs.
@@ -100,10 +104,11 @@ public class BeastMCMC {
 
     /**
      * parse command line arguments, and load file if specified
-     *
-     * @throws Exception *
+     * @throws IOException 
+     * @throws JSONException 
+     * @throws JSONParserException 
      */
-    public void parseArgs(String[] args) throws Exception {
+    public void parseArgs(String[] args) throws IOException, XMLParserException, JSONException {
         int i = 0;
         boolean resume = false;
 
@@ -111,7 +116,7 @@ public class BeastMCMC {
 
         try {
             while (i < args.length) {
-                int iOld = i;
+                int old = i;
                 if (i < args.length) {
                     if (args[i].equals("")) {
                         i += 1;
@@ -147,25 +152,25 @@ public class BeastMCMC {
                         System.setProperty("file.name.prefix", args[i + 1].trim());
                         i += 2;
                     }
-                    if (i == iOld) {
+                    if (i == old) {
                         if (i == args.length - 1) {
                             beastFile = new File(args[i]);
                             i++;
                         } else {
-                            throw new Exception("Wrong argument");
+                            throw new IllegalArgumentException("Wrong argument");
                         }
                     }
                 }
             }
         } catch (Exception e) {
             e.printStackTrace();
-            throw new Exception("Error parsing command line arguments: " + Arrays.toString(args) + "\nArguments ignored\n\n" + getUsage());
+            throw new IllegalArgumentException("Error parsing command line arguments: " + Arrays.toString(args) + "\nArguments ignored\n\n" + getUsage());
         }
 
         if (beastFile == null) {
             // Not resuming so get starting options...
 
-            List<String> MCMCargs = new ArrayList<String>();
+            List<String> MCMCargs = new ArrayList<>();
             Version version = new BEASTVersion();
             String titleString = "<html><center><p>Bayesian Evolutionary Analysis Sampling Trees<br>" +
                     "Version " + version.getVersionString() + ", " + version.getDateString() + "</p></center></html>";
@@ -227,7 +232,7 @@ public class BeastMCMC {
             File inputFile = dialog.getInputFile();
             if (!beagleShowInfo && inputFile == null) {
                 System.err.println("No input file specified");
-                System.exit(0);
+                System.exit(1);
             }
             MCMCargs.add(inputFile.getAbsolutePath());
 
@@ -239,9 +244,9 @@ public class BeastMCMC {
             return;
         }
 
-        System.err.println("File: " + beastFile.getName() + " seed: " + m_nSeed + " threads: " + m_nThreads);
+        Log.warning.println("File: " + beastFile.getName() + " seed: " + m_nSeed + " threads: " + m_nThreads);
         if (resume) {
-            System.out.println("Resuming from file");
+            Log.info.println("Resuming from file");
         }
 
         AddOnManager.loadExternalJars();
@@ -250,7 +255,11 @@ public class BeastMCMC {
         if (beastFile.getPath().toLowerCase().endsWith(".json")) {
             m_runnable = new JSONParser().parseFile(beastFile);
         } else {        	
-        	m_runnable = new XMLParser().parseFile(beastFile);
+        	try {
+				m_runnable = new XMLParser().parseFile(beastFile);
+			} catch (SAXException | ParserConfigurationException e) {
+				throw new IllegalArgumentException(e);
+			}
         }
         m_runnable.setStateFile(beastFile.getName() + ".state", resume);
     } // parseArgs
@@ -274,7 +283,8 @@ public class BeastMCMC {
     String getFileNameByDialog() {
         JFileChooser fc = new JFileChooser(System.getProperty("user.dir"));
         fc.addChoosableFileFilter(new FileFilter() {
-            public boolean accept(File f) {
+            @Override
+			public boolean accept(File f) {
                 if (f.isDirectory()) {
                     return true;
                 }
@@ -286,7 +296,8 @@ public class BeastMCMC {
             }
 
             // The description of this filter
-            public String getDescription() {
+            @Override
+			public String getDescription() {
                 return "xml files";
             }
         });
@@ -317,34 +328,34 @@ public class BeastMCMC {
         JTextField m_fileEntry;
         JTextField m_seedEntry;
         JCheckBox m_bUseGPU;
-        JComboBox m_mode;
+        JComboBox<String> m_mode;
 
         public BeastStartDialog() {
-            setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+            setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
             setModalityType(DEFAULT_MODALITY_TYPE);
             init();
             setVisible(true);
         }
 
         String[] getArgs() {
-            List<String> sArgs = new ArrayList<String>();
-            sArgs.add("-seed");
-            sArgs.add(m_seedEntry.getText());
+            List<String> args = new ArrayList<>();
+            args.add("-seed");
+            args.add(m_seedEntry.getText());
             switch (m_mode.getSelectedIndex()) {
                 case 0:
                     break;
                 case 1:
-                    sArgs.add("-overwrite");
+                    args.add("-overwrite");
                     break;
                 case 2:
-                    sArgs.add("-resume");
+                    args.add("-resume");
                     break;
             }
 //			if (m_bUseGPU.isSelected()) {
-//				sArgs.add("-useGPU");
+//				args.add("-useGPU");
 //			}
-            sArgs.add(m_fileEntry.getText());
-            return sArgs.toArray(new String[0]);
+            args.add(m_fileEntry.getText());
+            return args.toArray(new String[0]);
         }
 
         void init() {
@@ -377,17 +388,17 @@ public class BeastMCMC {
         private Component createHeader() {
             Box box = Box.createHorizontalBox();
 
-            String sIconLocation = "beast/app/draw/icons/beast.png";
+            String iconLocation = "beast/app/draw/icons/beast.png";
             ImageIcon icon = null;
             try {
-                URL url = (URL) ClassLoader.getSystemResource(sIconLocation);
+                URL url = ClassLoader.getSystemResource(iconLocation);
                 if (url == null) {
-                    System.err.println("Cannot find icon " + sIconLocation);
+                    System.err.println("Cannot find icon " + iconLocation);
                     return null;
                 }
                 icon = new ImageIcon(url);
             } catch (Exception e) {
-                System.err.println("Cannot load icon " + sIconLocation + " " + e.getMessage());
+                System.err.println("Cannot load icon " + iconLocation + " " + e.getMessage());
                 return null;
             }
 
@@ -396,7 +407,7 @@ public class BeastMCMC {
             label.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10));
             box.add(label, BorderLayout.WEST);
             label = new JLabel("<html><center>BEAST<br>Version: " + VERSION + "<br>Developers: " + DEVELOPERS + "<br>Copyright: " + COPYRIGHT + "</html>");
-            label.setHorizontalAlignment(JLabel.CENTER);
+            label.setHorizontalAlignment(SwingConstants.CENTER);
             box.add(label);
             return box;
         } // BeastStartDialog::createHeader
@@ -415,9 +426,7 @@ public class BeastMCMC {
             //box.add(Box.createHorizontalGlue());
 
             JButton button = new JButton("Choose file");
-            button.addActionListener(new ActionListener() {
-                @Override
-                public void actionPerformed(ActionEvent e) {
+            button.addActionListener(e -> {
                     JFileChooser fileChooser = new JFileChooser(Beauti.g_sDir);
                     File file = new File(m_fileEntry.getText());
                     if (file.exists())
@@ -426,14 +435,13 @@ public class BeastMCMC {
                     fileChooser.setDialogTitle("Select Beast 2 XML file");
                     int rval = fileChooser.showOpenDialog(null);
                     if (rval == JFileChooser.APPROVE_OPTION) {
-                        String sFileName = fileChooser.getSelectedFile().toString();
-                        if (sFileName.lastIndexOf('/') > 0) {
-                            Beauti.g_sDir = sFileName.substring(0, sFileName.lastIndexOf('/'));
+                        String fileName = fileChooser.getSelectedFile().toString();
+                        if (fileName.lastIndexOf('/') > 0) {
+                            Beauti.g_sDir = fileName.substring(0, fileName.lastIndexOf('/'));
                         }
-                        m_fileEntry.setText(sFileName);
+                        m_fileEntry.setText(fileName);
                     }
-                }
-            });
+                });
             box.add(button);
 
             return box;
@@ -443,7 +451,7 @@ public class BeastMCMC {
             Box box = Box.createHorizontalBox();
             box.add(new JLabel("Random number seed: "));
             m_seedEntry = new JTextField("127");
-            m_seedEntry.setHorizontalAlignment(JTextField.RIGHT);
+            m_seedEntry.setHorizontalAlignment(SwingConstants.RIGHT);
             Dimension size = new Dimension(100, 20);
             m_seedEntry.setMinimumSize(size);
             m_seedEntry.setPreferredSize(size);
@@ -455,19 +463,10 @@ public class BeastMCMC {
             return box;
         } // BeastStartDialog::createSeedInput
 
-        private Component createBeagleInput() {
-            Box box = Box.createHorizontalBox();
-            m_bUseGPU = new JCheckBox("Use GPU through Beagle (if available)");
-            box.add(m_bUseGPU);
-            box.add(Box.createHorizontalGlue());
-            return box;
-        } // BeastStartDialog::createSeedInput
-
-
         private Component createModeInput() {
             Box box = Box.createHorizontalBox();
             box.add(new JLabel("Mode of running: "));
-            m_mode = new JComboBox(new String[]{"default: only write new log files",
+            m_mode = new JComboBox<>(new String[]{"default: only write new log files",
                     "overwrite: overwrite log files",
                     "resume: appends log to existing files (if any)"});
             Dimension size = new Dimension(350, 20);
@@ -486,19 +485,15 @@ public class BeastMCMC {
             Box cancelOkBox = Box.createHorizontalBox();
             cancelOkBox.setBorder(new EtchedBorder());
             JButton okButton = new JButton("Run");
-            okButton.addActionListener(new ActionListener() {
-                public void actionPerformed(ActionEvent e) {
+            okButton.addActionListener(e -> {
                     m_bOK = true;
                     dispose();
-                }
-            });
+                });
             JButton cancelButton = new JButton("Quit");
-            cancelButton.addActionListener(new ActionListener() {
-                public void actionPerformed(ActionEvent e) {
+            cancelButton.addActionListener(e -> {
                     dispose();
                     System.exit(0);
-                }
-            });
+                });
             cancelOkBox.add(Box.createHorizontalGlue());
             cancelOkBox.add(cancelButton);
             cancelOkBox.add(Box.createHorizontalStrut(20));
diff --git a/src/beast/app/DocMaker.java b/src/beast/app/DocMaker.java
index f2de5df..2578d8e 100644
--- a/src/beast/app/DocMaker.java
+++ b/src/beast/app/DocMaker.java
@@ -26,7 +26,13 @@ package beast.app;
 
 
 
-import java.io.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.lang.reflect.ParameterizedType;
@@ -37,11 +43,12 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import beast.core.BEASTObject;
 import beast.core.Citation;
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.Loggable;
-import beast.core.BEASTObject;
+import beast.core.util.Log;
 import beast.util.AddOnManager;
 
 
@@ -57,8 +64,6 @@ import beast.util.AddOnManager;
  */
 public class DocMaker {
 
-    private static final long serialVersionUID = 1L;
-
     /**
      * output directory *
      */
@@ -66,7 +71,7 @@ public class DocMaker {
     /**
      * names of the plug-ins to document *
      */
-    List<String> m_sPluginNames;
+    List<String> m_beastObjectNames;
     /**
      * map of plug-in name to its derived plug-ins *
      */
@@ -97,32 +102,32 @@ public class DocMaker {
 
     public DocMaker() {
         // find plug ins to document
-        m_sPluginNames = AddOnManager.find(beast.core.BEASTObject.class, AddOnManager.IMPLEMENTATION_DIR);
+        m_beastObjectNames = AddOnManager.find(beast.core.BEASTObject.class, AddOnManager.IMPLEMENTATION_DIR);
         /** determine hierarchical relation between plug-ins **/
-        m_isa = new HashMap<String, String[]>();
-        m_ancestors = new HashMap<String, List<String>>();
-        m_descriptions = new HashMap<String, String>();
-        m_sLoggables = new HashSet<String>();
-        for (String sPlugin : m_sPluginNames) {
-            m_ancestors.put(sPlugin, new ArrayList<String>());
+        m_isa = new HashMap<>();
+        m_ancestors = new HashMap<>();
+        m_descriptions = new HashMap<>();
+        m_sLoggables = new HashSet<>();
+        for (String beastObjectName : m_beastObjectNames) {
+            m_ancestors.put(beastObjectName, new ArrayList<>());
         }
-        for (String sPlugin : m_sPluginNames) {
+        for (String beastObjectName : m_beastObjectNames) {
             try {
-                Class _class = Class.forName(sPlugin);
-                BEASTObject plugin = (BEASTObject) _class.newInstance();
-                String sDescription = getInheritableDescription(plugin.getClass());
-                System.err.println(sPlugin + " => " + sDescription);
-                m_descriptions.put(sPlugin, sDescription);
-                String[] sImplementations = getImplementations(plugin);
-                m_isa.put(sPlugin, sImplementations);
-                for (String sImp : sImplementations) {
-                    m_ancestors.get(sImp).add(sPlugin);
+                Class<?> _class = Class.forName(beastObjectName);
+                BEASTObject beastObject = (BEASTObject) _class.newInstance();
+                String description = getInheritableDescription(beastObject.getClass());
+                Log.warning.println(beastObjectName + " => " + description);
+                m_descriptions.put(beastObjectName, description);
+                String[] implementations = getImplementations(beastObject);
+                m_isa.put(beastObjectName, implementations);
+                for (String imp : implementations) {
+                    m_ancestors.get(imp).add(beastObjectName);
                 }
-                if (plugin instanceof Loggable) {
-                    m_sLoggables.add(sPlugin);
+                if (beastObject instanceof Loggable) {
+                    m_sLoggables.add(beastObjectName);
                 }
             } catch (Exception e) {
-                System.err.println(sPlugin + " not documented :" + e.getMessage());
+                Log.err.println(beastObjectName + " not documented :" + e.getMessage());
             }
         }
     } // c'tor
@@ -134,12 +139,12 @@ public class DocMaker {
      * for the Beast II SDK.
      */
     void makeJavaDoc() {
-        for (String sPlugin : m_sPluginNames) {
+        for (String beastObjectName : m_beastObjectNames) {
             try {
-                BEASTObject plugin = (BEASTObject) Class.forName(sPlugin).newInstance();
-                System.out.println(sPlugin + ":@description:" + plugin.getDescription());
-                for (Input<?> input : plugin.listInputs()) {
-                    System.out.println(sPlugin + ":" + input.getName() + ":" + input.getTipText());
+                BEASTObject beastObject = (BEASTObject) Class.forName(beastObjectName).newInstance();
+                Log.info.println(beastObjectName + ":@description:" + beastObject.getDescription());
+                for (Input<?> input : beastObject.listInputs()) {
+                    Log.info.println(beastObjectName + ":" + input.getName() + ":" + input.getTipText());
                 }
             } catch (Exception e) {
                 e.printStackTrace();
@@ -148,11 +153,13 @@ public class DocMaker {
     }
 
     /**
-     * create CSS style sheet for all pages *
+     * create CSS style sheet for all pages 
+     * @throws FileNotFoundException *
      */
-    void createCSS() throws Exception {
+    void createCSS() throws FileNotFoundException  {
         PrintStream out = new PrintStream(m_sDir + "/doc.css");
         out.println(getCSS());
+        out.close();
     }
 
     String getCSS() {
@@ -242,9 +249,10 @@ public class DocMaker {
     }
 
     /**
-     * create plug in index pages, shown in left frame *
+     * create plug in index pages, shown in left frame 
+     * @throws FileNotFoundException *
      */
-    void createIndex() throws Exception {
+    void createIndex() throws FileNotFoundException  {
         {
             PrintStream out = new PrintStream(m_sDir + "/index.html");
             out.println("<!DOCTYPE HTML PUBLIC '-//W3C//DTD HTML 4.01 Frameset//EN'\n" +
@@ -262,6 +270,7 @@ public class DocMaker {
                     "		  <FRAME name='display' src='contents.html'>\n" +
                     "		</FRAMESET>\n" +
                     "		</HTML>");
+            out.close();
         }
 
         {
@@ -279,7 +288,8 @@ public class DocMaker {
 	            in.close();
 	            out.close();
         	} catch (Exception e) {
-				// TODO: handle exception
+				// ignore exception -- too bad we could not 
+        		Log.warning.println("WARNING: something went wrong copying beast.png image:" + e.getMessage());
 			}
         }
         PrintStream out = new PrintStream(m_sDir + "/contents.html");
@@ -288,94 +298,97 @@ public class DocMaker {
                 "</head>\n");
         out.println("<body>\n");
         out.println("<h1>BEAST " + version.getVersionString() + " Documentation index</h1>\n");
-        String sPrev = null;
-        String sPrevPackage = null;
-        for (String sPlugin : m_sPluginNames) {
-            String sNext = sPlugin.substring(0, sPlugin.indexOf('.'));
-            if (sPrev != null && !sNext.equals(sPrev)) {
+        String prev = null;
+        String prevPackage = null;
+        for (String beastObjectName : m_beastObjectNames) {
+            String next = beastObjectName.substring(0, beastObjectName.indexOf('.'));
+            if (prev != null && !next.equals(prev)) {
                 out.println("<hr/>");
             }
-            sPrev = sNext;
-            String sName = sPlugin.substring(sPlugin.lastIndexOf('.') + 1);
-            String sPackage = sPlugin.substring(0, sPlugin.lastIndexOf('.'));
+            prev = next;
+            String name = beastObjectName.substring(beastObjectName.lastIndexOf('.') + 1);
+            String packageName = beastObjectName.substring(0, beastObjectName.lastIndexOf('.'));
             // count nr of packages
             int i = 0;
-            while (sPlugin.indexOf('.', i) > 0) {
-                sName = "." + sName;
-                i = sPlugin.indexOf('.', i) + 1;
+            while (beastObjectName.indexOf('.', i) > 0) {
+                name = "." + name;
+                i = beastObjectName.indexOf('.', i) + 1;
             }
-            System.err.println(sName + " <= " + sPlugin);
-            if (sPrevPackage == null || !sPackage.equals(sPrevPackage)) {
-                out.println("<span style='color:grey'>" + sPackage + "</span><br/>");
+            Log.warning.println(name + " <= " + beastObjectName);
+            if (prevPackage == null || !packageName.equals(prevPackage)) {
+                out.println("<span style='color:grey'>" + packageName + "</span><br/>");
             }
-            out.println("<a href='" + sPlugin + ".html' target='display'>" + sName + "</a><br/>");
-            sPrevPackage = sPackage;
+            out.println("<a href='" + beastObjectName + ".html' target='display'>" + name + "</a><br/>");
+            prevPackage = packageName;
         }
         out.println("</body>\n");
         out.println("</html>\n");
+        out.close();
     } // createIndex
 
     /**
-     * Find all plugins that are derived from given plugin *
+     * Find all beastObjects that are derived from given beastObject *
      */
-    String[] getImplementations(BEASTObject plugin) {
-        String sName = plugin.getClass().getName();
-        List<String> sImplementations = new ArrayList<String>();
-        for (String sPlugin : m_sPluginNames) {
+    String[] getImplementations(BEASTObject beastObject) {
+        String name = beastObject.getClass().getName();
+        List<String> implementations = new ArrayList<>();
+        for (String beastObjectName : m_beastObjectNames) {
             try {
-                if (!sPlugin.equals(sName) && plugin.getClass().isAssignableFrom(Class.forName(sPlugin))) {
-                    sImplementations.add(sPlugin);
+                if (!beastObjectName.equals(name) && beastObject.getClass().isAssignableFrom(Class.forName(beastObjectName))) {
+                    implementations.add(beastObjectName);
                 }
             } catch (ClassNotFoundException e) {
             }
         }
-        return sImplementations.toArray(new String[0]);
+        return implementations.toArray(new String[0]);
     }
 
     /**
      * Extract description from @Description annotation
      * but only if the description is inheritable *
      */
-    String getInheritableDescription(Class<?> pluginClass) {
-        String sStr = "";
-        Class<?> superClass = pluginClass.getSuperclass();
+    String getInheritableDescription(Class<?> beastObjectClass) {
+        String str = "";
+        Class<?> superClass = beastObjectClass.getSuperclass();
         if (superClass != null) {
-            String sSuper = getInheritableDescription(superClass);
-            if (sSuper != null) {
-                sStr += sSuper + "<br/>";
+            String superName = getInheritableDescription(superClass);
+            if (superName != null) {
+                str += superName + "<br/>";
             }
         }
-        Annotation[] classAnnotations = pluginClass.getAnnotations();
+        Annotation[] classAnnotations = beastObjectClass.getAnnotations();
         for (Annotation annotation : classAnnotations) {
             if (annotation instanceof Description) {
                 Description description = (Description) annotation;
                 if (description.isInheritable()) {
-                    sStr += description.value();
+                    str += description.value();
                 } else {
                     return null;
                 }
             }
         }
-        return sStr;
+        return str;
     }
 
     /**
-     * Create page for individual plug-in *
+     * Create page for individual plug-in 
+     * @throws FileNotFoundException *
      */
-    void createPluginPage(String sPlugin) throws Exception {
-        PrintStream out = new PrintStream(m_sDir + "/" + sPlugin + ".html");
+    void createBEASTObjectPage(String beastObjectName) throws FileNotFoundException {
+        PrintStream out = new PrintStream(m_sDir + "/" + beastObjectName + ".html");
         try {
-            out.print(getHTML(sPlugin, true));
+            out.print(getHTML(beastObjectName, true));
         } catch (Exception e) {
-            System.err.println("Page creation failed for " + sPlugin + ": " + e.getMessage());
+        	Log.warning.println("Page creation failed for " + beastObjectName + ": " + e.getMessage());
         }
-    } // createPluginPage
+        out.close();
+    } // createBEASTObjectPage
 
 
-    public String getHTML(String sPlugin, boolean bUseExternalStyleSheet) throws Exception {
+    public String getHTML(String beastObjectName, boolean useExternalStyleSheet) throws InstantiationException, IllegalAccessException, ClassNotFoundException  {
         StringBuffer buf = new StringBuffer();
-        buf.append("<html>\n<head>\n<title>BEAST " + version.getVersionString() + " Documentation: " + sPlugin + "</title>\n");
-        if (bUseExternalStyleSheet) {
+        buf.append("<html>\n<head>\n<title>BEAST " + version.getVersionString() + " Documentation: " + beastObjectName + "</title>\n");
+        if (useExternalStyleSheet) {
             buf.append("<link rel='StyleSheet' href='/tmp/styles.css' type='text/css'>\n");
         } else {
             buf.append("<style type='text/css'>\n");
@@ -384,33 +397,33 @@ public class DocMaker {
         }
         buf.append("</head>\n");
         buf.append("<body>\n");
-        buf.append("<h1>BEAST " + version.getVersionString() + " Documentation: " + sPlugin + "</h1>\n");
-        BEASTObject plugin = (BEASTObject) Class.forName(sPlugin).newInstance();
+        buf.append("<h1>BEAST " + version.getVersionString() + " Documentation: " + beastObjectName + "</h1>\n");
+        BEASTObject beastObject = (BEASTObject) Class.forName(beastObjectName).newInstance();
 
         // show all implementation of this plug-in
-        String[] sImplementations = m_isa.get(sPlugin);
-        if (sImplementations == null) {
+        String[] implementations = m_isa.get(beastObjectName);
+        if (implementations == null) {
             // this class is not documented, perhaps outside ClassDiscover path?
-            buf.append("No documentation available for " + sPlugin + ". Perhaps it is not in the ClassDiscovery path\n");
+            buf.append("No documentation available for " + beastObjectName + ". Perhaps it is not in the ClassDiscovery path\n");
             buf.append("</body>\n");
             buf.append("</html>\n");
             return buf.toString();
         }
 
-        if (sImplementations.length > 0) {
+        if (implementations.length > 0) {
             buf.append("<table border='1px'>\n");
             buf.append("<thead><tr><td>implemented by the following</td></tr></thead>\n");
-            for (String sImp : sImplementations) {
-                buf.append("<tr><td><a href='" + sImp + ".html'>" + sImp + "</a></td></tr>\n");
+            for (String imp : implementations) {
+                buf.append("<tr><td><a href='" + imp + ".html'>" + imp + "</a></td></tr>\n");
             }
             buf.append("</table>\n");
         }
 
         // show descriptions of all plug-ins implemented by this plug in...
-        buf.append("<p>" + m_descriptions.get(sPlugin) + "</p>\n");
+        buf.append("<p>" + m_descriptions.get(beastObjectName) + "</p>\n");
 
         // show citation (if any)
-        Citation citation = plugin.getCitation();
+        Citation citation = beastObject.getCitation();
         if (citation != null) {
             buf.append("<h2>Reference:</h2><p>" + citation.value() + "</p>\n");
             if (citation.DOI().length() > 0) {
@@ -419,7 +432,7 @@ public class DocMaker {
         }
 
         // show if this is Loggable
-        if (m_sLoggables.contains(sPlugin)) {
+        if (m_sLoggables.contains(beastObjectName)) {
             buf.append("<p>Logable:");
             buf.append(" yes, this can be used in a log.");
             buf.append("</p>\n");
@@ -430,7 +443,7 @@ public class DocMaker {
         // show short list its inputs
         buf.append("<h2>Inputs:</h2>\n");
         buf.append("<p>");
-        List<Input<?>> inputs = plugin.listInputs();
+        List<Input<?>> inputs = beastObject.listInputs();
         for (Input<?> input : inputs) {
         	buf.append("<a href='#" + input.getName()+"'>" + input.getName() + "</a>, ");
         }
@@ -445,7 +458,7 @@ public class DocMaker {
         	buf.append("<p>&nbsp</p>");
             buf.append("<table id='" + input.getName() + "' border='1px' width='90%'>\n");
             buf.append("<caption>" + input.getName() + "</caption>\n");
-            buf.append("<thead><tr bgcolor='#AAAAAA'><td>type: " + getType(plugin, input.getName()) + "</td></tr></thead>\n");
+            buf.append("<thead><tr bgcolor='#AAAAAA'><td>type: " + getType(beastObject, input.getName()) + "</td></tr></thead>\n");
             buf.append("<tr><td>" + input.getTipText() + "</td></tr>\n");
             buf.append("<tr><td>\n");
             switch (input.getRule()) {
@@ -466,6 +479,9 @@ public class DocMaker {
                 case XOR:
                     buf.append("Either this, or " + input.getOther().getName() + " needs to be specified");
                     break;
+                case FORBIDDEN:
+                    buf.append("Forbidden: must not be specified");
+                    break;
             }
             buf.append("</td></tr>\n");
             buf.append("</table>\n");
@@ -476,15 +492,15 @@ public class DocMaker {
     } // getHTML
 
     /**
-     * determine type of input of a plug in with name sName
+     * determine type of input of a plug in with name name
      */
-    String getType(BEASTObject plugin, String sName) {
+    String getType(BEASTObject beastObject, String name) {
         try {
-            Field[] fields = plugin.getClass().getFields();
+            Field[] fields = beastObject.getClass().getFields();
             for (int i = 0; i < fields.length; i++) {
                 if (fields[i].getType().isAssignableFrom(Input.class)) {
-                    Input<?> input = (Input<?>) fields[i].get(plugin);
-                    if (input.getName().equals(sName)) {
+                    final Input<?> input = (Input<?>) fields[i].get(beastObject);
+                    if (input.getName().equals(name)) {
                         Type t = fields[i].getGenericType();
                         Type[] genericTypes = ((ParameterizedType) t).getActualTypeArguments();
                         if (input.getType() != null) {
@@ -534,14 +550,15 @@ public class DocMaker {
      * including index page + frame
      * individual pages for each plug in
      * *
+     * @throws FileNotFoundException 
      */
-    public void generateDocs() throws Exception {
+    public void generateDocs() throws FileNotFoundException {
         // first, produce CSS & index page
         createCSS();
         createIndex();
         // next, produce pages for individual plug-ins
-        for (String sPlugin : m_sPluginNames) {
-            createPluginPage(sPlugin);
+        for (String beastObjectName : m_beastObjectNames) {
+            createBEASTObjectPage(beastObjectName);
         }
     } // generateDocs
 
diff --git a/src/beast/app/ModelBuilder.java b/src/beast/app/ModelBuilder.java
index a9221ee..5d0c94a 100644
--- a/src/beast/app/ModelBuilder.java
+++ b/src/beast/app/ModelBuilder.java
@@ -26,17 +26,18 @@ package beast.app;
 
 
 
-import javax.imageio.ImageIO;
-import javax.swing.*;
+import java.awt.BorderLayout;
+import java.net.URL;
+
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JMenuBar;
+import javax.swing.JPanel;
 
 import beast.util.AddOnManager;
 import beast.util.Randomizer;
 
 
-import java.awt.*;
-import java.net.URL;
-
-
 /**
  * Program for drawing BEAST 2.0 models.
  * This is a bit of a clutch... but potentially useful.
@@ -69,7 +70,7 @@ public class ModelBuilder extends JPanel {
         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 //        java.net.URL tempURL = ClassLoader.getSystemResource(beast.app.draw.ModelBuilder.ICONPATH + "/GenerationD.png");
         try {
-            URL url = (URL) ClassLoader.getSystemResource(beast.app.draw.ModelBuilder.ICONPATH + "/GenerationD.png");
+            URL url = ClassLoader.getSystemResource(beast.app.draw.ModelBuilder.ICONPATH + "/GenerationD.png");
             ImageIcon icon = new ImageIcon(url);
             f.setIconImage(icon.getImage());
         } catch (Exception e) {
diff --git a/src/beast/app/beastapp/BeastDialog.java b/src/beast/app/beastapp/BeastDialog.java
index 15742d5..d129c62 100644
--- a/src/beast/app/beastapp/BeastDialog.java
+++ b/src/beast/app/beastapp/BeastDialog.java
@@ -1,20 +1,28 @@
 package beast.app.beastapp;
 
-import jam.html.SimpleLinkListener;
-import jam.mac.Utils;
-import jam.panels.OptionsPanel;
+import java.awt.BorderLayout;
+import java.awt.Font;
+import java.io.File;
 
-import javax.swing.*;
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JEditorPane;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
 import javax.swing.border.EmptyBorder;
 import javax.swing.border.TitledBorder;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
-import javax.swing.filechooser.FileFilter;
 
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
+import jam.html.SimpleLinkListener;
+import jam.panels.OptionsPanel;
 
 
 public class BeastDialog {
@@ -22,19 +30,19 @@ public class BeastDialog {
 
     private final OptionsPanel optionPanel;
 
-    private final WholeNumberField seedText = new WholeNumberField((long) 1, Long.MAX_VALUE);
+    private final WholeNumberField seedText = new WholeNumberField(1, Long.MAX_VALUE);
     //    private final JCheckBox overwriteCheckBox = new JCheckBox("Allow overwriting of log files");
-    private final JComboBox logginMode = new JComboBox(new String[]{"default: only write new log files",
+    private final JComboBox<String> logginMode = new JComboBox<>(new String[]{"default: only write new log files",
             "overwrite: overwrite log files",
             "resume: appends log to existing files (if any)"});
 
     private final JCheckBox beagleCheckBox = new JCheckBox("Use BEAGLE library if available:");
     private final JCheckBox beagleInfoCheckBox = new JCheckBox("Show list of available BEAGLE resources and Quit");
-    private final JComboBox beagleResourceCombo = new JComboBox(new Object[]{"CPU", "GPU"});
+    private final JComboBox<Object> beagleResourceCombo = new JComboBox<>(new Object[]{"CPU", "GPU"});
     private final JCheckBox beagleSSECheckBox = new JCheckBox("Use CPU's SSE extensions");
-    private final JComboBox beaglePrecisionCombo = new JComboBox(new Object[]{"Double", "Single"});
+    private final JComboBox<Object> beaglePrecisionCombo = new JComboBox<>(new Object[]{"Double", "Single"});
 
-    private final JComboBox threadsCombo = new JComboBox(new Object[]{"Automatic", 0, 1, 2, 3, 4, 5, 6, 7, 8});
+    private final JComboBox<Object> threadsCombo = new JComboBox<>(new Object[]{"Automatic", 0, 1, 2, 3, 4, 5, 6, 7, 8});
 
     private File inputFile = null;
 
@@ -56,8 +64,7 @@ public class BeastDialog {
         final JButton inputFileButton = new JButton("Choose File...");
         final JTextField inputFileNameText = new JTextField("not selected", 16);
 
-        inputFileButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
+        inputFileButton.addActionListener(ae -> {
                 File file = beast.app.util.Utils.getLoadFile("Load xml file", inputFile, "Beast xml files", "xml");
                 if (file != null) {
                     inputFile = file;
@@ -105,8 +112,7 @@ public class BeastDialog {
 //                    inputFileNameText.setText(inputFile.getName());
 //
 //                }
-            }
-        });
+            });
         inputFileNameText.setEditable(false);
 
         JPanel panel1 = new JPanel(new BorderLayout(0, 0));
@@ -157,7 +163,8 @@ public class BeastDialog {
 
         beagleInfoCheckBox.setEnabled(false);
         beagleCheckBox.addChangeListener(new ChangeListener() {
-            public void stateChanged(ChangeEvent e) {
+            @Override
+			public void stateChanged(ChangeEvent e) {
                 beagleInfo.setEnabled(beagleCheckBox.isSelected());
                 beagleInfoCheckBox.setEnabled(beagleCheckBox.isSelected());
                 label1.setEnabled(beagleCheckBox.isSelected());
diff --git a/src/beast/app/beastapp/BeastLauncher.java b/src/beast/app/beastapp/BeastLauncher.java
index e50c6bc..84b9515 100644
--- a/src/beast/app/beastapp/BeastLauncher.java
+++ b/src/beast/app/beastapp/BeastLauncher.java
@@ -1,17 +1,20 @@
 package beast.app.beastapp;
 
+
 import java.io.File;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.net.MalformedURLException;
 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;
 
 
@@ -23,7 +26,7 @@ import beast.core.util.Log;
  * **/
 public class BeastLauncher {
 
-	public static void main(String[] args) throws Exception {
+	public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
 		if (javaVersionCheck("BEAST")) {
 			loadBEASTJars();
 			BeastMain.main(args);
@@ -37,28 +40,29 @@ public class BeastLauncher {
 	 **/
 	static protected void loadBEASTJars() throws IOException, NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
 		BeastLauncher clu = new BeastLauncher();
+
+		// first try beast from the package_user_dir/lib/beast.jar
+		String beastUserDir = getPackageUserDir();
+		String pathDelimiter = isWindows() ? "\\\\" : "/";
+		beastUserDir +=  pathDelimiter + "BEAST" + pathDelimiter;
+		String beastJar = beastUserDir + "lib";
+		boolean foundOne = checkForBEAST(new File(beastJar), clu);
+		
 		String launcherJar = clu.getClass().getProtectionDomain().getCodeSource().getLocation().getPath();
 		// deal with special characters and spaces in path
 		launcherJar = URLDecoder.decode(launcherJar, "UTF-8");
-
-		// TODO remove following debugging code
-		try {
-			FileWriter outfile = new FileWriter("/tmp/beast.log");
-			outfile.write("jardir = " + launcherJar);
-			outfile.close();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
-
-		System.err.println("jardir = " + launcherJar);
+		Log.warning.println("jardir = " + launcherJar);
 		File jarDir0 = new File(launcherJar).getParentFile();
-		boolean foundOne = false;
 		while ((!foundOne) && (jarDir0 != null)) { // && jarDir0.exists() &&
 											// jarDir0.isDirectory()) {
 			foundOne = checkForBEAST(jarDir0, clu);
 			foundOne = foundOne ||
 			    checkForBEAST((isWindows() ? new File(jarDir0.getAbsolutePath() + "\\lib") : new File(jarDir0.getAbsolutePath() + "/lib")), clu);
 			
+			if (foundOne) {
+				createBeastPackage(jarDir0, pathDelimiter);
+			}
+			
 			jarDir0 = jarDir0.getParentFile();
 		}
 		
@@ -74,8 +78,43 @@ public class BeastLauncher {
 
 	}
 
+	private static void createBeastPackage(File jarDir0, String pathDelimiter) {
+		try {
+			// create package user dir, if it not already exists
+	        File dir = new File(getPackageUserDir() + pathDelimiter + "BEAST" + pathDelimiter + "lib");
+	        if (!dir.exists()) {
+	            if (!dir.mkdirs()) {
+	            	// cannot create dir, let alone create a beast package
+	            	return;
+	            }
+	        }
+	        
+	        File beastJar = new File(jarDir0 + pathDelimiter + "lib" + pathDelimiter + "beast.jar");
+	        File target = new File(dir + pathDelimiter + "beast.jar");
+	        Files.copy(beastJar.toPath(), target.toPath());
+	        
+	        String version = "<addon name='BEAST' version='" + (new BEASTVersion()).getVersion() + "'>\n" +
+	        		"</addon>";
+	        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());
+
+	        // TODO: include templates?
+	        // if so, how to prevent clashes with templates in package and in installation dir?
+	        // TODO: what about examples?
+		} catch (Exception e) {
+			// do net let exceptions hold up launch of beast & friends
+			e.printStackTrace();
+		}
+
+	}
+
 	private static boolean checkForBEAST(File jarDir, Object clu) throws IOException {
-		System.err.println("Checking out " + jarDir.getAbsolutePath());
+		Log.warning.println("Checking out " + jarDir.getAbsolutePath());
 		boolean foundOne = false;
 		if (jarDir.exists()) {
 			URL url = new URL("file://" + (isWindows() ? "/" : "") + jarDir.getAbsolutePath() + "/beast.jar");
@@ -88,15 +127,15 @@ public class BeastLauncher {
 					Method method = sysclass.getDeclaredMethod("addURL", parameters);
 					method.setAccessible(true);
 					method.invoke(sysLoader, new Object[] { url });
-					System.err.println("Loaded URL " + url);
+					Log.warning.println("Loaded URL " + url);
 					foundOne = true;
 				} catch (Throwable t) {
 					t.printStackTrace();
 					throw new IOException("Error, could not add URL to system classloader");
 				}
 		        String classpath = System.getProperty("java.class.path");
-		        String sJar = url + "";
-		        classpath += System.getProperty("path.separator") + sJar.substring(5);
+		        String jar = url + "";
+		        classpath += System.getProperty("path.separator") + jar.substring(5);
 		        System.setProperty("java.class.path", classpath);
 			}
 		}
@@ -132,7 +171,7 @@ public class BeastLauncher {
 					} else {
 						JAVA_VERSION_MSG = JAVA_VERSION_MSG.replaceAll("<br>", "\n");
 						JAVA_VERSION_MSG = JAVA_VERSION_MSG.replaceAll("<[^<]*>", "");
-						System.err.println(JAVA_VERSION_MSG);
+						Log.warning.println(JAVA_VERSION_MSG);
 					}
 					return true;
 				}
@@ -149,4 +188,18 @@ public class BeastLauncher {
 		return true;
 	}
 
+    public static String getPackageUserDir() {
+        
+        if (System.getProperty("beast.user.package.dir") != null)
+            return System.getProperty("beast.user.package.dir");
+        
+        if (Utils.isWindows()) {
+            return System.getProperty("user.home") + "\\BEAST\\" + (new BEASTVersion()).getMajorVersion();
+        }
+        if (Utils.isMac()) {
+            return System.getProperty("user.home") + "/Library/Application Support/BEAST/" + (new BEASTVersion()).getMajorVersion();
+        }
+        // Linux and unices
+        return System.getProperty("user.home") + "/.beast/" + (new BEASTVersion()).getMajorVersion();
+    }
 }
diff --git a/src/beast/app/beastapp/BeastMain.java b/src/beast/app/beastapp/BeastMain.java
index ff89f9d..51ba2b6 100644
--- a/src/beast/app/beastapp/BeastMain.java
+++ b/src/beast/app/beastapp/BeastMain.java
@@ -1,5 +1,21 @@
 package beast.app.beastapp;
 
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Handler;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.WindowConstants;
+import javax.swing.filechooser.FileFilter;
+
 import beagle.BeagleFlag;
 import beagle.BeagleInfo;
 import beast.app.BEASTVersion;
@@ -14,18 +30,6 @@ import beast.util.Randomizer;
 import beast.util.XMLParserException;
 import jam.util.IconUtils;
 
-import javax.swing.*;
-import javax.swing.filechooser.FileFilter;
-
-import java.awt.*;
-import java.io.File;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.util.*;
-import java.util.List;
-import java.util.logging.*;
-
 public class BeastMain {
 
     private final static Version version = new BEASTVersion();
@@ -37,7 +41,8 @@ public class BeastMain {
             getDefaultFrame().setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
         }
 
-        public void doStop() {
+        @Override
+		public void doStop() {
             // thread.stop is deprecated so need to send a message to running threads...
 //            Iterator iter = parser.getThreads();
 //            while (iter.hasNext()) {
@@ -151,27 +156,25 @@ public class BeastMain {
                 // This call never returns as another RuntimeException exception is raised by
                 // the error log handler???
                 infoLogger.warning("Error running file: " + fileName);
-                System.err.println("Fatal exception: " + rex.getMessage());
+                Log.err.println("Fatal exception: " + rex.getMessage());
                 rex.printStackTrace(System.err);
             }
             */
         } catch (XMLParserException e) {
-            System.out.println(e.getMessage());
+           Log.info.println(e.getMessage());
             //e.printStackTrace();
         } catch (Exception e) {
-            e.printStackTrace(System.err);
+            infoLogger.severe("Fatal exception: " + e.getMessage());
+            Log.info.println("Fatal exception: " + e.getMessage());
+            e.printStackTrace(Log.err);
         }
-//            infoLogger.warning("Error running file: " + fileName);
-//            infoLogger.severe("Fatal exception: " + ex.getMessage());
-//            System.err.println("Fatal exception: " + ex.getMessage());
-//            ex.printStackTrace(System.err);
-//        }
     }
 
     static String getFileNameByDialog(final String title) {
         final JFileChooser fc = new JFileChooser(System.getProperty("user.dir"));
         fc.addChoosableFileFilter(new FileFilter() {
-            public boolean accept(final File f) {
+            @Override
+			public boolean accept(final File f) {
                 if (f.isDirectory()) {
                     return true;
                 }
@@ -183,7 +186,8 @@ public class BeastMain {
             }
 
             // The description of this filter
-            public String getDescription() {
+            @Override
+			public String getDescription() {
                 return "xml files";
             }
         });
@@ -202,22 +206,22 @@ public class BeastMain {
         final int n = pageWidth - line.length();
         final int n1 = n / 2;
         for (int i = 0; i < n1; i++) {
-            System.out.print(" ");
+            Log.info.print(" ");
         }
-        System.out.println(line);
+        Log.info.println(line);
     }
 
     public static void printTitle() {
 
         int pageWidth = 72;
 
-        System.out.println();
+        Log.info.println();
         centreLine("BEAST " + version.getVersionString() + ", " + version.getDateString(), pageWidth);
         centreLine("Bayesian Evolutionary Analysis Sampling Trees", pageWidth);
         for (final String creditLine : version.getCredits()) {
             centreLine(creditLine, pageWidth);
         }
-        System.out.println();
+        Log.info.println();
     }
 
     public static void printUsage(final Arguments arguments) {
@@ -233,7 +237,7 @@ public class BeastMain {
     //Main method
     public static void main(final String[] args) throws java.io.IOException {
 
-        final List<String> MCMCargs = new ArrayList<String>();
+        final List<String> MCMCargs = new ArrayList<>();
 //    	Utils.loadUIManager();
 
         final Arguments arguments = new Arguments(
@@ -257,10 +261,10 @@ public class BeastMain {
                         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"),
+                        new Arguments.IntegerOption("instances", "divide site patterns amongst number of threads (use with -threads option)"),
                         new Arguments.Option("beagle", "Use beagle library if available"),
                         new Arguments.Option("beagle_info", "BEAGLE: show information on available resources"),
                         new Arguments.StringOption("beagle_order", "order", "BEAGLE: set order of resource use"),
-                        new Arguments.IntegerOption("beagle_instances", "BEAGLE: divide site patterns amongst instances"),
                         new Arguments.Option("beagle_CPU", "BEAGLE: use CPU instance"),
                         new Arguments.Option("beagle_GPU", "BEAGLE: use GPU instance if available"),
                         new Arguments.Option("beagle_SSE", "BEAGLE: use SSE extensions if available"),
@@ -274,9 +278,9 @@ public class BeastMain {
         try {
             arguments.parseArguments(args);
         } catch (Arguments.ArgumentException ae) {
-            System.out.println();
-            System.out.println(ae.getMessage());
-            System.out.println();
+        	Log.info.println();
+        	Log.info.println(ae.getMessage());
+        	Log.info.println();
             printUsage(arguments);
             System.exit(1);
         }
@@ -322,8 +326,7 @@ public class BeastMain {
                 arguments.hasOption("beagle_SSE") ||
                 arguments.hasOption("beagle_double") ||
                 arguments.hasOption("beagle_single") ||
-                arguments.hasOption("beagle_order") ||
-                arguments.hasOption("beagle_instances");
+                arguments.hasOption("beagle_order");
 
         if (arguments.hasOption("beagle_scaling")) {
             System.setProperty("beagle.scaling", arguments.getStringOption("beagle_scaling"));
@@ -331,14 +334,21 @@ public class BeastMain {
 
         boolean beagleShowInfo = arguments.hasOption("beagle_info");
 
+        
+        boolean useSSE = true;
         if (arguments.hasOption("beagle_CPU")) {
             beagleFlags |= BeagleFlag.PROCESSOR_CPU.getMask();
+            useSSE = false;
         }
         if (arguments.hasOption("beagle_GPU")) {
             beagleFlags |= BeagleFlag.PROCESSOR_GPU.getMask();
+            useSSE = false;
         }
         if (arguments.hasOption("beagle_SSE")) {
             beagleFlags |= BeagleFlag.PROCESSOR_CPU.getMask();
+            useSSE = true;
+        }
+        if (useSSE) {
             beagleFlags |= BeagleFlag.VECTOR_SSE.getMask();
         }
         if (arguments.hasOption("beagle_double")) {
@@ -350,7 +360,8 @@ public class BeastMain {
 
         if (arguments.hasOption("noerr")) {
 		 	System.setErr(new PrintStream(new OutputStream() {
-		 		public void write(int b) {
+		 		@Override
+				public void write(int b) {
 		 		}
 		 	}));
         }        
@@ -359,8 +370,8 @@ public class BeastMain {
             System.setProperty("beagle.resource.order", arguments.getStringOption("beagle_order"));
         }
 
-        if (arguments.hasOption("beagle_instances")) {
-            System.setProperty("beagle.instance.count", Integer.toString(arguments.getIntegerOption("beagle_instances")));
+        if (arguments.hasOption("instances")) {
+            System.setProperty("beast.instance.count", Integer.toString(arguments.getIntegerOption("instances")));
         }
 
         if (arguments.hasOption("beagle_scaling")) {
@@ -369,18 +380,17 @@ public class BeastMain {
 
         if (arguments.hasOption("threads")) {
             threadCount = arguments.getIntegerOption("threads");
-            if (threadCount < 0) {
-                printTitle();
-                System.err.println("The number of threads should be >= 0");
-                System.exit(1);
-            }
+        }
+        if (threadCount <= 0) {
+        	threadCount = Runtime.getRuntime().availableProcessors();
+        	Log.warning.println("Setting number of threads to " + threadCount);
         }
 
         if (arguments.hasOption("seed")) {
             seed = arguments.getLongOption("seed");
             if (seed <= 0) {
                 printTitle();
-                System.err.println("The random number seed should be > 0");
+                Log.err.println("The random number seed should be > 0");
                 System.exit(1);
             }
         }
@@ -470,8 +480,8 @@ public class BeastMain {
 
             inputFile = dialog.getInputFile();
             if (!beagleShowInfo && inputFile == null) {
-                System.err.println("No input file specified");
-                return;
+            	Log.err.println("No input file specified");
+                System.exit(1);
             }
 
         } else {
@@ -486,7 +496,7 @@ public class BeastMain {
 
         if (beagleShowInfo) {
             BeagleInfo.printResourceList();
-            return;
+            System.exit(0);
         }
 
         if (inputFile == null) {
@@ -494,10 +504,10 @@ public class BeastMain {
             final String[] args2 = arguments.getLeftoverArguments();
 
             if (args2.length > 1) {
-                System.err.println("Unknown option: " + args2[1]);
-                System.err.println();
+            	Log.err.println("Unknown option: " + args2[1]);
+            	Log.err.println();
                 printUsage(arguments);
-                return;
+                System.exit(1);
             }
 
             String inputFileName = null;
@@ -561,7 +571,7 @@ public class BeastMain {
 
         if (stateFileName!= null && stateFileName.trim().length() > 0) {
             System.setProperty("state.file.name", stateFileName.trim());
-            System.out.println("Writing state to file " + stateFileName);
+            Log.info.println("Writing state to file " + stateFileName);
         }
 
 //        if (allowOverwrite) {
@@ -583,8 +593,8 @@ public class BeastMain {
         MCMCargs.add(seed + "");
         Randomizer.setSeed(seed);
 
-        System.out.println("Random number seed: " + seed);
-        System.out.println();
+        Log.info.println("Random number seed: " + seed);
+        Log.info.println();
 
         // Construct the beast object
         final BeastMCMC beastMCMC = new BeastMCMC();
@@ -614,8 +624,10 @@ public class BeastMain {
             // logger.severe will throw a RTE but we want to keep the console visible
         } catch (XMLParserException e) {
             System.out.println(e.getMessage());
+            System.exit(1);
         } catch (Exception e) {
             e.printStackTrace();
+            System.exit(1);
         }
 
         if (!window) {
diff --git a/src/beast/app/beastapp/WholeNumberField.java b/src/beast/app/beastapp/WholeNumberField.java
index 46c253c..3ee3c53 100644
--- a/src/beast/app/beastapp/WholeNumberField.java
+++ b/src/beast/app/beastapp/WholeNumberField.java
@@ -1,20 +1,28 @@
 package beast.app.beastapp;
 
-import javax.swing.*;
-import javax.swing.event.*;
+import java.awt.Toolkit;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+
+import javax.swing.JOptionPane;
+import javax.swing.JTextField;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.EventListenerList;
 import javax.swing.text.AttributeSet;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.Document;
 import javax.swing.text.PlainDocument;
-import java.awt.*;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
 
 
 public class WholeNumberField extends JTextField
         implements FocusListener, DocumentListener {
 
-    protected static char MINUS_CHAR = '-';
+ 	private static final long serialVersionUID = 1L;
+
+ 	protected static char MINUS_CHAR = '-';
     protected EventListenerList changeListeners = new EventListenerList();
     protected long min;
     protected long max;
@@ -41,10 +49,12 @@ public class WholeNumberField extends JTextField
         this.addFocusListener(this);
     }
 
-    public void focusGained(FocusEvent evt) {
+    @Override
+	public void focusGained(FocusEvent evt) {
     }
 
-    public void focusLost(FocusEvent evt) {
+    @Override
+	public void focusLost(FocusEvent evt) {
         if (range_check && !range_checked) {
             range_checked = true;
             try {
@@ -120,23 +130,27 @@ public class WholeNumberField extends JTextField
             return value;
     }
 
-    protected Document createDefaultModel() {
+    @Override
+	protected Document createDefaultModel() {
         Document doc = new WholeNumberFieldDocument();
         doc.addDocumentListener(this);
         return doc;
     }
 
-    public void insertUpdate(DocumentEvent e) {
+    @Override
+	public void insertUpdate(DocumentEvent e) {
         range_checked = false;
         fireChanged();
     }
 
-    public void removeUpdate(DocumentEvent e) {
+    @Override
+	public void removeUpdate(DocumentEvent e) {
         range_checked = false;
         fireChanged();
     }
 
-    public void changedUpdate(DocumentEvent e) {
+    @Override
+	public void changedUpdate(DocumentEvent e) {
         range_checked = false;
         fireChanged();
     }
@@ -146,7 +160,10 @@ public class WholeNumberField extends JTextField
     };
 
     class WholeNumberFieldDocument extends PlainDocument {
-        public void insertString(int offs, String str, AttributeSet a)
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public void insertString(int offs, String str, AttributeSet a)
                 throws BadLocationException {
 
             if (str == null) return;
diff --git a/src/beast/app/beauti/AlignmentListInputEditor.java b/src/beast/app/beauti/AlignmentListInputEditor.java
index 87dc9e6..24cc766 100644
--- a/src/beast/app/beauti/AlignmentListInputEditor.java
+++ b/src/beast/app/beauti/AlignmentListInputEditor.java
@@ -1,6 +1,9 @@
 package beast.app.beauti;
 
-import java.awt.*;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.MouseEvent;
@@ -12,7 +15,19 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import javax.swing.*;
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.DefaultCellEditor;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.UIManager;
 import javax.swing.border.Border;
 import javax.swing.event.CellEditorListener;
 import javax.swing.event.DocumentEvent;
@@ -24,13 +39,13 @@ import javax.swing.table.TableColumn;
 import beast.app.draw.ListInputEditor;
 import beast.app.draw.SmallButton;
 import beast.app.util.FileDrop;
+import beast.core.BEASTInterface;
 import beast.core.Input;
 import beast.core.MCMC;
-import beast.core.BEASTInterface;
-import beast.core.Input.Validate;
 import beast.core.State;
 import beast.core.StateNode;
 import beast.core.util.CompoundDistribution;
+import beast.core.util.Log;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.alignment.FilteredAlignment;
 import beast.evolution.alignment.Taxon;
@@ -64,7 +79,7 @@ public class AlignmentListInputEditor extends ListInputEditor {
 	 * alignments that form a partition. These can be FilteredAlignments *
 	 */
 	List<Alignment> alignments;
-	int nPartitions;
+	int partitionCount;
 	GenericTreeLikelihood[] likelihoods;
 	Object[][] tableData;
 	JTable table;
@@ -102,19 +117,20 @@ public class AlignmentListInputEditor extends ListInputEditor {
 		return types;
 	}
 
+	@Override
 	@SuppressWarnings("unchecked")
-	public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
+	public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
 		this.itemNr = itemNr;
 		if (input.get() instanceof List) {
 			alignments = (List<Alignment>) input.get();
 		} else {
 			// we just have a single Alignment
-			alignments = new ArrayList<Alignment>();
+			alignments = new ArrayList<>();
 			alignments.add((Alignment) input.get());
 		}
-		linkButtons = new ArrayList<JButton>();
-		unlinkButtons = new ArrayList<JButton>();
-		nPartitions = alignments.size();
+		linkButtons = new ArrayList<>();
+		unlinkButtons = new ArrayList<>();
+		partitionCount = alignments.size();
 
         // override BoxLayout in superclass
         setLayout(new BorderLayout());
@@ -134,7 +150,8 @@ public class AlignmentListInputEditor extends ListInputEditor {
         Color focusColor = UIManager.getColor("Focus.color");
         Border focusBorder = BorderFactory.createMatteBorder(2, 2, 2, 2, focusColor);
         new FileDrop(null, scrollPane, focusBorder, new FileDrop.Listener() {
-            public void filesDropped(java.io.File[] files) {
+            @Override
+			public void filesDropped(java.io.File[] files) {
                 addFiles(files);
             }   // end filesDropped
         }); // end FileDrop.Listener
@@ -176,7 +193,7 @@ public class AlignmentListInputEditor extends ListInputEditor {
         delButton.setName("-");
         delButton.setToolTipText("Delete selected items from the list");
         delButton.addActionListener(e -> {
-            if (doc.bHasLinkedAtLeastOnce) {
+            if (doc.hasLinkedAtLeastOnce) {
                 JOptionPane.showMessageDialog(null, "Cannot delete partition while parameters are linked");
                 return;
             }
@@ -197,7 +214,7 @@ public class AlignmentListInputEditor extends ListInputEditor {
     }
 
     private void addFiles(File[] fileArray) {
-        List<BEASTInterface> plugins = null;
+        List<BEASTInterface> beastObjects = null;
 
         List<BeautiAlignmentProvider> providers = doc.beautiConfig.alignmentProvider;
         BeautiAlignmentProvider selectedProvider = null;
@@ -213,11 +230,11 @@ public class AlignmentListInputEditor extends ListInputEditor {
             }
         }
 
-        plugins = selectedProvider.getAlignments(doc, fileArray);
+        beastObjects = selectedProvider.getAlignments(doc, fileArray);
 
         // create taxon sets, if any
-        if (plugins != null) {
-	        for (BEASTInterface o : plugins) {
+        if (beastObjects != null) {
+	        for (BEASTInterface o : beastObjects) {
 	        	if (o instanceof Alignment) {
 	        		try {
 						BeautiDoc.createTaxonSet((Alignment) o, doc);
@@ -229,7 +246,7 @@ public class AlignmentListInputEditor extends ListInputEditor {
         }
 
         // Component c = this;
-        if (plugins != null) {
+        if (beastObjects != null) {
             refreshPanel();
         }
     }
@@ -239,62 +256,62 @@ public class AlignmentListInputEditor extends ListInputEditor {
 	/**
      * This method just adds the two buttons (with add()) and does not add any glue or struts before or after.
      * @param box
-     * @param sLabel
+     * @param label
      */
-	private void addLinkUnlinkPair(Box box, String sLabel) {
+	private void addLinkUnlinkPair(Box box, String label) {
 
-        //JLabel label = new JLabel(sLabel+":");
+        //JLabel label = new JLabel(label+":");
         //box.add(label);
-        JButton linkSModelButton = new JButton("Link " + sLabel);
-		linkSModelButton.setName("Link " + sLabel);
+        JButton linkSModelButton = new JButton("Link " + label);
+		linkSModelButton.setName("Link " + label);
 		linkSModelButton.addActionListener(e -> {
             JButton button = (JButton) e.getSource();
             link(columnLabelToNr(button.getText()));
             table.repaint();
         });
 		box.add(linkSModelButton);
-		linkSModelButton.setEnabled(!getDoc().bHasLinkedAtLeastOnce);
-		JButton unlinkSModelButton = new JButton("Unlink " + sLabel);
-		unlinkSModelButton.setName("Unlink " + sLabel);
+		linkSModelButton.setEnabled(!getDoc().hasLinkedAtLeastOnce);
+		JButton unlinkSModelButton = new JButton("Unlink " + label);
+		unlinkSModelButton.setName("Unlink " + label);
 		unlinkSModelButton.addActionListener(e -> {
             JButton button = (JButton) e.getSource();
             unlink(columnLabelToNr(button.getText()));
             table.repaint();
         });
 		box.add(unlinkSModelButton);
-		unlinkSModelButton.setEnabled(!getDoc().bHasLinkedAtLeastOnce);
+		unlinkSModelButton.setEnabled(!getDoc().hasLinkedAtLeastOnce);
 
 		linkButtons.add(linkSModelButton);
 		unlinkButtons.add(unlinkSModelButton);
 	}
 
-	private int columnLabelToNr(String sColumn) {
-		int nColumn;
-		if (sColumn.contains("Tree")) {
-			nColumn = TREE_COLUMN;
-		} else if (sColumn.contains("Clock")) {
-			nColumn = CLOCKMODEL_COLUMN;
+	private int columnLabelToNr(String column) {
+		int columnNr;
+		if (column.contains("Tree")) {
+			columnNr = TREE_COLUMN;
+		} else if (column.contains("Clock")) {
+			columnNr = CLOCKMODEL_COLUMN;
 		} else {
-			nColumn = SITEMODEL_COLUMN;
+			columnNr = SITEMODEL_COLUMN;
 		}
-		return nColumn;
+		return columnNr;
 	}
 
-	private void link(int nColumn) {
-		int[] nSelected = getTableRowSelection();
+	private void link(int columnNr) {
+		int[] selected = getTableRowSelection();
 		// do the actual linking
-		for (int i = 1; i < nSelected.length; i++) {
-			int iRow = nSelected[i];
-			Object old = tableData[iRow][nColumn];
-			tableData[iRow][nColumn] = tableData[nSelected[0]][nColumn];
+		for (int i = 1; i < selected.length; i++) {
+			int rowNr = selected[i];
+			Object old = tableData[rowNr][columnNr];
+			tableData[rowNr][columnNr] = tableData[selected[0]][columnNr];
 			try {
-				updateModel(nColumn, iRow);
+				updateModel(columnNr, rowNr);
 			} catch (Exception ex) {
-				System.err.println(ex.getMessage());
+				Log.warning.println(ex.getMessage());
 				// unlink if we could not link
-				tableData[iRow][nColumn] = old;
+				tableData[rowNr][columnNr] = old;
 				try {
-					updateModel(nColumn, iRow);
+					updateModel(columnNr, rowNr);
 				} catch (Exception ex2) {
 					// ignore
 				}
@@ -302,15 +319,15 @@ public class AlignmentListInputEditor extends ListInputEditor {
 		}
 	}
 
-	private void unlink(int nColumn) {
-		int[] nSelected = getTableRowSelection();
-		for (int i = 1; i < nSelected.length; i++) {
-			int iRow = nSelected[i];
-			tableData[iRow][nColumn] = getDoc().sPartitionNames.get(iRow).partition;
+	private void unlink(int columnNr) {
+		int[] selected = getTableRowSelection();
+		for (int i = 1; i < selected.length; i++) {
+			int rowNr = selected[i];
+			tableData[rowNr][columnNr] = getDoc().partitionNames.get(rowNr).partition;
 			try {
-				updateModel(nColumn, iRow);
+				updateModel(columnNr, rowNr);
 			} catch (Exception ex) {
-				System.err.println(ex.getMessage());
+				Log.err.println(ex.getMessage());
 				ex.printStackTrace();
 			}
 		}
@@ -321,53 +338,53 @@ public class AlignmentListInputEditor extends ListInputEditor {
         return table.getSelectedRows();
 	}
 
-	/** set partition of type nColumn to partition model nr iRow **/
-	void updateModel(int nColumn, int iRow) throws Exception {
-		System.err.println("updateModel: " + iRow + " " + nColumn + " " + table.getSelectedRow() + " "
+	/** set partition of type columnNr to partition model nr rowNr **/
+	void updateModel(int columnNr, int rowNr) {
+		Log.warning.println("updateModel: " + rowNr + " " + columnNr + " " + table.getSelectedRow() + " "
 				+ table.getSelectedColumn());
-		for (int i = 0; i < nPartitions; i++) {
-			System.err.println(i + " " + tableData[i][0] + " " + tableData[i][SITEMODEL_COLUMN] + " "
+		for (int i = 0; i < partitionCount; i++) {
+			Log.warning.println(i + " " + tableData[i][0] + " " + tableData[i][SITEMODEL_COLUMN] + " "
 					+ tableData[i][CLOCKMODEL_COLUMN] + " " + tableData[i][TREE_COLUMN]);
 		}
 
 		getDoc();
-		String sPartition = (String) tableData[iRow][nColumn];
+		String partition = (String) tableData[rowNr][columnNr];
 
 		// check if partition needs renaming
 		String oldName = null;
 		boolean isRenaming = false;
 		try {
-			switch (nColumn) {
+			switch (columnNr) {
 			case SITEMODEL_COLUMN:
-				if (!doc.pluginmap.containsKey("SiteModel.s:" + sPartition)) {
-					String sID = ((BEASTInterface)likelihoods[iRow].siteModelInput.get()).getID();
-					oldName = BeautiDoc.parsePartition(sID);
-					doc.renamePartition(BeautiDoc.SITEMODEL_PARTITION, oldName, sPartition);
+				if (!doc.pluginmap.containsKey("SiteModel.s:" + partition)) {
+					String id = ((BEASTInterface)likelihoods[rowNr].siteModelInput.get()).getID();
+					oldName = BeautiDoc.parsePartition(id);
+					doc.renamePartition(BeautiDoc.SITEMODEL_PARTITION, oldName, partition);
 					isRenaming = true;
 				}
 				break;
 			case CLOCKMODEL_COLUMN: {
-				String sID = likelihoods[iRow].branchRateModelInput.get().getID();
-				String sClockModelName = sID.substring(0, sID.indexOf('.')) + ".c:" + sPartition;
-				if (!doc.pluginmap.containsKey(sClockModelName)) {
-					oldName = BeautiDoc.parsePartition(sID);
-					doc.renamePartition(BeautiDoc.CLOCKMODEL_PARTITION, oldName, sPartition);
+				String id = likelihoods[rowNr].branchRateModelInput.get().getID();
+				String clockModelName = id.substring(0, id.indexOf('.')) + ".c:" + partition;
+				if (!doc.pluginmap.containsKey(clockModelName)) {
+					oldName = BeautiDoc.parsePartition(id);
+					doc.renamePartition(BeautiDoc.CLOCKMODEL_PARTITION, oldName, partition);
 					isRenaming = true;
 				}
 			}
 				break;
 			case TREE_COLUMN:
-				if (!doc.pluginmap.containsKey("Tree.t:" + sPartition)) {
-					String sID = likelihoods[iRow].treeInput.get().getID();
-					oldName = BeautiDoc.parsePartition(sID);
-					doc.renamePartition(BeautiDoc.TREEMODEL_PARTITION, oldName, sPartition);
+				if (!doc.pluginmap.containsKey("Tree.t:" + partition)) {
+					String id = likelihoods[rowNr].treeInput.get().getID();
+					oldName = BeautiDoc.parsePartition(id);
+					doc.renamePartition(BeautiDoc.TREEMODEL_PARTITION, oldName, partition);
 					isRenaming = true;
 				}
 				break;
 			}
 		} catch (Exception e) {
 			JOptionPane.showMessageDialog(this, "Cannot rename item: " + e.getMessage());
-			tableData[iRow][nColumn] = oldName;
+			tableData[rowNr][columnNr] = oldName;
 			return;
 		}
 		if (isRenaming) {
@@ -379,7 +396,7 @@ public class AlignmentListInputEditor extends ListInputEditor {
 		}
 		
 		int partitionID = BeautiDoc.ALIGNMENT_PARTITION;
-		switch (nColumn) {
+		switch (columnNr) {
 		case SITEMODEL_COLUMN:
 			partitionID = BeautiDoc.SITEMODEL_PARTITION;
 			break;
@@ -390,62 +407,72 @@ public class AlignmentListInputEditor extends ListInputEditor {
 			partitionID = BeautiDoc.TREEMODEL_PARTITION;
 			break;
 		}
-		int nPartition = doc.getPartitionNr(sPartition, partitionID);
+		int partitionNr = doc.getPartitionNr(partition, partitionID);
 		GenericTreeLikelihood treeLikelihood = null;
-		if (nPartition >= 0) {
+		if (partitionNr >= 0) {
 			// we ar linking
-			treeLikelihood = likelihoods[nPartition];
+			treeLikelihood = likelihoods[partitionNr];
 		}
 		// (TreeLikelihood) doc.pluginmap.get("treeLikelihood." +
-		// tableData[iRow][NAME_COLUMN]);
+		// tableData[rowNr][NAME_COLUMN]);
 
 		boolean needsRePartition = false;
 		
-		PartitionContext oldContext = new PartitionContext(this.likelihoods[iRow]);
+		PartitionContext oldContext = new PartitionContext(this.likelihoods[rowNr]);
 
-		switch (nColumn) {
+		switch (columnNr) {
 		case SITEMODEL_COLUMN: {
 			SiteModelInterface siteModel = null;
-			if (treeLikelihood != null) { // getDoc().getPartitionNr(sPartition,
+			if (treeLikelihood != null) { // getDoc().getPartitionNr(partition,
 											// BeautiDoc.SITEMODEL_PARTITION) !=
-											// iRow) {
+											// rowNr) {
 				siteModel = treeLikelihood.siteModelInput.get();
 			} else {
-				siteModel = (SiteModel) doc.pluginmap.get("SiteModel.s:" + sPartition);
-				if (siteModel != likelihoods[iRow].siteModelInput.get()) {
-					PartitionContext context = getPartitionContext(iRow);
-					siteModel = (SiteModel.Base) BeautiDoc.deepCopyPlugin((BEASTInterface) likelihoods[iRow].siteModelInput.get(),
-							likelihoods[iRow], (MCMC) doc.mcmc.get(), context, doc, null);
+				siteModel = (SiteModel) doc.pluginmap.get("SiteModel.s:" + partition);
+				if (siteModel != likelihoods[rowNr].siteModelInput.get()) {
+					PartitionContext context = getPartitionContext(rowNr);
+					try {
+					siteModel = (SiteModel.Base) BeautiDoc.deepCopyPlugin((BEASTInterface) likelihoods[rowNr].siteModelInput.get(),
+							likelihoods[rowNr], (MCMC) doc.mcmc.get(), oldContext, context, doc, null);
+					} catch (RuntimeException e) {
+						JOptionPane.showMessageDialog(this, "Could not clone site model: " + e.getMessage());
+						return;
+					}
 				}
 			}
-			SiteModelInterface target = this.likelihoods[iRow].siteModelInput.get();
+			SiteModelInterface target = this.likelihoods[rowNr].siteModelInput.get();
 			if (target instanceof SiteModel.Base && siteModel instanceof SiteModel.Base) {
 				if (!((SiteModel.Base)target).substModelInput.canSetValue(((SiteModel.Base)siteModel).substModelInput.get(), (SiteModel.Base) target)) {
-					throw new Exception("Cannot link site model: substitution models are incompatible");
+					throw new IllegalArgumentException("Cannot link site model: substitution models are incompatible");
 				}
 			} else {
-				throw new Exception("Don't know how to link this site model");
+				throw new IllegalArgumentException("Don't know how to link this site model");
 			}
-			needsRePartition = (this.likelihoods[iRow].siteModelInput.get() != siteModel);
-			this.likelihoods[iRow].siteModelInput.setValue(siteModel, this.likelihoods[iRow]);
+			needsRePartition = (this.likelihoods[rowNr].siteModelInput.get() != siteModel);
+			this.likelihoods[rowNr].siteModelInput.setValue(siteModel, this.likelihoods[rowNr]);
 
-			sPartition = ((BEASTInterface)likelihoods[iRow].siteModelInput.get()).getID();
-			sPartition = BeautiDoc.parsePartition(sPartition);
-			getDoc().setCurrentPartition(BeautiDoc.SITEMODEL_PARTITION, iRow, sPartition);
+			partition = ((BEASTInterface)likelihoods[rowNr].siteModelInput.get()).getID();
+			partition = BeautiDoc.parsePartition(partition);
+			getDoc().setCurrentPartition(BeautiDoc.SITEMODEL_PARTITION, rowNr, partition);
 		}
 			break;
 		case CLOCKMODEL_COLUMN: {
 			BranchRateModel clockModel = null;
-			if (treeLikelihood != null) { // getDoc().getPartitionNr(sPartition,
+			if (treeLikelihood != null) { // getDoc().getPartitionNr(partition,
 											// BeautiDoc.CLOCKMODEL_PARTITION)
-											// != iRow) {
+											// != rowNr) {
 				clockModel = treeLikelihood.branchRateModelInput.get();
 			} else {
-				clockModel = getDoc().getClockModel(sPartition);
-				if (clockModel != likelihoods[iRow].branchRateModelInput.get()) {
-					PartitionContext context = getPartitionContext(iRow);
-					clockModel = (BranchRateModel) BeautiDoc.deepCopyPlugin(likelihoods[iRow].branchRateModelInput.get(),
-							likelihoods[iRow], (MCMC) doc.mcmc.get(), context, doc, null);
+				clockModel = getDoc().getClockModel(partition);
+				if (clockModel != likelihoods[rowNr].branchRateModelInput.get()) {
+					PartitionContext context = getPartitionContext(rowNr);
+					try {
+						clockModel = (BranchRateModel) BeautiDoc.deepCopyPlugin(likelihoods[rowNr].branchRateModelInput.get(),
+							likelihoods[rowNr], (MCMC) doc.mcmc.get(), oldContext, context, doc, null);
+					} catch (RuntimeException e) {
+						JOptionPane.showMessageDialog(this, "Could not clone clock model: " + e.getMessage());
+						return;
+					}
 				}
 			}
 			// make sure that *if* the clock model has a tree as input, it is
@@ -458,49 +485,61 @@ public class AlignmentListInputEditor extends ListInputEditor {
 				}
 
 			}
-			if (tree != null && tree != this.likelihoods[iRow].treeInput.get()) {
-				throw new Exception("Cannot link clock model with different trees");
+			if (tree != null && tree != this.likelihoods[rowNr].treeInput.get()) {
+				throw new IllegalArgumentException("Cannot link clock model with different trees");
 			}
 
-			needsRePartition = (this.likelihoods[iRow].branchRateModelInput.get() != clockModel);
-			this.likelihoods[iRow].branchRateModelInput.setValue(clockModel, this.likelihoods[iRow]);
-			sPartition = likelihoods[iRow].branchRateModelInput.get().getID();
-			sPartition = BeautiDoc.parsePartition(sPartition);
-			getDoc().setCurrentPartition(BeautiDoc.CLOCKMODEL_PARTITION, iRow, sPartition);
+			needsRePartition = (this.likelihoods[rowNr].branchRateModelInput.get() != clockModel);
+			this.likelihoods[rowNr].branchRateModelInput.setValue(clockModel, this.likelihoods[rowNr]);
+			partition = likelihoods[rowNr].branchRateModelInput.get().getID();
+			partition = BeautiDoc.parsePartition(partition);
+			getDoc().setCurrentPartition(BeautiDoc.CLOCKMODEL_PARTITION, rowNr, partition);
 		}
 			break;
 		case TREE_COLUMN: {
 			TreeInterface tree = null;
-			if (treeLikelihood != null) { // getDoc().getPartitionNr(sPartition,
+			if (treeLikelihood != null) { // getDoc().getPartitionNr(partition,
 											// BeautiDoc.TREEMODEL_PARTITION) !=
-											// iRow) {
+											// rowNr) {
 				tree = treeLikelihood.treeInput.get();
 			} else {
-				tree = (TreeInterface) doc.pluginmap.get("Tree.t:" + sPartition);
-				if (tree != likelihoods[iRow].treeInput.get()) {
-					PartitionContext context = getPartitionContext(iRow);
-					tree = (TreeInterface) BeautiDoc.deepCopyPlugin((BEASTInterface) likelihoods[iRow].treeInput.get(), likelihoods[iRow],
-							(MCMC) doc.mcmc.get(), context, doc, null);
+				tree = (TreeInterface) doc.pluginmap.get("Tree.t:" + partition);
+				if (tree != likelihoods[rowNr].treeInput.get()) {
+					PartitionContext context = getPartitionContext(rowNr);
+					try {
+						tree = (TreeInterface) BeautiDoc.deepCopyPlugin((BEASTInterface) likelihoods[rowNr].treeInput.get(), likelihoods[rowNr],
+							(MCMC) doc.mcmc.get(), oldContext, context, doc, null);
+					} catch (RuntimeException e) {
+						JOptionPane.showMessageDialog(this, "Could not clone tree model: " + e.getMessage());
+						return;
+					}
 					
 					State state = ((MCMC) doc.mcmc.get()).startStateInput.get();
 					List<StateNode> stateNodes = new ArrayList<>();
 					stateNodes.addAll(state.stateNodeInput.get());
 					for (StateNode s : stateNodes) {
 						if (s.getID().endsWith(".t:" + oldContext.tree) && !(s instanceof TreeInterface)) {
-							StateNode copy = (StateNode) BeautiDoc.deepCopyPlugin(s, likelihoods[iRow], (MCMC) doc.mcmc.get(), context, doc, null);
+							try {
+								@SuppressWarnings("unused")
+								StateNode copy = (StateNode) BeautiDoc.deepCopyPlugin(s, likelihoods[rowNr], (MCMC) doc.mcmc.get(), oldContext, context, doc, null);
+							} catch (RuntimeException e) {
+								JOptionPane.showMessageDialog(this, "Could not clone tree model: " + e.getMessage());
+								return;
+							}
+
 						}
 					}
 				}
 			}
 			// sanity check: make sure taxon sets are compatible
 			Taxon.assertSameTaxa(tree.getID(), tree.getTaxonset().getTaxaNames(),
-					likelihoods[iRow].dataInput.get().getID(), likelihoods[iRow].dataInput.get().getTaxaNames());
+					likelihoods[rowNr].dataInput.get().getID(), likelihoods[rowNr].dataInput.get().getTaxaNames());
 
-			needsRePartition = (this.likelihoods[iRow].treeInput.get() != tree);
-System.err.println("needsRePartition = " + needsRePartition);			
+			needsRePartition = (this.likelihoods[rowNr].treeInput.get() != tree);
+			Log.warning.println("needsRePartition = " + needsRePartition);			
 			if (needsRePartition) {
-				TreeInterface oldTree = this.likelihoods[iRow].treeInput.get();
-				List<TreeInterface> tModels = new ArrayList<TreeInterface>();
+				TreeInterface oldTree = this.likelihoods[rowNr].treeInput.get();
+				List<TreeInterface> tModels = new ArrayList<>();
 				for (GenericTreeLikelihood likelihood : likelihoods) {
 					if (likelihood.treeInput.get() == oldTree) {
 						tModels.add(likelihood.treeInput.get());
@@ -510,17 +549,18 @@ System.err.println("needsRePartition = " + needsRePartition);
 					// remove old tree from model
 					((BEASTInterface)oldTree).setInputValue("estimate", false);
                 	// use toArray to prevent ConcurrentModificationException
-					for (Object plugin : BEASTInterface.getOutputs(oldTree).toArray()) { //.toArray(new BEASTInterface[0])) {
-						for (Input<?> input : ((BEASTInterface)plugin).listInputs()) {
+					for (Object beastObject : BEASTInterface.getOutputs(oldTree).toArray()) { //.toArray(new BEASTInterface[0])) {
+						for (Input<?> input : ((BEASTInterface)beastObject).listInputs()) {
 							try {
 							if (input.get() == oldTree) {
 								if (input.getRule() != Input.Validate.REQUIRED) {
-									input.setValue(tree/*null*/, (BEASTInterface) plugin);
+									input.setValue(tree/*null*/, (BEASTInterface) beastObject);
 								//} else {
-									//input.setValue(tree, (BEASTInterface) plugin);
+									//input.setValue(tree, (BEASTInterface) beastObject);
 								}
 							} else if (input.get() instanceof List) {
-								List list = (List) input.get();
+								@SuppressWarnings("unchecked")
+								List<TreeInterface> list = (List<TreeInterface>) input.get();
 								if (list.contains(oldTree)) { // && input.getRule() != Validate.REQUIRED) {
 									list.remove(oldTree);
 									if (!list.contains(tree)) {
@@ -535,21 +575,21 @@ System.err.println("needsRePartition = " + needsRePartition);
 					}
 				}
 			}
-			likelihoods[iRow].treeInput.setValue(tree, likelihoods[iRow]);
-			// TreeDistribution d = getDoc().getTreePrior(sPartition);
+			likelihoods[rowNr].treeInput.setValue(tree, likelihoods[rowNr]);
+			// TreeDistribution d = getDoc().getTreePrior(partition);
 			// CompoundDistribution prior = (CompoundDistribution)
 			// doc.pluginmap.get("prior");
 			// if (!getDoc().posteriorPredecessors.contains(d)) {
 			// prior.pDistributions.setValue(d, prior);
 			// }
-			sPartition = likelihoods[iRow].treeInput.get().getID();
-			sPartition = BeautiDoc.parsePartition(sPartition);
-			getDoc().setCurrentPartition(BeautiDoc.TREEMODEL_PARTITION, iRow, sPartition);
+			partition = likelihoods[rowNr].treeInput.get().getID();
+			partition = BeautiDoc.parsePartition(partition);
+			getDoc().setCurrentPartition(BeautiDoc.TREEMODEL_PARTITION, rowNr, partition);
 		}
 		}
-		tableData[iRow][nColumn] = sPartition;
+		tableData[rowNr][columnNr] = partition;
 		if (needsRePartition) {
-			List<BeautiSubTemplate> templates = new ArrayList<BeautiSubTemplate>();
+			List<BeautiSubTemplate> templates = new ArrayList<>();
 			templates.add(doc.beautiConfig.partitionTemplate.get());
 			templates.addAll(doc.beautiConfig.subTemplates);
 			// keep applying rules till model does not change
@@ -570,12 +610,12 @@ System.err.println("needsRePartition = " + needsRePartition);
 		updateStatus();
 	}
 
-	private PartitionContext getPartitionContext(int iRow) {
+	private PartitionContext getPartitionContext(int rowNr) {
 		PartitionContext context = new PartitionContext(
-				tableData[iRow][NAME_COLUMN].toString(),
-				tableData[iRow][SITEMODEL_COLUMN].toString(),
-				tableData[iRow][CLOCKMODEL_COLUMN].toString(),
-				tableData[iRow][TREE_COLUMN].toString());
+				tableData[rowNr][NAME_COLUMN].toString(),
+				tableData[rowNr][SITEMODEL_COLUMN].toString(),
+				tableData[rowNr][CLOCKMODEL_COLUMN].toString(),
+				tableData[rowNr][TREE_COLUMN].toString());
 		return context;
 	}
 
@@ -584,13 +624,13 @@ System.err.println("needsRePartition = " + needsRePartition);
 	}
 
 	void initTableData() {
-		this.likelihoods = new GenericTreeLikelihood[nPartitions];
+		this.likelihoods = new GenericTreeLikelihood[partitionCount];
 		if (tableData == null) {
-			tableData = new Object[nPartitions][NR_OF_COLUMNS];
+			tableData = new Object[partitionCount][NR_OF_COLUMNS];
 		}
 		CompoundDistribution likelihoods = (CompoundDistribution) doc.pluginmap.get("likelihood");
 
-		for (int i = 0; i < nPartitions; i++) {
+		for (int i = 0; i < partitionCount; i++) {
 			Alignment data = alignments.get(i);
 			// partition name
 			tableData[i][NAME_COLUMN] = data;
@@ -642,10 +682,10 @@ System.err.println("needsRePartition = " + needsRePartition);
 	}
 
 	private String getPartition(Input<?> input) {
-		BEASTInterface plugin = (BEASTInterface) input.get();
-		String sID = plugin.getID();
-		String sPartition = BeautiDoc.parsePartition(sID);
-		return sPartition;
+		BEASTInterface beastObject = (BEASTInterface) input.get();
+		String id = beastObject.getID();
+		String partition = BeautiDoc.parsePartition(id);
+		return partition;
 	}
 
 	protected Component createListBox() {
@@ -739,27 +779,27 @@ System.err.println("needsRePartition = " + needsRePartition);
 
 			@Override
 			public boolean stopCellEditing() {
-				System.err.println("stopCellEditing()");
+				//Log.warning.println("stopCellEditing()");
 				table.removeEditor();
-				String sText = m_textField.getText();
+				String text = m_textField.getText();
 				try {
-					Double.parseDouble(sText);
+					Double.parseDouble(text);
 				} catch (Exception e) {
 					return false;
 				}
-				tableData[m_iRow][m_iCol] = sText;
+				tableData[m_iRow][m_iCol] = text;
 				return true;
 			}
 
 			@Override
 			public boolean isCellEditable(EventObject anEvent) {
-				System.err.println("isCellEditable()");
+				//Log.warning.println("isCellEditable()");
 				return table.getSelectedColumn() == 0;
 			}
 
 			@Override
-			public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int iRow,
-					int iCol) {
+			public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int rowNr,
+					int colNr) {
 				return null;
 			}
 
@@ -810,8 +850,8 @@ System.err.println("needsRePartition = " + needsRePartition);
 			public void mouseClicked(MouseEvent e) {
 				if (e.getClickCount() > 1) {
 					try {
-						int iAlignmemt = table.rowAtPoint(e.getPoint());
-						Alignment alignment = alignments.get(iAlignmemt);
+						int alignmemt = table.rowAtPoint(e.getPoint());
+						Alignment alignment = alignments.get(alignmemt);
 						int best = 0;
 						BeautiAlignmentProvider provider = null;
 						for (BeautiAlignmentProvider provider2 : doc.beautiConfig.alignmentProvider) {
@@ -842,48 +882,49 @@ System.err.println("needsRePartition = " + needsRePartition);
 	
 	void setUpComboBoxes() {
 		// set up comboboxes
+		@SuppressWarnings("unchecked")
 		Set<String>[] partitionNames = new HashSet[3];
 		for (int i = 0; i < 3; i++) {
-			partitionNames[i] = new HashSet<String>();
+			partitionNames[i] = new HashSet<>();
 		}
-		for (int i = 0; i < nPartitions; i++) {
+		for (int i = 0; i < partitionCount; i++) {
 			partitionNames[0].add(((BEASTInterface) likelihoods[i].siteModelInput.get()).getID());
 			partitionNames[1].add(likelihoods[i].branchRateModelInput.get().getID());
 			partitionNames[2].add(likelihoods[i].treeInput.get().getID());
 		}
-		String[][] sPartitionNames = new String[3][];
+		String[][] partitionNameStrings = new String[3][];
 		for (int i = 0; i < 3; i++) {
-			sPartitionNames[i] = partitionNames[i].toArray(new String[0]);
+			partitionNameStrings[i] = partitionNames[i].toArray(new String[0]);
 		}
 		for (int j = 0; j < 3; j++) {
-			for (int i = 0; i < sPartitionNames[j].length; i++) {
-				sPartitionNames[j][i] = BeautiDoc.parsePartition(sPartitionNames[j][i]);
+			for (int i = 0; i < partitionNameStrings[j].length; i++) {
+				partitionNameStrings[j][i] = BeautiDoc.parsePartition(partitionNameStrings[j][i]);
 			}
 		}
 		TableColumn col = table.getColumnModel().getColumn(SITEMODEL_COLUMN);
-		JComboBox siteModelComboBox = new JComboBox(sPartitionNames[0]);
+		JComboBox<String> siteModelComboBox = new JComboBox<>(partitionNameStrings[0]);
 		siteModelComboBox.setEditable(true);
 		siteModelComboBox.addActionListener(new ComboActionListener(SITEMODEL_COLUMN));
 
 		col.setCellEditor(new DefaultCellEditor(siteModelComboBox));
 		// If the cell should appear like a combobox in its
 		// non-editing state, also set the combobox renderer
-		col.setCellRenderer(new MyComboBoxRenderer(sPartitionNames[0]));
+		col.setCellRenderer(new MyComboBoxRenderer(partitionNameStrings[0]));
 		col = table.getColumnModel().getColumn(CLOCKMODEL_COLUMN);
 
-		JComboBox clockModelComboBox = new JComboBox(sPartitionNames[1]);
+		JComboBox<String> clockModelComboBox = new JComboBox<>(partitionNameStrings[1]);
 		clockModelComboBox.setEditable(true);
 		clockModelComboBox.addActionListener(new ComboActionListener(CLOCKMODEL_COLUMN));
 
 		col.setCellEditor(new DefaultCellEditor(clockModelComboBox));
-		col.setCellRenderer(new MyComboBoxRenderer(sPartitionNames[1]));
+		col.setCellRenderer(new MyComboBoxRenderer(partitionNameStrings[1]));
 		col = table.getColumnModel().getColumn(TREE_COLUMN);
 
-		JComboBox treeComboBox = new JComboBox(sPartitionNames[2]);
+		JComboBox<String> treeComboBox = new JComboBox<>(partitionNameStrings[2]);
 		treeComboBox.setEditable(true);
 		treeComboBox.addActionListener(new ComboActionListener(TREE_COLUMN));
 		col.setCellEditor(new DefaultCellEditor(treeComboBox));
-		col.setCellRenderer(new MyComboBoxRenderer(sPartitionNames[2]));
+		col.setCellRenderer(new MyComboBoxRenderer(partitionNameStrings[2]));
 		col = table.getColumnModel().getColumn(TAXA_COLUMN);
 		col.setPreferredWidth(30);
 		col = table.getColumnModel().getColumn(SITES_COLUMN);
@@ -891,13 +932,9 @@ System.err.println("needsRePartition = " + needsRePartition);
 		
 		col = table.getColumnModel().getColumn(USE_AMBIGUITIES_COLUMN);
 		JCheckBox checkBox = new JCheckBox();
-		checkBox.addActionListener(new ActionListener() {
-			
-			@Override
-			public void actionPerformed(ActionEvent e) {
-				JCheckBox checkBox = (JCheckBox) e.getSource();
+		checkBox.addActionListener(e -> {
 				if (table.getSelectedRow() >= 0 && table.getSelectedColumn() >= 0) {
-					System.err.println(" " + table.getValueAt(table.getSelectedRow(), table.getSelectedColumn()));
+					Log.warning.println(" " + table.getValueAt(table.getSelectedRow(), table.getSelectedColumn()));
 				}
 				try {
 					int row = table.getSelectedRow();
@@ -913,8 +950,7 @@ System.err.println("needsRePartition = " + needsRePartition);
 					// TODO: handle exception
 				}
 		
-			}
-		});
+			});
 		col.setCellEditor(new DefaultCellEditor(checkBox));
 		col.setCellRenderer(new MyCheckBoxRenderer());
 		col.setPreferredWidth(20);
@@ -922,8 +958,8 @@ System.err.println("needsRePartition = " + needsRePartition);
 	}
 
 	void processPartitionName() {
-		System.err.println("processPartitionName");
-		System.err.println(table.getSelectedColumn() + " " + table.getSelectedRow());
+		Log.warning.println("processPartitionName");
+		Log.warning.println(table.getSelectedColumn() + " " + table.getSelectedRow());
 		String oldName = tableData[table.getSelectedRow()][table.getSelectedColumn()].toString();
 		String newName = nameEditor.getText();
 		if (!oldName.equals(newName) && newName.indexOf(".") >= 0) {
@@ -949,7 +985,7 @@ System.err.println("needsRePartition = " + needsRePartition);
 					partitionID = BeautiDoc.TREEMODEL_PARTITION;
 					break;
 				default:
-					throw new Exception("Cannot rename item in column");
+					throw new IllegalArgumentException("Cannot rename item in column");
 				}
 				getDoc().renamePartition(partitionID, oldName, newName);
 				table.setValueAt(newName, table.getSelectedRow(), table.getSelectedColumn());
@@ -959,16 +995,16 @@ System.err.println("needsRePartition = " + needsRePartition);
 			}
 		}
 		// debugging code:
-		for (int i = 0; i < nPartitions; i++) {
-			System.err.println(i + " " + tableData[i][0]);
-		}
+		//for (int i = 0; i < partitionCount; i++) {
+		//	Log.warning.println(i + " " + tableData[i][0]);
+		//}
 	}
 
 	class ComboActionListener implements ActionListener {
 		int m_nColumn;
 
-		public ComboActionListener(int nColumn) {
-			m_nColumn = nColumn;
+		public ComboActionListener(int columnNr) {
+			m_nColumn = columnNr;
 		}
 
 		@Override
@@ -976,23 +1012,23 @@ System.err.println("needsRePartition = " + needsRePartition);
 //			 SwingUtilities.invokeLater(new Runnable() {
 //			 @Override
 //			 public void run() {
-			System.err.println("actionPerformed ");
-			System.err.println(table.getSelectedRow() + " " + table.getSelectedColumn());
+			Log.warning.println("actionPerformed ");
+			Log.warning.println(table.getSelectedRow() + " " + table.getSelectedColumn());
 			if (table.getSelectedRow() >= 0 && table.getSelectedColumn() >= 0) {
-				System.err.println(" " + table.getValueAt(table.getSelectedRow(), table.getSelectedColumn()));
+				Log.warning.println(" " + table.getValueAt(table.getSelectedRow(), table.getSelectedColumn()));
 			}
-			for (int i = 0; i < nPartitions; i++) {
+			for (int i = 0; i < partitionCount; i++) {
 				try {
 					updateModel(m_nColumn, i);
 				} catch (Exception ex) {
-					System.err.println(ex.getMessage());
+					Log.warning.println(ex.getMessage());
 				}
 			}
 //		    }});
 		}
 	}
 
-	public class MyComboBoxRenderer extends JComboBox implements TableCellRenderer {
+	public class MyComboBoxRenderer extends JComboBox<String> implements TableCellRenderer {
 		private static final long serialVersionUID = 1L;
 
 		public MyComboBoxRenderer(String[] items) {
@@ -1000,6 +1036,7 @@ System.err.println("needsRePartition = " + needsRePartition);
 			setOpaque(true);
 		}
 
+		@Override
 		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
 				boolean hasFocus, int row, int column) {
 			if (isSelected) {
@@ -1024,6 +1061,7 @@ System.err.println("needsRePartition = " + needsRePartition);
 			setOpaque(true);
 		}
 
+		@Override
 		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
 				boolean hasFocus, int row, int column) {
 			if (hasUseAmbiguitiesInput(row)) {
@@ -1044,46 +1082,46 @@ System.err.println("needsRePartition = " + needsRePartition);
 	}
 
 	@Override
-	protected void addSingleItem(BEASTInterface plugin) {
+	protected void addSingleItem(BEASTInterface beastObject) {
 		initTableData();
 		repaint();
 	}
 
 	@Override
 	protected void addItem() {
-		List<BEASTInterface> plugins = doc.beautiConfig.selectAlignments(doc, this);
+		List<BEASTInterface> beastObjects = doc.beautiConfig.selectAlignments(doc, this);
 
 		// Component c = this;
-		if (plugins != null) {
+		if (beastObjects != null) {
 			refreshPanel();
 		}
 	} // addItem
 
 	void delItem() {
-		int[] nSelected = getTableRowSelection();
-		if (nSelected.length == 0) {
+		int[] selected = getTableRowSelection();
+		if (selected.length == 0) {
 			JOptionPane.showMessageDialog(this, "Select partitions to delete, before hitting the delete button");
 		}
 		// do the actual deleting
-		for (int i = nSelected.length - 1; i >= 0; i--) {
-			int iRow = nSelected[i];
+		for (int i = selected.length - 1; i >= 0; i--) {
+			int rowNr = selected[i];
 			
 			// before deleting, unlink site model, clock model and tree
 			
 			// check whether any of the models are linked
-			BranchRateModel.Base clockModel = likelihoods[iRow].branchRateModelInput.get();
-			SiteModelInterface siteModel = likelihoods[iRow].siteModelInput.get();
-			TreeInterface tree = likelihoods[iRow].treeInput.get();
-			List<GenericTreeLikelihood> cModels = new ArrayList<GenericTreeLikelihood>();
-			List<GenericTreeLikelihood> sModels = new ArrayList<GenericTreeLikelihood>();
-			List<GenericTreeLikelihood> tModels = new ArrayList<GenericTreeLikelihood>();
+			BranchRateModel.Base clockModel = likelihoods[rowNr].branchRateModelInput.get();
+			SiteModelInterface siteModel = likelihoods[rowNr].siteModelInput.get();
+			TreeInterface tree = likelihoods[rowNr].treeInput.get();
+			List<GenericTreeLikelihood> cModels = new ArrayList<>();
+			List<GenericTreeLikelihood> models = new ArrayList<>();
+			List<GenericTreeLikelihood> tModels = new ArrayList<>();
 			for (GenericTreeLikelihood likelihood : likelihoods) {
-				if (likelihood != likelihoods[iRow]) {
+				if (likelihood != likelihoods[rowNr]) {
 				if (likelihood.branchRateModelInput.get() == clockModel) {
 					cModels.add(likelihood);
 				}
 				if (likelihood.siteModelInput.get() == siteModel) {
-					sModels.add(likelihood);
+					models.add(likelihood);
 				}
 				if (likelihood.treeInput.get() == tree) {
 					tModels.add(likelihood);
@@ -1094,49 +1132,49 @@ System.err.println("needsRePartition = " + needsRePartition);
 			try {
 				if (cModels.size() > 0) {
 					// clock model is linked, so we need to unlink
-					if (doc.getPartitionNr(clockModel) != iRow) {
-						tableData[iRow][CLOCKMODEL_COLUMN] = getDoc().sPartitionNames.get(iRow).partition;
+					if (doc.getPartitionNr(clockModel) != rowNr) {
+						tableData[rowNr][CLOCKMODEL_COLUMN] = getDoc().partitionNames.get(rowNr).partition;
 					} else {
-						int iFreePartition = doc.getPartitionNr(cModels.get(0));
-						tableData[iRow][CLOCKMODEL_COLUMN] = getDoc().sPartitionNames.get(iFreePartition).partition;
+						int freePartition = doc.getPartitionNr(cModels.get(0));
+						tableData[rowNr][CLOCKMODEL_COLUMN] = getDoc().partitionNames.get(freePartition).partition;
 					}
-					updateModel(CLOCKMODEL_COLUMN, iRow);
+					updateModel(CLOCKMODEL_COLUMN, rowNr);
 				}
 				
-				if (sModels.size() > 0) {
+				if (models.size() > 0) {
 					// site model is linked, so we need to unlink
-					if (doc.getPartitionNr((BEASTInterface) siteModel) != iRow) {
-						tableData[iRow][SITEMODEL_COLUMN] = getDoc().sPartitionNames.get(iRow).partition;
+					if (doc.getPartitionNr((BEASTInterface) siteModel) != rowNr) {
+						tableData[rowNr][SITEMODEL_COLUMN] = getDoc().partitionNames.get(rowNr).partition;
 					} else {
-						int iFreePartition = doc.getPartitionNr(sModels.get(0));
-						tableData[iRow][SITEMODEL_COLUMN] = getDoc().sPartitionNames.get(iFreePartition).partition;
+						int freePartition = doc.getPartitionNr(models.get(0));
+						tableData[rowNr][SITEMODEL_COLUMN] = getDoc().partitionNames.get(freePartition).partition;
 					}
-					updateModel(SITEMODEL_COLUMN, iRow);
+					updateModel(SITEMODEL_COLUMN, rowNr);
 				}
 				
 				if (tModels.size() > 0) {
 					// tree is linked, so we need to unlink
-					if (doc.getPartitionNr((BEASTInterface) tree) != iRow) {
-						tableData[iRow][TREE_COLUMN] = getDoc().sPartitionNames.get(iRow).partition;
+					if (doc.getPartitionNr((BEASTInterface) tree) != rowNr) {
+						tableData[rowNr][TREE_COLUMN] = getDoc().partitionNames.get(rowNr).partition;
 					} else {
-						int iFreePartition = doc.getPartitionNr(tModels.get(0));
-						tableData[iRow][TREE_COLUMN] = getDoc().sPartitionNames.get(iFreePartition).partition;
+						int freePartition = doc.getPartitionNr(tModels.get(0));
+						tableData[rowNr][TREE_COLUMN] = getDoc().partitionNames.get(freePartition).partition;
 					}
-					updateModel(TREE_COLUMN, iRow);
+					updateModel(TREE_COLUMN, rowNr);
 				}
-				getDoc().delAlignmentWithSubnet(alignments.get(iRow));
-				alignments.remove(iRow);
+				getDoc().delAlignmentWithSubnet(alignments.get(rowNr));
+				alignments.remove(rowNr);
 			    // remove deleted likelihood from likelihoods array
 				GenericTreeLikelihood[] tmp = new GenericTreeLikelihood[likelihoods.length - 1];
 				int k = 0;
 				for (int j = 0; j < likelihoods.length; j++) {
-					if (j != iRow) {
+					if (j != rowNr) {
 						tmp[k] = likelihoods[j];
 						k++;
 					}
 				}
 				likelihoods = tmp;
-				nPartitions--;
+				partitionCount--;
 			} catch (Exception e) {
 				JOptionPane.showMessageDialog(null, "Deletion failed: " + e.getMessage());
 				e.printStackTrace();
@@ -1146,8 +1184,8 @@ System.err.println("needsRePartition = " + needsRePartition);
 	} // delItem
 
 	void splitItem() {
-		int[] nSelected = getTableRowSelection();
-		if (nSelected.length == 0) {
+		int[] selected = getTableRowSelection();
+		if (selected.length == 0) {
 			JOptionPane.showMessageDialog(this, "Select partitions to split, before hitting the split button");
 			return;
 		}
@@ -1183,9 +1221,9 @@ System.err.println("needsRePartition = " + needsRePartition);
 			return;
 		}
 
-		for (int i = nSelected.length - 1; i >= 0; i--) {
-			int iRow = nSelected[i];
-			Alignment alignment = alignments.remove(iRow);
+		for (int i = selected.length - 1; i >= 0; i--) {
+			int rowNr = selected[i];
+			Alignment alignment = alignments.remove(rowNr);
 			getDoc().delAlignmentWithSubnet(alignment);
 			try {
 				for (int j = 0; j < filters.length; j++) {
diff --git a/src/beast/app/beauti/AlignmentViewer.java b/src/beast/app/beauti/AlignmentViewer.java
index e514437..eaf25ed 100644
--- a/src/beast/app/beauti/AlignmentViewer.java
+++ b/src/beast/app/beauti/AlignmentViewer.java
@@ -1,21 +1,31 @@
 package beast.app.beauti;
 
-import javax.swing.*;
-import javax.swing.table.*;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.Box;
+import javax.swing.JCheckBox;
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JViewport;
+import javax.swing.ListSelectionModel;
+import javax.swing.ScrollPaneConstants;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableModel;
 
 import beast.evolution.alignment.Alignment;
 import beast.evolution.datatype.DataType;
 import beast.util.NexusParser;
 
 
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
-import java.util.HashMap;
-import java.util.Map;
-
-
 public class AlignmentViewer extends JPanel {
     private static final long serialVersionUID = 1L;
 
@@ -25,7 +35,7 @@ public class AlignmentViewer extends JPanel {
     // flag to indicate that the most frequently occurring character is shown as a dot
     boolean useDots = true;
     Alignment m_alignment;
-    Map<Character, Color> m_customColorMap = new HashMap<Character, Color>();
+    Map<Character, Color> m_customColorMap = new HashMap<>();
 
     /**
      * define which character maps to which color *
@@ -39,26 +49,26 @@ public class AlignmentViewer extends JPanel {
     /**
      * constructor processes alignment and sets up table with first column fixed *
      */
-    public AlignmentViewer(Alignment data) throws Exception {
+    public AlignmentViewer(Alignment data) {
         m_alignment = data;
-        int nSites = data.getSiteCount();
-        int nTaxa = data.getNrTaxa();
-        tableData = new Object[nTaxa][nSites + 1];
+        int siteCount = data.getSiteCount();
+        int taxonCount = data.getTaxonCount();
+        tableData = new Object[taxonCount][siteCount + 1];
         char[] headerChar = updateTableData();
 
         // set up row labels
-        for (int i = 0; i < nTaxa; i++) {
+        for (int i = 0; i < taxonCount; i++) {
             tableData[i][0] = data.getTaxaNames().get(i);
         }
 
         // set up column labels
-        columnData = new Object[nSites + 1];
-        for (int i = 1; i < nSites + 1; i++) {
+        columnData = new Object[siteCount + 1];
+        for (int i = 1; i < siteCount + 1; i++) {
             columnData[i] = "<html>.<br>" + headerChar[i - 1] + "</html>";
         }
         columnData[0] = "<html><br>taxon name</html>";
         columnData[1] = "<html>1<br>" + headerChar[0] + "</html>";
-        for (int i = 10; i < nSites; i += 10) {
+        for (int i = 10; i < siteCount; i += 10) {
             String s = i + "";
             for (int j = 0; j < s.length(); j++) {
             	if (i+j < columnData.length) {
@@ -72,19 +82,23 @@ public class AlignmentViewer extends JPanel {
         final TableModel fixedColumnModel = new AbstractTableModel() {
             private static final long serialVersionUID = 1L;
 
-            public int getColumnCount() {
+            @Override
+			public int getColumnCount() {
                 return 1;
             }
 
-            public String getColumnName(int column) {
+            @Override
+			public String getColumnName(int column) {
                 return columnData[column] + "";
             }
 
-            public int getRowCount() {
+            @Override
+			public int getRowCount() {
                 return tableData.length;
             }
 
-            public Object getValueAt(int row, int column) {
+            @Override
+			public Object getValueAt(int row, int column) {
                 return tableData[row][column];
             }
         };
@@ -92,19 +106,23 @@ public class AlignmentViewer extends JPanel {
         final TableModel mainModel = new AbstractTableModel() {
             private static final long serialVersionUID = 1L;
 
-            public int getColumnCount() {
+            @Override
+			public int getColumnCount() {
                 return columnData.length - 1;
             }
 
-            public String getColumnName(int column) {
+            @Override
+			public String getColumnName(int column) {
                 return columnData[column + 1] + "";
             }
 
-            public int getRowCount() {
+            @Override
+			public int getRowCount() {
                 return tableData.length;
             }
 
-            public Object getValueAt(int row, int column) {
+            @Override
+			public Object getValueAt(int row, int column) {
                 return tableData[row][column + 1];
             }
         };
@@ -122,7 +140,7 @@ public class AlignmentViewer extends JPanel {
         mainTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
         mainTable.setFont(font);
         mainTable.getTableHeader().setFont(font);
-        for (int i = 0; i < nSites; i++) {
+        for (int i = 0; i < siteCount; i++) {
             col = mainTable.getColumnModel().getColumn(i);
             col.setPreferredWidth(6);
         }
@@ -137,7 +155,7 @@ public class AlignmentViewer extends JPanel {
         viewport.setView(fixedTable);
         viewport.setPreferredSize(fixedSize);
         viewport.setMaximumSize(fixedSize);
-        scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable.getTableHeader());
+        scrollPane.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, fixedTable.getTableHeader());
         scrollPane.setRowHeaderView(viewport);
 
 
@@ -146,21 +164,21 @@ public class AlignmentViewer extends JPanel {
     }
 
     private char[] updateTableData() {
-        int nSites = m_alignment.getSiteCount();
-        int nTaxa = m_alignment.getNrTaxa();
+        int siteCount = m_alignment.getSiteCount();
+        int taxonCount = m_alignment.getTaxonCount();
 
         // set up table content
         DataType dataType = m_alignment.getDataType();
-        char[] headerChar = new char[nSites];
+        char[] headerChar = new char[siteCount];
         Object[][] colorMap = setupColorMap();
         try {
-            for (int i = 0; i < nSites; i++) {
-                int iPattern = m_alignment.getPatternIndex(i);
-                int[] pattern = m_alignment.getPattern(iPattern);
-                String sPattern = dataType.state2string(pattern);
-                headerChar[i] = mostFrequentCharInPattern(sPattern);
-                for (int j = 0; j < nTaxa; j++) {
-                    char c = sPattern.charAt(j);
+            for (int i = 0; i < siteCount; i++) {
+                int patternIndex_ = m_alignment.getPatternIndex(i);
+                int[] pattern = m_alignment.getPattern(patternIndex_);
+                String patternString = dataType.state2string(pattern);
+                headerChar[i] = mostFrequentCharInPattern(patternString);
+                for (int j = 0; j < taxonCount; j++) {
+                    char c = patternString.charAt(j);
                     if (c == headerChar[i]) {
                         tableData[j][i + 1] = colorMap[0][c];
                     } else {
@@ -188,12 +206,12 @@ public class AlignmentViewer extends JPanel {
             String[][] colorMap = new String[2][256];
             for (int k = 'A'; k < 'Z'; k++) {
                 int i = k - 'A';
-                int nRed = ((i & 0x80) >> 7) + ((i & 0x10) >> 4) + ((i & 0x2) << 1);
-                int nGreen = ((i & 0x40) >> 6) + ((i & 0x08) >> 2) + ((i & 0x4));
-                int nBlue = ((i & 0x20) >> 5) + ((i & 0x04) >> 1) + ((i & 0x1) << 2);
-                int nColor = (nRed << 21 + (nGreen << 18)) + (nGreen << 13) + (nBlue << 10) + (nBlue << 5) + (nRed << 2);
-                colorMap[0][k] = "<html><font color='#" + Integer.toString(nColor, 16) + "'><b>.</b></html>";
-                colorMap[1][k] = "<html><font color='#" + Integer.toString(nColor, 16) + "'><b>" + ((char) k) + "</font></html>";
+                int red = ((i & 0x80) >> 7) + ((i & 0x10) >> 4) + ((i & 0x2) << 1);
+                int green = ((i & 0x40) >> 6) + ((i & 0x08) >> 2) + ((i & 0x4));
+                int blue = ((i & 0x20) >> 5) + ((i & 0x04) >> 1) + ((i & 0x1) << 2);
+                int color = (red << 21 + (green << 18)) + (green << 13) + (blue << 10) + (blue << 5) + (red << 2);
+                colorMap[0][k] = "<html><font color='#" + Integer.toString(color, 16) + "'><b>.</b></html>";
+                colorMap[1][k] = "<html><font color='#" + Integer.toString(color, 16) + "'><b>" + ((char) k) + "</font></html>";
             }
             for (char c : m_customColorMap.keySet()) {
                 Color color = m_customColorMap.get(c);
@@ -217,19 +235,19 @@ public class AlignmentViewer extends JPanel {
         }
     }
 
-    private char mostFrequentCharInPattern(String sPattern) {
+    private char mostFrequentCharInPattern(String pattern) {
         char[] counts = new char[256];
-        for (int i = 0; i < sPattern.length(); i++) {
-            counts[sPattern.charAt(i)]++;
+        for (int i = 0; i < pattern.length(); i++) {
+            counts[pattern.charAt(i)]++;
         }
-        int iMax = 0, nMax = 0;
+        int maxIndex = 0, max = 0;
         for (int i = 0; i < counts.length; i++) {
-            if (counts[i] > nMax) {
-                iMax = i;
-                nMax = counts[i];
+            if (counts[i] > max) {
+                maxIndex = i;
+                max = counts[i];
             }
         }
-        return (char) iMax;
+        return (char) maxIndex;
     }
 
     public void showInDialog() {
@@ -239,30 +257,22 @@ public class AlignmentViewer extends JPanel {
 
         Box buttonBox = Box.createHorizontalBox();
         JCheckBox useDotsCheckBox = new JCheckBox("Use dots", true);
-        useDotsCheckBox.addActionListener(new ActionListener() {
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        useDotsCheckBox.addActionListener(e -> {
                 JCheckBox _useDots = (JCheckBox) e.getSource();
                 useDots = _useDots.isSelected();
                 updateTableData();
                 repaint();
-            }
-        });
+            });
         buttonBox.add(useDotsCheckBox);
 
         JCheckBox useColorCheckBox = new JCheckBox("Use Color");
         useColorCheckBox.setName("UseColor");
-        useColorCheckBox.addActionListener(new ActionListener() {
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        useColorCheckBox.addActionListener(e -> {
                 JCheckBox hasColor = (JCheckBox) e.getSource();
                 useColor = hasColor.isSelected();
                 updateTableData();
                 repaint();
-            }
-        });
+            });
         buttonBox.add(useColorCheckBox);
         dlg.add(buttonBox, BorderLayout.SOUTH);
 
diff --git a/src/beast/app/beauti/Beauti.java b/src/beast/app/beauti/Beauti.java
index 9733ac7..5137330 100644
--- a/src/beast/app/beauti/Beauti.java
+++ b/src/beast/app/beauti/Beauti.java
@@ -1,45 +1,68 @@
 package beast.app.beauti;
 
 
-import beast.app.BEASTVersion;
-import beast.app.beauti.BeautiDoc.ActionOnExit;
-import beast.app.beauti.BeautiDoc.DOC_STATUS;
-import beast.app.draw.BEASTObjectPanel;
-import beast.app.draw.HelpBrowser;
-import beast.app.draw.ModelBuilder;
-import beast.app.draw.MyAction;
-import beast.app.util.Utils;
-import beast.core.BEASTInterface;
-import beast.core.util.Log;
-import beast.evolution.alignment.Alignment;
-import beast.util.AddOnManager;
-import jam.framework.DocumentFrame;
-
-import org.fest.util.Files;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-
-import javax.swing.*;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import java.awt.*;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Cursor;
+import java.awt.Toolkit;
 import java.awt.datatransfer.Clipboard;
 import java.awt.datatransfer.ClipboardOwner;
 import java.awt.datatransfer.StringSelection;
 import java.awt.datatransfer.Transferable;
-import java.awt.event.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.IOException;
 import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextArea;
+import javax.swing.WindowConstants;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import beast.app.BEASTVersion;
+import beast.app.beauti.BeautiDoc.ActionOnExit;
+import beast.app.beauti.BeautiDoc.DOC_STATUS;
+import beast.app.draw.BEASTObjectPanel;
+import beast.app.draw.HelpBrowser;
+import beast.app.draw.ModelBuilder;
+import beast.app.draw.MyAction;
+import beast.app.util.Utils;
+import beast.core.BEASTInterface;
+import beast.core.util.Log;
+import beast.evolution.alignment.Alignment;
+import beast.util.AddOnManager;
+import jam.framework.DocumentFrame;
+
 
 public class Beauti extends JTabbedPane implements BeautiDocListener {
     private static final long serialVersionUID = 1L;
@@ -70,7 +93,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
      */
     public BeautiPanel currentTab;
 
-    public boolean[] bPaneIsVisible;
+    public boolean[] isPaneIsVisible;
     public BeautiPanel[] panels;
 
     /**
@@ -98,8 +121,8 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
     public boolean isInitialising = true;
 
     public Beauti(BeautiDoc doc) {
-        bPaneIsVisible = new boolean[doc.beautiConfig.panels.size()];
-        Arrays.fill(bPaneIsVisible, true);
+        isPaneIsVisible = new boolean[doc.beautiConfig.panels.size()];
+        Arrays.fill(isPaneIsVisible, true);
         // m_panels = new BeautiPanel[NR_OF_PANELS];
         this.doc = doc;
         this.doc.addBeautiDocListener(this);
@@ -111,28 +134,28 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                 + doc.getFileName());
     }
 
-    void toggleVisible(int nPanelNr) {
-        if (bPaneIsVisible[nPanelNr]) {
-            bPaneIsVisible[nPanelNr] = false;
-            int nTabNr = tabNrForPanel(nPanelNr);
-            removeTabAt(nTabNr);
+    void toggleVisible(int panelNr) {
+        if (isPaneIsVisible[panelNr]) {
+            isPaneIsVisible[panelNr] = false;
+            int tabNr = tabNrForPanel(panelNr);
+            removeTabAt(tabNr);
         } else {
-            bPaneIsVisible[nPanelNr] = true;
-            int nTabNr = tabNrForPanel(nPanelNr);
-            BeautiPanelConfig panel = doc.beautiConfig.panels.get(nPanelNr);
+            isPaneIsVisible[panelNr] = true;
+            int tabNr = tabNrForPanel(panelNr);
+            BeautiPanelConfig panel = doc.beautiConfig.panels.get(panelNr);
             insertTab(
                     doc.beautiConfig.getButtonLabel(this,
-                            panel.sNameInput.get()), null, panels[nPanelNr],
-                    panel.sTipTextInput.get(), nTabNr);
+                            panel.nameInput.get()), null, panels[panelNr],
+                    panel.tipTextInput.get(), tabNr);
             // }
-            setSelectedIndex(nTabNr);
+            setSelectedIndex(tabNr);
         }
     }
 
-    int tabNrForPanel(int nPanelNr) {
+    int tabNrForPanel(int panelNr) {
         int k = 0;
-        for (int i = 0; i < nPanelNr; i++) {
-            if (bPaneIsVisible[i]) {
+        for (int i = 0; i < panelNr; i++) {
+            if (isPaneIsVisible[i]) {
                 k++;
             }
         }
@@ -157,7 +180,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
     Action a_viewModel = new ActionViewModel();
 
     @Override
-    public void docHasChanged() throws Exception {
+    public void docHasChanged() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         setUpPanels();
         setUpViewMenu();
         setTitle();
@@ -171,12 +194,13 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             setEnabled(false);
         } // c'tor
 
-        public ActionSave(String sName, String sToolTipText, String sIcon,
+        public ActionSave(String name, String toolTipText, String icon,
                           int acceleratorKey) {
-            super(sName, sToolTipText, sIcon, acceleratorKey);
+            super(name, toolTipText, icon, acceleratorKey);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             if (!doc.getFileName().equals("")) {
                 if (doc.validateModel() != DOC_STATUS.DIRTY) {
                     JOptionPane.showMessageDialog(null,
@@ -205,7 +229,8 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             setEnabled(false);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             saveAs();
         } // actionPerformed
     } // class ActionSaveAs
@@ -248,14 +273,14 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
         return false;
     } // saveAs
 
-    public void saveFile(String sFileName) {
+    public void saveFile(String fileName) {
         try {
             if (currentTab != null) {
-                currentTab.config.sync(currentTab.iPartition);
+                currentTab.config.sync(currentTab.partitionIndex);
             } else {
                 panels[0].config.sync(0);
             }
-            doc.save(sFileName);
+            doc.save(fileName);
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -268,7 +293,8 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             super("New", "Start new analysis", "new", KeyEvent.VK_N);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             main2(new String[0]);
             // doc.newAnalysis();
             // a_save.setEnabled(false);
@@ -284,12 +310,13 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             super("Load", "Load Beast File", "open", KeyEvent.VK_O);
         }
 
-        public ActionLoad(String sName, String sToolTipText, String sIcon,
+        public ActionLoad(String name, String toolTipText, String icon,
                           int acceleratorKey) {
-            super(sName, sToolTipText, sIcon, acceleratorKey);
+            super(name, toolTipText, icon, acceleratorKey);
         }
 
-        public void actionPerformed(ActionEvent ae) {
+        @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");
             // JFileChooser fileChooser = new JFileChooser(g_sDir);
@@ -297,7 +324,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             // fileChooser.setDialogTitle("Load Beast XML File");
             // if (fileChooser.showOpenDialog(null) ==
             // JFileChooser.APPROVE_OPTION) {
-            // sFileName = fileChooser.getSelectedFile().toString();
+            // fileName = fileChooser.getSelectedFile().toString();
             if (file != null) {
                 setCursor(new Cursor(Cursor.WAIT_CURSOR));
                 doc.newAnalysis();
@@ -335,7 +362,8 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                     "template", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             setCursor(new Cursor(Cursor.WAIT_CURSOR));
             File file = beast.app.util.Utils
                     .getLoadFile("Load Template XML File");
@@ -345,11 +373,11 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             // fileChooser.setDialogTitle("Load Template XML File");
             // if (fileChooser.showOpenDialog(null) ==
             // JFileChooser.APPROVE_OPTION) {
-            // String sFileName = fileChooser.getSelectedFile().toString();
+            // String fileName = fileChooser.getSelectedFile().toString();
             if (file != null) {
-                String sFileName = file.getAbsolutePath();
+                String fileName = file.getAbsolutePath();
                 try {
-                    doc.loadNewTemplate(sFileName);
+                    doc.loadNewTemplate(fileName);
                 } catch (Exception e) {
                     e.printStackTrace();
                     JOptionPane.showMessageDialog(
@@ -370,7 +398,8 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             super("Manage Packages", "Manage Packages", "package", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
         	JPackageDialog panel = new JPackageDialog();
         	JDialog dlg = panel.asDialog(frame);
             dlg.setVisible(true);
@@ -394,9 +423,9 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
 //                    KeyEvent.VK_I);
 //        }
 //
-//        public ActionImport(String sName, String sToolTipText, String sIcon,
+//        public ActionImport(String name, String toolTipText, String icon,
 //                            int acceleratorKey) {
-//            super(sName, sToolTipText, sIcon, acceleratorKey);
+//            super(name, toolTipText, icon, acceleratorKey);
 //        }
 //
 //        public void actionPerformed(ActionEvent ae) {
@@ -441,7 +470,8 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             super("Close", "Close Window", "close", KeyEvent.VK_W);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             // if (!m_doc.m_bIsSaved) {
             if (!quit()) {
                 return;
@@ -469,7 +499,8 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             putValue(Action.MNEMONIC_KEY, new Integer('x'));
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             // if (!m_doc.m_bIsSaved) {
             if (!quit()) {
                 return;
@@ -483,7 +514,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             int result = JOptionPane.showConfirmDialog(null,
                     "Do you want to save the Beast specification?",
                     "Save before closing?", JOptionPane.YES_NO_CANCEL_OPTION);
-            System.err.println("result=" + result);
+            Log.err.println("result=" + result);
             if (result == JOptionPane.CANCEL_OPTION) {
                 return false;
             }
@@ -502,17 +533,17 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
         private static final long serialVersionUID = 1L;
         int m_iPanel;
 
-        ViewPanelCheckBoxMenuItem(int iPanel) {
+        ViewPanelCheckBoxMenuItem(int panelIndex) {
             super("Show "
-                    + doc.beautiConfig.panels.get(iPanel).sNameInput.get()
+                    + doc.beautiConfig.panels.get(panelIndex).nameInput.get()
                     + " panel",
-                    doc.beautiConfig.panels.get(iPanel).bIsVisibleInput.get());
-            m_iPanel = iPanel;
+                    doc.beautiConfig.panels.get(panelIndex).isVisibleInput.get());
+            m_iPanel = panelIndex;
             if (m_viewPanelCheckBoxMenuItems == null) {
                 m_viewPanelCheckBoxMenuItems = new ViewPanelCheckBoxMenuItem[doc.beautiConfig.panels
                         .size()];
             }
-            m_viewPanelCheckBoxMenuItems[iPanel] = this;
+            m_viewPanelCheckBoxMenuItems[panelIndex] = this;
         } // c'tor
 
         void doAction() {
@@ -532,11 +563,12 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             super("View all", "View all panels", "viewall", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
-            for (int nPanelNr = 0; nPanelNr < bPaneIsVisible.length; nPanelNr++) {
-                if (!bPaneIsVisible[nPanelNr]) {
-                    toggleVisible(nPanelNr);
-                    m_viewPanelCheckBoxMenuItems[nPanelNr].setState(true);
+        @Override
+		public void actionPerformed(ActionEvent ae) {
+            for (int panelNr = 0; panelNr < isPaneIsVisible.length; panelNr++) {
+                if (!isPaneIsVisible[panelNr]) {
+                    toggleVisible(panelNr);
+                    m_viewPanelCheckBoxMenuItems[panelNr].setState(true);
                 }
             }
         } // actionPerformed
@@ -549,7 +581,8 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             super("About", "Help about", "about", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             BEASTVersion version = new BEASTVersion();
             JOptionPane.showMessageDialog(null, version.getCredits(),
                     "About Beauti " + version.getVersionString(), JOptionPane.PLAIN_MESSAGE,
@@ -564,12 +597,13 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             super("Help", "Help on current panel", "help", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             setCursor(new Cursor(Cursor.WAIT_CURSOR));
             HelpBrowser b = new HelpBrowser(currentTab.config.getType());
             b.setSize(800, 800);
             b.setVisible(true);
-            b.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+            b.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
             setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
         }
     } // class ActionHelp
@@ -581,12 +615,13 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             super("Messages", "Show information, warning and error messages", "msgs", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
-        	if (doc.baos == null) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
+        	if (BeautiDoc.baos == null) {
         		JOptionPane.showMessageDialog(frame, "<html>Error and warning messages are printed to Stdout and Stderr<br>" +
         				"To show them here, start BEAUti with the -capture argument.</html>");
         	} else {
-	        	String msgs = doc.baos.toString();
+	        	String msgs = BeautiDoc.baos.toString();
 	        	JTextArea textArea = new JTextArea(msgs);
 	        	textArea.setRows(40);
 	        	textArea.setColumns(50);
@@ -606,18 +641,19 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                     "citation", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
-            String sCitations = doc.mcmc.get().getCitations();
+        @Override
+		public void actionPerformed(ActionEvent ae) {
+            String citations = doc.mcmc.get().getCitations();
             try {
                 StringSelection stringSelection = new StringSelection(
-                        sCitations);
+                        citations);
                 Clipboard clipboard = Toolkit.getDefaultToolkit()
                         .getSystemClipboard();
                 clipboard.setContents(stringSelection, this);
             } catch (Exception e) {
                 e.printStackTrace();
             }
-            JOptionPane.showMessageDialog(null, sCitations
+            JOptionPane.showMessageDialog(null, citations
                     + "\nCitations copied to clipboard",
                     "Citation(s) applicable to this model:",
                     JOptionPane.INFORMATION_MESSAGE);
@@ -637,7 +673,8 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             super("View model", "View model graph", "model", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             JFrame frame = new JFrame("Model Builder");
             ModelBuilder modelBuilder = new ModelBuilder();
             modelBuilder.init();
@@ -678,44 +715,36 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
         modeMenu.setMnemonic('M');
 
         autoSetClockRate = new JCheckBoxMenuItem(
-                "Automatic set clock rate", this.doc.bAutoSetClockRate);
-        autoSetClockRate.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
-                doc.bAutoSetClockRate = autoSetClockRate.getState();
+                "Automatic set clock rate", this.doc.autoSetClockRate);
+        autoSetClockRate.addActionListener(ae -> {
+                doc.autoSetClockRate = autoSetClockRate.getState();
                 refreshPanel();
-            }
-        });
+            });
         modeMenu.add(autoSetClockRate);
 
         allowLinking = new JCheckBoxMenuItem(
-                "Allow parameter linking", this.doc.bAllowLinking);
-        allowLinking.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
-                doc.bAllowLinking = allowLinking.getState();
+                "Allow parameter linking", this.doc.allowLinking);
+        allowLinking.addActionListener(ae -> {
+                doc.allowLinking = allowLinking.getState();
                 doc.determineLinks();
                 refreshPanel();
-            }
-        });
+            });
         modeMenu.add(allowLinking);
 
         autoUpdateOperatorWeights = new JCheckBoxMenuItem(
-                "Automatic change operator weights for *BEAST analyses", this.doc.bAutoUpdateOperatorWeights);
-        autoUpdateOperatorWeights.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
-                doc.bAutoUpdateOperatorWeights = autoUpdateOperatorWeights.getState();
+                "Automatic change operator weights for *BEAST analyses", this.doc.autoUpdateOperatorWeights);
+        autoUpdateOperatorWeights.addActionListener(ae -> {
+                doc.autoUpdateOperatorWeights = autoUpdateOperatorWeights.getState();
                 refreshPanel();
-            }
-        });
+            });
         modeMenu.add(autoUpdateOperatorWeights);
 
         autoUpdateFixMeanSubstRate = new JCheckBoxMenuItem(
-                "Automatic set fix mean substitution rate flag", this.doc.bAutoUpdateFixMeanSubstRate);
-        autoUpdateFixMeanSubstRate.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
-                doc.bAutoUpdateFixMeanSubstRate = autoUpdateFixMeanSubstRate.getState();
+                "Automatic set fix mean substitution rate flag", this.doc.autoUpdateFixMeanSubstRate);
+        autoUpdateFixMeanSubstRate.addActionListener(ae -> {
+                doc.autoUpdateFixMeanSubstRate = autoUpdateFixMeanSubstRate.getState();
                 refreshPanel();
-            }
-        });
+            });
         modeMenu.add(autoUpdateFixMeanSubstRate);
 
         // final JCheckBoxMenuItem muteSound = new
@@ -795,9 +824,9 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
 		                setCursor(new Cursor(Cursor.WAIT_CURSOR));
 
 		                // get user-specified alignments
-				        List<BEASTInterface> plugins = provider.getAlignments(doc);
-				        if (plugins != null) {
-					        for (BEASTInterface o : plugins) {
+				        List<BEASTInterface> beastObjects = provider.getAlignments(doc);
+				        if (beastObjects != null) {
+					        for (BEASTInterface o : beastObjects) {
 					        	if (o instanceof Alignment) {
 					        		try {
 					        			BeautiDoc.createTaxonSet((Alignment) o, doc);
@@ -841,14 +870,12 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
 	void setUpViewMenu() {
         m_viewPanelCheckBoxMenuItems = null;
         viewMenu.removeAll();
-        for (int iPanel = 0; iPanel < doc.beautiConfig.panels.size(); iPanel++) {
+        for (int panelIndex = 0; panelIndex < doc.beautiConfig.panels.size(); panelIndex++) {
             final ViewPanelCheckBoxMenuItem viewPanelAction = new ViewPanelCheckBoxMenuItem(
-                    iPanel);
-            viewPanelAction.addActionListener(new ActionListener() {
-                public void actionPerformed(ActionEvent ae) {
+                    panelIndex);
+            viewPanelAction.addActionListener(ae -> {
                     viewPanelAction.doAction();
-                }
-            });
+                });
             viewMenu.add(viewPanelAction);
         }
         viewMenu.addSeparator();
@@ -869,9 +896,9 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                 fileSep = "\\";
             }
             int i = m_sFileName.lastIndexOf(fileSep) + 1;
-            String sName = m_sFileName.substring(
+            String name = m_sFileName.substring(
                     i, m_sFileName.length() - 4);
-            putValue(Action.NAME, sName);
+            putValue(Action.NAME, name);
             try {
                 DocumentBuilderFactory factory = DocumentBuilderFactory
                         .newInstance();
@@ -881,7 +908,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                 Element template = doc.getDocumentElement();
                 templateInfo = template.getAttribute("templateinfo");
                 if (templateInfo == null || templateInfo.length() == 0) {
-                    templateInfo = "switch to " + sName + " template";
+                    templateInfo = "switch to " + name + " template";
                 }
                 //templateInfo = "<html>" + templateInfo + "</html>";
                 putValue(Action.SHORT_DESCRIPTION, templateInfo);
@@ -915,10 +942,10 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
     }
 
 	private List<AbstractAction> getTemplateActions() {
-        List<AbstractAction> actions = new ArrayList<AbstractAction>();
-        List<String> sBeastDirectories = AddOnManager.getBeastDirectories();
-        for (String sDir : sBeastDirectories) {
-            File dir = new File(sDir + "/templates");
+        List<AbstractAction> actions = new ArrayList<>();
+        List<String> beastDirectories = AddOnManager.getBeastDirectories();
+        for (String dirName : beastDirectories) {
+            File dir = new File(dirName + "/templates");
             getTemplateActionForDir(dir, actions);
         }
         return actions;
@@ -931,14 +958,14 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                 for (File template : files) {
                     if (template.getName().toLowerCase().endsWith(".xml")) {
                         try {
-                            String sXML2 = BeautiDoc.load(template.getAbsolutePath());
-                            if (sXML2.contains("templateinfo=")) {
-                            	String sFileName = template.getName();
-                                sFileName = sFileName.substring(0, sFileName.length() - 4);
+                            String xml2 = BeautiDoc.load(template.getAbsolutePath());
+                            if (xml2.contains("templateinfo=")) {
+                            	String fileName = template.getName();
+                                fileName = fileName.substring(0, fileName.length() - 4);
                                 boolean duplicate = false;
                             	for (AbstractAction action : actions) {
                             		String name = action.getValue(Action.NAME).toString(); 
-                            		if (name.equals(sFileName)) {
+                            		if (name.equals(fileName)) {
                             			duplicate = true;
                             		}
                             	}
@@ -947,7 +974,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                             	}
                             }
                         } catch (Exception e) {
-                            System.err.println(e.getMessage());
+                        	Log.warning.println(e.getMessage());
                         }
                     }
                 }
@@ -956,7 +983,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
     }
 
     private List<AbstractAction> getWorkDirActions() {
-        List<AbstractAction> actions = new ArrayList<AbstractAction>();
+        List<AbstractAction> actions = new ArrayList<>();
         List<String> beastDirectories = AddOnManager.getBeastDirectories();
         for (String dir : beastDirectories) {
         	String exampledir = dir + File.separator+ "examples";
@@ -984,25 +1011,25 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
         return actions;
     }
 
-    void setMenuVisibiliy(String sParentName, Component c) {
-        String sName = "";
+    void setMenuVisibiliy(String parentName, Component c) {
+        String name = "";
         if (c instanceof JMenu) {
-            sName = ((JMenu) c).getText();
+            name = ((JMenu) c).getText();
         } else if (c instanceof JMenuItem) {
-            sName = ((JMenuItem) c).getText();
+            name = ((JMenuItem) c).getText();
         }
-        if (sName.length() > 0
-                && doc.beautiConfig.menuIsInvisible(sParentName + sName)) {
+        if (name.length() > 0
+                && doc.beautiConfig.menuIsInvisible(parentName + name)) {
             c.setVisible(false);
         }
         if (c instanceof JMenu) {
             for (Component x : ((JMenu) c).getMenuComponents()) {
-                setMenuVisibiliy(sParentName + sName
-                        + (sName.length() > 0 ? "." : ""), x);
+                setMenuVisibiliy(parentName + name
+                        + (name.length() > 0 ? "." : ""), x);
             }
         } else if (c instanceof Container) {
             for (int i = 0; i < ((Container) c).getComponentCount(); i++) {
-                setMenuVisibiliy(sParentName, ((Container) c).getComponent(i));
+                setMenuVisibiliy(parentName, ((Container) c).getComponent(i));
             }
         }
     }
@@ -1010,41 +1037,41 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
     // hide panels as indicated in the hidepanels attribute in the XML template,
     // or use default tabs to hide otherwise.
     public void hidePanels() {
-        // for (int iPanel = 0; iPanel < BeautiConfig.g_panels.size(); iPanel++)
+        // for (int panelIndex = 0; panelIndex < BeautiConfig.g_panels.size(); panelIndex++)
         // {
-        // BeautiPanelConfig panelConfig = BeautiConfig.g_panels.get(iPanel);
+        // BeautiPanelConfig panelConfig = BeautiConfig.g_panels.get(panelIndex);
         // if (!panelConfig.m_bIsVisibleInput.get()) {
-        // toggleVisible(iPanel);
+        // toggleVisible(panelIndex);
         // }
         // }
     } // hidePanels
 
-    public void setUpPanels() throws Exception {
+    public void setUpPanels() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         isInitialising = true;
         // remove any existing tabs
         if (getTabCount() > 0) {
             while (getTabCount() > 0) {
                 removeTabAt(0);
             }
-            bPaneIsVisible = new boolean[doc.beautiConfig.panels.size()];
-            Arrays.fill(bPaneIsVisible, true);
+            isPaneIsVisible = new boolean[doc.beautiConfig.panels.size()];
+            Arrays.fill(isPaneIsVisible, true);
         }
-        for (int iPanel = 0; iPanel < doc.beautiConfig.panels.size(); iPanel++) {
-            BeautiPanelConfig panelConfig = doc.beautiConfig.panels.get(iPanel);
-            bPaneIsVisible[iPanel] = panelConfig.bIsVisibleInput.get();
+        for (int panelIndex = 0; panelIndex < doc.beautiConfig.panels.size(); panelIndex++) {
+            BeautiPanelConfig panelConfig = doc.beautiConfig.panels.get(panelIndex);
+            isPaneIsVisible[panelIndex] = panelConfig.isVisibleInput.get();
         }
         // add panels according to BeautiConfig
         panels = new BeautiPanel[doc.beautiConfig.panels.size()];
-        for (int iPanel = 0; iPanel < doc.beautiConfig.panels.size(); iPanel++) {
-            BeautiPanelConfig panelConfig = doc.beautiConfig.panels.get(iPanel);
-            panels[iPanel] = new BeautiPanel(iPanel, this.doc, panelConfig);
+        for (int panelIndex = 0; panelIndex < doc.beautiConfig.panels.size(); panelIndex++) {
+            BeautiPanelConfig panelConfig = doc.beautiConfig.panels.get(panelIndex);
+            panels[panelIndex] = new BeautiPanel(panelIndex, this.doc, panelConfig);
             addTab(doc.beautiConfig.getButtonLabel(this, panelConfig.getName()),
-                    null, panels[iPanel], panelConfig.getTipText());
+                    null, panels[panelIndex], panelConfig.getTipText());
         }
 
-        for (int iPanel = doc.beautiConfig.panels.size() - 1; iPanel >= 0; iPanel--) {
-            if (!bPaneIsVisible[iPanel]) {
-                removeTabAt(iPanel);
+        for (int panelIndex = doc.beautiConfig.panels.size() - 1; panelIndex >= 0; panelIndex--) {
+            if (!isPaneIsVisible[panelIndex]) {
+                removeTabAt(panelIndex);
             }
         }
         isInitialising = false;
@@ -1054,6 +1081,9 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
      * record number of frames. If the last frame is closed, exit the app. *
      */
     static int BEAUtiIntances = 0;
+    static public boolean isInBeauti() {
+    	return BEAUtiIntances > 0;
+    }
 
     public static Beauti main2(String[] args) {
         try {
@@ -1111,7 +1141,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             BEASTObjectPanel.init();
 
             BeautiDoc doc = new BeautiDoc();
-            doc.baos = baos;
+            BeautiDoc.baos = baos;
             if (doc.parseArgs(args) == ActionOnExit.WRITE_XML) {
                 return null;
             }
@@ -1127,7 +1157,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                     if (url != null) {
                         icon = new ImageIcon(url);
                     } else {
-                        System.err.println("Unable to find image: " + ModelBuilder.ICONPATH + "beauti.png");
+                    	Log.warning.println("Unable to find image: " + ModelBuilder.ICONPATH + "beauti.png");
                     }
                     jam.framework.Application application = new jam.framework.MultiDocApplication(null, "BEAUti", "about", icon) {
 
@@ -1182,7 +1212,7 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
                     if (beauti.currentTab != null) {
                         if (!beauti.isInitialising) {
                             beauti.currentTab.config
-                                    .sync(beauti.currentTab.iPartition);
+                                    .sync(beauti.currentTab.partitionIndex);
                         }
                         BeautiPanel panel = (BeautiPanel) beauti
                                 .getSelectedComponent();
@@ -1216,10 +1246,11 @@ public class Beauti extends JTabbedPane implements BeautiDocListener {
             frame.setVisible(true);
 
             // check file needs to be save on closing main frame
-            frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
+            frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
             BEAUtiIntances++;
             frame.addWindowListener(new WindowAdapter() {
-                public void windowClosing(WindowEvent e) {
+                @Override
+				public void windowClosing(WindowEvent e) {
                     if (!beauti.quit()) {
                         return;
                     }
diff --git a/src/beast/app/beauti/BeautiAlignmentProvider.java b/src/beast/app/beauti/BeautiAlignmentProvider.java
index 820e165..94a03cb 100644
--- a/src/beast/app/beauti/BeautiAlignmentProvider.java
+++ b/src/beast/app/beauti/BeautiAlignmentProvider.java
@@ -4,8 +4,13 @@ package beast.app.beauti;
 
 
 
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.StringReader;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -14,15 +19,17 @@ import java.util.Set;
 
 import javax.swing.JOptionPane;
 import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.NodeList;
 import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
 
+import beast.core.BEASTInterface;
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 import beast.core.Input.Validate;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.alignment.FilteredAlignment;
@@ -36,11 +43,11 @@ import beast.util.XMLParser;
 @Description("Class for creating new alignments to be edited by AlignmentListInputEditor")
 public class BeautiAlignmentProvider extends BEASTObject {
 	
-	public Input<BeautiSubTemplate> template = new Input<BeautiSubTemplate>("template", "template to be used after creating a new alignment. ", Validate.REQUIRED);
+	final public Input<BeautiSubTemplate> template = new Input<>("template", "template to be used after creating a new alignment. ", Validate.REQUIRED);
 
 	
 	@Override
-	public void initAndValidate() throws Exception {
+	public void initAndValidate() {
 	}
 	
 	/** 
@@ -54,7 +61,7 @@ public class BeautiAlignmentProvider extends BEASTObject {
 	/** 
 	 * return new alignment, return null if not successful 
 	 * **/
-	List<BEASTInterface> getAlignments(BeautiDoc doc) {
+	protected List<BEASTInterface> getAlignments(BeautiDoc doc) {
         File [] files = beast.app.util.Utils.getLoadFiles("Load Alignment File",
                 new File(Beauti.g_sDir), "Alignment files", "xml", 
                 "fa","fas","fst","fasta","fna","ffn","faa","frn",
@@ -72,7 +79,7 @@ public class BeautiAlignmentProvider extends BEASTObject {
      * @return
      */
     public List<BEASTInterface> getAlignments(BeautiDoc doc, File[] files) {
-        List<BEASTInterface> selectedPlugins = new ArrayList<BEASTInterface>();
+        List<BEASTInterface> selectedBEASTObjects = new ArrayList<>();
         for (File file : files) {
             String fileName = file.getName();
 			String fileExtension = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
@@ -91,7 +98,7 @@ public class BeautiAlignmentProvider extends BEASTObject {
 							 * overlap
 							 **/
 							int[] used = new int[parser.m_alignment.getSiteCount()];
-							Set<Integer> overlap = new HashSet<Integer>();
+							Set<Integer> overlap = new HashSet<>();
 							int partitionNr = 1;
 							for (Alignment data : parser.filteredAlignments) {
 								int[] indices = ((FilteredAlignment) data).indices();
@@ -116,11 +123,11 @@ public class BeautiAlignmentProvider extends BEASTObject {
 							}
 							/** add alignments **/
 							for (Alignment data : parser.filteredAlignments) {
-								Alignment.sortByTaxonName(data.sequenceInput.get());
-								selectedPlugins.add(data);
+								sortByTaxonName(data.sequenceInput.get());
+								selectedBEASTObjects.add(data);
 							}
 						} else {
-							selectedPlugins.add(parser.m_alignment);
+							selectedBEASTObjects.add(parser.m_alignment);
 						}
 					} catch (Exception ex) {
 						ex.printStackTrace();
@@ -131,7 +138,7 @@ public class BeautiAlignmentProvider extends BEASTObject {
 
 				case ".xml":
 					alignment = (Alignment)getXMLData(file);
-					selectedPlugins.add(alignment);
+					selectedBEASTObjects.add(alignment);
 					break;
 
 				case ".fa":
@@ -143,8 +150,8 @@ public class BeautiAlignmentProvider extends BEASTObject {
 				case ".faa":
 				case ".frn":
 					alignment = getFASTAData(file);
-					Alignment.sortByTaxonName(alignment.sequenceInput.get());
-					selectedPlugins.add(alignment);
+					sortByTaxonName(alignment.sequenceInput.get());
+					selectedBEASTObjects.add(alignment);
 					break;
 
                 default:
@@ -154,19 +161,19 @@ public class BeautiAlignmentProvider extends BEASTObject {
                     break;
 			}
         }
-        for (BEASTInterface plugin : selectedPlugins) {
+        for (BEASTInterface beastObject : selectedBEASTObjects) {
         	// ensure ID of alignment is unique
         	int k = 0;
-        	String id = plugin.getID();
+        	String id = beastObject.getID();
         	while (doc.pluginmap.containsKey(id)) {
         		k++;
-        		id = plugin.getID() + k;
+        		id = beastObject.getID() + k;
         	}
-        	plugin.setID(id);
-        	Alignment.sortByTaxonName(((Alignment) plugin).sequenceInput.get());
-            doc.addAlignmentWithSubnet((Alignment) plugin, getStartTemplate());
+        	beastObject.setID(id);
+        	sortByTaxonName(((Alignment) beastObject).sequenceInput.get());
+            doc.addAlignmentWithSubnet((Alignment) beastObject, getStartTemplate());
         }
-        return selectedPlugins;
+        return selectedBEASTObjects;
     }
 
 	/** provide GUI for manipulating the alignment **/
@@ -193,17 +200,24 @@ public class BeautiAlignmentProvider extends BEASTObject {
 		return template.get();
 	}
 
+    private void sortByTaxonName(List<Sequence> seqs) {
+        Collections.sort(seqs, (Sequence o1, Sequence o2) -> {
+                return o1.taxonInput.get().compareTo(o2.taxonInput.get());
+            }
+        );
+    }
+
 	static public BEASTInterface getXMLData(File file) {
-		String sXML = "";
+		String xml = "";
 		try {
 			// parse as BEAST 2 xml fragment
 			XMLParser parser = new XMLParser();
 			BufferedReader fin = new BufferedReader(new FileReader(file));
 			while (fin.ready()) {
-				sXML += fin.readLine() + "\n";
+				xml += fin.readLine() + "\n";
 			}
 			fin.close();
-			BEASTInterface runnable = parser.parseBareFragment(sXML, false);
+			BEASTInterface runnable = parser.parseBareFragment(xml, false);
 			BEASTInterface alignment = getAlignment(runnable);
             alignment.initAndValidate();
             return alignment;
@@ -212,7 +226,7 @@ public class BeautiAlignmentProvider extends BEASTObject {
 			try {
 				String ID = file.getName();
 				ID = ID.substring(0, ID.lastIndexOf('.')).replaceAll("\\..*", "");
-				BEASTInterface alignment = parseBeast1XML(ID, sXML);
+				BEASTInterface alignment = parseBeast1XML(ID, xml);
 				if (alignment != null) {
 					alignment.setID(file.getName().substring(0, file.getName().length() - 4).replaceAll("\\..*", ""));
 				}
@@ -229,13 +243,13 @@ public class BeautiAlignmentProvider extends BEASTObject {
     private Alignment getFASTAData(File file) {
     	try {
     		// grab alignment data
-        	Map<String, StringBuilder> seqMap = new HashMap<String, StringBuilder>();
-        	List<String> sTaxa = new ArrayList<String>();
+        	Map<String, StringBuilder> seqMap = new HashMap<>();
+        	List<String> taxa = new ArrayList<>();
         	String currentTaxon = null;
 			BufferedReader fin = new BufferedReader(new FileReader(file));
-	        String sMissing = "?";
-	        String sGap = "-";
-	        int nTotalCount = 4;
+	        String missing = "?";
+	        String gap = "-";
+	        int totalCount = 4;
 	        String datatype = "nucleotide";
 	        // According to http://en.wikipedia.org/wiki/FASTA_format lists file formats and their data content
 			// .fna = nucleic acid
@@ -256,6 +270,7 @@ public class BeautiAlignmentProvider extends BEASTObject {
 				} else {
 					// it is a data line
 					if (currentTaxon == null) {
+						fin.close();
 						throw new RuntimeException("Expected taxon defined on first line");
 					}
 					if (seqMap.containsKey(currentTaxon)) {
@@ -265,40 +280,40 @@ public class BeautiAlignmentProvider extends BEASTObject {
 						StringBuilder sb = new StringBuilder();
 						seqMap.put(currentTaxon, sb);
 						sb.append(line);
-						sTaxa.add(currentTaxon);
+						taxa.add(currentTaxon);
 					}
 				}
 			}
 			fin.close();
 			
-			int nChar = -1;
+			int charCount = -1;
 			Alignment alignment = new Alignment();
-	        for (final String sTaxon : sTaxa) {
-	            final StringBuilder bsData = seqMap.get(sTaxon);
-	            String sData = bsData.toString();
-	            sData = sData.replaceAll("\\s", "");
-	            seqMap.put(sTaxon, new StringBuilder(sData));
+	        for (final String taxon : taxa) {
+	            final StringBuilder bsData = seqMap.get(taxon);
+	            String data = bsData.toString();
+	            data = data.replaceAll("\\s", "");
+	            seqMap.put(taxon, new StringBuilder(data));
 
-	            if (nChar < 0) {nChar = sData.length();}
-	            if (sData.length() != nChar) {
-	                throw new Exception("Expected sequence of length " + nChar + " instead of " + sData.length() + " for taxon " + sTaxon);
+	            if (charCount < 0) {charCount = data.length();}
+	            if (data.length() != charCount) {
+	                throw new IllegalArgumentException("Expected sequence of length " + charCount + " instead of " + data.length() + " for taxon " + taxon);
 	            }
 	            // map to standard missing and gap chars
-	            sData = sData.replace(sMissing.charAt(0), DataType.MISSING_CHAR);
-	            sData = sData.replace(sGap.charAt(0), DataType.GAP_CHAR);
+	            data = data.replace(missing.charAt(0), DataType.MISSING_CHAR);
+	            data = data.replace(gap.charAt(0), DataType.GAP_CHAR);
 
-	            if (mayBeAminoacid && datatype.equals("nucleotide") && !sData.matches("[ACGTUXNacgtuxn?_-]+")) {
+	            if (mayBeAminoacid && datatype.equals("nucleotide") && !data.matches("[ACGTUXNacgtuxn?_-]+")) {
 	            	datatype = "aminoacid";
-	            	nTotalCount = 20;
+	            	totalCount = 20;
 	            	for (Sequence seq : alignment.sequenceInput.get()) {
-	            		seq.totalCountInput.setValue(nTotalCount, seq);
+	            		seq.totalCountInput.setValue(totalCount, seq);
 	            	}
 	            }
 	            
 	            final Sequence sequence = new Sequence();
-	            sData = sData.replaceAll("[Xx]", "?");
-	            sequence.init(nTotalCount, sTaxon, sData);
-	            sequence.setID(NexusParser.generateSequenceID(sTaxon));
+	            data = data.replaceAll("[Xx]", "?");
+	            sequence.init(totalCount, taxon, data);
+	            sequence.setID(NexusParser.generateSequenceID(taxon));
 	            alignment.sequenceInput.setValue(sequence, alignment);
 	        }
 	        String ID = file.getName();
@@ -314,9 +329,9 @@ public class BeautiAlignmentProvider extends BEASTObject {
 		return null;
 	}
 
-	private static BEASTInterface parseBeast1XML(String ID, String sXML) throws Exception {
+	private static BEASTInterface parseBeast1XML(String ID, String xml) throws SAXException, IOException, ParserConfigurationException  {
 		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-		Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(sXML)));
+		Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
 		doc.normalize();
 
 		NodeList alignments = doc.getElementsByTagName("alignment");
@@ -326,16 +341,16 @@ public class BeautiAlignmentProvider extends BEASTObject {
 		// parse first alignment
 		org.w3c.dom.Node node = alignments.item(0);
 
-		String sDataType = node.getAttributes().getNamedItem("dataType").getNodeValue();
-		int nTotalCount = 4;
-		if (sDataType == null) {
+		String dataTypeName = node.getAttributes().getNamedItem("dataType").getNodeValue();
+		int totalCount = 4;
+		if (dataTypeName == null) {
 			alignment.dataTypeInput.setValue("integer", alignment);
-		} else if (sDataType.toLowerCase().equals("dna") || sDataType.toLowerCase().equals("nucleotide")) {
+		} else if (dataTypeName.toLowerCase().equals("dna") || dataTypeName.toLowerCase().equals("nucleotide")) {
 			alignment.dataTypeInput.setValue("nucleotide", alignment);
-			nTotalCount = 4;
-		} else if (sDataType.toLowerCase().equals("aminoacid") || sDataType.toLowerCase().equals("protein")) {
+			totalCount = 4;
+		} else if (dataTypeName.toLowerCase().equals("aminoacid") || dataTypeName.toLowerCase().equals("protein")) {
 			alignment.dataTypeInput.setValue("aminoacid", alignment);
-			nTotalCount = 20;
+			totalCount = 20;
 		} else {
 			alignment.dataTypeInput.setValue("integer", alignment);
 		}
@@ -355,7 +370,7 @@ public class BeautiAlignmentProvider extends BEASTObject {
 					}
 				}
 				String data = child.getTextContent();
-				sequence.initByName("totalcount", nTotalCount, "taxon", taxon, "value", data);
+				sequence.initByName("totalcount", totalCount, "taxon", taxon, "value", data);
 				sequence.setID("seq_" + taxon);
 				alignment.sequenceInput.setValue(sequence, alignment);
 
@@ -367,14 +382,14 @@ public class BeautiAlignmentProvider extends BEASTObject {
 	} // parseBeast1XML
 
 
-	static BEASTInterface getAlignment(BEASTInterface plugin) throws IllegalArgumentException, IllegalAccessException {
-		if (plugin instanceof Alignment) {
-			return plugin;
+	static BEASTInterface getAlignment(BEASTInterface beastObject) throws IllegalArgumentException, IllegalAccessException {
+		if (beastObject instanceof Alignment) {
+			return beastObject;
 		}
-		for (BEASTInterface plugin2 : plugin.listActivePlugins()) {
-			plugin2 = getAlignment(plugin2);
-			if (plugin2 != null) {
-				return plugin2;
+		for (BEASTInterface beastObject2 : beastObject.listActiveBEASTObjects()) {
+			beastObject2 = getAlignment(beastObject2);
+			if (beastObject2 != null) {
+				return beastObject2;
 			}
 		}
 		return null;
diff --git a/src/beast/app/beauti/BeautiConfig.java b/src/beast/app/beauti/BeautiConfig.java
index dc51d4d..a1e8bbe 100644
--- a/src/beast/app/beauti/BeautiConfig.java
+++ b/src/beast/app/beauti/BeautiConfig.java
@@ -7,76 +7,77 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import javax.swing.JComponent;
+import javax.swing.JOptionPane;
+
+import beast.core.BEASTInterface;
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 import beast.core.Input.Validate;
 import beast.evolution.alignment.Alignment;
 import beast.util.XMLParser;
 
-import javax.swing.*;
-
 @Description("Beauti configuration object, used to find Beauti configuration " +
         "information from Beauti template files.")
 public class BeautiConfig extends BEASTObject {
-    public Input<String> inlineInput = new Input<String>("inlinePlugins", "comma separated list of inputs that should " +
+    final public Input<String> inlineInput = new Input<>("inlinePlugins", "comma separated list of inputs that should " +
             "go inline, e.g. beast.evolution.sitemodel.SiteModel.substModel");
-    public Input<String> collapsedInput = new Input<String>("collapsedPlugins", "comma separated list of inputs that should " +
+    final public Input<String> collapsedInput = new Input<>("collapsedPlugins", "comma separated list of inputs that should " +
             "go inline, but are initially collapsed, e.g. beast.core.MCMC.logger");
-    public Input<String> suppressInputs = new Input<String>("suppressPlugins", "comma separated list of inputs that should " +
+    final public Input<String> suppressInputs = new Input<>("suppressPlugins", "comma separated list of inputs that should " +
             "be suppressed. e.g. beast.core.MCMC.operator");
-    public Input<String> inputLabelMapInput = new Input<String>("inputLabelMap", "comma separated list of inputs and their " +
+    final public Input<String> inputLabelMapInput = new Input<>("inputLabelMap", "comma separated list of inputs and their " +
             "display labels separated by a '=', e.g. beast.core.MCMC.logger=Loggers ");
-    //	public Input<String> m_hidePanels = new Input<String>("hidePanels","comma separated list of panes that should not" +
+    //	public Input<String> m_hidePanels = new Input<>("hidePanels","comma separated list of panes that should not" +
 //			"be displayed when starting beauti, e.g. TAXON_SETS_PANEL,TIP_DATES_PANEL");
-    public Input<String> buttonLabelMapInput = new Input<String>("buttonLabelMap", "comma separated list of buttons in dialogs and their " +
+    final public Input<String> buttonLabelMapInput = new Input<>("buttonLabelMap", "comma separated list of buttons in dialogs and their " +
             "display labels separated by a '=', e.g. beast.app.beauti.BeautiInitDlg.>> details=Edit parameters");
-    public Input<String> disableMenus = new Input<String>("disableMenus", "comma separated list of menus that should " +
+    final public Input<String> disableMenus = new Input<>("disableMenus", "comma separated list of menus that should " +
             "not be visible, e.g., View.Show Data Panel,Mode");
-    public Input<String> disableButtons = new Input<String>("disableButtons", "comma separated list of buttons that should " +
+    final public Input<String> disableButtons = new Input<>("disableButtons", "comma separated list of buttons that should " +
             "not be visible, e.g., beast.app.beauti.BeautiInitDlg.Analysis template:");
-//	public Input<String> m_editButtonStatus = new Input<String>("editButtonStatus","comma separated list of list-inputs with custom " +
+//	public Input<String> m_editButtonStatus = new Input<>("editButtonStatus","comma separated list of list-inputs with custom " +
 //	"button status. One of 'none', 'addonly' 'delonly' +, e.g., beast.core.MCMC.operator=addonly");
 
-    public Input<List<BeautiPanelConfig>> panelsInput = new Input<List<BeautiPanelConfig>>("panel", "define custom panels and their properties",
-            new ArrayList<BeautiPanelConfig>());
-    public Input<Boolean> bIsExpertInput = new Input<Boolean>("isExpert", "flag to indicate Beauti should start in expert mode", false);
+    final public Input<List<BeautiPanelConfig>> panelsInput = new Input<>("panel", "define custom panels and their properties",
+            new ArrayList<>());
+    final public Input<Boolean> isExpertInput = new Input<>("isExpert", "flag to indicate Beauti should start in expert mode", false);
 
 
-    public Input<BeautiSubTemplate> partitionTemplate = new Input<BeautiSubTemplate>("partitiontemplate", "defines template used when creating a partition", Validate.REQUIRED);
-    public Input<List<BeautiSubTemplate>> subTemplatesInput = new Input<List<BeautiSubTemplate>>("subtemplate", "defines subtemplates for creating selected classes",
-            new ArrayList<BeautiSubTemplate>());
+    final public Input<BeautiSubTemplate> partitionTemplate = new Input<>("partitiontemplate", "defines template used when creating a partition", Validate.REQUIRED);
+    final public Input<List<BeautiSubTemplate>> subTemplatesInput = new Input<>("subtemplate", "defines subtemplates for creating selected classes",
+            new ArrayList<>());
 
-    public Input<List<BeautiAlignmentProvider>> alignmentProviderInput = new Input<List<BeautiAlignmentProvider>>("alignmentProvider", "defines providers for adding new alignments",
-            new ArrayList<BeautiAlignmentProvider>());
+    final public Input<List<BeautiAlignmentProvider>> alignmentProviderInput = new Input<>("alignmentProvider", "defines providers for adding new alignments",
+            new ArrayList<>());
 
     /**
      * list of inputs for which the input editor should be expanded inline in a dialog
      * in the format <className>.<inputName>, e.g. beast.evolution.sitemodel.SiteModel.substModel
      */
-    public Set<String> inlinePlugins = new HashSet<String>();
+    public Set<String> inlineBEASTObject = new HashSet<>();
     /**
      * list of inputs for which the input editor should be expanded inline in a dialog but initially collapsed.
      * e.g. beast.evolution.sitemodel.SiteModel.substModel
      */
-    public Set<String> collapsedPlugins = new HashSet<String>();
+    public Set<String> collapsedBEASTObjects = new HashSet<>();
     /**
-     * list of inputs that should not be shown in a dialog. Same format as for m_inlinePlugins*
+     * list of inputs that should not be shown in a dialog. Same format as for inlineBEASTObjects*
      */
-    public Set<String> suppressPlugins = new HashSet<String>();
+    public Set<String> suppressBEASTObjects = new HashSet<>();
     /**
      * map that identifies the label to be used for a particular input *
      */
-    public HashMap<String, String> inputLabelMap = new HashMap<String, String>();
-    public HashMap<String, String> buttonLabelMap = new HashMap<String, String>();
-//	public static HashMap<String, String> g_sEditButtonStatus = new HashMap<String, String>();
+    public HashMap<String, String> inputLabelMap = new HashMap<>();
+    public HashMap<String, String> buttonLabelMap = new HashMap<>();
+//	public static HashMap<String, String> g_sEditButtonStatus = new HashMap<>();
 
-    //	public static Set<String> g_sHidePanels = new HashSet<String>();
-    public Set<String> sDisabledMenus = new HashSet<String>();
-    public Set<String> sDisabledButtons = new HashSet<String>();
+    //	public static Set<String> g_sHidePanels = new HashSet<>();
+    public Set<String> disabledMenus = new HashSet<>();
+    public Set<String> disabledButtons = new HashSet<>();
 
-    public List<BeautiPanelConfig> panels = new ArrayList<BeautiPanelConfig>();
+    public List<BeautiPanelConfig> panels = new ArrayList<>();
 
     public List<BeautiSubTemplate> subTemplates;
     public List<BeautiAlignmentProvider> alignmentProvider;
@@ -85,13 +86,13 @@ public class BeautiConfig extends BEASTObject {
     
     @Override
     public void initAndValidate() {
-        parseSet(inlineInput.get(), null, inlinePlugins);
-        parseSet(collapsedInput.get(), null, collapsedPlugins);
-        inlinePlugins.addAll(collapsedPlugins);
+        parseSet(inlineInput.get(), null, inlineBEASTObject);
+        parseSet(collapsedInput.get(), null, collapsedBEASTObjects);
+        inlineBEASTObject.addAll(collapsedBEASTObjects);
 //		parseSet(m_hidePanels.get(), "TAXON_SETS_PANEL,TIP_DATES_PANEL,PRIORS_PANEL,OPERATORS_PANEL", g_sHidePanels);
-        parseSet(suppressInputs.get(), null, suppressPlugins);
-        parseSet(disableMenus.get(), null, sDisabledMenus);
-        parseSet(disableButtons.get(), null, sDisabledButtons);
+        parseSet(suppressInputs.get(), null, suppressBEASTObjects);
+        parseSet(disableMenus.get(), null, disabledMenus);
+        parseSet(disableButtons.get(), null, disabledButtons);
 
         parseMap(inputLabelMapInput.get(), inputLabelMap);
         parseMap(buttonLabelMapInput.get(), buttonLabelMap);
@@ -100,13 +101,13 @@ public class BeautiConfig extends BEASTObject {
             panels.add(panel);
             // check for duplicates
             for (BeautiPanelConfig panel2 : panels) {
-                if (panel2.sNameInput.get().equals(panel.sNameInput.get()) && panel2 != panel) {
+                if (panel2.nameInput.get().equals(panel.nameInput.get()) && panel2 != panel) {
                     panels.remove(panels.size() - 1);
                     break;
                 }
             }
         }
-        //InputEditor.setExpertMode(bIsExpertInput.get());
+        //InputEditor.setExpertMode(isExpertInput.get());
         subTemplates = subTemplatesInput.get();
         alignmentProvider = alignmentProviderInput.get();
 
@@ -125,11 +126,11 @@ public class BeautiConfig extends BEASTObject {
     		"    	<!-- Parameter Hyper Prior -->\n" +
     		"    	        <subtemplate id='HyperPrior' class='beast.math.distributions.Prior' mainid='HyperPrior.$(n)'>\n" +
     		"    	<![CDATA[\n" +
-    		"    	        <plugin id='HyperPrior.$(n)' spec='Prior' x='@parameter.$(n)'>\n" +
+    		"    	        <beastObject id='HyperPrior.$(n)' spec='Prior' x='@parameter.$(n)'>\n" +
     		"    	            <distr spec='OneOnX'/>\n" +
-    		"    			</plugin>\n" +
+    		"    			</beastObject>\n" +
     		"\n" +
-    		"    	        <plugin id='hyperScaler.$(n)' spec='ScaleOperator' scaleFactor='0.5' weight='0.1' parameter='@parameter.$(n)'/>\n" +
+    		"    	        <beastObject id='hyperScaler.$(n)' spec='ScaleOperator' scaleFactor='0.5' weight='0.1' parameter='@parameter.$(n)'/>\n" +
     		"    	]]>\n" +
     		"    	            <connect srcID='parameter.$(n)'            targetID='state' inputName='stateNode' if='inposterior(parameter.$(n)) and parameter.$(n)/estimate=true'/>\n" +
     		"\n" +
@@ -147,19 +148,19 @@ public class BeautiConfig extends BEASTObject {
         for (BeautiSubTemplate sub : subTemplates) {
             sub.setDoc(doc);
         }
-        doc.setExpertMode(bIsExpertInput.get());
+        doc.setExpertMode(isExpertInput.get());
         hyperPriorTemplate.doc = doc;
     }
 
     public void clear() {
-        inlinePlugins = new HashSet<String>();
-        collapsedPlugins = new HashSet<String>();
-        suppressPlugins = new HashSet<String>();
-        inputLabelMap = new HashMap<String, String>();
-        buttonLabelMap = new HashMap<String, String>();
-        sDisabledMenus = new HashSet<String>();
-        sDisabledButtons = new HashSet<String>();
-        panels = new ArrayList<BeautiPanelConfig>();
+        inlineBEASTObject = new HashSet<>();
+        collapsedBEASTObjects = new HashSet<>();
+        suppressBEASTObjects = new HashSet<>();
+        inputLabelMap = new HashMap<>();
+        buttonLabelMap = new HashMap<>();
+        disabledMenus = new HashSet<>();
+        disabledButtons = new HashSet<>();
+        panels = new ArrayList<>();
     }
 
     /**
@@ -181,10 +182,10 @@ public class BeautiConfig extends BEASTObject {
                 return null;
             }
         }
-        List<BEASTInterface> plugins = selectedProvider.getAlignments(doc);
+        List<BEASTInterface> beastObjects = selectedProvider.getAlignments(doc);
         // create taxon sets, if any
-        if (plugins != null) {
-	        for (BEASTInterface o : plugins) {
+        if (beastObjects != null) {
+	        for (BEASTInterface o : beastObjects) {
 	        	if (o instanceof Alignment) {
 	        		try {
 	        			BeautiDoc.createTaxonSet((Alignment) o, doc);
@@ -194,15 +195,15 @@ public class BeautiConfig extends BEASTObject {
 	        	}
 	        }
         }
-        return plugins;
+        return beastObjects;
     } // selectAlignments
     
-    public List<BeautiSubTemplate> getInputCandidates(BEASTInterface plugin, Input<?> input, Class<?> type) {
-        List<BeautiSubTemplate> candidates = new ArrayList<BeautiSubTemplate>();
+    public List<BeautiSubTemplate> getInputCandidates(BEASTInterface beastObject, Input<?> input, Class<?> type) {
+        List<BeautiSubTemplate> candidates = new ArrayList<>();
         for (BeautiSubTemplate template : subTemplates) {
             if (type.isAssignableFrom(template._class)) {
                 try {
-                    if (input.canSetValue(template.instance, plugin)) {
+                    if (input.canSetValue(template.instance, beastObject)) {
                         candidates.add(template);
                     }
                 } catch (Exception e) {
@@ -213,62 +214,62 @@ public class BeautiConfig extends BEASTObject {
         return candidates;
     }
 
-    private void parseMap(String sStr, HashMap<String, String> stringMap) {
-        if (sStr != null) {
-            for (String sStr2 : sStr.split(",")) {
-                String[] sStrs = sStr2.split("=");
-                stringMap.put(normalize(sStrs[0]), normalize(sStrs.length == 1 ? "" : sStrs[1]));
+    private void parseMap(String str, HashMap<String, String> stringMap) {
+        if (str != null) {
+            for (String str2 : str.split(",")) {
+                String[] strs = str2.split("=");
+                stringMap.put(normalize(strs[0]), normalize(strs.length == 1 ? "" : strs[1]));
             }
         }
     }
 
-    private void parseSet(String sStr, String sDefault, Set<String> stringSet) {
-        if (sStr == null) {
-            sStr = sDefault;
+    private void parseSet(String str, String defaultValue, Set<String> stringSet) {
+        if (str == null) {
+            str = defaultValue;
         }
-        if (sStr != null) {
-            for (String sStr2 : sStr.split(",")) {
-                stringSet.add(normalize(sStr2));
+        if (str != null) {
+            for (String str2 : str.split(",")) {
+                stringSet.add(normalize(str2));
             }
         }
     }
 
     // remove leading and tailing spaces
-    String normalize(String sStr) {
+    String normalize(String str) {
         int i = 0;
-        int n = sStr.length();
-        while (i < n && Character.isWhitespace(sStr.charAt(i))) {
+        int n = str.length();
+        while (i < n && Character.isWhitespace(str.charAt(i))) {
             i++;
         }
-        while (n > 0 && Character.isWhitespace(sStr.charAt(n - 1))) {
+        while (n > 0 && Character.isWhitespace(str.charAt(n - 1))) {
             n--;
         }
-        return sStr.substring(i, n);
+        return str.substring(i, n);
     }
 
-    public String getButtonLabel(String sClass, String sStr) {
-        if (buttonLabelMap.containsKey(sClass + "." + sStr)) {
-            return buttonLabelMap.get(sClass + "." + sStr);
+    public String getButtonLabel(String className, String str) {
+        if (buttonLabelMap.containsKey(className + "." + str)) {
+            return buttonLabelMap.get(className + "." + str);
         }
-        return sStr;
+        return str;
     }
 
-    public String getButtonLabel(Object o, String sStr) {
-        if (buttonLabelMap.containsKey(o.getClass().getName() + "." + sStr)) {
-            return buttonLabelMap.get(o.getClass().getName() + "." + sStr);
+    public String getButtonLabel(Object o, String str) {
+        if (buttonLabelMap.containsKey(o.getClass().getName() + "." + str)) {
+            return buttonLabelMap.get(o.getClass().getName() + "." + str);
         }
-        return sStr;
+        return str;
     }
 
-    public String getInputLabel(BEASTInterface plugin, String sName) {
-        if (inputLabelMap.containsKey(plugin.getClass().getName() + "." + sName)) {
-            sName = inputLabelMap.get(plugin.getClass().getName() + "." + sName);
+    public String getInputLabel(BEASTInterface beastObject, String name) {
+        if (inputLabelMap.containsKey(beastObject.getClass().getName() + "." + name)) {
+            name = inputLabelMap.get(beastObject.getClass().getName() + "." + name);
         }
-        return sName;
+        return name;
     }
 
-    public boolean menuIsInvisible(String sMenuName) {
-        return sDisabledMenus.contains(sMenuName);
+    public boolean menuIsInvisible(String menuName) {
+        return disabledMenus.contains(menuName);
     }
 
     static BeautiSubTemplate NULL_TEMPLATE = new BeautiSubTemplate();
@@ -280,22 +281,22 @@ public class BeautiConfig extends BEASTObject {
         return NULL_TEMPLATE;
     }
 
-//	public static boolean hasDeleteButton(String sFullInputName) {
-//		if (!g_sEditButtonStatus.containsKey(sFullInputName)) {
+//	public static boolean hasDeleteButton(String fullInputName) {
+//		if (!g_sEditButtonStatus.containsKey(fullInputName)) {
 //			return true;
 //		}
-//		String sStatus = g_sEditButtonStatus.get(sFullInputName);
-//		if (sStatus.equals("none") || sStatus.equals("onlyadd")) {
+//		String status = g_sEditButtonStatus.get(fullInputName);
+//		if (status.equals("none") || status.equals("onlyadd")) {
 //			return false;
 //		}
 //		return true;
 //	}
-//	public static boolean hasAddButton(String sFullInputName) {
-//		if (!g_sEditButtonStatus.containsKey(sFullInputName)) {
+//	public static boolean hasAddButton(String fullInputName) {
+//		if (!g_sEditButtonStatus.containsKey(fullInputName)) {
 //			return true;
 //		}
-//		String sStatus = g_sEditButtonStatus.get(sFullInputName);
-//		if (sStatus.equals("none") || sStatus.equals("onlydel")) {
+//		String status = g_sEditButtonStatus.get(fullInputName);
+//		if (status.equals("none") || status.equals("onlydel")) {
 //			return false;
 //		}
 //		return true;
diff --git a/src/beast/app/beauti/BeautiConnector.java b/src/beast/app/beauti/BeautiConnector.java
index 05b73de..6250c4a 100644
--- a/src/beast/app/beauti/BeautiConnector.java
+++ b/src/beast/app/beauti/BeautiConnector.java
@@ -4,36 +4,36 @@ package beast.app.beauti;
 import java.lang.reflect.Method;
 import java.util.List;
 
+import beast.core.BEASTInterface;
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Input;
+import beast.core.Input.Validate;
 import beast.core.MCMC;
 import beast.core.Operator;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
-import beast.core.Input.Validate;
 
 
 
 @Description("Specifies which part of the template get connected to the main network")
 public class BeautiConnector extends BEASTObject {
-    public Input<String> sMethodnput = new Input<String>("method", "name of static method that should be called with BeautiDoc as " +
+    final public Input<String> methodnput = new Input<>("method", "name of static method that should be called with BeautiDoc as " +
     		"argument. For example beast.app.beauti.SiteModelInputEditor.custmoConnector");
 
-    public Input<String> sSourceIDInput = new Input<String>("srcID", "ID of the plugin to be connected", Validate.XOR, sMethodnput);
-    public Input<String> sTargetIDInput = new Input<String>("targetID", "ID of plugin to connect to", Validate.XOR, sMethodnput);
-    public Input<String> sInputNameInput = new Input<String>("inputName", "name of the input of the plugin to connect to", Validate.XOR, sMethodnput);
-    public Input<String> sTipText = new Input<String>("value", "associate some tip text with the srcID plugin, useful for displaying prior and operator specific information");
+    final public Input<String> sourceIDInput = new Input<>("srcID", "ID of the beastObject to be connected", Validate.XOR, methodnput);
+    final public Input<String> targetIDInput = new Input<>("targetID", "ID of beastObject to connect to", Validate.XOR, methodnput);
+    final public Input<String> inputNameInput = new Input<>("inputName", "name of the input of the beastObject to connect to", Validate.XOR, methodnput);
+    final public Input<String> tipText = new Input<>("value", "associate some tip text with the srcID beastObject, useful for displaying prior and operator specific information");
 
-    public Input<String> sConditionInput = new Input<String>("if", "condition under which this connector should be executed." +
+    final public Input<String> conditionInput = new Input<>("if", "condition under which this connector should be executed." +
             "These should be of the form " +
             "inposterior(id) or id/input=value, e.g. inposterior(kappa), kappa/estimate=true. " +
-            "inlikelihood(id) to check there is a plugin with suplied id that is predecessor of likelihood. " +
+            "inlikelihood(id) to check there is a beastObject with suplied id that is predecessor of likelihood. " +
             "nooperator(id) to check there is no operator with suplied id. " +
             "isInitialising to execute only when subtemplate is first instantiated. " +
             "For partition specific ids, use $(n), e.g. e.g. kappa.$(n)/estimate=true. " +
             "For multiple conditions, separate by 'and', e.g. inposterior(kappa.$(n)) and kappa.$(n)/estimate=true");
 //	public enum ConnectCondition {always, ifunlinked};
-//	public Input<ConnectCondition> connectCondition = new Input<ConnectCondition>("connect","condition when to connect. Default is 'always'. " +
+//	public Input<ConnectCondition> connectCondition = new Input<>("connect","condition when to connect. Default is 'always'. " +
 //			"With ifunlinked, the connector is only activated if the link does not already exists. " +
 //			"Possible values: " + ConnectCondition.values(),
 //			ConnectCondition.always, ConnectCondition.values());
@@ -43,14 +43,14 @@ public class BeautiConnector extends BEASTObject {
 //	final static String IS_IN_POSTERIOR = "x";
 //	final static String AT_INITIALISATION_ONLY = "y";
 
-    String sSourceID;
-    String sTargetID;
-    String sTargetInput;
+    String sourceID;
+    String targetID;
+    String targetInput;
 
-    String[] sConditionIDs;
-    String[] sConditionInputs;
+    String[] conditionIDs;
+    String[] conditionInputs;
     Operation[] conditionOperations;
-    String[] sConditionValues;
+    String[] conditionValues;
     
     boolean isRegularConnector = true;
     
@@ -58,69 +58,74 @@ public class BeautiConnector extends BEASTObject {
 
     public BeautiConnector() {}
 
-    public BeautiConnector(String sourceID, String targetID, String inputName, String condition) throws Exception {
+    public BeautiConnector(String sourceID, String targetID, String inputName, String condition) {
 		initByName("srcID", sourceID, "targetID", targetID, "inputName", inputName, 
 				"if", condition);
     }
 
 
 	@Override
-    public void initAndValidate() throws Exception {
-        sSourceID = sSourceIDInput.get();
-        sTargetID = sTargetIDInput.get();
-        sTargetInput = sInputNameInput.get();
-
-        if (sConditionInput.get() != null) {
-            String[] sConditions = sConditionInput.get().split("\\s+and\\s+");
-            sConditionIDs = new String[sConditions.length];
-            sConditionInputs = new String[sConditions.length];
-            sConditionValues = new String[sConditions.length];
-            conditionOperations = new Operation[sConditions.length];
-            for (int i = 0; i < sConditions.length; i++) {
-                String s = sConditions[i];
+    public void initAndValidate() {
+        sourceID = sourceIDInput.get();
+        targetID = targetIDInput.get();
+        targetInput = inputNameInput.get();
+
+        if (conditionInput.get() != null) {
+            String[] conditions = conditionInput.get().split("\\s+and\\s+");
+            conditionIDs = new String[conditions.length];
+            conditionInputs = new String[conditions.length];
+            conditionValues = new String[conditions.length];
+            conditionOperations = new Operation[conditions.length];
+            for (int i = 0; i < conditions.length; i++) {
+                String s = conditions[i];
                 if (s.startsWith("inposterior(")) {
-                    sConditionIDs[i] = s.substring(s.indexOf("(") + 1, s.lastIndexOf(")"));
-                    sConditionInputs[i] = null;
+                    conditionIDs[i] = s.substring(s.indexOf("(") + 1, s.lastIndexOf(")"));
+                    conditionInputs[i] = null;
                     conditionOperations[i] = Operation.IS_IN_POSTERIOR;
-                    sConditionValues[i] = null;
+                    conditionValues[i] = null;
                 } else if (s.startsWith("inlikelihood(")) {
-                    sConditionIDs[i] = s.substring(s.indexOf("(") + 1, s.lastIndexOf(")"));
-                    sConditionInputs[i] = null;
+                    conditionIDs[i] = s.substring(s.indexOf("(") + 1, s.lastIndexOf(")"));
+                    conditionInputs[i] = null;
                     conditionOperations[i] = Operation.IS_IN_LIKELIHOOD;
-                    sConditionValues[i] = null;
+                    conditionValues[i] = null;
                 } else if (s.startsWith("nooperator")) {
-                    sConditionIDs[i] = s.substring(s.indexOf("(") + 1, s.lastIndexOf(")"));
+                    conditionIDs[i] = s.substring(s.indexOf("(") + 1, s.lastIndexOf(")"));
                     conditionOperations[i] = Operation.IS_NOT_AN_OPERTOR;
-                    sConditionInputs[i] = null;
-                    sConditionValues[i] = null;
+                    conditionInputs[i] = null;
+                    conditionValues[i] = null;
                 } else if (s.startsWith("isInitializing")) {
-                    sConditionIDs[i] = null;
+                    conditionIDs[i] = null;
                     conditionOperations[i] = Operation.AT_INITIALISATION_ONLY;
-                    sConditionInputs[i] = null;
-                    sConditionValues[i] = null;
+                    conditionInputs[i] = null;
+                    conditionValues[i] = null;
                 } else {
-                    sConditionIDs[i] = s.substring(0, s.indexOf("/"));
-                    sConditionInputs[i] = s.substring(s.indexOf("/") + 1, s.indexOf("="));
-                    sConditionValues[i] = s.substring(s.indexOf("=") + 1);
+                    conditionIDs[i] = s.substring(0, s.indexOf("/"));
+                    conditionInputs[i] = s.substring(s.indexOf("/") + 1, s.indexOf("="));
+                    conditionValues[i] = s.substring(s.indexOf("=") + 1);
                     conditionOperations[i] = Operation.EQUALS;
-                    if (sConditionInputs[i].endsWith("!")) {
-                        sConditionInputs[i] = sConditionInputs[i].substring(0, sConditionInputs[i].length() - 1);
+                    if (conditionInputs[i].endsWith("!")) {
+                        conditionInputs[i] = conditionInputs[i].substring(0, conditionInputs[i].length() - 1);
                         conditionOperations[i] = Operation.NOT_EQUALS;
                     }
                 }
             }
         } else {
-            sConditionIDs = new String[0];
-            sConditionInputs = new String[0];
+            conditionIDs = new String[0];
+            conditionInputs = new String[0];
             conditionOperations = new Operation[0];
-            sConditionValues = new String[0];
+            conditionValues = new String[0];
         }
-        if (sMethodnput.get() != null) {
-        	String fullMethod = sMethodnput.get();
+        if (methodnput.get() != null) {
+        	String fullMethod = methodnput.get();
         	String className = fullMethod.substring(0, fullMethod.lastIndexOf('.'));
         	String methodName = fullMethod.substring(fullMethod.lastIndexOf('.') + 1);
-        	Class<?> class_ = Class.forName(className);
-        	method = class_.getMethod(methodName, BeautiDoc.class);
+        	Class<?> class_;
+			try {
+				class_ = Class.forName(className);
+	        	method = class_.getMethod(methodName, BeautiDoc.class);
+			} catch (ClassNotFoundException | NoSuchMethodException | SecurityException e) {
+				throw new IllegalArgumentException(e.getMessage());
+			}
             isRegularConnector = false;
         }
 
@@ -143,10 +148,10 @@ public class BeautiConnector extends BEASTObject {
         if (atInitialisationOnly()) {
             return false;
         }
-        if (sMethodnput.get() != null) {
+        if (methodnput.get() != null) {
 //        if (method != null) {
 	    	try {
-            	String fullMethod = sMethodnput.get();
+            	String fullMethod = methodnput.get();
             	String className = fullMethod.substring(0, fullMethod.lastIndexOf('.'));
             	String methodName = fullMethod.substring(fullMethod.lastIndexOf('.') + 1);
             	Class<?> class_ = Class.forName(className);
@@ -157,30 +162,30 @@ public class BeautiConnector extends BEASTObject {
         	}
         }
 
-        boolean bIsActive = true;
-        for (int i = 0; i < sConditionIDs.length; i++) {
-        	//String sID = sConditionIDs[i].replaceAll("\\$\\(n\\)", sPartition);
-        	String sID = BeautiDoc.translatePartitionNames(sConditionIDs[i], partitionContext);
-            BEASTInterface plugin = doc.pluginmap.get(sID);
-            if (plugin == null) {
+        boolean isActive = true;
+        for (int i = 0; i < conditionIDs.length; i++) {
+        	//String id = conditionIDs[i].replaceAll("\\$\\(n\\)", partition);
+        	String id = BeautiDoc.translatePartitionNames(conditionIDs[i], partitionContext);
+            BEASTInterface beastObject = doc.pluginmap.get(id);
+            if (beastObject == null) {
             	if (conditionOperations[i] != Operation.IS_NOT_AN_OPERTOR) {
                     return false;
             		
             	}
-                //System.err.println("isActivated::no plugin found");
+                //System.err.println("isActivated::no beastObject found");
             }
-            //System.err.println("isActivated::found " + sID);
+            //System.err.println("isActivated::found " + id);
             try {
                 switch (conditionOperations[i]) {
                     case IS_IN_POSTERIOR:
-                        if (!posteriorPredecessors.contains(plugin)) {
+                        if (!posteriorPredecessors.contains(beastObject)) {
                             //System.err.println(posteriorPredecessors);
                             //System.err.println("isActivated::is not in posterior, return false");
                             return false;
                         }
                         break;
                     case IS_IN_LIKELIHOOD:
-                        if (!likelihoodPredecessors.contains(plugin)) {
+                        if (!likelihoodPredecessors.contains(beastObject)) {
                             //System.err.println(posteriorPredecessors);
                             //System.err.println("isActivated::is not in posterior, return false");
                             return false;
@@ -189,64 +194,65 @@ public class BeautiConnector extends BEASTObject {
                     //System.err.println("isActivated::is in posterior");
                     case IS_NOT_AN_OPERTOR:
         				List<Operator> operators = ((MCMC) doc.mcmc.get()).operatorsInput.get();
-        				if (operators.contains(plugin)) {
+        				if (operators.contains(beastObject)) {
         					return false;
         				}
                     	break;
                     case EQUALS:
-                        Input<?> input = plugin.getInput(sConditionInputs[i]);
-                        //System.err.println("isActivated::input " + input.get().toString() + " expected " + sConditionValues[i]);
+                        final Input<?> input = beastObject.getInput(conditionInputs[i]);
+                        //System.err.println("isActivated::input " + input.get().toString() + " expected " + conditionValues[i]);
                         if (input.get() == null) {
-                        	if (!sConditionValues[i].equals("null")) {
+                        	if (!conditionValues[i].equals("null")) {
                         		return false;
                         	}
-                        } else if (!input.get().toString().equals(sConditionValues[i])) {
+                        } else if (!input.get().toString().equals(conditionValues[i])) {
                             //System.err.println("isActivated::return false");
                             return false;
                         }
                         break;
                     case NOT_EQUALS:
-                        Input<?> input2 = plugin.getInput(sConditionInputs[i]);
-                        //System.err.println("isActivated::input " + input.get().toString() + " expected " + sConditionValues[i]);
+                        final Input<?> input2 = beastObject.getInput(conditionInputs[i]);
+                        //System.err.println("isActivated::input " + input.get().toString() + " expected " + conditionValues[i]);
                         if (input2.get() == null) {
-                        	if (sConditionValues[i].equals("null")) {
+                        	if (conditionValues[i].equals("null")) {
                         		return false;
                         	}
-                        } else if (input2.get().toString().equals(sConditionValues[i])) {
+                        } else if (input2.get().toString().equals(conditionValues[i])) {
                             //System.err.println("isActivated::return false");
                             return false;
                         }
                         break;
                     default:
-                        throw new Exception("Unexpected operation: " + conditionOperations[i]);
+                        throw new IllegalArgumentException("Unexpected operation: " + conditionOperations[i]);
                 }
             } catch (Exception e) {
                 e.printStackTrace();
                 return false;
             }
         }
-        //if (sConditionIDs.length > 0) {
+        //if (conditionIDs.length > 0) {
         //	System.err.println("isActivated::return true");
         //}
-        return bIsActive;
+        return isActive;
     }
 
     public String getTipText() {
-        return sTipText.get();
+        return tipText.get();
     }
 
-    public String toString() {
-    	if (sMethodnput.get() != null) {
-    		return "call " + sMethodnput.get();
+    @Override
+	public String toString() {
+    	if (methodnput.get() != null) {
+    		return "call " + methodnput.get();
     	}
-        return "@" + sSourceID + " -> @" + sTargetID + "/" + sTargetInput;
+        return "@" + sourceID + " -> @" + targetID + "/" + targetInput;
     }
 
 
     public String toString(PartitionContext context) {
-    	if (sMethodnput.get() != null) {
+    	if (methodnput.get() != null) {
     		return toString();
     	}
-        return "@" + BeautiDoc.translatePartitionNames(sSourceID, context) + " -> @" + sTargetID + "/" + BeautiDoc.translatePartitionNames(sTargetInput, context);
+        return "@" + BeautiDoc.translatePartitionNames(sourceID, context) + " -> @" + targetID + "/" + BeautiDoc.translatePartitionNames(targetInput, context);
     }
 }
diff --git a/src/beast/app/beauti/BeautiDoc.java b/src/beast/app/beauti/BeautiDoc.java
index 7b44194..0574181 100644
--- a/src/beast/app/beauti/BeautiDoc.java
+++ b/src/beast/app/beauti/BeautiDoc.java
@@ -1,11 +1,58 @@
 package beast.app.beauti;
 
 
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.PrintStream;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
 import beast.app.draw.BEASTObjectPanel;
 import beast.app.draw.InputEditor;
 import beast.app.draw.InputEditorFactory;
-import beast.core.*;
+import beast.core.BEASTInterface;
+import beast.core.BEASTObject;
+import beast.core.Description;
+import beast.core.Distribution;
+import beast.core.Input;
 import beast.core.Input.Validate;
+import beast.core.MCMC;
+import beast.core.Operator;
+import beast.core.StateNode;
 import beast.core.parameter.Parameter;
 import beast.core.parameter.RealParameter;
 import beast.core.util.CompoundDistribution;
@@ -25,25 +72,9 @@ import beast.util.JSONProducer;
 import beast.util.NexusParser;
 import beast.util.XMLParser;
 import beast.util.XMLParser.RequiredInputProvider;
+import beast.util.XMLParserException;
 import beast.util.XMLProducer;
 
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-
-import javax.swing.*;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
-
-import java.io.*;
-import java.util.*;
-
 
 @Description("Beauti document in doc-view pattern, not useful in models")
 public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
@@ -58,9 +89,9 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         UNKNOWN, SHOW_DETAILS_USE_TEMPLATE, SHOW_DETAILS_USE_XML_SPEC, WRITE_XML, MERGE_AND_WRITE_XML
     }
 
-    public List<Alignment> alignments = new ArrayList<Alignment>();
+    public List<Alignment> alignments = new ArrayList<>();
 
-    public Input<beast.core.Runnable> mcmc = new Input<beast.core.Runnable>("runnable", "main entry of analysis",
+    final public Input<beast.core.Runnable> mcmc = new Input<>("runnable", "main entry of analysis",
             Validate.REQUIRED);
 
     protected List<BranchRateModel> clockModels;
@@ -69,27 +100,27 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
      * contains all loggers from the template *
      */
 
-    public boolean bAutoSetClockRate = true;
+    public boolean autoSetClockRate = true;
         
-    public boolean bAutoUpdateOperatorWeights = true;
+    public boolean autoUpdateOperatorWeights = true;
 
-    public boolean bAutoUpdateFixMeanSubstRate = true;
+    public boolean autoUpdateFixMeanSubstRate = true;
     /**
      * flags for whether parameters can be linked.
      * Once a parameter is linked, (un)linking in the alignment editor should be disabled
      */
-    public boolean bAllowLinking = false;
-    public boolean bHasLinkedAtLeastOnce = false;
+    public boolean allowLinking = false;
+    public boolean hasLinkedAtLeastOnce = false;
 
     /**
      * [0] = sitemodel [1] = clock model [2] = tree *
      */
     List<BEASTInterface>[] pPartitionByAlignments;
     List<BEASTInterface>[] pPartition;
-    private List<Integer>[] nCurrentPartitions;
+    private List<Integer>[] currentPartitions;
     // partition names
-    List<PartitionContext> sPartitionNames = new ArrayList<PartitionContext>();
-    Set<PartitionContext> possibleContexts = new HashSet<PartitionContext>();
+    List<PartitionContext> partitionNames = new ArrayList<>();
+    Set<PartitionContext> possibleContexts = new HashSet<>();
 
     public BeautiConfig beautiConfig;
     Beauti beauti;
@@ -97,14 +128,15 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     private String templateName = null;
     private String templateFileName = STANDARD_TEMPLATE;
 
-    Map<String, String> tipTextMap = new HashMap<String, String>();
+    Map<String, String> tipTextMap = new HashMap<>();
 
     /**
-     * list of all plugins in the model, mapped by its ID *
+     * list of all beastObjects in the model, mapped by its ID *
      */
     public HashMap<String, BEASTInterface> pluginmap = null;
+    private Map<BEASTInterface, String> reversePluginmap;
     /**
-     * list of all plugins in the model that have an impact on the posterior
+     * list of all beastObjects in the model that have an impact on the posterior
      */
     List<BEASTInterface> posteriorPredecessors = null;
     List<BEASTInterface> likelihoodPredecessors = null;
@@ -116,7 +148,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 
     private boolean isExpertMode = false;
 
-    public Set<InputEditor> currentInputEditors = new HashSet<InputEditor>();
+    public Set<InputEditor> currentInputEditors = new HashSet<>();
 
     /**
      * name of current file, used for saving (as opposed to saveAs) *
@@ -155,17 +187,17 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         return templateName;
     }
     
-    public ActionOnExit parseArgs(String[] args) throws Exception {
+    public ActionOnExit parseArgs(String[] args) throws XMLParserException, SAXException, IOException, ParserConfigurationException  {
         ActionOnExit endState = ActionOnExit.UNKNOWN;
-        String sOutputFileName = "beast.xml";
-        String sXML = null;
-        String sTemplateXML = null;
+        String outputFileName = "beast.xml";
+        String xml = null;
+        String templateXML = null;
         TraitSet traitset = null;
 
         int i = 0;
         try {
             while (i < args.length) {
-                int iOld = i;
+                int old = i;
                 if (args[i].equals("")) {
                     i += 1;
                 } else if (args[i].equals("-h") || args[i].equals("-help")) {
@@ -175,18 +207,18 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                 	// already done in beast.app.beauti.Beauti
                 	i += 1;
                 } else if (args[i].equals("-xml")) {
-                    String sFileName = args[i + 1];
-                    sXML = load(sFileName);
+                    String fileName = args[i + 1];
+                    xml = load(fileName);
                     // XMLParser parser = new XMLParser();
-                    // m_doc.m_mcmc.setValue(parser.parseFile(sFileName),
+                    // m_doc.m_mcmc.setValue(parser.parseFile(fileName),
                     // m_doc);
-                    this.fileName = nameFromFile(sFileName);
+                    this.fileName = nameFromFile(fileName);
                     i += 2;
                 } else if (args[i].equals("-template")) {
-                    String sFileName = args[i + 1];
-                    sTemplateXML = processTemplate(sFileName);
-                    templateFileName = sFileName;
-                    templateName = nameFromFile(sFileName);
+                    String fileName = args[i + 1];
+                    templateXML = processTemplate(fileName);
+                    templateFileName = fileName;
+                    templateName = nameFromFile(fileName);
                     i += 2;
                 } else if (args[i].equals("-nex")) {
                     // NB: multiple -nex/-xmldata commands can be processed!
@@ -218,22 +250,23 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                     } else if (args[i + 1].equals("merge")) {
                         endState = ActionOnExit.MERGE_AND_WRITE_XML;
                     } else {
-                        throw new Exception("Expected one of 'writexml','usetemplate' or 'usexml', not " + args[i + 1]);
+                        throw new IllegalArgumentException("Expected one of 'writexml','usetemplate' or 'usexml', not " + args[i + 1]);
                     }
                     i += 2;
                 } else if (args[i].equals("-out")) {
-                    sOutputFileName = args[i + 1];
+                    outputFileName = args[i + 1];
                     i += 2;
                 } else if (args[i].equals("-noerr")) {
                     System.setErr(new PrintStream(new OutputStream() {
-                        public void write(int b) {
+                        @Override
+						public void write(int b) {
                         }
                     }));
                     i += 1;
                 }
 
-                if (i == iOld) {
-                    throw new Exception("Wrong argument: " + args[i]);
+                if (i == old) {
+                    throw new IllegalArgumentException("Wrong argument: " + args[i]);
                 }
             }
         } catch (Exception e) {
@@ -242,18 +275,18 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             System.exit(1);
         }
 
-        initialize(endState, sXML, sTemplateXML, sOutputFileName);
+        initialize(endState, xml, templateXML, outputFileName);
         addTraitSet(traitset);
         return endState;
     } // parseArgs
 
-    String nameFromFile(String sFileName) {
-        if (sFileName.contains("/")) {
-            return sFileName.substring(sFileName.lastIndexOf("/") + 1, sFileName.length() - 4);
-        } else if (sFileName.contains("\\")) {
-            return sFileName.substring(sFileName.lastIndexOf("\\") + 1, sFileName.length() - 4);
+    String nameFromFile(String fileName) {
+        if (fileName.contains("/")) {
+            return fileName.substring(fileName.lastIndexOf("/") + 1, fileName.length() - 4);
+        } else if (fileName.contains("\\")) {
+            return fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.length() - 4);
         }
-        return sFileName.substring(0, sFileName.length() - 4);
+        return fileName.substring(0, fileName.length() - 4);
     }
 
     void showUsageAndExit() {
@@ -267,7 +300,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                 + "-xml [beast file]\n" + "-out [output file name]\n" + "-exitaction [writexml|usetemplate|usexml]\n";
     }
 
-    private Set<BeautiDocListener> listeners = new HashSet<BeautiDocListener>();
+    private Set<BeautiDocListener> listeners = new HashSet<>();
 
     public void addBeautiDocListener(BeautiDocListener listener) {
         listeners.add(listener);
@@ -275,50 +308,62 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 
     @SuppressWarnings("unchecked")
     void clear() {
-        clockModels = new ArrayList<BranchRateModel>();
-        // treePriors = new ArrayList<TreeDistribution>();
-        alignments = new ArrayList<Alignment>();
+        clockModels = new ArrayList<>();
+        // treePriors = new ArrayList<>();
+        alignments = new ArrayList<>();
 
         pPartitionByAlignments = new List[3];
         pPartition = new List[3];
-        nCurrentPartitions = new List[3];
-        sPartitionNames = new ArrayList<PartitionContext>();
+        currentPartitions = new List[3];
+        partitionNames = new ArrayList<>();
         for (int i = 0; i < 3; i++) {
-            pPartitionByAlignments[i] = new ArrayList<BEASTInterface>();
-            pPartition[i] = new ArrayList<BEASTInterface>();
-            nCurrentPartitions[i] = new ArrayList<Integer>();
+            pPartitionByAlignments[i] = new ArrayList<>();
+            pPartition[i] = new ArrayList<>();
+            currentPartitions[i] = new ArrayList<>();
         }
-        tipTextMap = new HashMap<String, String>();
+        tipTextMap = new HashMap<>();
 
-        pluginmap = new HashMap<String, BEASTInterface>();
-        taxaset = new HashMap<String, Taxon>();
+        pluginmap = new HashMap<>();
+        reversePluginmap = new HashMap<>();
+        taxaset = new HashMap<>();
         fileName = "";
-        linked = new HashSet<Input<?>>();
+        linked = new HashSet<>();
     }
 
-    public void registerPlugin(BEASTInterface plugin) {
-        // first make sure to remove plug-ins when the id of a plugin changed
-        unregisterPlugin(plugin);
+    public void registerPlugin(BEASTInterface beastObject) {
+        // first make sure to remove plug-ins when the id of a beastObject changed
+        unregisterPlugin(beastObject);
 
-        pluginmap.put(plugin.getID(), plugin);
-        if (plugin instanceof Taxon) {
-        	Taxon taxon = (Taxon) plugin;
+        pluginmap.put(beastObject.getID(), beastObject);
+        reversePluginmap.put(beastObject, beastObject.getID());
+        if (beastObject instanceof Taxon) {
+        	Taxon taxon = (Taxon) beastObject;
             taxaset.put(taxon.getID(), taxon);
         }
     }
 
-    public void unregisterPlugin(BEASTInterface plugin) {
-        String oldID = null;
-        for (String id : pluginmap.keySet()) {
-            if (pluginmap.get(id).equals(plugin)) {
-                oldID = id;
-                break;
-            }
-        }
-        if (oldID != null) {
-            pluginmap.remove(oldID);
+    public void unregisterPlugin(BEASTInterface beastObject) {
+        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 
+        // but less reliable since ID may have changed.
+        String id = reversePluginmap.get(beastObject);
+        if (id != null && pluginmap.containsKey(id)) {
+            pluginmap.remove(id);
         }
-        taxaset.remove(plugin.getID());
+        
+//        String oldID = null;
+//        for (String id : pluginmap.keySet()) {
+//            if (pluginmap.get(id).equals(beastObject)) {
+//                oldID = id;
+//                break;
+//            }
+//        }
+//        if (oldID != null) {
+//            pluginmap.remove(oldID);
+//        }
     }
 
     /**
@@ -329,8 +374,8 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             clear();
             BEASTObjectPanel.init();
             beautiConfig.clear();
-            String sXML = processTemplate(templateFileName);
-            loadTemplate(sXML);
+            String xml = processTemplate(templateFileName);
+            loadTemplate(xml);
 
             for (BeautiDocListener listener : listeners) {
                 listener.docHasChanged();
@@ -340,19 +385,19 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         }
     }
 
-    public void loadXML(File file) throws Exception {
-        String sXML = load(file);
-        extractSequences(sXML);
+    public void loadXML(File file) throws IOException, XMLParserException, SAXException, ParserConfigurationException  {
+        String xml = load(file);
+        extractSequences(xml);
         scrubAll(true, false);
         fireDocHasChanged();
     }
 
-    public void loadNewTemplate(String fileName) throws Exception {
+    public void loadNewTemplate(String fileName)  {
         templateFileName = fileName;
         newAnalysis();
     }
 
-    public void importNexus(File file) throws Exception {
+    public void importNexus(File file) throws IOException  {
         NexusParser parser = new NexusParser();
         parser.parseFile(file);
         if (parser.filteredAlignments.size() > 0) {
@@ -367,7 +412,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 //      fireDocHasChanged();
     }
 
-    public void importXMLAlignment(File file) throws Exception {
+    public void importXMLAlignment(File file)  {
         Alignment data = (Alignment) BeautiAlignmentProvider.getXMLData(file);
         data.initAndValidate();
         addAlignmentWithSubnet(data, beautiConfig.partitionTemplate.get());
@@ -375,80 +420,85 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 //      fireDocHasChanged();
     }
 
-    void fireDocHasChanged() throws Exception {
+    void fireDocHasChanged()  {
         for (BeautiDocListener listener : listeners) {
-            listener.docHasChanged();
+            try {
+				listener.docHasChanged();
+			} catch (Exception e) {
+				e.printStackTrace();
+			}
         }
     }
 
-    void initialize(ActionOnExit endState, String sXML, String sTemplate, String sFileName) throws Exception {
+    void initialize(ActionOnExit endState, String xml, String template, String fileName) throws XMLParserException, SAXException, IOException, ParserConfigurationException {
         // beautiConfig.clear();
         switch (endState) {
             case UNKNOWN:
             case SHOW_DETAILS_USE_TEMPLATE: {
-                mergeSequences(sTemplate);
+                mergeSequences(template);
                 // scrubAll(true, );
                 connectModel();
                 break;
             }
             case SHOW_DETAILS_USE_XML_SPEC: {
-                if (sTemplate == null) {
-                    sTemplate = processTemplate(STANDARD_TEMPLATE);
+                if (template == null) {
+                    template = processTemplate(STANDARD_TEMPLATE);
                 }
-                loadTemplate(sTemplate);
-                extractSequences(sXML);
+                loadTemplate(template);
+                extractSequences(xml);
                 connectModel();
                 break;
             }
             case WRITE_XML: {
-                mergeSequences(sTemplate);
+                mergeSequences(template);
                 connectModel();
-                save(sFileName);
+                save(fileName);
                 break;
             }
             case MERGE_AND_WRITE_XML: {
                 // merge alignment with XML
 //	        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-//	        Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(sXML)));
+//	        Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
 //	        doc.normalize();
 //	        NodeList nodes = doc.getElementsByTagName("data");
 //
 //			XMLProducer producer = new XMLProducer();
 //			producer.toRawXML(alignments.get(0));
 //			
-//			Pplugin plugin =  parser.parseFragment(sXML, false);
-//			int i = sXML.indexOf("<data");
-//			for (Plugin plugin : pluginmap.values()) {
-//				if (plugin instanceof Alignment) {
+//			Pplugin beastObject =  parser.parseFragment(xml, false);
+//			int i = xml.indexOf("<data");
+//			for (BEASTObject beastObject : pluginmap.values()) {
+//				if (beastObject instanceof Alignment) {
 //					
 //				}
 //			}
-//			save(sFileName);
+//			save(fileName);
                 System.exit(1);
                 break;
             }
             // // load standard template
-            // String sTemplateXML =
+            // String templateXML =
             // BeautiInitDlg.processTemplate(STANDARD_TEMPLATE);
-            // loadTemplate(sTemplateXML);
+            // loadTemplate(templateXML);
             // connectModel();
         }
     }
 
     /**
-     * public to allow access for unit test *
+     * public to allow access for unit test 
+     * @throws IOException *
      */
-    public String processTemplate(String sFileName) throws Exception {
+    public String processTemplate(String fileName) throws IOException {
         final String MERGE_ELEMENT = "mergepoint";
         // first gather the set of potential directories with templates
-        Set<String> sDirs = new HashSet<String>();// AddOnManager.getBeastDirectories();
+        Set<String> dirs = new HashSet<>();// AddOnManager.getBeastDirectories();
         String pathSep = System.getProperty("path.separator");
         String classpath = System.getProperty("java.class.path");
         String fileSep = System.getProperty("file.separator");
         if (fileSep.equals("\\")) {
             fileSep = "\\\\";
         }
-        sDirs.add(".");
+        dirs.add(".");
         for (String path : classpath.split(pathSep)) {
             path = path.replaceAll(fileSep, "/");
             if (path.endsWith(".jar")) {
@@ -457,37 +507,37 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             if (path.indexOf("/") >= 0) {
                 path = path.substring(0, path.lastIndexOf("/"));
             }
-            if (!sDirs.contains(path)) {
-                sDirs.add(path);
+            if (!dirs.contains(path)) {
+                dirs.add(path);
             }
         }
 
         // read main template, try all template directories if necessary
-        File mainTemplate = new File(sFileName);
-        for (String sDir : sDirs) {
+        File mainTemplate = new File(fileName);
+        for (String dirName : dirs) {
             if (!mainTemplate.exists()) {
-                mainTemplate = new File(sDir + fileSep + sFileName);
+                mainTemplate = new File(dirName + fileSep + fileName);
             }
             if (!mainTemplate.exists()) {
-                mainTemplate = new File(sDir + fileSep + "templates" + fileSep + sFileName);
+                mainTemplate = new File(dirName + fileSep + "templates" + fileSep + fileName);
             }
         }
-        System.err.println("Loading template " + mainTemplate.getAbsolutePath());
-        String sTemplateXML = load(mainTemplate.getAbsolutePath());
+        Log.warning.println("Loading template " + mainTemplate.getAbsolutePath());
+        String templateXML = load(mainTemplate.getAbsolutePath());
 
         // find merge points
         int i = 0;
-        HashMap<String, String> sMergePoints = new HashMap<String, String>();
+        HashMap<String, String> mergePoints = new HashMap<>();
         while (i >= 0) {
-            i = sTemplateXML.indexOf("<" + MERGE_ELEMENT, i + 1);
+            i = templateXML.indexOf("<" + MERGE_ELEMENT, i + 1);
             if (i > 0) {
-                int j = sTemplateXML.indexOf('>', i);
-                String sStr = sTemplateXML.substring(i, j);
-                sStr = sStr.replaceAll(".*id=", "");
-                char c = sStr.charAt(0);
-                sStr = sStr.replaceAll(c + "[^" + c + "]*$", "");
-                sStr = sStr.substring(1);
-                sMergePoints.put(sStr, "");
+                int j = templateXML.indexOf('>', i);
+                String str = templateXML.substring(i, j);
+                str = str.replaceAll(".*id=", "");
+                char c = str.charAt(0);
+                str = str.replaceAll(c + "[^" + c + "]*$", "");
+                str = str.substring(1);
+                mergePoints.put(str, "");
             }
         }
 
@@ -495,20 +545,20 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         // ensure processed templates are unique in name.
         // This prevents loading templates twice, once from the development area
         // and once from .beast2-addon area
-        Set<String> loadedTemplates = new HashSet<String>();
-        for (String sDir : sDirs) {
-            System.out.println("Investigating " + sDir);
-            File templates = new File(sDir + fileSep + "templates");
+        Set<String> loadedTemplates = new HashSet<>();
+        for (String dirName : dirs) {
+            Log.info.println("Investigating " + dirName);
+            File templates = new File(dirName + fileSep + "templates");
             File[] files = templates.listFiles();
             if (files != null) {
                 for (File template : files) {
                     if (!template.getAbsolutePath().equals(mainTemplate.getAbsolutePath())
                             && template.getName().toLowerCase().endsWith(".xml")) {
                         if (!loadedTemplates.contains(template.getName())) {
-                            System.err.println("Processing " + template.getAbsolutePath());
+                        	Log.warning.println("Processing " + template.getAbsolutePath());
                             loadedTemplates.add(template.getName());
-                            String sXML2 = load(template.getAbsolutePath());
-                            if (!sXML2.contains("<mergepoint ")) {
+                            String xml2 = load(template.getAbsolutePath());
+                            if (!xml2.contains("<mergepoint ")) {
                                 try {
 
                                     DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
@@ -520,34 +570,34 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 
                                     // find mergewith elements
                                     NodeList nodes = doc.getElementsByTagName("mergewith");
-                                    for (int iMergeElement = 0; iMergeElement < nodes.getLength(); iMergeElement++) {
-                                        Node mergeElement = nodes.item(iMergeElement);
-                                        String sMergePoint = mergeElement.getAttributes().getNamedItem("point")
+                                    for (int mergeElementIndex = 0; mergeElementIndex < nodes.getLength(); mergeElementIndex++) {
+                                        Node mergeElement = nodes.item(mergeElementIndex);
+                                        String mergePoint = mergeElement.getAttributes().getNamedItem("point")
                                                 .getNodeValue();
-                                        if (!sMergePoints.containsKey(sMergePoint)) {
-                                            System.err.println("Cannot find merge point named " + sMergePoint
+                                        if (!mergePoints.containsKey(mergePoint)) {
+                                        	Log.warning.println("Cannot find merge point named " + mergePoint
                                                     + " from " + template.getName()
                                                     + " in template. MergeWith ignored.");
                                         } else {
-                                            String sXML = "";
+                                            String xml = "";
                                             NodeList children = mergeElement.getChildNodes();
-                                            for (int iChild = 0; iChild < children.getLength(); iChild++) {
-                                                sXML += nodeToString(children.item(iChild));
+                                            for (int childIndex = 0; childIndex < children.getLength(); childIndex++) {
+                                                xml += nodeToString(children.item(childIndex));
                                             }
-                                            String sStr = sMergePoints.get(sMergePoint);
-                                            sStr += sXML;
-                                            sMergePoints.put(sMergePoint, sStr);
+                                            String str = mergePoints.get(mergePoint);
+                                            str += xml;
+                                            mergePoints.put(mergePoint, str);
                                         }
 
                                     }
                                 } catch (Exception e) {
                                     if (!e.getMessage().contains("beast.app.beauti.InputConstraint")) {
-                                        System.err.println(e.getMessage());
+                                    	Log.warning.println(e.getMessage());
                                     }
                                 }
                             }
                         } else {
-                            System.err.println("Skipping " + template.getAbsolutePath() + " since "
+                        	Log.warning.println("Skipping " + template.getAbsolutePath() + " since "
                                     + template.getName() + " is already processed");
                         }
 
@@ -559,43 +609,43 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         // merge XML
         i = 0;
         while (i >= 0) {
-            i = sTemplateXML.indexOf("<" + MERGE_ELEMENT, i + 1);
+            i = templateXML.indexOf("<" + MERGE_ELEMENT, i + 1);
             if (i > 0) {
-                int j = sTemplateXML.indexOf('>', i);
-                String sStr = sTemplateXML.substring(i, j);
-                sStr = sStr.replaceAll(".*id=", "");
-                char c = sStr.charAt(0);
-                sStr = sStr.replaceAll(c + "[^" + c + "]*$", "");
-                sStr = sStr.substring(1);
-                String sXML = sMergePoints.get(sStr);
-                sTemplateXML = sTemplateXML.substring(0, i) + sXML + sTemplateXML.substring(j + 1);
+                int j = templateXML.indexOf('>', i);
+                String str = templateXML.substring(i, j);
+                str = str.replaceAll(".*id=", "");
+                char c = str.charAt(0);
+                str = str.replaceAll(c + "[^" + c + "]*$", "");
+                str = str.substring(1);
+                String xml = mergePoints.get(str);
+                templateXML = templateXML.substring(0, i) + xml + templateXML.substring(j + 1);
             }
         }
-        templateName = nameFromFile(sFileName);
+        templateName = nameFromFile(fileName);
 
         if (Boolean.valueOf(System.getProperty("beast.debug"))) {
             Writer out = new OutputStreamWriter(new FileOutputStream("/tmp/beast.xml"));
             try {
-                out.write(sTemplateXML);
+                out.write(templateXML);
             } finally {
                 out.close();
             }
         }
 
-        return sTemplateXML;
+        return templateXML;
     }
 
-    void processBeautiConfig(Document doc) throws Exception {
+    void processBeautiConfig(Document doc) throws XMLParserException, TransformerException  {
         // find configuration elements, process and remove
         NodeList nodes = doc.getElementsByTagName("beauticonfig");
         Node topNode = doc.getElementsByTagName("*").item(0);
-        String sNameSpaceStr = XMLParser.getAttribute(topNode, "namespace");
-        for (int iConfigElement = 0; iConfigElement < nodes.getLength(); iConfigElement++) {
-            Node configElement = nodes.item(iConfigElement);
-            String sXML = nodeToString(configElement);
+        String nameSpaceStr = XMLParser.getAttribute(topNode, "namespace");
+        for (int configElementIndex = 0; configElementIndex < nodes.getLength(); configElementIndex++) {
+            Node configElement = nodes.item(configElementIndex);
+            String xml = nodeToString(configElement);
             XMLParser parser = new XMLParser();
-            parser.setNameSpace(sNameSpaceStr);
-            parser.parseBareFragment(sXML, true);
+            parser.setNameSpace(nameSpaceStr);
+            parser.parseBareFragment(xml, true);
             configElement.getParentNode().removeChild(configElement);
         }
     }
@@ -616,21 +666,21 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     static public String load(File file) throws IOException {
         BufferedReader fin = new BufferedReader(new FileReader(file));
         StringBuffer buf = new StringBuffer();
-        String sStr = null;
+        String str = null;
         while (fin.ready()) {
-            sStr = fin.readLine();
-            buf.append(sStr);
+            str = fin.readLine();
+            buf.append(str);
             buf.append('\n');
         }
         fin.close();
         return buf.toString();
     }
 
-    Alignment getPartition(BEASTInterface plugin) {
-        String sPartition = plugin.getID();
-        sPartition = parsePartition(sPartition);
+    Alignment getPartition(BEASTInterface beastObject) {
+        String partition = beastObject.getID();
+        partition = parsePartition(partition);
         for (Alignment data : alignments) {
-            if (data.getID().equals(sPartition)) {
+            if (data.getID().equals(partition)) {
                 return data;
             }
         }
@@ -645,15 +695,15 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     }
 
     public DOC_STATUS validateModel() {
-        if (mcmc == null || (mcmc.get().hasPartitions() && sPartitionNames.size() == 0)) {
+        if (mcmc == null || (mcmc.get().hasPartitions() && partitionNames.size() == 0)) {
             return DOC_STATUS.NO_DOCUMENT;
         }
         try {
             // check if file is already saved and not changed wrt file on disk
             if (fileName != null && fileName.length() > 0) {
-                String sFileXML = load(fileName);
-                String sXML = toXML();
-                if (sFileXML.equals(sXML)) {
+                String fileXML = load(fileName);
+                String xml = toXML();
+                if (fileXML.equals(xml)) {
                     return DOC_STATUS.SAVED;
                 }
             }
@@ -664,19 +714,21 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     } // validateModel
 
     /**
-     * save specification in file *
+     * save specification in file 
+     * @throws IOException *
      */
-    public void save(String sFileName) throws Exception {
-        save(new File(sFileName));
+    public void save(String fileName) throws IOException  {
+        save(new File(fileName));
     } // save
 
     /**
-     * save specification in file *
+     * save specification in file 
+     * @throws IOException *
      */
-    public void save(File file) throws Exception {
+    public void save(File file) throws IOException  {
         determinePartitions();
         scrubAll(false, false);
-        // String sXML = new XMLProducer().toXML(mcmc.get(), );
+        // String xml = new XMLProducer().toXML(mcmc.get(), );
         String spec = null;
         if (file.getPath().toLowerCase().endsWith(".json")) {
             spec = toJSON();
@@ -689,50 +741,50 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     } // save
 
     private String toJSON() {
-        Set<BEASTInterface> plugins = new HashSet<BEASTInterface>();
-        String json = new JSONProducer().toJSON(mcmc.get(), plugins);
+        Set<BEASTInterface> beastObjects = new HashSet<>();
+        String json = new JSONProducer().toJSON(mcmc.get(), beastObjects);
 
         json = json.replaceFirst("\\{", "{ beautitemplate:\"" + templateName + "\", beautistatus:\"" + getBeautiStatus() + "\", ");
         return json + "\n";
     }
 
     public String toXML() {
-        Set<BEASTInterface> plugins = new HashSet<BEASTInterface>();
-//		for (Plugin plugin : pluginmap.values()) {
-//			String sName = plugin.getClass().getName();
-//			if (!sName.startsWith("beast.app.beauti")) {
-//				plugins.add(plugin);
+        Set<BEASTInterface> beastObjects = new HashSet<>();
+//		for (BEASTObject beastObject : pluginmap.values()) {
+//			String name = beastObject.getClass().getName();
+//			if (!name.startsWith("beast.app.beauti")) {
+//				beastObjects.add(beastObject);
 //			}
 //		}
-        String sXML = new XMLProducer().toXML(mcmc.get(), plugins);
+        String xml = new XMLProducer().toXML(mcmc.get(), beastObjects);
 
-        sXML = sXML.replaceFirst("<beast ", "<beast beautitemplate='" + templateName + "' beautistatus='" + getBeautiStatus() + "' ");
-        return sXML + "\n";
+        xml = xml.replaceFirst("<beast ", "<beast beautitemplate='" + templateName + "' beautistatus='" + getBeautiStatus() + "' ");
+        return xml + "\n";
     }
 
     /** get status of mode-flags in BEAUti, so these can be restored when reloading an XML file **/
     String getBeautiStatus() {
 	    String beautiStatus = "";
-	    if (!bAutoSetClockRate) {
+	    if (!autoSetClockRate) {
 	        beautiStatus = "noAutoSetClockRate";
 	    }
-	    if (bAllowLinking) {
+	    if (allowLinking) {
 	        beautiStatus += (beautiStatus.length() > 0 ? "|" : "") + "allowLinking";
 	    }
-	    if (!bAutoUpdateOperatorWeights) {
+	    if (!autoUpdateOperatorWeights) {
 	        beautiStatus += (beautiStatus.length() > 0 ? "|" : "") + "noAutoUpdateOperatorWeights";
 	    }
-	    if (!bAutoUpdateFixMeanSubstRate) {
+	    if (!autoUpdateFixMeanSubstRate) {
 	        beautiStatus += (beautiStatus.length() > 0 ? "|" : "") + "noAutoUpdateFixMeanSubstRate";
 	    }
 	    return beautiStatus;
     }
 
-    void extractSequences(String sXML) throws Exception {
+    void extractSequences(String xml) throws XMLParserException, SAXException, IOException, ParserConfigurationException  {
 
         // parse the XML fragment into a DOM document
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(sXML)));
+        Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
         doc.normalize();
         // find top level beast element
         NodeList nodes = doc.getElementsByTagName("*");
@@ -745,30 +797,30 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
             // load standard template
             if (beautiConfig == null) {
-                String sTemplateXML = processTemplate(STANDARD_TEMPLATE);
-                loadTemplate(sTemplateXML);
+                String templateXML = processTemplate(STANDARD_TEMPLATE);
+                loadTemplate(templateXML);
             }
         } else {
-            String sTemplateXML = processTemplate(beautiTemplate + ".xml");
-            loadTemplate(sTemplateXML);
+            String templateXML = processTemplate(beautiTemplate + ".xml");
+            loadTemplate(templateXML);
         }
 
         String beautiStatus = XMLParser.getAttribute(topNode, "beautistatus");
         if (beautiStatus == null) {
             beautiStatus = "";
         }
-        bAutoSetClockRate = !beautiStatus.contains("noAutoSetClockRate");
-        beauti.autoSetClockRate.setSelected(bAutoSetClockRate);
-        bAllowLinking = beautiStatus.contains("allowLinking");
-        beauti.allowLinking.setSelected(bAllowLinking);
-        bAutoUpdateOperatorWeights = !beautiStatus.contains("noAutoUpdateOperatorWeights");
-        beauti.autoUpdateOperatorWeights.setSelected(bAutoUpdateOperatorWeights);
-        bAutoUpdateFixMeanSubstRate = !beautiStatus.contains("noAutoUpdateFixMeanSubstRate"); 
-        beauti.autoUpdateFixMeanSubstRate.setSelected(bAutoUpdateFixMeanSubstRate);
+        autoSetClockRate = !beautiStatus.contains("noAutoSetClockRate");
+        beauti.autoSetClockRate.setSelected(autoSetClockRate);
+        allowLinking = beautiStatus.contains("allowLinking");
+        beauti.allowLinking.setSelected(allowLinking);
+        autoUpdateOperatorWeights = !beautiStatus.contains("noAutoUpdateOperatorWeights");
+        beauti.autoUpdateOperatorWeights.setSelected(autoUpdateOperatorWeights);
+        autoUpdateFixMeanSubstRate = !beautiStatus.contains("noAutoUpdateFixMeanSubstRate"); 
+        beauti.autoUpdateFixMeanSubstRate.setSelected(autoUpdateFixMeanSubstRate);
 
         // parse file
         XMLParser parser = new XMLParser();
-        BEASTInterface MCMC = parser.parseFragment(sXML, true);
+        BEASTInterface MCMC = parser.parseFragment(xml, true);
         mcmc.setValue(MCMC, this);
         BEASTObjectPanel.addPluginToMap(MCMC, this);
 
@@ -801,19 +853,19 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             //e.printStackTrace();
         }
 
-//		MCMC = parser.parseFragment(sXML, true);
+//		MCMC = parser.parseFragment(xml, true);
 //		mcmc.setValue(MCMC, this);
 //		PluginPanel.addPluginToMap(MCMC, this);
 
-//		if (sXML.indexOf(XMLProducer.DO_NOT_EDIT_WARNING) > 0) {
-//			int iStart = sXML.indexOf(XMLProducer.DO_NOT_EDIT_WARNING);
-//			int iEnd = sXML.lastIndexOf("-->");
-//			sXML = sXML.substring(iStart, iEnd);
-//			sXML = sXML.replaceAll(XMLProducer.DO_NOT_EDIT_WARNING, "");
-//			sXML = "<beast namespace='" + XMLProducer.DEFAULT_NAMESPACE + "'>" + sXML + "</beast>";
-//			List<Plugin> plugins = parser.parseBareFragments(sXML, true);
-//			for (Plugin plugin : plugins) {
-//				PluginPanel.addPluginToMap(plugin, this);
+//		if (xml.indexOf(XMLProducer.DO_NOT_EDIT_WARNING) > 0) {
+//			int start = xml.indexOf(XMLProducer.DO_NOT_EDIT_WARNING);
+//			int end = xml.lastIndexOf("-->");
+//			xml = xml.substring(start, end);
+//			xml = xml.replaceAll(XMLProducer.DO_NOT_EDIT_WARNING, "");
+//			xml = "<beast namespace='" + XMLProducer.DEFAULT_NAMESPACE + "'>" + xml + "</beast>";
+//			List<BEASTObject> beastObjects = parser.parseBareFragments(xml, true);
+//			for (BEASTObject beastObject : beastObjects) {
+//				PluginPanel.addPluginToMap(beastObject, this);
 //			}
 //		}
 
@@ -822,13 +874,17 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     }
 
     /**
-     * Merge sequence data with sXML specification.
+     * Merge sequence data with xml specification.
+     * @throws ParserConfigurationException 
+     * @throws IOException 
+     * @throws SAXException 
+     * @throws XMLParserException 
      */
-    void mergeSequences(String sXML) throws Exception {
-        if (sXML == null) {
-            sXML = processTemplate(STANDARD_TEMPLATE);
+    void mergeSequences(String xml) throws XMLParserException, SAXException, IOException, ParserConfigurationException {
+        if (xml == null) {
+            xml = processTemplate(STANDARD_TEMPLATE);
         }
-        loadTemplate(sXML);
+        loadTemplate(xml);
         // create XML for alignments
         if (beautiConfig != null) {
             for (Alignment alignment : alignments) {
@@ -836,11 +892,11 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
         } else {
             // replace alignment
-            for (BEASTInterface plugin : pluginmap.values()) {
-                if (plugin instanceof Alignment) {
+            for (BEASTInterface beastObject : pluginmap.values()) {
+                if (beastObject instanceof Alignment) {
                 	// use toArray to prevent ConcurrentModificationException
-                    for (Object output : plugin.getOutputs().toArray()) {
-                        replaceInputs((BEASTInterface) output, plugin, alignments.get(0));
+                    for (Object output : beastObject.getOutputs().toArray()) {
+                        replaceInputs((BEASTInterface) output, beastObject, alignments.get(0));
                     }
                 }
             }
@@ -850,19 +906,20 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 
     } // mergeSequences
 
-    private void replaceInputs(BEASTInterface plugin, BEASTInterface original, BEASTInterface replacement) {
+    private void replaceInputs(BEASTInterface beastObject, BEASTInterface original, BEASTInterface replacement) {
         try {
-            for (Input input : plugin.listInputs()) {
+            for (Input<?> input : beastObject.listInputs()) {
                 if (input.get() != null) {
                     if (input.get() instanceof List) {
-                        List list = (List) input.get();
+                        @SuppressWarnings("unchecked")
+						List<BEASTInterface> list = (List<BEASTInterface>) input.get();
                         if (list.contains(original)) {
                             list.remove(original);
                             list.add(replacement);
                         }
                     } else {
                         if (input.get().equals(original)) {
-                            input.setValue(replacement, plugin);
+                            input.setValue(replacement, beastObject);
                         }
                     }
                 }
@@ -872,21 +929,21 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         }
     }
 
-    void loadTemplate(String sXML) throws Exception {
+    void loadTemplate(String xml) throws XMLParserException, SAXException, IOException, ParserConfigurationException  {
         // load the template and its beauti configuration parts
         XMLParser parser = new XMLParser();
         BEASTObjectPanel.init();
-        List<BEASTInterface> plugins = parser.parseTemplate(sXML, new HashMap<String, BEASTInterface>(), true);
-        for (BEASTInterface plugin : plugins) {
-            if (plugin instanceof beast.core.Runnable) {
-                mcmc.setValue(plugin, this);
-            } else if (plugin instanceof BeautiConfig) {
-                beautiConfig = (BeautiConfig) plugin;
+        List<BEASTInterface> beastObjects = parser.parseTemplate(xml, new HashMap<>(), true);
+        for (BEASTInterface beastObject : beastObjects) {
+            if (beastObject instanceof beast.core.Runnable) {
+                mcmc.setValue(beastObject, this);
+            } else if (beastObject instanceof BeautiConfig) {
+                beautiConfig = (BeautiConfig) beastObject;
                 beautiConfig.setDoc(this);
             } else {
-                System.err.println("template item " + plugin.getID() + " is ignored");
+            	Log.warning.println("template item " + beastObject.getID() + " is ignored");
             }
-            BEASTObjectPanel.addPluginToMap(plugin, this);
+            BEASTObjectPanel.addPluginToMap(beastObject, this);
         }
     }
 
@@ -915,23 +972,23 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     /**
      * Connect all inputs to the relevant ancestors of m_runnable.
      *
-     * @throws Exception *
+     * @ *
      */
-    void connectModel() throws Exception {
+    void connectModel()  {
         scrubAll(true, true);
     }
 
     private void collectClockModels() {
         // collect branch rate models from model
         CompoundDistribution likelihood = (CompoundDistribution) pluginmap.get("likelihood");
-        while (clockModels.size() < sPartitionNames.size()) {
+        while (clockModels.size() < partitionNames.size()) {
             try {
                 GenericTreeLikelihood treelikelihood = new GenericTreeLikelihood();
                 treelikelihood.branchRateModelInput.setValue(new StrictClockModel(), treelikelihood);
-                List<BeautiSubTemplate> sAvailablePlugins = inputEditorFactory.getAvailableTemplates(
+                List<BeautiSubTemplate> availableBEASTObjects = inputEditorFactory.getAvailableTemplates(
                         treelikelihood.branchRateModelInput, treelikelihood, null, this);
-                BEASTInterface plugin = sAvailablePlugins.get(0).createSubNet(sPartitionNames.get(clockModels.size()), true);
-                clockModels.add((BranchRateModel.Base) plugin);
+                BEASTInterface beastObject = availableBEASTObjects.get(0).createSubNet(partitionNames.get(clockModels.size()), true);
+                clockModels.add((BranchRateModel.Base) beastObject);
             } catch (Exception e) {
                 // TODO Auto-generated catch block
                 e.printStackTrace();
@@ -951,7 +1008,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                 }
                 if (tree != null && tree != ((GenericTreeLikelihood) d).treeInput.get()) {
                     clockModel = clockModels.get(k);
-                    System.err.println("WARNING: unlinking clock model for " + d.getID());
+                    Log.warning.println("WARNING: unlinking clock model for " + d.getID());
                     ((GenericTreeLikelihood) d).branchRateModelInput.setValue(clockModel, d);
                 }
             } catch (Exception e) {
@@ -959,10 +1016,10 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
 
             if (clockModel != null) {
-                String sID = ((BEASTInterface) clockModel).getID();
-                sID = parsePartition(sID);
-                String sPartition = alignments.get(k).getID();
-                if (sID.equals(sPartition)) {
+                String id = ((BEASTInterface) clockModel).getID();
+                id = parsePartition(id);
+                String partition = alignments.get(k).getID();
+                if (id.equals(partition)) {
                     clockModels.set(k, clockModel);
                 }
                 k++;
@@ -974,24 +1031,24 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     // // collect tree priors from model
     // CompoundDistribution prior = (CompoundDistribution)
     // pluginmap.get("prior");
-    // while (treePriors.size() < sPartitionNames.size()) {
+    // while (treePriors.size() < partitionNames.size()) {
     // try {
     // CompoundDistribution distr = new CompoundDistribution();
     // distr.pDistributions.setValue(new YuleModel(), distr);
-    // List<BeautiSubTemplate> sAvailablePlugins =
+    // List<BeautiSubTemplate> availableBEASTObjects =
     // inputEditorFactory.getAvailableTemplates(distr.pDistributions, distr,
     // null, this);
-    // for (int i = sAvailablePlugins.size() - 1; i >= 0; i--) {
+    // for (int i = availableBEASTObjects.size() - 1; i >= 0; i--) {
     // if
-    // (!TreeDistribution.class.isAssignableFrom(sAvailablePlugins.get(i)._class))
+    // (!TreeDistribution.class.isAssignableFrom(availableBEASTObjects.get(i)._class))
     // {
-    // sAvailablePlugins.remove(i);
+    // availableBEASTObjects.remove(i);
     // }
     // }
-    // if (sAvailablePlugins.size() > 0) {
-    // Plugin plugin =
-    // sAvailablePlugins.get(0).createSubNet(sPartitionNames.get(treePriors.size()));
-    // treePriors.add((TreeDistribution) plugin);
+    // if (availableBEASTObjects.size() > 0) {
+    // BEASTObject beastObject =
+    // availableBEASTObjects.get(0).createSubNet(partitionNames.get(treePriors.size()));
+    // treePriors.add((TreeDistribution) beastObject);
     // } else {
     // treePriors.add(null);
     // }
@@ -1011,20 +1068,20 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     // TreeLikelihood tl = (TreeLikelihood) distr;
     // Tree tree = tl.m_tree.get();
     // int partition = getPartitionNr(tree);
-    // for (Plugin plugin : tree.outputs) {
-    // if (plugin instanceof TreeDistribution &&
-    // posteriorPredecessors.contains(plugin)) {
-    // treePriors.set(partition, (TreeDistribution) plugin);
+    // for (BEASTObject beastObject : tree.outputs) {
+    // if (beastObject instanceof TreeDistribution &&
+    // posteriorPredecessors.contains(beastObject)) {
+    // treePriors.set(partition, (TreeDistribution) beastObject);
     // }
     // }
     // }
     // }
     // }
 
-    BranchRateModel getClockModel(String sPartition) {
+    BranchRateModel getClockModel(String partition) {
         int k = 0;
         for (Alignment data : alignments) {
-            if (data.getID().equals(sPartition)) {
+            if (data.getID().equals(partition)) {
                 return clockModels.get(k);
             }
             k++;
@@ -1032,10 +1089,10 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         return null;
     }
 
-    // TreeDistribution getTreePrior(String sPartition) {
+    // TreeDistribution getTreePrior(String partition) {
     // int k = 0;
     // for (Alignment data : alignments) {
-    // if (data.getID().equals(sPartition)) {
+    // if (data.getID().equals(partition)) {
     // return treePriors.get(k);
     // }
     // k++;
@@ -1043,25 +1100,25 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     // return null;
     // }
 
-    synchronized public void scrubAll(boolean bUseNotEstimatedStateNodes, boolean bInitial) {
+    synchronized public void scrubAll(boolean useNotEstimatedStateNodes, boolean isInitial) {
         try {
-            if (bAutoSetClockRate) {
+            if (autoSetClockRate) {
                 setClockRate();
             }
-            if (bAutoUpdateFixMeanSubstRate) {
+            if (autoUpdateFixMeanSubstRate) {
             	SiteModelInputEditor.customConnector(this);
             }
 
             // set estimate flag on tree, only if tree occurs in a partition
-            for (BEASTInterface plugin : pluginmap.values()) {
-                if (plugin instanceof Tree) {
-                    Tree tree = (Tree) plugin;
+            for (BEASTInterface beastObject : pluginmap.values()) {
+                if (beastObject instanceof Tree) {
+                    Tree tree = (Tree) beastObject;
                     tree.isEstimatedInput.setValue(false, tree);
                 }
             }
-            for (BEASTInterface plugin : pPartition[2]) {
+            for (BEASTInterface beastObject : pPartition[2]) {
                 // TODO: this might not be a valid type conversion from TreeInterface to Tree
-                Tree tree = (Tree) ((GenericTreeLikelihood) plugin).treeInput.get();
+                Tree tree = (Tree) ((GenericTreeLikelihood) beastObject).treeInput.get();
                 tree.isEstimatedInput.setValue(true, tree);
             }
             if (pluginmap.containsKey("Tree.t:Species")) {
@@ -1070,64 +1127,64 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
 
             // go through all templates, and process connectors in relevant ones
-            boolean bProgress = true;
-            while (bProgress) {
+            boolean progress = true;
+            while (progress) {
                 warning("============================ start scrubbing ===========================");
-                bProgress = false;
+                progress = false;
                 setUpActivePlugins();
 
                 // process MRCA priors
-                for (String sID : pluginmap.keySet()) {
-                    if (sID.endsWith(".prior")) {
-                    	BEASTInterface plugin = pluginmap.get(sID);
-                        if (plugin instanceof MRCAPrior) {
-                            MRCAPrior prior = (MRCAPrior) plugin;
+                for (String id : pluginmap.keySet()) {
+                    if (id.endsWith(".prior")) {
+                    	BEASTInterface beastObject = pluginmap.get(id);
+                        if (beastObject instanceof MRCAPrior) {
+                            MRCAPrior prior = (MRCAPrior) beastObject;
                             if (prior.treeInput.get().isEstimatedInput.get() == false) {
                                 // disconnect
-                                disconnect(plugin, "prior", "distribution");
+                                disconnect(beastObject, "prior", "distribution");
                             } else {
                                 // connect
-                                connect(plugin, "prior", "distribution");
+                                connect(beastObject, "prior", "distribution");
                             }
                         }
                     }
                 }
 
-                List<BeautiSubTemplate> templates = new ArrayList<BeautiSubTemplate>();
+                List<BeautiSubTemplate> templates = new ArrayList<>();
                 templates.add(beautiConfig.partitionTemplate.get());
                 templates.addAll(beautiConfig.subTemplates);
 
                 for (PartitionContext context : possibleContexts) {
-                    applyBeautiRules(templates, bInitial, context);
+                    applyBeautiRules(templates, isInitial, context);
                 }
                 // add 'Species' as special partition name
-                applyBeautiRules(templates, bInitial, new PartitionContext("Species"));
+                applyBeautiRules(templates, isInitial, new PartitionContext("Species"));
 
                 // if the model changed, some rules that use inposterior() may
                 // not have been triggered properly
                 // so we need to check that the model changed, and if so,
                 // revisit the BeautiConnectors
-                List<BEASTInterface> posteriorPredecessors2 = new ArrayList<BEASTInterface>();
+                List<BEASTInterface> posteriorPredecessors2 = new ArrayList<>();
                 collectPredecessors(((MCMC) mcmc.get()).posteriorInput.get(), posteriorPredecessors2);
                 if (posteriorPredecessors.size() != posteriorPredecessors2.size()) {
-                    bProgress = true;
+                    progress = true;
                 } else {
-                    for (BEASTInterface plugin : posteriorPredecessors2) {
-                        if (!posteriorPredecessors.contains(plugin)) {
-                            bProgress = true;
+                    for (BEASTInterface beastObject : posteriorPredecessors2) {
+                        if (!posteriorPredecessors.contains(beastObject)) {
+                            progress = true;
                             break;
                         }
                     }
                 }
             }
 
-            List<BeautiSubTemplate> templates = new ArrayList<BeautiSubTemplate>();
+            List<BeautiSubTemplate> templates = new ArrayList<>();
             templates.add(beautiConfig.hyperPriorTemplate);
-            for (BEASTInterface plugin : pluginmap.values()) {
-                if (plugin instanceof RealParameter) {
-                    if (plugin.getID().startsWith("parameter.")) {
-                        PartitionContext context = new PartitionContext(plugin.getID().substring("parameter.".length()));
-                        applyBeautiRules(templates, bInitial, context);
+            for (BEASTInterface beastObject : pluginmap.values()) {
+                if (beastObject instanceof RealParameter) {
+                    if (beastObject.getID().startsWith("parameter.")) {
+                        PartitionContext context = new PartitionContext(beastObject.getID().substring("parameter.".length()));
+                        applyBeautiRules(templates, isInitial, context);
                     }
                 }
             }
@@ -1136,53 +1193,53 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             collectClockModels();
             // collectTreePriors();
 
-            System.err.println("PARTITIONS:\n");
-            System.err.println(Arrays.toString(nCurrentPartitions));
+            Log.warning.println("PARTITIONS:\n");
+            Log.warning.println(Arrays.toString(currentPartitions));
 
             determineLinks();
         } catch (Exception e) {
-            System.err.println(e.getMessage());
+            Log.err.println(e.getMessage());
         }
         
-        if (bAutoUpdateOperatorWeights) {
+        if (autoUpdateOperatorWeights) {
         	reweightSpeciesPartitionOperators();
         }
     } // scrubAll
 
     protected void setUpActivePlugins() {
-        posteriorPredecessors = new ArrayList<BEASTInterface>();
+        posteriorPredecessors = new ArrayList<>();
         collectPredecessors(((MCMC) mcmc.get()).posteriorInput.get(), posteriorPredecessors);
-        likelihoodPredecessors = new ArrayList<BEASTInterface>();
+        likelihoodPredecessors = new ArrayList<>();
         if (pluginmap.containsKey("likelihood")) {
             collectPredecessors(pluginmap.get("likelihood"), likelihoodPredecessors);
         }
         
                 
-        System.err.print("InPosterior=");
+        Log.warning.print("InPosterior=");
         for (BEASTInterface o : posteriorPredecessors) {
         	pluginmap.put(o.getID(), o);
-        	System.err.print(o.getID() + " ");
+        	Log.warning.print(o.getID() + " ");
         	//if (!pluginmap.containsKey(o)) {
         	//	System.err.println("MISSING: " + o.getID());
         	//}
         }
-        System.err.println();
+        Log.warning.println();
     }
 
-    public static String translatePartitionNames(String sStr, PartitionContext partition) {
-//        sStr = sStr.replaceAll(".s:\\$\\(n\\)", ".s:" + partition.siteModel);
-//        sStr = sStr.replaceAll(".c:\\$\\(n\\)", ".c:" + partition.clockModel);
-//        sStr = sStr.replaceAll(".t:\\$\\(n\\)", ".t:" + partition.tree);
-//        sStr = sStr.replaceAll("\\$\\(n\\)", partition.partition);
+    public static String translatePartitionNames(String str, PartitionContext partition) {
+//        str = str.replaceAll(".s:\\$\\(n\\)", ".s:" + partition.siteModel);
+//        str = str.replaceAll(".c:\\$\\(n\\)", ".c:" + partition.clockModel);
+//        str = str.replaceAll(".t:\\$\\(n\\)", ".t:" + partition.tree);
+//        str = str.replaceAll("\\$\\(n\\)", partition.partition);
         // optimised code, based on (probably incorrect) profiler output
 		StringBuilder sb = new StringBuilder();
-		int len = sStr.length();
+		int len = str.length();
 		for (int i = 0; i < len; i++) {
-			char c = sStr.charAt(i);
+			char c = str.charAt(i);
 			if (c == '.' && i < len - 6) {
-				if (sStr.charAt(i + 2) == ':' && sStr.charAt(i + 3) == '$' && 
-						sStr.charAt(i + 4) == '(' && sStr.charAt(i + 5) == 'n' && sStr.charAt(i + 6) == ')') {
-					switch (sStr.charAt(i+1)) {
+				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;
@@ -1202,7 +1259,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 					sb.append('.');
 				}
 			} else if (c == '$' && i < len - 3) {
-				if (sStr.charAt(i + 1) == '(' && sStr.charAt(i + 2) == 'n' && sStr.charAt(i + 3) == ')') {
+				if (str.charAt(i + 1) == '(' && str.charAt(i + 2) == 'n' && str.charAt(i + 3) == ')') {
 					sb.append(partition.partition);
 					i+= 3;
 				} else {
@@ -1215,18 +1272,18 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         return sb.toString();
     }
 
-    void applyBeautiRules(List<BeautiSubTemplate> templates, boolean bInitial, PartitionContext context) throws Exception {
+    void applyBeautiRules(List<BeautiSubTemplate> templates, boolean isInitial, PartitionContext context) {
         for (BeautiSubTemplate template : templates) {
-            String sTemplateID = translatePartitionNames(template.getMainID(), context);
-            BEASTInterface plugin = pluginmap.get(sTemplateID);
+            String templateID = translatePartitionNames(template.getMainID(), context);
+            BEASTInterface beastObject = pluginmap.get(templateID);
 
             // check if template is in use
-            if (plugin != null) {
+            if (beastObject != null) {
                 // if so, run through all connectors
                 for (BeautiConnector connector : template.connectors) {
 
                     if (connector.atInitialisationOnly()) {
-                        if (bInitial) {
+                        if (isInitial) {
                             warning("connect: " + connector.toString(context) + "\n");
                             connect(connector, context);
                         }
@@ -1252,16 +1309,16 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         }
     }
 
-    void setClockRate() throws Exception {
-    	boolean bNeedsEstimationBySPTree = false;
+    void setClockRate()  {
+    	boolean needsEstimationBySPTree = false;
         if (pluginmap.containsKey("Tree.t:Species")) {
         	Tree sptree = (Tree) pluginmap.get("Tree.t:Species");
 	        // check whether there is a calibration
-	        for (Object plugin : sptree.getOutputs()) {
-	            if (plugin instanceof MRCAPrior) {
-	                MRCAPrior prior = (MRCAPrior) plugin;
+	        for (Object beastObject : sptree.getOutputs()) {
+	            if (beastObject instanceof MRCAPrior) {
+	                MRCAPrior prior = (MRCAPrior) beastObject;
 	                if (prior.distInput.get() != null) {
-	                    bNeedsEstimationBySPTree = true;
+	                    needsEstimationBySPTree = true;
 	                }
 	            }
 	        }
@@ -1274,31 +1331,31 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             for (Distribution distr : ((CompoundDistribution) likelihood).pDistributions.get()) {
                 if (distr instanceof GenericTreeLikelihood) {
                     GenericTreeLikelihood treeLikelihood = (GenericTreeLikelihood) distr;
-                    boolean bNeedsEstimation = bNeedsEstimationBySPTree;
+                    boolean needsEstimation = needsEstimationBySPTree;
                     if (i > 0) {
-                        BranchRateModel.Base model = (BranchRateModel.Base) treeLikelihood.branchRateModelInput.get();
-                        bNeedsEstimation = (model.meanRateInput.get() != firstClock) || firstClock.isEstimatedInput.get();
+                        BranchRateModel.Base model = treeLikelihood.branchRateModelInput.get();
+                        needsEstimation = (model.meanRateInput.get() != firstClock) || firstClock.isEstimatedInput.get();
                     } else {
                         // TODO: this might not be a valid type conversion from TreeInterface to Tree
                         Tree tree = (Tree) treeLikelihood.treeInput.get();
                         // check whether there are tip dates
                         if (tree.hasDateTrait()) {
-                            bNeedsEstimation = true;
+                            needsEstimation = true;
                         }
                         // check whether there is a calibration
-                        for (Object plugin : tree.getOutputs()) {
-                            if (plugin instanceof MRCAPrior) {
-                                MRCAPrior prior = (MRCAPrior) plugin;
+                        for (Object beastObject : tree.getOutputs()) {
+                            if (beastObject instanceof MRCAPrior) {
+                                MRCAPrior prior = (MRCAPrior) beastObject;
                                 if (prior.distInput.get() != null) {
-                                    bNeedsEstimation = true;
+                                    needsEstimation = true;
                                 }
                             }
                         }
                     }
-                    BranchRateModel.Base model = (BranchRateModel.Base) treeLikelihood.branchRateModelInput.get();
+                    BranchRateModel.Base model = treeLikelihood.branchRateModelInput.get();
                     if (model != null) {
                         RealParameter clockRate = model.meanRateInput.get();
-                        clockRate.isEstimatedInput.setValue(bNeedsEstimation, clockRate);
+                        clockRate.isEstimatedInput.setValue(needsEstimation, clockRate);
                         if (firstClock == null) {
                             firstClock = clockRate;
                         }
@@ -1309,14 +1366,14 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         }
     }
 
-    public void addPlugin(final BEASTInterface plugin) { // throws Exception {
+    public void addPlugin(final BEASTInterface beastObject) { //  {
         // SwingUtilities.invokeLater(new Runnable() {
         // @Override
         // public void run() {
         //
-        BEASTObjectPanel.addPluginToMap(plugin, this);
+        BEASTObjectPanel.addPluginToMap(beastObject, this);
         try {
-            for (Input<?> input : plugin.listInputs()) {
+            for (Input<?> input : beastObject.listInputs()) {
                 if (input.get() != null) {
                     if (input.get() instanceof BEASTInterface) {
                         BEASTObjectPanel.addPluginToMap((BEASTInterface) input.get(), this);
@@ -1332,94 +1389,94 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
         } catch (Exception e) {
             // ignore
-            System.err.println(e.getClass().getName() + " " + e.getMessage());
+        	Log.warning.println(e.getClass().getName() + " " + e.getMessage());
         }
 
         // }});
 
-        // m_sIDMap.put(plugin.getID(), plugin);
-        // for (Plugin plugin2 : plugin.listActivePlugins()) {
-        // addPlugin(plugin2);
+        // m_sIDMap.put(beastObject.getID(), beastObject);
+        // for (BEASTObject beastObject2 : beastObject.listActivePlugins()) {
+        // addPlugin(beastObject2);
         // }
     }
 
     /**
-     * connect source plugin with target plugin
+     * connect source beastObject with target beastObject
      *
-     * @throws Exception *
+     * @ *
      */
-    public void connect(BeautiConnector connector, PartitionContext context) throws Exception {
+    public void connect(BeautiConnector connector, PartitionContext context) {
         if (!connector.isRegularConnector) {
             return;
         }
-        String sSrcID = translatePartitionNames(connector.sSourceID, context);
-        BEASTInterface srcPlugin = pluginmap.get(sSrcID);
-        if (srcPlugin == null) {
-            throw new Exception("Could not find plugin with id " + sSrcID + ". Typo in template perhaps?\n");
+        String srcID = translatePartitionNames(connector.sourceID, context);
+        BEASTInterface srcBEASTObject = pluginmap.get(srcID);
+        if (srcBEASTObject == null) {
+            throw new IllegalArgumentException("Could not find beastObject with id " + srcID + ". Typo in template perhaps?\n");
         }
-        String sTargetID = translatePartitionNames(connector.sTargetID, context);
-        connect(srcPlugin, sTargetID, connector.sTargetInput);
+        String targetID = translatePartitionNames(connector.targetID, context);
+        connect(srcBEASTObject, targetID, connector.targetInput);
     }
 
-    public void connect(BEASTInterface srcPlugin, String sTargetID, String sInputName) {
+    public void connect(BEASTInterface srcBEASTObject, String targetID, String inputName) {
         try {
-        	BEASTInterface target = pluginmap.get(sTargetID);
+        	BEASTInterface target = pluginmap.get(targetID);
             if (target == null) {
-            	Log.trace.println("BeautiDoc: Could not find object " + sTargetID);
+            	Log.trace.println("BeautiDoc: Could not find object " + targetID);
             	return;
             }
             // prevent duplication inserts in list
-            Object o = target.getInputValue(sInputName);
+            Object o = target.getInputValue(inputName);
             if (o instanceof List) {
                 // System.err.println("   " + ((List)o).size());
-                if (((List<?>) o).contains(srcPlugin)) {
-                    warning("   " + sTargetID + "/" + sInputName + " already contains " + (srcPlugin == null ? "nulls" : srcPlugin.getID()) + "\n");
+                if (((List<?>) o).contains(srcBEASTObject)) {
+                    warning("   " + targetID + "/" + inputName + " already contains " + (srcBEASTObject == null ? "nulls" : srcBEASTObject.getID()) + "\n");
                     return;
                 }
             }
 
-            target.setInputValue(sInputName, srcPlugin);
+            target.setInputValue(inputName, srcBEASTObject);
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 
     /**
-     * disconnect source plugin with target plugin *
+     * disconnect source beastObject with target beastObject *
      */
     public void disconnect(BeautiConnector connector, PartitionContext context) {
         if (!connector.isRegularConnector) {
             return;
         }
-        BEASTInterface srcPlugin = pluginmap.get(translatePartitionNames(connector.sSourceID, context));
-        String sTargetID = translatePartitionNames(connector.sTargetID, context);
-        disconnect(srcPlugin, sTargetID, connector.sTargetInput);
+        BEASTInterface srcBEASTObject = pluginmap.get(translatePartitionNames(connector.sourceID, context));
+        String targetID = translatePartitionNames(connector.targetID, context);
+        disconnect(srcBEASTObject, targetID, connector.targetInput);
     }
 
-    public void disconnect(BEASTInterface srcPlugin, String sTargetID, String sInputName) {
+    public void disconnect(BEASTInterface srcBEASTObject, String targetID, String inputName) {
         try {
-        	BEASTInterface target = pluginmap.get(sTargetID);
+        	BEASTInterface target = pluginmap.get(targetID);
             if (target == null) {
                 return;
             }
-            Input<?> input = target.getInput(sInputName);
+            final Input<?> input = target.getInput(inputName);
             Object o = input.get();
             if (o instanceof List) {
                 List<?> list = (List<?>) o;
                 // System.err.println("   " + ((List)o).size());
                 for (int i = 0; i < list.size(); i++) {
-                    if (list.get(i) == srcPlugin) {
-                        warning("  DEL " + sTargetID + "/" + sInputName + " contains " + (srcPlugin == null ? "null" : srcPlugin.getID()) + "\n");
+                    if (list.get(i) == srcBEASTObject) {
+                        warning("  DEL " + targetID + "/" + inputName + " contains " + (srcBEASTObject == null ? "null" : srcBEASTObject.getID()) + "\n");
                         list.remove(i);
                     }
                 }
-                if (srcPlugin != null && srcPlugin.getOutputs() != null) {
-                    srcPlugin.getOutputs().remove(target);
+                if (srcBEASTObject != null && srcBEASTObject.getOutputs() != null) {
+                    srcBEASTObject.getOutputs().remove(target);
                 }
             } else {
                 if (input.get() != null && input.get() instanceof BEASTInterface &&
-                		input.get() == srcPlugin) {
-                        //((BEASTInterface) input.get()).getID().equals(sTargetID)) {
+                		input.get() == srcBEASTObject) {
+                        //((BEASTInterface) input.get()).getID().equals(targetID)) {
                     input.setValue(null, target);
                 }
             }
@@ -1445,7 +1502,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     	if (!(mcmc.get() instanceof MCMC)) {
     		return;
     	}
-    	List<Operator> speciesOperators = new ArrayList<Operator>(); 
+    	List<Operator> speciesOperators = new ArrayList<>(); 
     	double totalWeight = 0;
     	double speciesWeight = 0;
     	for (Operator operator : ((MCMC)mcmc.get()).operatorsInput.get()) {
@@ -1469,7 +1526,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 		
 	}
 
-	public BEASTInterface addAlignmentWithSubnet(PartitionContext context, BeautiSubTemplate template) throws Exception {
+	public BEASTInterface addAlignmentWithSubnet(PartitionContext context, BeautiSubTemplate template)  {
         BEASTInterface data = template.createSubNet(context, true);
         alignments.add((Alignment) data);
         // re-determine partitions
@@ -1481,7 +1538,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         alignments.remove(data);
         try {
             PartitionContext context = null;
-            for (PartitionContext context2 : sPartitionNames) {
+            for (PartitionContext context2 : partitionNames) {
                 if (context2.partition.equals(data.getID())) {
                     context = context2;
                     break;
@@ -1515,14 +1572,14 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         if (likelihood == null) {
             return;
         }
-        sPartitionNames.clear();
+        partitionNames.clear();
         possibleContexts.clear();
         for (Distribution distr : likelihood.pDistributions.get()) {
             if (distr instanceof GenericTreeLikelihood) {
                 GenericTreeLikelihood treeLikelihood = (GenericTreeLikelihood) distr;
                 alignments.add(treeLikelihood.dataInput.get());
                 PartitionContext context = new PartitionContext(treeLikelihood);
-                sPartitionNames.add(context);
+                partitionNames.add(context);
                 boolean found = false;
                 for (PartitionContext context2 : possibleContexts) {
                     if (context.equals(context2)) {
@@ -1539,9 +1596,9 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         for (int i = 0; i < 3; i++) {
             pPartitionByAlignments[i].clear();
             pPartition[i].clear();
-            nCurrentPartitions[i].clear();
+            currentPartitions[i].clear();
         }
-        List<GenericTreeLikelihood> treeLikelihoods = new ArrayList<GenericTreeLikelihood>();
+        List<GenericTreeLikelihood> treeLikelihoods = new ArrayList<>();
         for (Distribution distr : likelihood.pDistributions.get()) {
             if (distr instanceof GenericTreeLikelihood) {
                 GenericTreeLikelihood treeLikelihood = (GenericTreeLikelihood) distr;
@@ -1556,26 +1613,26 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                     // sync SiteModel, ClockModel and Tree to any changes that
                     // may have occurred
                     // this should only affect the clock model in practice
-                    int nPartition = getPartitionNr((BEASTInterface) treeLikelihood.siteModelInput.get());
-                    GenericTreeLikelihood treeLikelihood2 = treeLikelihoods.get(nPartition);
+                    int partition = getPartitionNr((BEASTInterface) treeLikelihood.siteModelInput.get());
+                    GenericTreeLikelihood treeLikelihood2 = treeLikelihoods.get(partition);
                     treeLikelihood.siteModelInput.setValue(treeLikelihood2.siteModelInput.get(), treeLikelihood);
-                    nCurrentPartitions[0].add(nPartition);
+                    currentPartitions[0].add(partition);
 
                     BranchRateModel rateModel = treeLikelihood.branchRateModelInput.get();
                     if (rateModel != null) {
-                        nPartition = getPartitionNr((BEASTInterface) rateModel);
-                        treeLikelihood2 = treeLikelihoods.get(nPartition);
+                        partition = getPartitionNr((BEASTInterface) rateModel);
+                        treeLikelihood2 = treeLikelihoods.get(partition);
                         treeLikelihood.branchRateModelInput.setValue(treeLikelihood2.branchRateModelInput.get(),
                                 treeLikelihood);
-                        nCurrentPartitions[1].add(nPartition);
+                        currentPartitions[1].add(partition);
                     } else {
-                        nCurrentPartitions[1].add(0);
+                        currentPartitions[1].add(0);
                     }
 
-                    nPartition = getPartitionNr((BEASTInterface) treeLikelihood.treeInput.get());
-                    treeLikelihood2 = treeLikelihoods.get(nPartition);
+                    partition = getPartitionNr((BEASTInterface) treeLikelihood.treeInput.get());
+                    treeLikelihood2 = treeLikelihoods.get(partition);
                     treeLikelihood.treeInput.setValue(treeLikelihood2.treeInput.get(), treeLikelihood);
-                    nCurrentPartitions[2].add(nPartition);
+                    currentPartitions[2].add(partition);
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
@@ -1586,26 +1643,26 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
         }
 
-        int nPartitions = sPartitionNames.size();
+        int partitionCount = partitionNames.size();
         for (int i = 0; i < 3; i++) {
-            boolean[] bUsedPartition = new boolean[nPartitions];
-            for (int j = 0; j < nPartitions; j++) {
-                int iPartition = nCurrentPartitions[i].get(j);// getPartitionNr(m_pPartitionByAlignments[i].get(j));
-                bUsedPartition[iPartition] = true;
+            boolean[] usedPartition = new boolean[partitionCount];
+            for (int j = 0; j < partitionCount; j++) {
+                int partitionIndex = currentPartitions[i].get(j);// getPartitionNr(m_pPartitionByAlignments[i].get(j));
+                usedPartition[partitionIndex] = true;
             }
-            for (int j = 0; j < nPartitions; j++) {
-                if (bUsedPartition[j]) {
+            for (int j = 0; j < partitionCount; j++) {
+                if (usedPartition[j]) {
                     pPartition[i].add(pPartitionByAlignments[i].get(j));
                 }
             }
         }
-        System.err.println("PARTITIONS0:\n");
-        System.err.println(Arrays.toString(nCurrentPartitions));
+        Log.warning.println("PARTITIONS0:\n");
+        Log.warning.println(Arrays.toString(currentPartitions));
     }
 
     int getPartitionNr(String partition, int partitionID) {
-        for (int i = 0; i < sPartitionNames.size(); i++) {
-            PartitionContext context = sPartitionNames.get(i);
+        for (int i = 0; i < partitionNames.size(); i++) {
+            PartitionContext context = partitionNames.get(i);
             switch (partitionID) {
                 case ALIGNMENT_PARTITION:
                     if (context.partition.equals(partition)) {
@@ -1632,8 +1689,8 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         return -1;
     }
 
-    int getPartitionNr(BEASTInterface plugin) {
-        String ID = plugin.getID();
+    int getPartitionNr(BEASTInterface beastObject) {
+        String ID = beastObject.getID();
         String partition = ID;
         if (ID.indexOf('.') >= 0) {
             partition = ID.substring(ID.indexOf('.') + 1);
@@ -1657,37 +1714,37 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         return getPartitionNr(partition, partitionID);
     }
 
-    public List<BEASTInterface> getPartitions(String sType) {
-        if (sType == null) {
+    public List<BEASTInterface> getPartitions(String typeName) {
+        if (typeName == null) {
             return pPartition[2];
         }
-        if (sType.contains("Partitions")) {
-            List<BEASTInterface> plugins = new ArrayList<BEASTInterface>();
-            plugins.addAll(alignments);
-            return plugins;
+        if (typeName.contains("Partitions")) {
+            List<BEASTInterface> beastObjects = new ArrayList<>();
+            beastObjects.addAll(alignments);
+            return beastObjects;
         }
-        if (sType.contains("SiteModel")) {
+        if (typeName.contains("SiteModel")) {
             return pPartition[0];
         }
-        if (sType.contains("ClockModel")) {
+        if (typeName.contains("ClockModel")) {
             return pPartition[1];
         }
         return pPartition[2];
     }
 
-    public void setCurrentPartition(int iCol, int iRow, String sPartition) {
-        int nCurrentPartion = getPartitionNr(sPartition, iCol);
-        nCurrentPartitions[iCol].set(iRow, nCurrentPartion);
+    public void setCurrentPartition(int colNr, int rowNr, String partition) {
+        int currentPartion = getPartitionNr(partition, colNr);
+        currentPartitions[colNr].set(rowNr, currentPartion);
     }
 
     @Override
-    public Object createInput(BEASTInterface plugin, Input<?> input, PartitionContext context) {
+    public Object createInput(BEASTInterface beastObject, Input<?> input, PartitionContext context) {
         for (BeautiSubTemplate template : beautiConfig.subTemplates) {
             try {
-                if (input.canSetValue(template.instance, plugin)) {
-                    String sPartition = plugin.getID();
-                    sPartition = parsePartition(sPartition);
-                    Object o = template.createSubNet(context, plugin, input, true);
+                if (input.canSetValue(template.instance, beastObject)) {
+                    String partition = beastObject.getID();
+                    partition = parsePartition(partition);
+                    Object o = template.createSubNet(context, beastObject, input, true);
                     return o;
                 }
             } catch (Exception e) {
@@ -1699,7 +1756,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 
     private void warning(String s) {
         if (Boolean.valueOf(System.getProperty("beast.debug"))) {
-            System.err.print(s);
+        	Log.warning.print(s);
         }
     }
 
@@ -1711,29 +1768,29 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         isExpertMode = expertMode;
     }
 
-    static public String parsePartition(String sID) {
-        String sPartition = sID.substring(sID.indexOf('.') + 1);
-        if (sPartition.indexOf(':') >= 0) {
-            sPartition = sPartition.substring(sPartition.indexOf(':') + 1);
+    static public String parsePartition(String id) {
+        String partition = id.substring(id.indexOf('.') + 1);
+        if (partition.indexOf(':') >= 0) {
+            partition = partition.substring(partition.indexOf(':') + 1);
         }
-        return sPartition;
+        return partition;
     }
 
     /**
-     * Create a deep copy of a plugin, but in a different partition context
-     * First, find all plugins that are predecesors of the plugin to be copied
+     * Create a deep copy of a beastObject, but in a different partition context
+     * First, find all beastObjects that are predecesors of the beastObject to be copied
      * that are ancestors of statenodes
      *
-     * @param plugin
+     * @param beastObject
      * @param parent
      * @return
-     * @throws Exception
      */
-    static public BEASTInterface deepCopyPlugin(BEASTInterface plugin, BEASTInterface parent, MCMC mcmc,
-                                             PartitionContext partitionContext, BeautiDoc doc, List<BEASTInterface> tabooList)
-            throws Exception {
-        /** taboo = list of plugins that should not be copied **/
-        Set<BEASTInterface> taboo = new HashSet<BEASTInterface>();
+    static public BEASTInterface deepCopyPlugin(BEASTInterface beastObject, BEASTInterface parent, MCMC mcmc,
+    										PartitionContext oldContext,
+                                            PartitionContext newContext, BeautiDoc doc, List<BEASTInterface> tabooList)
+          {
+        /** taboo = list of beastObjects that should not be copied **/
+        Set<BEASTInterface> taboo = new HashSet<>();
         taboo.add(parent);
         // add state
         taboo.add(mcmc.startStateInput.get());
@@ -1772,24 +1829,24 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             taboo.addAll(tabooList);
         }
 
-        // find predecessors of plugin to be copied
-        List<BEASTInterface> predecessors = new ArrayList<BEASTInterface>();
-        collectPredecessors(plugin, predecessors);
+        // find predecessors of beastObject to be copied
+        List<BEASTInterface> predecessors = new ArrayList<>();
+        collectPredecessors(beastObject, predecessors);
 
-        // find ancestors of StateNodes that are predecessors + the plugin
+        // find ancestors of StateNodes that are predecessors + the beastObject
         // itself
-        Set<BEASTInterface> ancestors = new HashSet<BEASTInterface>();
-        collectAncestors(plugin, ancestors, taboo);
-		System.out.print(Arrays.toString(ancestors.toArray()));
-        for (BEASTInterface plugin2 : predecessors) {
-            if (plugin2 instanceof StateNode) {
-                Set<BEASTInterface> ancestors2 = new HashSet<BEASTInterface>();
-                collectAncestors(plugin2, ancestors2, taboo);
+        Set<BEASTInterface> ancestors = new HashSet<>();
+        collectAncestors(beastObject, ancestors, taboo);
+		Log.info.print(Arrays.toString(ancestors.toArray()));
+        for (BEASTInterface beastObject2 : predecessors) {
+            if (beastObject2 instanceof StateNode) {
+                Set<BEASTInterface> ancestors2 = new HashSet<>();
+                collectAncestors(beastObject2, ancestors2, taboo);
                 ancestors.addAll(ancestors2);
-            } else if (plugin2 instanceof Alignment || plugin2 instanceof FilteredAlignment) {
-                for (Object output : plugin2.getOutputs()) {
+            } else if (beastObject2 instanceof Alignment || beastObject2 instanceof FilteredAlignment) {
+                for (Object output : beastObject2.getOutputs()) {
                     if (!taboo.contains(output)) {
-                        Set<BEASTInterface> ancestors2 = new HashSet<BEASTInterface>();
+                        Set<BEASTInterface> ancestors2 = new HashSet<>();
                         collectAncestors((BEASTInterface)output, ancestors2, taboo);
                         ancestors.addAll(ancestors2);
                     }
@@ -1797,74 +1854,94 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
         }
 
-//		System.out.print(Arrays.toString(predecessors.toArray()));
-//		for (Plugin p : ancestors) {
-//			System.out.print("(");
-//			for (Plugin p2 : p.listActivePlugins()) {
+//		Log.info.print(Arrays.toString(predecessors.toArray()));
+//		for (BEASTObject p : ancestors) {
+//			Log.info.print("(");
+//			for (BEASTObject p2 : p.listActivePlugins()) {
 //				if (ancestors.contains(p2)) {
-//					System.out.print(p2.getID()+ " ");
+//					Log.info.print(p2.getID()+ " ");
 //				}
 //			}
-//			System.out.print(") ");
-//			System.out.println(p.getID());
+//			Log.info.print(") ");
+//			Log.info.println(p.getID());
 //		}
 
-        // now the ancestors contain all plugins to be copied
-        // make a copy of all individual Pluings, before connecting them up
+        // now the ancestors contain all beastObjects to be copied
+        // make a copy of all individual BEASTObjects, before connecting them up
         Map<String, BEASTInterface> copySet = new HashMap<>();
-        for (BEASTInterface plugin2 : ancestors) {
-            String id = plugin2.getID();
-            String copyID = renameId(id, partitionContext);
+        for (BEASTInterface beastObject2 : ancestors) {
+            String id = beastObject2.getID();
+            String copyID = renameId(id, oldContext, newContext);
             if (!id.equals(copyID)) {
 	            if (doc.pluginmap.containsKey(copyID)) {
 	            	BEASTInterface org = doc.pluginmap.get(copyID);
 	                copySet.put(id, org);
 	            } else {
-	            	BEASTInterface copy = (BEASTInterface) plugin2.getClass().newInstance();
-	            	copy.setID(copyID);
-	                copySet.put(id, copy);
+	            	BEASTInterface copy;
+					try {
+						copy = beastObject2.getClass().newInstance();
+		            	copy.setID(copyID);
+		                copySet.put(id, copy);
+					} catch (InstantiationException | IllegalAccessException e) {
+						e.printStackTrace();
+						throw new RuntimeException("Programmer error: every object in the model should have a default constructor that is publicly accessible");
+					}
 	            }
             }
-			System.err.println("Copy: " + id + " -> " + copyID);
+            Log.warning.println("Copy: " + id + " -> " + copyID);
         }
 
-        // set all inputs of copied plugins + outputs to taboo
-		for (BEASTInterface plugin2 : ancestors) {
-            String id = plugin2.getID();
+        // set all inputs of copied beastObjects + outputs to taboo
+		for (BEASTInterface beastObject2 : ancestors) {
+            String id = beastObject2.getID();
             BEASTInterface copy = copySet.get(id);
             if (copy != null) {
-            System.err.println("Processing: " + id + " -> " + copy.getID());
+            	Log.warning.println("Processing: " + id + " -> " + copy.getID());
             // set inputs
-            for (Input<?> input : plugin2.listInputs()) {
+            for (Input<?> input : beastObject2.listInputs()) {
                 if (input.get() != null) {
                     if (input.get() instanceof List) {
                         // handle lists
                     	//((List)copy.getInput(input.getName())).clear();
                         for (Object o : (List<?>) input.get()) {
                             if (o instanceof BEASTInterface) {
-                            	BEASTInterface value = getCopyValue((BEASTInterface) o, copySet, partitionContext, doc);
-                                copy.setInputValue(input.getName(), value);
+                            	BEASTInterface value = getCopyValue((BEASTInterface) o, copySet, oldContext, newContext, doc);
+                            	// make sure it is not already in the list
+                            	Object o2 = copy.getInput(input.getName()).get();
+                            	boolean alreadyInList = false;
+                            	if (o2 instanceof List) {
+                            		List<?> currentList = (List<?>) o2; 
+	                            	for (Object v : currentList) {
+	                            		if (v == value) {
+	                            			alreadyInList = true;
+	                            			break;
+	                            		}
+	                            	}
+                            	}
+                            	if (!alreadyInList) {
+                            		// add to the list
+                            		copy.setInputValue(input.getName(), value);
+                            	}
                             } else {
                                 // it is a primitive value
-                            	
                             	if (copy instanceof Parameter.Base && input.getName().equals("value")) {
                             	//	// prevent appending to parameter values
-                            		Parameter.Base p = ((Parameter.Base) copy);
-                            		((List) p.valuesInput.get()).clear();
+                            		Parameter.Base<?> p = ((Parameter.Base<?>) copy);
+                            		((List<?>) p.valuesInput.get()).clear();
                             	}
                                 copy.setInputValue(input.getName(), input.get());
                             }
                         }
                     } else if (input.get() instanceof BEASTInterface) {
-                        // handle Plugin
-                    	BEASTInterface value = getCopyValue((BEASTInterface) input.get(), copySet, partitionContext, doc);
+                        // handle BEASTObject
+                    	BEASTInterface value = getCopyValue((BEASTInterface) input.get(), copySet, oldContext, newContext, doc);
                         copy.setInputValue(input.getName(), value);
                     } else if (input.get() instanceof String) {
                 		// may need to replace partition info
                 		String s = (String) input.get();
-                		s = s.replaceAll("\\.c:[a-zA-Z0-9_]*", ".c:" + partitionContext.clockModel);
-                		s = s.replaceAll("\\.s:[a-zA-Z0-9_]*", ".s:" + partitionContext.siteModel);
-                		s = s.replaceAll("\\.t:[a-zA-Z0-9_]*", ".t:" + partitionContext.tree);
+                		s = s.replaceAll("\\.c:[a-zA-Z0-9_]*", ".c:" + newContext.clockModel);
+                		s = s.replaceAll("\\.s:[a-zA-Z0-9_]*", ".s:" + newContext.siteModel);
+                		s = s.replaceAll("\\.t:[a-zA-Z0-9_]*", ".t:" + newContext.tree);
                 		copy.setInputValue(input.getName(), s);
                 	} else {
                         // it is a primitive value
@@ -1874,16 +1951,16 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
 
             // set outputs
-            for (Object output : plugin2.getOutputs()) {
+            for (Object output : beastObject2.getOutputs()) {
                 if (taboo.contains(output) && output != parent) {
-                	BEASTInterface output2 = getCopyValue((BEASTInterface)output, copySet, partitionContext, doc);
+                	BEASTInterface output2 = getCopyValue((BEASTInterface)output, copySet, oldContext, newContext, doc);
                     for (Input<?> input : ((BEASTInterface)output).listInputs()) {
                         // do not add state node initialisers automatically
                         if (input.get() instanceof List &&
                                 // do not update state node initialisers
                                 !(taboo.contains(output2) && input.getName().equals("init"))) {
                             List<?> list = (List<?>) input.get();
-                            if (list.contains(plugin2)) {
+                            if (list.contains(beastObject2)) {
                             	List<?> list2 = (List<?>)output2.getInput(input.getName()).get();
                             	if (!list2.contains(copy)) {
                             		output2.setInputValue(input.getName(), copy);
@@ -1896,23 +1973,23 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
 
             copySet.put(id, copy);
-    		//System.err.println(base.operatorsAsString());
+    		//Log.warning.println(base.operatorsAsString());
             }
         }
 
 		// deep copy must be obtained from copyset, before sorting
         // since the sorting changes (deletes items) from the copySet map
-        BEASTInterface deepCopy = copySet.get(plugin.getID());
+        BEASTInterface deepCopy = copySet.get(beastObject.getID());
 
         // first need to sort copySet by topology, before we can initAndValidate
         // them
-        List<BEASTInterface> sorted = new ArrayList<BEASTInterface>();
+        List<BEASTInterface> sorted = new ArrayList<>();
         Collection<BEASTInterface> values = copySet.values();
         while (values.size() > 0) {
             for (BEASTInterface copy : values) {
                 boolean found = false;
-                for (BEASTInterface plugin2 : copy.listActivePlugins()) {
-                    if (values.contains(plugin2)) {
+                for (BEASTInterface beastObject2 : copy.listActiveBEASTObjects()) {
+                    if (values.contains(beastObject2)) {
                         found = true;
                         break;
                     }
@@ -1923,8 +2000,8 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
             values.remove(sorted.get(sorted.size() - 1));
         }
-        // initialise copied plugins
-        Set<BEASTInterface> done = new HashSet<BEASTInterface>();
+        // initialise copied beastObjects
+        Set<BEASTInterface> done = new HashSet<>();
         for (BEASTInterface copy : sorted) {
             try {
                 if (!done.contains(copy)) {
@@ -1933,7 +2010,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                 }
             } catch (Exception e) {
                 // ignore
-                System.err.print(e.getMessage());
+            	Log.warning.print(e.getMessage());
             }
             if (doc != null) {
                 doc.addPlugin(copy);
@@ -1944,7 +2021,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         return deepCopy;
     } // deepCopyPlugin
 
-    private static BEASTInterface getCopyValue(BEASTInterface value, Map<String, BEASTInterface> copySet, PartitionContext partitionContext, BeautiDoc doc) {
+    private static BEASTInterface getCopyValue(BEASTInterface value, Map<String, BEASTInterface> copySet, PartitionContext oldContext, PartitionContext partitionContext, BeautiDoc doc) {
         if (copySet.containsKey(value.getID())) {
             value = copySet.get(value.getID());
             return value;
@@ -1954,7 +2031,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             return value;
         }
         if (valueID.indexOf('.') >= 0) {
-            String valueCopyID = renameId(valueID, partitionContext);
+            String valueCopyID = renameId(valueID, oldContext, partitionContext);
             if (doc.pluginmap.containsKey(valueCopyID)) {
                 value = doc.pluginmap.get(valueCopyID);
             }
@@ -1964,57 +2041,63 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         return value;
     }
 
-    public static String renameId(String sID, PartitionContext context) {
-        String sOldPartition = sID.substring(sID.indexOf('.') + 1);
-        String sNewPartition = null;
-        if (sOldPartition.indexOf(':') >= 0) {
-            char c = sOldPartition.charAt(0);
+    public static String renameId(String id, PartitionContext oldContext, PartitionContext newContext) {
+        String oldPartition = id.substring(id.indexOf('.') + 1);
+        String newPartition = null;
+        if (oldPartition.indexOf(':') >= 0) {
+            char c = oldPartition.charAt(0);
             switch (c) {
                 case 's':
-                    sNewPartition = context.siteModel;
+                    newPartition = newContext.siteModel;
+                    oldPartition  = oldContext.siteModel;
                     break;
                 case 'c':
-                    sNewPartition = context.clockModel;
+                    newPartition = newContext.clockModel;
+                    oldPartition  = oldContext.clockModel;
                     break;
                 case 't':
-                    sNewPartition = context.tree;
+                    newPartition = newContext.tree;
+                    oldPartition  = oldContext.tree;
                     break;
             }
-            sOldPartition = sOldPartition.substring(sOldPartition.indexOf(':') + 1);
+            //oldPartition = oldPartition.substring(oldPartition.indexOf(':') + 1);
         } else {
-            sNewPartition = context.partition;
+            newPartition = newContext.partition;
+            oldPartition = oldContext.partition;
+        }
+        if (id.indexOf('.') < 0 || !(id.endsWith(oldPartition))) {
+        	// original id does not contain partition info
+        	return id;
         }
-        sID = sID.substring(0, sID.length() - sOldPartition.length()) + sNewPartition;
-        return sID;
+        id = id.substring(0, id.length() - oldPartition.length()) + newPartition;
+        return id;
     }
 
-    static public void collectPredecessors(BEASTInterface plugin, List<BEASTInterface> predecessors) {
-        predecessors.add(plugin);
-        if (plugin instanceof Alignment || plugin instanceof FilteredAlignment) {
+    static public void collectPredecessors(BEASTInterface beastObject, List<BEASTInterface> predecessors) {
+        predecessors.add(beastObject);
+        if (beastObject instanceof Alignment || beastObject instanceof FilteredAlignment) {
             return;
         }
         try {
-            for (BEASTInterface plugin2 : plugin.listActivePlugins()) {
-                if (!predecessors.contains(plugin2)) {
-                    collectPredecessors(plugin2, predecessors);
+            for (BEASTInterface beastObject2 : beastObject.listActiveBEASTObjects()) {
+                if (!predecessors.contains(beastObject2)) {
+                    collectPredecessors(beastObject2, predecessors);
                 }
             }
         } catch (IllegalArgumentException e) {
             e.printStackTrace();
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
         }
     }
 
-    static public void collectAncestors(BEASTInterface plugin, Set<BEASTInterface> ancestors, Set<BEASTInterface> tabu) {
-        if ((plugin instanceof GenericTreeLikelihood) || (plugin instanceof BeautiPanelConfig)) {
+    static public void collectAncestors(BEASTInterface beastObject, Set<BEASTInterface> ancestors, Set<BEASTInterface> tabu) {
+        if ((beastObject instanceof GenericTreeLikelihood) || (beastObject instanceof BeautiPanelConfig)) {
             return;
         }
-        ancestors.add(plugin);
+        ancestors.add(beastObject);
         try {
-            for (Object plugin2 : plugin.getOutputs()) {
-                if (!ancestors.contains(plugin2) && !tabu.contains(plugin2)) {
-                    collectAncestors((BEASTInterface)plugin2, ancestors, tabu);
+            for (Object beastObject2 : beastObject.getOutputs()) {
+                if (!ancestors.contains(beastObject2) && !tabu.contains(beastObject2)) {
+                    collectAncestors((BEASTInterface)beastObject2, ancestors, tabu);
                 }
             }
         } catch (IllegalArgumentException e) {
@@ -2022,8 +2105,8 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         }
     }
 
-    public void renamePartition(int partitionID, String oldName, String newName) throws Exception {
-        System.err.println("renamePartition: " + partitionID + " " + oldName + " " + newName);
+    public void renamePartition(int partitionID, String oldName, String newName)  {
+    	Log.warning.println("renamePartition: " + partitionID + " " + oldName + " " + newName);
         // sanity check: make sure newName is not already in use by another partition
         String newsuffix = null;
         switch (partitionID) {
@@ -2042,9 +2125,9 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             default:
                 throw new IllegalArgumentException();
         }
-        for (BEASTInterface plugin : pluginmap.values()) {
-            if (plugin.getID().endsWith(newsuffix)) {
-                throw new Exception("Name " + newName + " is already in use");
+        for (BEASTInterface beastObject : pluginmap.values()) {
+            if (beastObject.getID().endsWith(newsuffix)) {
+                throw new IllegalArgumentException("Name " + newName + " is already in use");
             }
         }
 
@@ -2066,29 +2149,29 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             default:
                 throw new IllegalArgumentException();
         }
-        for (BEASTInterface plugin : pluginmap.values()) {
-            if (plugin.getID().endsWith(oldsuffix)) {
-                String sID = plugin.getID();
-                sID = sID.substring(0, sID.indexOf(oldsuffix)) + newsuffix;
-                plugin.setID(sID);
+        for (BEASTInterface beastObject : pluginmap.values()) {
+            if (beastObject.getID().endsWith(oldsuffix)) {
+                String id = beastObject.getID();
+                id = id.substring(0, id.indexOf(oldsuffix)) + newsuffix;
+                beastObject.setID(id);
             }
         }
         if (partitionID == ALIGNMENT_PARTITION) {
             // make exception for renaming alignment: its ID does not contain a dot
-            for (BEASTInterface plugin : pluginmap.values()) {
-                if (plugin.getID().equals(oldName)) {
-                    plugin.setID(newName);
+            for (BEASTInterface beastObject : pluginmap.values()) {
+                if (beastObject.getID().equals(oldName)) {
+                    beastObject.setID(newName);
                 }
             }
         }
 
-        // update plugin map
+        // update beastObject map
         String[] keyset = pluginmap.keySet().toArray(new String[0]);
         for (String key : keyset) {
             if (key.endsWith(oldsuffix)) {
-            	BEASTInterface plugin = pluginmap.remove(key);
+            	BEASTInterface beastObject = pluginmap.remove(key);
                 key = key.substring(0, key.indexOf(oldsuffix)) + newsuffix;
-                pluginmap.put(key, plugin);
+                pluginmap.put(key, beastObject);
             }
         }
 
@@ -2107,13 +2190,13 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
         determinePartitions();
     } // renamePartition
 
-    public PartitionContext getContextFor(BEASTInterface plugin) {
-        String sID = plugin.getID();
-        String sPartition = sID.substring(sID.indexOf('.') + 1);
+    public PartitionContext getContextFor(BEASTInterface beastObject) {
+        String id = beastObject.getID();
+        String partition = id.substring(id.indexOf('.') + 1);
 
         int partitionID = ALIGNMENT_PARTITION;
-        if (sPartition.indexOf(':') >= 0) {
-            char c = sPartition.charAt(0);
+        if (partition.indexOf(':') >= 0) {
+            char c = partition.charAt(0);
             switch (c) {
                 case 's':
                     partitionID = SITEMODEL_PARTITION;
@@ -2125,28 +2208,28 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                     partitionID = TREEMODEL_PARTITION;
                     break;
             }
-            sPartition = parsePartition(sID);
+            partition = parsePartition(id);
         }
 
-        for (PartitionContext context : sPartitionNames) {
+        for (PartitionContext context : partitionNames) {
             switch (partitionID) {
                 case ALIGNMENT_PARTITION:
-                    if (context.partition.equals(sPartition)) {
+                    if (context.partition.equals(partition)) {
                         return context;
                     }
                     break;
                 case SITEMODEL_PARTITION:
-                    if (context.siteModel.equals(sPartition)) {
+                    if (context.siteModel.equals(partition)) {
                         return context;
                     }
                     break;
                 case CLOCKMODEL_PARTITION:
-                    if (context.clockModel.equals(sPartition)) {
+                    if (context.clockModel.equals(partition)) {
                         return context;
                     }
                     break;
                 case TREEMODEL_PARTITION:
-                    if (context.tree.equals(sPartition)) {
+                    if (context.tree.equals(partition)) {
                         return context;
                     }
                     break;
@@ -2155,51 +2238,51 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                     return null;
             }
         }
-        return new PartitionContext(sPartition);
+        return new PartitionContext(partition);
     }
 
 
     // methods for dealing with linking
     void determineLinks() {
-        if (!bAllowLinking) {
+        if (!allowLinking) {
             return;
         }
         linked.clear();
-        for (BEASTInterface plugin : posteriorPredecessors) {
-            Map<String, Integer> outputIDs = new HashMap<String, Integer>();
-            for (Object output : plugin.getOutputs()) {
+        for (BEASTInterface beastObject : posteriorPredecessors) {
+            Map<String, Integer> outputIDs = new HashMap<>();
+            for (Object output : beastObject.getOutputs()) {
                 if (posteriorPredecessors.contains(output)) {
-                    String sID = ((BEASTInterface)output).getID();
-                    if (sID.indexOf('.') >= 0) {
-                        sID = sID.substring(0, sID.indexOf('.'));
-                        if (outputIDs.containsKey(sID)) {
-                            outputIDs.put(sID, outputIDs.get(sID) + 1);
+                    String id = ((BEASTInterface)output).getID();
+                    if (id.indexOf('.') >= 0) {
+                        id = id.substring(0, id.indexOf('.'));
+                        if (outputIDs.containsKey(id)) {
+                            outputIDs.put(id, outputIDs.get(id) + 1);
                         } else {
-                            outputIDs.put(sID, 1);
+                            outputIDs.put(id, 1);
                         }
                     }
                 }
             }
-            for (Object output : plugin.getOutputs()) {
+            for (Object output : beastObject.getOutputs()) {
                 if (posteriorPredecessors.contains(output)) {
-                    String sID = ((BEASTInterface)output).getID();
-                    if (sID.indexOf('.') >= 0) {
-                        sID = sID.substring(0, sID.indexOf('.'));
-                        if (outputIDs.get(sID) > 1) {
-                            addLink((BEASTInterface)plugin, (BEASTInterface)output);
+                    String id = ((BEASTInterface)output).getID();
+                    if (id.indexOf('.') >= 0) {
+                        id = id.substring(0, id.indexOf('.'));
+                        if (outputIDs.get(id) > 1) {
+                            addLink(beastObject, (BEASTInterface)output);
                         }
                     }
                 }
             }
             // add parameters that have more than 1 outputs into susbtitution models
-            if (plugin instanceof Parameter<?>) {
-                for (Object output : plugin.getOutputs()) {
+            if (beastObject instanceof Parameter<?>) {
+                for (Object output : beastObject.getOutputs()) {
                     if (posteriorPredecessors.contains(output)) {
                         if (output instanceof SubstitutionModel) {
                             int nrOfSubstModelsInOutput = 0;
                             try {
                                 for (Input<?> input : ((BEASTInterface)output).listInputs()) {
-                                    if (input.get() != null && input.get().equals(plugin)) {
+                                    if (input.get() != null && input.get().equals(beastObject)) {
                                         nrOfSubstModelsInOutput++;
                                     }
                                 }
@@ -2207,7 +2290,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                                 // ignore
                             }
                             if (nrOfSubstModelsInOutput > 1) {
-                                addLink((BEASTInterface)plugin, (BEASTInterface)output);
+                                addLink(beastObject, (BEASTInterface)output);
                             }
                         }
                     }
@@ -2215,10 +2298,10 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
             }
         }
 
-        bHasLinkedAtLeastOnce = false;
+        hasLinkedAtLeastOnce = false;
         for (Input<?> input : linked) {
             if (input.getType().isAssignableFrom(RealParameter.class)) {
-                bHasLinkedAtLeastOnce = true;
+                hasLinkedAtLeastOnce = true;
                 break;
             }
         }
@@ -2236,7 +2319,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                 // does it make sense to link list inputs?
 //				if (input.get() instanceof List<?>) {
 //					for (Object o : (List<?>) input.get()) {
-//						if (o instanceof Plugin) {
+//						if (o instanceof BEASTObject) {
 //							if (o == from) {
 //								addLink(input);
 //								return;
@@ -2252,7 +2335,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
 
     public void addLink(Input<?> input) {
         linked.add(input);
-        bHasLinkedAtLeastOnce = true;
+        hasLinkedAtLeastOnce = true;
     }
 
     public void deLink(Input<?> input) {
@@ -2268,37 +2351,37 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
      * the same ID in another partition, or
      * the same partition with the same substitution model as output
      *
-     * @param plugin
+     * @param beastObject
      * @return
      */
-    public List<BEASTInterface> suggestedLinks(BEASTInterface plugin) {
-        String sID = plugin.getID();
-        List<BEASTInterface> list = new ArrayList<BEASTInterface>();
+    public List<BEASTInterface> suggestedLinks(BEASTInterface beastObject) {
+        String id = beastObject.getID();
+        List<BEASTInterface> list = new ArrayList<>();
         String partitionID = null;
-        if (sID.indexOf('.') >= 0) {
-            partitionID = sID.substring(sID.indexOf('.') + 1);
-            sID = sID.substring(0, sID.indexOf('.'));
+        if (id.indexOf('.') >= 0) {
+            partitionID = id.substring(id.indexOf('.') + 1);
+            id = id.substring(0, id.indexOf('.'));
         } else {
             return list;
         }
         for (BEASTInterface candidate : posteriorPredecessors) {
-            String sID2 = candidate.getID();
-            if (sID2.indexOf('.') >= 0) {
-                String partitionID2 = sID2.substring(sID2.indexOf('.') + 1);
-                sID2 = sID2.substring(0, sID2.indexOf('.'));
-                if (sID2.equals(sID)) {
+            String id2 = candidate.getID();
+            if (id2.indexOf('.') >= 0) {
+                String partitionID2 = id2.substring(id2.indexOf('.') + 1);
+                id2 = id2.substring(0, id2.indexOf('.'));
+                if (id2.equals(id)) {
                     list.add(candidate);
                 }
-                if (plugin instanceof Parameter<?> &&
+                if (beastObject instanceof Parameter<?> &&
                         partitionID2.equals(partitionID) &&
-                        candidate.getClass().equals(plugin.getClass())) {
+                        candidate.getClass().equals(beastObject.getClass())) {
                     boolean dimensionMatches = true;
-                    if (((Parameter<?>) plugin).getDimension() != ((Parameter<?>) candidate).getDimension()) {
+                    if (((Parameter<?>) beastObject).getDimension() != ((Parameter<?>) candidate).getDimension()) {
                         dimensionMatches = false;
                     }
                     // ensure they share an output
                     boolean foundCommonOutput = false;
-                    for (Object out1 : plugin.getOutputs()) {
+                    for (Object out1 : beastObject.getOutputs()) {
                         for (Object out2 : candidate.getOutputs()) {
                             if (out1 == out2 && out1 instanceof SubstitutionModel) {
                                 foundCommonOutput = true;
@@ -2312,14 +2395,15 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
                 }
             }
         }
-        list.remove(plugin);
+        list.remove(beastObject);
         return list;
     }
 
-    public BEASTInterface getUnlinkCandidate(Input<?> input, BEASTInterface parent) throws Exception {
-        PartitionContext context = getContextFor(parent);
-        BEASTInterface plugin = deepCopyPlugin((BEASTInterface) input.get(), parent, (MCMC) mcmc.get(), context, this, null);
-        return plugin;
+    public BEASTInterface getUnlinkCandidate(Input<?> input, BEASTInterface parent) {
+        PartitionContext oldContext = getContextFor((BEASTInterface)input.get());
+        PartitionContext newContext = getContextFor(parent);
+        BEASTInterface beastObject = deepCopyPlugin((BEASTInterface) input.get(), parent, (MCMC) mcmc.get(), oldContext, newContext, this, null);
+        return beastObject;
     }
 
     public void setBeauti(Beauti beauti) {
@@ -2331,7 +2415,7 @@ public class BeautiDoc extends BEASTObject implements RequiredInputProvider {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
     }
 
     /** create taxonset, one taxon for each sequence in the alignment
diff --git a/src/beast/app/beauti/BeautiLauncher.java b/src/beast/app/beauti/BeautiLauncher.java
index 90549b9..ad06a68 100644
--- a/src/beast/app/beauti/BeautiLauncher.java
+++ b/src/beast/app/beauti/BeautiLauncher.java
@@ -1,6 +1,9 @@
 package beast.app.beauti;
 
 
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
 import beast.app.beastapp.BeastLauncher;
 import beast.app.util.Utils6;
 
@@ -12,7 +15,7 @@ import beast.app.util.Utils6;
  * **/
 public class BeautiLauncher extends BeastLauncher {
 
-	public static void main(String[] args) throws Exception {
+	public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
 		Utils6.startSplashScreen();
 		if (javaVersionCheck("BEAUti")) {
 			loadBEASTJars();
diff --git a/src/beast/app/beauti/BeautiPanel.java b/src/beast/app/beauti/BeautiPanel.java
index bcc4e3a..b1de4f1 100644
--- a/src/beast/app/beauti/BeautiPanel.java
+++ b/src/beast/app/beauti/BeautiPanel.java
@@ -1,5 +1,27 @@
 package beast.app.beauti;
 
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Rectangle;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.Box;
+import javax.swing.DefaultListModel;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JViewport;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingConstants;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
 import beast.app.beauti.BeautiPanelConfig.Partition;
 import beast.app.draw.InputEditor;
 import beast.app.draw.InputEditor.ExpandOption;
@@ -15,14 +37,6 @@ import beast.evolution.sitemodel.SiteModel;
 import beast.evolution.sitemodel.SiteModelInterface;
 import beast.evolution.tree.TreeInterface;
 
-import javax.swing.*;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-
-import java.awt.*;
-import java.util.List;
-import java.util.Set;
-
 /**
  * panel making up each of the tabs in Beauti *
  */
@@ -52,12 +66,12 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
     /**
      * panel number *
      */
-    int iPanel;
+    int panelIndex;
 
     /**
      * partition currently on display *
      */
-    public int iPartition = 0;
+    public int partitionIndex = 0;
 
     /**
      * box containing the list of partitions, to make (in)visible on update *
@@ -66,11 +80,11 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
     /**
      * list of partitions in m_listBox *
      */
-    JList listOfPartitions;
+    JList<String> listOfPartitions;
     /**
      * model for m_listOfPartitions *
      */
-    DefaultListModel listModel;
+    DefaultListModel<String> listModel;
 
     JScrollPane scroller;
 
@@ -82,15 +96,15 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
     public BeautiPanel() {
     }
 
-    public BeautiPanel(int iPanel, BeautiDoc doc, BeautiPanelConfig config) throws Exception {
+    public BeautiPanel(int panelIndex, BeautiDoc doc, BeautiPanelConfig config) throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         this.doc = doc;
-        this.iPanel = iPanel;
+        this.panelIndex = panelIndex;
 
         setLayout(new BorderLayout());
 
         this.config = config;
         if (this.config.hasPartition() != Partition.none &&
-                doc.getPartitions(config.bHasPartitionsInput.get().toString()).size() > 1) {
+                doc.getPartitions(config.hasPartitionsInput.get().toString()).size() > 1) {
             splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
             add(splitPane,BorderLayout.CENTER);
         } else {
@@ -98,24 +112,24 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
         }
 
         refreshPanel();
-        addPartitionPanel(this.config.hasPartition(), iPanel);
+        addPartitionPanel(this.config.hasPartition(), panelIndex);
 
         setOpaque(false);
     } // c'tor
 
-    void addPartitionPanel(Partition bHasPartition, int iPanel) {
+    void addPartitionPanel(Partition hasPartition, int panelIndex) {
         Box box = Box.createVerticalBox();
-        if (splitPane != null && bHasPartition != Partition.none) {
+        if (splitPane != null && hasPartition != Partition.none) {
             box.add(createList());
         } else {
             return;
         }
         box.add(Box.createVerticalGlue());
-        box.add(new JLabel(Utils.getIcon(iPanel, config)));
+        box.add(new JLabel(Utils.getIcon(panelIndex, config)));
 
         splitPane.add(box, JSplitPane.LEFT);
         if (listOfPartitions != null) {
-            listOfPartitions.setSelectedIndex(iPartition);
+            listOfPartitions.setSelectedIndex(partitionIndex);
         }
     }
 
@@ -127,10 +141,10 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
         partitionComponent = new JPanel();
         partitionComponent.setLayout(new BorderLayout());
         JLabel partitionLabel = new JLabel("Partition");
-        partitionLabel.setHorizontalAlignment(JLabel.CENTER);
+        partitionLabel.setHorizontalAlignment(SwingConstants.CENTER);
         partitionComponent.add(partitionLabel, BorderLayout.NORTH);
-        listModel = new DefaultListModel();
-        listOfPartitions = new JList(listModel);
+        listModel = new DefaultListModel<>();
+        listOfPartitions = new JList<>(listModel);
         listOfPartitions.setName("listOfPartitions");
         listOfPartitions.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
 
@@ -163,24 +177,24 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
             // this is a weird bit of code, since listModel.clear should ensure that size()==0, but it doesn't
             return;
         }
-        String type = config.bHasPartitionsInput.get().toString();
+        String type = config.hasPartitionsInput.get().toString();
         for (BEASTInterface partition : doc.getPartitions(type)) {
         	if (type.equals("SiteModel")) {
         		partition = (BEASTInterface) ((GenericTreeLikelihood) partition).siteModelInput.get();
         	} else if (type.equals("ClockModel")) {
-        		partition = (BEASTInterface) ((GenericTreeLikelihood) partition).branchRateModelInput.get();
+        		partition = ((GenericTreeLikelihood) partition).branchRateModelInput.get();
         	} else if (type.equals("Tree")) {
         		partition = (BEASTInterface) ((GenericTreeLikelihood) partition).treeInput.get();
         	}
-            String sPartition = partition.getID();
-            sPartition = sPartition.substring(sPartition.lastIndexOf('.') + 1);
-            if (sPartition.length() > 1 && sPartition.charAt(1) == ':') {
-            	sPartition = sPartition.substring(2);
+            String partitionID = partition.getID();
+            partitionID = partitionID.substring(partitionID.lastIndexOf('.') + 1);
+            if (partitionID.length() > 1 && partitionID.charAt(1) == ':') {
+            	partitionID = partitionID.substring(2);
             }
-            listModel.addElement(sPartition);
+            listModel.addElement(partitionID);
         }
-        if (iPartition >= 0 && listModel.size() > 0)
-            listOfPartitions.setSelectedIndex(iPartition);
+        if (partitionIndex >= 0 && listModel.size() > 0)
+            listOfPartitions.setSelectedIndex(partitionIndex);
     }
 
     
@@ -188,7 +202,7 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
     // AR remove globals (doesn't seem to be used anywhere)...
 //	static BeautiPanel g_currentPanel = null;
 
-    public void refreshPanel() throws Exception {
+    public void refreshPanel() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         if (doc.alignments.size() == 0) {
             refreshInputPanel();
             return;
@@ -197,13 +211,13 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
 
         // toggle splitpane
         if (splitPane == null && config.hasPartition() != Partition.none &&
-                doc.getPartitions(config.bHasPartitionsInput.get().toString()).size() > 1) {
+                doc.getPartitions(config.hasPartitionsInput.get().toString()).size() > 1) {
             splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
             add(splitPane,BorderLayout.CENTER);
-            addPartitionPanel(config.hasPartition(), iPanel);
+            addPartitionPanel(config.hasPartition(), panelIndex);
         }
         if (splitPane != null && (config.hasPartition() == Partition.none ||
-                doc.getPartitions(config.bHasPartitionsInput.get().toString()).size() <= 1)) {
+                doc.getPartitions(config.hasPartitionsInput.get().toString()).size() <= 1)) {
             remove(splitPane);
             splitPane = null;
         }
@@ -216,13 +230,13 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
 //		g_currentPanel = this;
     }
     
-    void refreshInputPanel(BEASTInterface plugin, Input<?> input, boolean bAddButtons, InputEditor.ExpandOption bForceExpansion) throws Exception {
+    void refreshInputPanel(BEASTInterface beastObject, Input<?> input, boolean addButtons, InputEditor.ExpandOption forceExpansion) throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         if (centralComponent != null) {
             remove(centralComponent);
         }
         if (input != null && input.get() != null && input.getType() != null) {
             InputEditor.ButtonStatus bs = config.buttonStatusInput.get();
-            InputEditor inputEditor = doc.getInputEditorFactory().createInputEditor(input, plugin, bAddButtons, bForceExpansion, bs, null, doc);
+            InputEditor inputEditor = doc.getInputEditorFactory().createInputEditor(input, beastObject, addButtons, forceExpansion, bs, null, doc);
 
             JPanel p = new JPanel();
             p.setLayout(new BorderLayout());
@@ -265,15 +279,15 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
         }
     }
 
-    void refreshInputPanel() throws Exception {
+    void refreshInputPanel() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         doc.currentInputEditors.clear();
-        InputEditor.Base.g_nLabelWidth = config.nLabelWidthInput.get();
-        BEASTInterface plugin = config;
-        Input<?> input = config.resolveInput(doc, iPartition);
+        InputEditor.Base.g_nLabelWidth = config.labelWidthInput.get();
+        BEASTInterface beastObject = config;
+        final Input<?> input = config.resolveInput(doc, partitionIndex);
 
-        boolean bAddButtons = config.addButtons();
-        ExpandOption bForceExpansion = config.forceExpansion();
-        refreshInputPanel(plugin, input, bAddButtons, bForceExpansion);
+        boolean addButtons = config.addButtons();
+        ExpandOption forceExpansion = config.forceExpansion();
+        refreshInputPanel(beastObject, input, addButtons, forceExpansion);
     }
 
     /** 
@@ -287,39 +301,40 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
     		return;
     	}
 
-    	String type = config.bHasPartitionsInput.get().toString();
+    	String type = config.hasPartitionsInput.get().toString();
     	java.util.List<BEASTInterface> list = doc.getPartitions(type);
-    	int iSource = -1, iTarget = -1;
+    	int source = -1, target = -1;
         for (int i = 0; i < list.size(); i++) {
         	BEASTInterface partition = list.get(i);
         	if (type.equals("SiteModel")) {
         		partition = (BEASTInterface) ((GenericTreeLikelihood) partition).siteModelInput.get();
         	} else if (type.equals("ClockModel")) {
-        		partition = (BEASTInterface) ((GenericTreeLikelihood) partition).branchRateModelInput.get();
+        		partition = ((GenericTreeLikelihood) partition).branchRateModelInput.get();
         	} else if (type.equals("Tree")) {
         		partition = (BEASTInterface) ((GenericTreeLikelihood) partition).treeInput.get();
         	}
-            String sPartition = partition.getID();
-            sPartition = sPartition.substring(sPartition.lastIndexOf('.') + 1);
-            if (sPartition.length() > 1 && sPartition.charAt(1) == ':') {
-            	sPartition = sPartition.substring(2);
+            String partitionID = partition.getID();
+            partitionID = partitionID.substring(partitionID.lastIndexOf('.') + 1);
+            if (partitionID.length() > 1 && partitionID.charAt(1) == ':') {
+            	partitionID = partitionID.substring(2);
             }
-            if (sPartition.equals(sourceID)) {
-            	iSource = i;
+            if (partitionID.equals(sourceID)) {
+            	source = i;
             }
-            if (sPartition.equals(targetID)) {
-            	iTarget = i;
+            if (partitionID.equals(targetID)) {
+            	target = i;
             }
         } 
-    	if (iTarget == -1) {
+    	if (target == -1) {
     		throw new RuntimeException("Programmer error: sourceID and targetID should be in list");
     	}
     	
 		CompoundDistribution likelihoods = (CompoundDistribution) doc.pluginmap.get("likelihood");
 		
-		GenericTreeLikelihood likelihoodSource = (GenericTreeLikelihood) likelihoods.pDistributions.get().get(iSource);
-		GenericTreeLikelihood likelihood = (GenericTreeLikelihood) likelihoods.pDistributions.get().get(iTarget);
-		PartitionContext context = doc.getContextFor(likelihood);
+		GenericTreeLikelihood likelihoodSource = (GenericTreeLikelihood) likelihoods.pDistributions.get().get(source);
+		GenericTreeLikelihood likelihood = (GenericTreeLikelihood) likelihoods.pDistributions.get().get(target);
+		PartitionContext oldContext = doc.getContextFor(likelihoodSource);
+		PartitionContext newContext = doc.getContextFor(likelihood);
 		// this ensures the config.sync does not set any input value
 		config._input.setValue(null, config);
 
@@ -328,8 +343,8 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
 			SiteModelInterface  siteModel = null;
 			try {
 				siteModel = (SiteModel.Base) BeautiDoc.deepCopyPlugin((BEASTInterface) siteModelSource,
-					likelihood, (MCMC) doc.mcmc.get(), context, doc, null);
-			} catch (Exception e) {
+					likelihood, (MCMC) doc.mcmc.get(), oldContext, newContext, doc, null);
+			} catch (RuntimeException e) {
 				JOptionPane.showMessageDialog(this, "Could not clone " + sourceID + " to " + targetID + " " + e.getMessage());
 				return;
 			}
@@ -340,7 +355,7 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
     		BranchRateModel clockModel = null;
 			try {
 				clockModel = (BranchRateModel) BeautiDoc.deepCopyPlugin((BEASTInterface) clockModelSource,
-						likelihood, (MCMC) doc.mcmc.get(), context, doc, null);
+						likelihood, (MCMC) doc.mcmc.get(), oldContext, newContext, doc, null);
 			} catch (Exception e) {
 				JOptionPane.showMessageDialog(this, "Could not clone " + sourceID + " to " + targetID + " " + e.getMessage());
 				return;
@@ -358,9 +373,6 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
 			} catch (IllegalArgumentException e) {
 				// TODO Auto-generated catch block
 				e.printStackTrace();
-			} catch (IllegalAccessException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
 			}
 			if (tree != null && tree != likelihood.treeInput.get()) {
 				//likelihood.treeInput.setValue(tree, likelihood);
@@ -375,7 +387,7 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
 			TreeInterface treeSource = likelihoodSource.treeInput.get();
 			try {
 			tree = (TreeInterface) BeautiDoc.deepCopyPlugin((BEASTInterface) treeSource, likelihood,
-							(MCMC) doc.mcmc.get(), context, doc, null);
+							(MCMC) doc.mcmc.get(), oldContext, newContext, doc, null);
 				} catch (Exception e) {
 					JOptionPane.showMessageDialog(this, "Could not clone " + sourceID + " to " + targetID + " " + e.getMessage());
 					return;
@@ -428,9 +440,9 @@ public class BeautiPanel extends JPanel implements ListSelectionListener {
     public void valueChanged(ListSelectionEvent e) {
         //System.err.print("BeautiPanel::valueChanged " + m_iPartition + " => ");
         if (e != null) {
-            config.sync(iPartition);
+            config.sync(partitionIndex);
             if (listOfPartitions != null) {
-                iPartition = Math.max(0, listOfPartitions.getSelectedIndex());
+                partitionIndex = Math.max(0, listOfPartitions.getSelectedIndex());
             }
         }
 //        BeautiPanel.playSound("woosh.wav");
diff --git a/src/beast/app/beauti/BeautiPanelConfig.java b/src/beast/app/beauti/BeautiPanelConfig.java
index 05b5b0b..3e7efde 100644
--- a/src/beast/app/beauti/BeautiPanelConfig.java
+++ b/src/beast/app/beauti/BeautiPanelConfig.java
@@ -5,13 +5,14 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
-import beast.app.draw.InputEditor;
 import beast.app.draw.BEASTObjectPanel;
+import beast.app.draw.InputEditor;
+import beast.core.BEASTInterface;
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 import beast.core.Input.Validate;
+import beast.core.util.Log;
 
 
 
@@ -22,55 +23,55 @@ public class BeautiPanelConfig extends BEASTObject {
         none, Partition, SiteModel, ClockModel, Tree
     }
 
-    public Input<String> sNameInput = new Input<String>("panelname", "name of the panel, used to label the panel and in the visibility menu", Validate.REQUIRED);
-    public Input<String> sTipTextInput = new Input<String>("tiptext", "tiptext shown when hovering over the tab", Validate.REQUIRED);
+    final public Input<String> nameInput = new Input<>("panelname", "name of the panel, used to label the panel and in the visibility menu", Validate.REQUIRED);
+    final public Input<String> tipTextInput = new Input<>("tiptext", "tiptext shown when hovering over the tab", Validate.REQUIRED);
 
-    public Input<String> sPathInput = new Input<String>("path", "path of the Plugin to be shown in this panel, in xpath-like format. " +
+    final public Input<String> pathInput = new Input<>("path", "path of the BEASTObject to be shown in this panel, in xpath-like format. " +
             "For example operator to edit the operator input of the top level run element. " +
             "distribution/distribution[id='prior'] for prior distributions." +
             "distribution/distribution[id='posterior']/traitset all posterior inputs with name traitset", Validate.REQUIRED);
 
-    public Input<Partition> bHasPartitionsInput = new Input<Partition>("hasPartitions", "flag to indicate the panel has" +
+    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());
 
-    public Input<Boolean> bAddButtonsInput = new Input<Boolean>("addButtons", "flag to indicate buttons should be added, default true", true);
-    public Input<Boolean> bIsVisibleInput = new Input<Boolean>("isVisible", "flag to indicate panel is visible on startup, default true", true);
+    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);
 
 
-    public Input<String> sIconInput = new Input<String>("icon", "icon shown in the panel relative to /beast/app/beauti, default 0.png", "0.png");
+    final public Input<String> iconInput = new Input<>("icon", "icon shown in the panel relative to /beast/app/beauti, default 0.png", "0.png");
 
-    public Input<InputEditor.ExpandOption> forceExpansionInput = new Input<InputEditor.ExpandOption>("forceExpansion", "whether to expand the input(s)" +
+    final public Input<InputEditor.ExpandOption> forceExpansionInput = new Input<>("forceExpansion", "whether to expand the input(s)" +
             "This can be " + Arrays.toString(InputEditor.ExpandOption.values()) + " (default 'FALSE')", InputEditor.ExpandOption.FALSE, InputEditor.ExpandOption.values());
-    public Input<String> sTypeInput = new Input<String>("type", "type used for finding the appropriate plugin editor. By default, type is determined " +
+    final public Input<String> typeInput = new Input<>("type", "type used for finding the appropriate beastObject editor. By default, type is determined " +
             "by the input type of the last component of the path");
 
-    public Input<Integer> nLabelWidthInput = new Input<Integer>("labelWidth", "width of labels used to show name of inputs in input editors", 150);
+    final public Input<Integer> labelWidthInput = new Input<>("labelWidth", "width of labels used to show name of inputs in input editors", 150);
 
-    public Input<InputEditor.ButtonStatus> buttonStatusInput = new Input<InputEditor.ButtonStatus>("buttonStatus", "whether to show add and delete buttons. " +
+    final public Input<InputEditor.ButtonStatus> buttonStatusInput = new Input<>("buttonStatus", "whether to show add and delete buttons. " +
             "This can be " + Arrays.toString(InputEditor.ButtonStatus.values()) + " (default 'ALL')", InputEditor.ButtonStatus.ALL, InputEditor.ButtonStatus.values());
 
-    String[] sPathComponents;
-    String[] sConditionalAttribute;
-    String[] sConditionalValue;
+    String[] pathComponents;
+    String[] conditionalAttribute;
+    String[] conditionalValue;
     Class<?> type;
 
     /**
-     * plugins associated with inputs *
+     * beastObjects associated with inputs *
      */
     List<BEASTInterface> inputs;
     /**
-     * plugins associated with inputs before editing starts *
+     * beastObjects associated with inputs before editing starts *
      */
     List<BEASTInterface> startInputs;
     /**
-     * plugins that are parents, i.e. contain inputs of m_inputs *
+     * beastObjects that are parents, i.e. contain inputs of m_inputs *
      */
-    List<BEASTInterface> parentPlugins;
-    List<Input<?>> parentInputs = new ArrayList<Input<?>>();
+    List<BEASTInterface> parentBEASTObjects;
+    List<Input<?>> parentInputs = new ArrayList<>();
     /**
      * flag to indicate we are dealing with a list input *
      */
-    boolean bIsList;
+    boolean isList;
 
 
     FlexibleInput<?> _input;
@@ -85,31 +86,32 @@ public class BeautiPanelConfig extends BEASTObject {
             super("xx", "", arrayList);
         }
 
-        public void setType(Class<?> type) {
+        @Override
+		public void setType(Class<?> type) {
             theClass = type;
         }
     }
 
     @Override
-    public void initAndValidate() throws Exception {
-        sPathComponents = sPathInput.get().split("/");
-        if (sPathComponents[0].equals("")) {
-            sPathComponents = new String[0];
+    public void initAndValidate() {
+        pathComponents = pathInput.get().split("/");
+        if (pathComponents[0].equals("")) {
+            pathComponents = new String[0];
         }
-        sConditionalAttribute = new String[sPathComponents.length];
-        sConditionalValue = new String[sPathComponents.length];
-        for (int i = 0; i < sPathComponents.length; i++) {
-            int j = sPathComponents[i].indexOf('[');
+        conditionalAttribute = new String[pathComponents.length];
+        conditionalValue = new String[pathComponents.length];
+        for (int i = 0; i < pathComponents.length; i++) {
+            int j = pathComponents[i].indexOf('[');
             if (j >= 0) {
-                String sConditionalComponents = sPathComponents[i].substring(j + 1, sPathComponents[i].lastIndexOf(']'));
-                String[] sStrs = sConditionalComponents.split("=");
-                sConditionalAttribute[i] = sStrs[0];
-                sConditionalValue[i] = sStrs[1].substring(1, sStrs[1].length() - 1);
-                sPathComponents[i] = sPathComponents[i].substring(0, j);
+                String conditionalComponents = pathComponents[i].substring(j + 1, pathComponents[i].lastIndexOf(']'));
+                String[] strs = conditionalComponents.split("=");
+                conditionalAttribute[i] = strs[0];
+                conditionalValue[i] = strs[1].substring(1, strs[1].length() - 1);
+                pathComponents[i] = pathComponents[i].substring(0, j);
             }
         }
-        inputs = new ArrayList<BEASTInterface>();
-        startInputs = new ArrayList<BEASTInterface>();
+        inputs = new ArrayList<>();
+        startInputs = new ArrayList<>();
         BEASTObjectPanel.getID(this);
     }
 
@@ -117,11 +119,11 @@ public class BeautiPanelConfig extends BEASTObject {
      * more elegant getters for resolving Input values*
      */
     public String getName() {
-        return sNameInput.get();
+        return nameInput.get();
     }
 
     public Partition hasPartition() {
-        return bHasPartitionsInput.get();
+        return hasPartitionsInput.get();
     }
 
     public boolean addButtons() {
@@ -129,11 +131,11 @@ public class BeautiPanelConfig extends BEASTObject {
     }
 
     public String getIcon() {
-        return sIconInput.get();
+        return iconInput.get();
     }
 
     public String getTipText() {
-        return sTipTextInput.get();
+        return tipTextInput.get();
     }
 
     public InputEditor.ExpandOption forceExpansion() {
@@ -145,117 +147,117 @@ public class BeautiPanelConfig extends BEASTObject {
      * based on the path Input.
      */
     @SuppressWarnings("unchecked")
-    public Input<?> resolveInput(BeautiDoc doc, int iPartition) {
+    final public Input<?> resolveInput(BeautiDoc doc, int partitionIndex) {
         try {
-//            if (parentPlugins != null && parentPlugins.size() > 0 && _input != null)
-//                System.err.println("sync " + parentPlugins.get(iPartition) + "[?] = " + _input.get());
+//            if (parentBEASTObjects != null && parentBEASTObjects.size() > 0 && _input != null)
+//                System.err.println("sync " + parentBEASTObjects.get(partitionIndex) + "[?] = " + _input.get());
 
-            List<BEASTInterface> plugins;
-            if (bHasPartitionsInput.get() == Partition.none) {
-                plugins = new ArrayList<BEASTInterface>();
-                plugins.add(doc.mcmc.get());
+            List<BEASTInterface> beastObjects;
+            if (hasPartitionsInput.get() == Partition.none) {
+                beastObjects = new ArrayList<>();
+                beastObjects.add(doc.mcmc.get());
             } else {
-                plugins = doc.getPartitions(bHasPartitionsInput.get().toString());
+                beastObjects = doc.getPartitions(hasPartitionsInput.get().toString());
             }
-            parentPlugins = new ArrayList<BEASTInterface>();
-            parentInputs = new ArrayList<Input<?>>();
+            parentBEASTObjects = new ArrayList<>();
+            parentInputs = new ArrayList<>();
 
-            parentPlugins.add(doc);
+            parentBEASTObjects.add(doc);
             parentInputs.add(doc.mcmc);
             type = doc.mcmc.getType();
-            bIsList = false;
-            for (int i = 0; i < sPathComponents.length; i++) {
-                List<BEASTInterface> oldPlugins = plugins;
-                plugins = new ArrayList<BEASTInterface>();
-                parentPlugins = new ArrayList<BEASTInterface>();
-                parentInputs = new ArrayList<Input<?>>();
-                for (BEASTInterface plugin : oldPlugins) {
-                    Input<?> namedInput = plugin.getInput(sPathComponents[i]);
+            isList = false;
+            for (int i = 0; i < pathComponents.length; i++) {
+                List<BEASTInterface> oldPlugins = beastObjects;
+                beastObjects = new ArrayList<>();
+                parentBEASTObjects = new ArrayList<>();
+                parentInputs = new ArrayList<>();
+                for (BEASTInterface beastObject : oldPlugins) {
+                    final Input<?> namedInput = beastObject.getInput(pathComponents[i]);
                     type = namedInput.getType();
                     if (namedInput.get() instanceof List<?>) {
-                        bIsList = true;
+                        isList = true;
                         List<?> list = (List<?>) namedInput.get();
-                        if (sConditionalAttribute[i] == null) {
+                        if (conditionalAttribute[i] == null) {
                             for (Object o : list) {
-                                BEASTInterface plugin2 = (BEASTInterface) o;
-                                plugins.add(plugin2);
-                                parentPlugins.add(plugin);
+                                BEASTInterface beastObject2 = (BEASTInterface) o;
+                                beastObjects.add(beastObject2);
+                                parentBEASTObjects.add(beastObject);
                                 parentInputs.add(namedInput);
                             }
                             //throw new Exception ("Don't know which element to pick from the list. List component should come with a condition. " + m_sPathComponents[i]);
                         } else {
-                            int nMatches = 0;
+                            int matches = 0;
                             for (int j = 0; j < list.size(); j++) {
-                                BEASTInterface plugin2 = (BEASTInterface) list.get(j);
-                                if (matches(plugin2, sConditionalAttribute[i], sConditionalValue[i])) {
-                                    plugins.add(plugin2);
-                                    parentPlugins.add(plugin);
+                                BEASTInterface beastObject2 = (BEASTInterface) list.get(j);
+                                if (matches(beastObject2, conditionalAttribute[i], conditionalValue[i])) {
+                                    beastObjects.add(beastObject2);
+                                    parentBEASTObjects.add(beastObject);
                                     parentInputs.add(namedInput);
-                                    nMatches++;
+                                    matches++;
                                     break;
                                 }
                             }
-                            if (nMatches == 0) {
+                            if (matches == 0) {
                                 parentInputs.add(namedInput);
-                                parentPlugins.add(plugin);
+                                parentBEASTObjects.add(beastObject);
                             }
                         }
                     } else if (namedInput.get() instanceof BEASTInterface) {
-                        bIsList = false;
-                        if (sConditionalAttribute[i] == null) {
-                            plugins.add((BEASTInterface) namedInput.get());
-                            parentPlugins.add(plugin);
+                        isList = false;
+                        if (conditionalAttribute[i] == null) {
+                            beastObjects.add((BEASTInterface) namedInput.get());
+                            parentBEASTObjects.add(beastObject);
                             parentInputs.add(namedInput);
                         } else {
-                            if (matches(plugin, sConditionalAttribute[i], sConditionalValue[i])) {
-//							if ((m_sConditionalAttribute[i].equals("id") && plugin.getID().equals(m_sConditionalValue[i])) ||
-//							    (m_sConditionalAttribute[i].equals("type") && plugin.getClass().getName().equals(m_sConditionalValue[i]))) {
-                                plugins.add(plugin);
-                                parentPlugins.add(plugin);
+                            if (matches(beastObject, conditionalAttribute[i], conditionalValue[i])) {
+//							if ((m_sConditionalAttribute[i].equals("id") && beastObject.getID().equals(m_sConditionalValue[i])) ||
+//							    (m_sConditionalAttribute[i].equals("type") && beastObject.getClass().getName().equals(m_sConditionalValue[i]))) {
+                                beastObjects.add(beastObject);
+                                parentBEASTObjects.add(beastObject);
                                 parentInputs.add(namedInput);
                             }
                         }
                     } else {
-                        throw new Exception("input " + sPathComponents[i] + "  is not a plugin or list");
+                        throw new IllegalArgumentException("input " + pathComponents[i] + "  is not a beastObject or list");
                     }
                 }
             }
-            if (sTypeInput.get() != null) {
-                type = Class.forName(sTypeInput.get());
+            if (typeInput.get() != null) {
+                type = Class.forName(typeInput.get());
             }
             // sanity check
-            if (!bIsList && (bHasPartitionsInput.get() == Partition.none) && plugins.size() > 1) {
-                System.err.println("WARNING: multiple plugins match, but hasPartitions=none");
-                // this makes sure that all mathing plugins are available in one go
-                bIsList = true;
+            if (!isList && (hasPartitionsInput.get() == Partition.none) && beastObjects.size() > 1) {
+            	Log.warning.println("WARNING: multiple beastObjects match, but hasPartitions=none");
+                // this makes sure that all mathing beastObjects are available in one go
+                isList = true;
                 // this suppresses syncing
                 parentInputs.clear();
             }
             inputs.clear();
             startInputs.clear();
-            for (BEASTInterface plugin : plugins) {
-                inputs.add(plugin);
-                startInputs.add(plugin);
+            for (BEASTInterface beastObject : beastObjects) {
+                inputs.add(beastObject);
+                startInputs.add(beastObject);
             }
 
-            if (!bIsList) {
-                _input = new FlexibleInput<BEASTInterface>();
+            if (!isList) {
+                _input = new FlexibleInput<>();
             } else {
-                _input = new FlexibleInput<ArrayList<BEASTInterface>>(new ArrayList<BEASTInterface>());
+                _input = new FlexibleInput<>(new ArrayList<>());
             }
             _input.setRule(Validate.REQUIRED);
-            syncTo(iPartition);
-//            if (parentPlugins != null && parentPlugins.size() > 0)
-//                System.err.println("sync " + parentPlugins.get(iPartition) + "[?] = " + _input.get());
+            syncTo(partitionIndex);
+//            if (parentBEASTObjects != null && parentBEASTObjects.size() > 0)
+//                System.err.println("sync " + parentBEASTObjects.get(partitionIndex) + "[?] = " + _input.get());
 
 
-            if (bIsList) {
+            if (isList) {
                 checkForDups((List<Object>) _input.get());
             }
 
             return _input;
         } catch (Exception e) {
-            System.err.println("Warning: could not find objects in path " + Arrays.toString(sPathComponents));
+            Log.err.println("Warning: could not find objects in path " + Arrays.toString(pathComponents));
         }
         return null;
     } // resolveInputs
@@ -263,7 +265,7 @@ public class BeautiPanelConfig extends BEASTObject {
     private void checkForDups(List<Object> list) {
         for (int i = 0; i < list.size(); i++) {
             if (list.lastIndexOf(list.get(i)) != i) {
-                System.err.println("We have a dup: " + list.get(i));
+            	Log.warning.println("We have a dup: " + list.get(i));
                 list.remove(i);
                 i--;
             }
@@ -271,37 +273,37 @@ public class BeautiPanelConfig extends BEASTObject {
 
     }
 
-    private boolean matches(BEASTInterface plugin2, String sConditionalAttribute, String sConditionalValue) {
-        if (sConditionalAttribute.equals("id") && plugin2.getID().equals(sConditionalValue)) return true;
-        if (sConditionalAttribute.equals("type") && plugin2.getClass().getName().equals(sConditionalValue)) return true;
-        if (sConditionalAttribute.equals("type!") && !plugin2.getClass().getName().equals(sConditionalValue))
+    private boolean matches(BEASTInterface beastObject2, String conditionalAttribute, String conditionalValue) {
+        if (conditionalAttribute.equals("id") && beastObject2.getID().equals(conditionalValue)) return true;
+        if (conditionalAttribute.equals("type") && beastObject2.getClass().getName().equals(conditionalValue)) return true;
+        if (conditionalAttribute.equals("type!") && !beastObject2.getClass().getName().equals(conditionalValue))
             return true;
         return false;
     }
 
     @SuppressWarnings("unchecked")
-    public void sync(int iPartition) {
+    public void sync(int partitionIndex) {
         if (parentInputs.size() > 0 && _input.get() != null) {
-            Input<?> input = parentInputs.get(iPartition);
-            if (bIsList) {
+            final Input<?> input = parentInputs.get(partitionIndex);
+            if (isList) {
                 List<Object> list = (List<Object>) _input.get();
                 List<Object> targetList = ((List<Object>) input.get());
                 //targetList.clear();
                 // only clear former members
-                for (BEASTInterface plugin : startInputs) {
-                    targetList.remove(plugin);
+                for (BEASTInterface beastObject : startInputs) {
+                    targetList.remove(beastObject);
                 }
                 targetList.addAll(list);
                 // sync outputs of items in list
                 for (Object o : list) {
                 	if (o instanceof BEASTInterface) {
-                		((BEASTInterface)o).getOutputs().add(parentPlugins.get(iPartition));
+                		((BEASTInterface)o).getOutputs().add(parentBEASTObjects.get(partitionIndex));
                 	}
                 }
             } else {
                 try {
-                    //System.err.println("sync " + parentPlugins.get(iPartition) + "[" + input.getName() + "] = " + _input.get());
-                    input.setValue(_input.get(), parentPlugins.get(iPartition));
+                    //System.err.println("sync " + parentBEASTObjects.get(partitionIndex) + "[" + input.getName() + "] = " + _input.get());
+                    input.setValue(_input.get(), parentBEASTObjects.get(partitionIndex));
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
@@ -310,19 +312,19 @@ public class BeautiPanelConfig extends BEASTObject {
     }
 
     /**
-     * initialise m_input, and either m_plugin or m_pluginList *
+     * initialise m_input, and either m_beastObject or m_pluginList *
      */
-    public void syncTo(int iPartition) {
+    public void syncTo(int partitionIndex) {
         _input.setType(type);
         try {
-            if (bIsList) {
-                for (BEASTInterface plugin : inputs) {
-                    _input.setValue(plugin, this);
+            if (isList) {
+                for (BEASTInterface beastObject : inputs) {
+                    _input.setValue(beastObject, this);
                 }
             } else {
             	if (inputs.size() > 0) {
-	                BEASTInterface plugin = inputs.get(iPartition);
-	                _input.setValue(plugin, this);
+	                BEASTInterface beastObject = inputs.get(partitionIndex);
+	                _input.setValue(beastObject, this);
             	}
             }
         } catch (Exception e) {
@@ -330,15 +332,15 @@ public class BeautiPanelConfig extends BEASTObject {
         }
     }
 
-    Input<?> getInput() {
+    final Input<?> getInput() {
         return _input;
     }
 
     /**
-     * returns name of the plugin *
+     * returns name of the beastObject *
      */
     public String getType() {
-        if (bIsList) {
+        if (isList) {
             return inputs.get(0).getClass().getName();
         }
         if (_input == null) {
@@ -347,7 +349,7 @@ public class BeautiPanelConfig extends BEASTObject {
         return _input.get().getClass().getName();
     }
 
-//	public void addItem(Plugin plugin) {
+//	public void addItem(BEASTObject beastObject) {
 //		m_parentInputs.add(m_parentInputs.get(m_parentInputs.size()-1));
 //		m_parentPlugins.add(m_parentPlugins.get(m_parentPlugins.size()-1));
 //	}
diff --git a/src/beast/app/beauti/BeautiSubTemplate.java b/src/beast/app/beauti/BeautiSubTemplate.java
index 164051b..6b989d2 100644
--- a/src/beast/app/beauti/BeautiSubTemplate.java
+++ b/src/beast/app/beauti/BeautiSubTemplate.java
@@ -1,6 +1,7 @@
 package beast.app.beauti;
 
 
+import java.io.IOException;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.util.ArrayList;
@@ -8,8 +9,10 @@ import java.util.HashMap;
 import java.util.List;
 
 import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
@@ -18,13 +21,14 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
 
+import beast.core.BEASTInterface;
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.Logger;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 import beast.core.Input.Validate;
+import beast.core.Logger;
 import beast.core.util.Log;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.alignment.FilteredAlignment;
@@ -37,69 +41,79 @@ import beast.util.XMLParser;
 //import beast.app.beauti.BeautiConnector.ConnectCondition;
 
 @Description("Template that specifies which sub-net needs to be created when " +
-        "a plugin of a paricular class is created.")
+        "a beastObject of a paricular class is created.")
 public class BeautiSubTemplate extends BEASTObject {
-    public Input<String> sClassInput = new Input<String>("class", "name of the class (with full class path) to be created", Validate.REQUIRED);
-    public Input<String> sMainInput = new Input<String>("mainid", "specifies id of the main plugin to be created by the template", Validate.REQUIRED);
-    //public Input<XML> sXMLInput = new Input<XML>("value","collection of objects to be created in Beast2 xml format", Validate.REQUIRED);
-    public Input<String> sXMLInput = new Input<String>("value", "collection of objects to be created in Beast2 xml format", Validate.REQUIRED);
-    public Input<List<BeautiConnector>> connectorsInput = new Input<List<BeautiConnector>>("connect", "Specifies which part of the template get connected to the main network", new ArrayList<BeautiConnector>());
-    public Input<String> suppressedInputs = new Input<String>("suppressInputs", "comma separated list of inputs that should not be shown");
-    public Input<String> inlineInput = new Input<String>("inlineInputs", "comma separated list of inputs that should " +
+    final public Input<String> classInput = new Input<>("class", "name of the class (with full class path) to be created", Validate.REQUIRED);
+    final public Input<String> mainInput = new Input<>("mainid", "specifies id of the main beastObject to be created by the template", Validate.REQUIRED);
+    //public Input<XML> xMLInput = new Input<>("value","collection of objects to be created in Beast2 xml format", Validate.REQUIRED);
+    final public Input<String> xMLInput = new Input<>("value", "collection of objects to be created in Beast2 xml format", Validate.REQUIRED);
+    final public Input<List<BeautiConnector>> connectorsInput = new Input<>("connect", "Specifies which part of the template get connected to the main network", new ArrayList<>());
+    final public Input<String> suppressedInputs = new Input<>("suppressInputs", "comma separated list of inputs that should not be shown");
+    final public Input<String> inlineInput = new Input<>("inlineInputs", "comma separated list of inputs that should " +
             "go inline, e.g. beast.evolution.sitemodel.SiteModel.substModel");
-    public Input<String> collapsedInput = new Input<String>("collapsedInputs", "comma separated list of inputs that should " +
+    final public Input<String> collapsedInput = new Input<>("collapsedInputs", "comma separated list of inputs that should " +
             "go inline, but are initially collapsed, e.g. beast.core.MCMC.logger");
 
     Class<?> _class = null;
     Object instance;
-    String sXML = null;
+    String xml = null;
     List<BeautiConnector> connectors;
 
     BeautiDoc doc;
 
-    //	String [] sSrcIDs;
-//	String [] sTargetIDs;
-//	String [] sTargetInputs;
+    //	String [] srcIDs;
+//	String [] targetIDs;
+//	String [] targetInputs;
 //	ConnectCondition [] conditions;
-    String sMainID = "";
-    String sShortClassName;
+    String mainID = "";
+    String shortClassName;
 
     @Override
-    public void initAndValidate() throws Exception {
-        _class = Class.forName(sClassInput.get());
-        sShortClassName = sClassInput.get().substring(sClassInput.get().lastIndexOf('.') + 1);
+    public void initAndValidate() {
+    	try {
+        _class = Class.forName(classInput.get());
+        shortClassName = classInput.get().substring(classInput.get().lastIndexOf('.') + 1);
         instance = _class.newInstance();
-        sXML = sXMLInput.get();//.m_sValue.get();
-        sMainID = sMainInput.get();
+        xml = xMLInput.get();//.m_sValue.get();
+        mainID = mainInput.get();
         // sanity check: make sure the XML is parseable
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        Document doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader("<beast xmlns:beauti='http://beast2.org'>" + sXML + "</beast>")));
-        sXML = processDoc(doc);
+        Document doc;
+		try {
+			doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader("<beast xmlns:beauti='http://beast2.org'>" + xml + "</beast>")));
+	        xml = processDoc(doc);
+		} catch (SAXException | IOException | ParserConfigurationException | TransformerException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
+       
         
         // make sure there are no comments in the XML: this screws up any XML when saved to file
-        if (sXML.contains("<!--")) {
-            while (sXML.contains("<!--")) {
-                int iStart = sXML.indexOf("<!--");
+        if (xml.contains("<!--")) {
+            while (xml.contains("<!--")) {
+                int start = xml.indexOf("<!--");
                 // next line is guaranteed to find something, things we already checked this is valid XML
-                int iEnd = sXML.indexOf("-->", iStart);
-                sXML = sXML.substring(0, iStart) + sXML.substring(iEnd + 3);
+                int end = xml.indexOf("-->", start);
+                xml = xml.substring(0, start) + xml.substring(end + 3);
             }
         }
         //m_sXMLInput.get().m_sValue.setValue("<![CDATA[" + m_sXML + "]]>", m_sXMLInput.get());
-        sXMLInput.setValue("<![CDATA[" + sXML + "]]>", this);
+        xMLInput.setValue("<![CDATA[" + xml + "]]>", this);
 
         connectors = connectorsInput.get();
-//		int nConnectors = connections.get().size();
-//		sSrcIDs = new String[nConnectors];
-//		sTargetIDs = new String[nConnectors];
-//		sTargetInputs = new String[nConnectors];
-////		conditions = new ConnectCondition[nConnectors];
+    	} catch (IllegalAccessException | ClassNotFoundException | InstantiationException e) {
+    		throw new IllegalArgumentException(e.getMessage());
+    	}
+//		int connectors = connections.get().size();
+//		srcIDs = new String[connectors];
+//		targetIDs = new String[connectors];
+//		targetInputs = new String[connectors];
+////		conditions = new ConnectCondition[connectors];
 //
-//		for (int i = 0; i < nConnectors; i++) {
+//		for (int i = 0; i < connectors; i++) {
 //			BeautiConnector connector = connections.get().get(i);
-//			sSrcIDs[i] = connector.sSourceID.get();
-//			sTargetIDs[i] = connector.sTargetID.get();
-//			sTargetInputs[i] = connector.sInputName.get();
+//			srcIDs[i] = connector.sourceID.get();
+//			targetIDs[i] = connector.targetID.get();
+//			targetInputs[i] = connector.inputName.get();
 ////			conditions[i] = connector.connectCondition.get(); 
 //		}
     }
@@ -108,11 +122,11 @@ public class BeautiSubTemplate extends BEASTObject {
      * pick up items that should be translated to BeautiConnectors
      * Remove any connector related code from DOM and return resulting XML as String
      */
-    private String processDoc(Document doc) throws Exception {
+    private String processDoc(Document doc) throws TransformerException {
         // find top level beast element
         final NodeList nodes = doc.getElementsByTagName("*");
         if (nodes == null || nodes.getLength() == 0) {
-            throw new Exception("Expected top level beast element in XML");
+            throw new IllegalArgumentException("Expected top level beast element in XML");
         }
         final Node topNode = nodes.item(0);
         // process top level elements
@@ -168,7 +182,7 @@ public class BeautiSubTemplate extends BEASTObject {
         	        						hasIDRef = false;
         	        					}
         	        					if (sourceID == null) {
-        	        						throw new Exception("idref and id not specified on element with name '" + name +"'");
+        	        						throw new RuntimeException("idref and id not specified on element with name '" + name +"'");
         	        					}
         	        					inputName = child2.getNodeName();
         	        					String name2 = XMLParser.getAttribute(child2, "name");
@@ -198,11 +212,11 @@ public class BeautiSubTemplate extends BEASTObject {
 	        						hasIDRef = false;
 	        					}
 	        					if (sourceID == null) {
-	        						throw new Exception("idref and id not specified on element with name '" + name +"'");
+	        						throw new RuntimeException("idref and id not specified on element with name '" + name +"'");
 	        					}
 	        					String condition = XMLParser.getAttribute(child, "beauti:if");
 	        					if (condition != null) {
-	        						Node ifNode = child.getAttributes().removeNamedItem("beauti:if");
+	        						child.getAttributes().removeNamedItem("beauti:if");
 	        					}
 	
 	        					BeautiConnector connector = new BeautiConnector(sourceID, targetID, inputName, condition);
@@ -230,76 +244,76 @@ public class BeautiSubTemplate extends BEASTObject {
 	    Transformer transformer = tf.newTransformer();
 	    transformer.setOutputProperty(OutputKeys.INDENT, "yes");
 	    transformer.transform(domSource, result);
-	    String sXML = writer.toString();
-	    sXML = sXML.substring(sXML.indexOf("<beast xmlns:beauti=\"http://beast2.org\">") + 40, sXML.lastIndexOf("</beast>"));
-	    return sXML;
+	    String xml = writer.toString();
+	    xml = xml.substring(xml.indexOf("<beast xmlns:beauti=\"http://beast2.org\">") + 40, xml.lastIndexOf("</beast>"));
+	    return xml;
 	}
 
     public void setDoc(BeautiDoc doc) {
         this.doc = doc;
     }
 
-    void removeSubNet(BeautiSubTemplate template, PartitionContext context) throws Exception {
+    void removeSubNet(BeautiSubTemplate template, PartitionContext context)  {
         // disconnect all connection points in the template
         for (BeautiConnector connector : template.connectors) {
             doc.disconnect(connector, context);
         }
     }
     
-    void removeSubNet(Object o) throws Exception {
+    void removeSubNet(Object o)  {
         if (o == null) {
             // nothing to do
             return;
         }
-        BEASTInterface plugin = null;
+        BEASTInterface beastObject = null;
         if (o instanceof BEASTInterface) {
-            plugin = (BEASTInterface) o;
+            beastObject = (BEASTInterface) o;
         }
 
-        // find template that created this plugin
-        String sID = plugin.getID();
-        //String sPartition = BeautiDoc.parsePartition(sID);
-        sID = sID.substring(0, sID.indexOf("."));
+        // find template that created this beastObject
+        String id = beastObject.getID();
+        //String partition = BeautiDoc.parsePartition(id);
+        id = id.substring(0, id.indexOf("."));
         BeautiSubTemplate template = null;
         for (BeautiSubTemplate template2 : doc.beautiConfig.subTemplatesInput.get()) {
-            if (template2.matchesName(sID)) {
+            if (template2.matchesName(id)) {
                 template = template2;
                 break;
             }
         }
         if (template == null) {
-            throw new Exception("Cannot find template for removing " + plugin.getID());
+            throw new RuntimeException("Cannot find template for removing " + beastObject.getID());
         }
-        PartitionContext context = doc.getContextFor(plugin);
+        PartitionContext context = doc.getContextFor(beastObject);
         removeSubNet(template, context);
     }
 
-    public BEASTInterface createSubNet(PartitionContext partition, BEASTInterface plugin, Input<?> input, boolean init) throws Exception {
+    public BEASTInterface createSubNet(PartitionContext partition, BEASTInterface beastObject, Input<?> input, boolean init)  {
         removeSubNet(input.get());
-        if (sXML == null) {
+        if (xml == null) {
             // this is the NULL_TEMPLATE
-            input.setValue(null, plugin);
+            input.setValue(null, beastObject);
             return null;
         }
         BEASTInterface o = createSubNet(partition, doc.pluginmap, init);
-        input.setValue(o, plugin);
+        input.setValue(o, beastObject);
         return o;
     }
 
-    public BEASTInterface createSubNet(PartitionContext partition, List<BEASTInterface> list, int iItem, boolean init) throws Exception {
-        removeSubNet(list.get(iItem));
-        if (sXML == null) {
+    public BEASTInterface createSubNet(PartitionContext partition, List<BEASTInterface> list, int item, boolean init)  {
+        removeSubNet(list.get(item));
+        if (xml == null) {
             // this is the NULL_TEMPLATE
-            list.set(iItem, null);
+            list.set(item, null);
             return null;
         }
         BEASTInterface o = createSubNet(partition, doc.pluginmap, init);
-        list.set(iItem, o);
+        list.set(item, o);
         return o;
     }
 
-    public BEASTInterface createSubNet(PartitionContext partition, boolean init) throws Exception {
-        if (sXML == null) {
+    public BEASTInterface createSubNet(PartitionContext partition, boolean init)  {
+        if (xml == null) {
             // this is the NULL_TEMPLATE
             return null;
         }
@@ -309,36 +323,36 @@ public class BeautiSubTemplate extends BEASTObject {
 
 
     BEASTInterface createSubNet(Alignment data, BeautiDoc doc, boolean init) {
-        String sPartition = data.getID();
-        HashMap<String, BEASTInterface> sIDMap = doc.pluginmap;//new HashMap<String, Plugin>();
-        sIDMap.put(sPartition, data);
-        return createSubNet(new PartitionContext(sPartition), sIDMap, init);
+        String partition = data.getID();
+        HashMap<String, BEASTInterface> idMap = doc.pluginmap;//new HashMap<>();
+        idMap.put(partition, data);
+        return createSubNet(new PartitionContext(partition), idMap, init);
     }
 
-    private BEASTInterface createSubNet(PartitionContext context, /*BeautiDoc doc,*/ HashMap<String, BEASTInterface> sIDMap, boolean init) {
+    private BEASTInterface createSubNet(PartitionContext context, /*BeautiDoc doc,*/ HashMap<String, BEASTInterface> idMap, boolean init) {
         // wrap in a beast element with appropriate name spaces
         String _sXML = "<beast version='2.0' \n" +
                 "namespace='beast.app.beauti:beast.core:beast.evolution.branchratemodel:beast.evolution.speciation:beast.evolution.tree.coalescent:beast.core.util:beast.evolution.nuc:beast.evolution.operators:beast.evolution.sitemodel:beast.evolution.substitutionmodel:beast.evolution.likelihood:beast.evolution:beast.math.distributions'>\n" +
-                sXML +
+                xml +
                 "</beast>\n";
 
         // resolve alignment references
         _sXML = _sXML.replaceAll("idref=[\"']data['\"]", "idref='" + context.partition + "'");
         _sXML = _sXML.replaceAll("[\"']@data['\"]", "'@" + context.partition + "'");
         // ensure uniqueness of IDs
-        _sXML = BeautiDoc.translatePartitionNames(_sXML, context);//_sXML.replaceAll("\\$\\(n\\)", sPartition);
+        _sXML = BeautiDoc.translatePartitionNames(_sXML, context);//_sXML.replaceAll("\\$\\(n\\)", partition);
 
         XMLParser parser = new XMLParser();
         parser.setRequiredInputProvider(doc, context);
-        List<BEASTInterface> plugins = null;
+        List<BEASTInterface> beastObjects = null;
         try {
-            plugins = parser.parseTemplate(_sXML, sIDMap, true);
-            for (BEASTInterface plugin : plugins) {
-                doc.addPlugin(plugin);
+            beastObjects = parser.parseTemplate(_sXML, idMap, true);
+            for (BEASTInterface beastObject : beastObjects) {
+                doc.addPlugin(beastObject);
                 try {
-                	System.err.println("Adding " + plugin.getClass().getName() + " " + plugin);
+                	Log.warning.println("Adding " + beastObject.getClass().getName() + " " + beastObject);
                 } catch (Exception e) {
-                	System.err.println("Adding " + plugin.getClass().getName());
+                	Log.err.println("Adding " + beastObject.getClass().getName());
 				}
             }
 
@@ -346,12 +360,12 @@ public class BeautiSubTemplate extends BEASTObject {
                 if (init && connector.atInitialisationOnly()) {// ||
                     doc.connect(connector, context);
                 }
-                //System.out.println(connector.sSourceID + " == " + connector.sTargetID);
-                if (connector.sTargetID != null && connector.sTargetID.equals("prior")) {
-                	Log.warning.println(">>> No description for connector " + connector.sSourceID + " == " + connector.sTargetID);
+                //System.out.println(connector.sourceID + " == " + connector.targetID);
+                if (connector.targetID != null && connector.targetID.equals("prior")) {
+                	Log.warning.println(">>> No description for connector " + connector.sourceID + " == " + connector.targetID);
                 }
                 if (connector.getTipText() != null) {
-                	String ID = BeautiDoc.translatePartitionNames(connector.sSourceID, context);
+                	String ID = BeautiDoc.translatePartitionNames(connector.sourceID, context);
                 	String tipText = BeautiDoc.translatePartitionNames(connector.getTipText(), context).trim().replaceAll("\\s+", " ");
                 	//System.out.println(ID + " -> " + tipText);
                     doc.tipTextMap.put(ID, tipText);
@@ -362,7 +376,7 @@ public class BeautiSubTemplate extends BEASTObject {
                 String[] inputs = suppressedInputs.get().split(",");
                 for (String input : inputs) {
                     input = input.trim();
-                    doc.beautiConfig.suppressPlugins.add(input);
+                    doc.beautiConfig.suppressBEASTObjects.add(input);
                 }
             }
 
@@ -370,7 +384,7 @@ public class BeautiSubTemplate extends BEASTObject {
                 String[] inputs = inlineInput.get().split(",");
                 for (String input : inputs) {
                     input = input.trim();
-                    doc.beautiConfig.inlinePlugins.add(input);
+                    doc.beautiConfig.inlineBEASTObject.add(input);
                 }
             }
 
@@ -378,7 +392,7 @@ public class BeautiSubTemplate extends BEASTObject {
                 String[] inputs = collapsedInput.get().split(",");
                 for (String input : inputs) {
                     input = input.trim();
-                    doc.beautiConfig.collapsedPlugins.add(input);
+                    doc.beautiConfig.collapsedBEASTObjects.add(input);
                 }
             }
 
@@ -387,13 +401,13 @@ public class BeautiSubTemplate extends BEASTObject {
             e.printStackTrace();
         }
 
-        if (sMainID.equals("[top]")) {
-            return plugins.get(0);
+        if (mainID.equals("[top]")) {
+            return beastObjects.get(0);
         }
 
-        String sID = sMainID;
-        sID = BeautiDoc.translatePartitionNames(sID, context); //sID.replaceAll("\\$\\(n\\)", sPartition);
-        BEASTInterface plugin = doc.pluginmap.get(sID);
+        String id = mainID;
+        id = BeautiDoc.translatePartitionNames(id, context); //id.replaceAll("\\$\\(n\\)", partition);
+        BEASTInterface beastObject = doc.pluginmap.get(id);
 
         if (this == doc.beautiConfig.partitionTemplate.get()) {
             // HACK: need to make sure the subst model is of the correct type
@@ -432,31 +446,31 @@ public class BeautiSubTemplate extends BEASTObject {
             }
         }
 
-        //System.err.println(new XMLProducer().toXML(plugin));
-        return plugin;
+        //System.err.println(new XMLProducer().toXML(beastObject));
+        return beastObject;
     }
 
     public String getMainID() {
-        return sMainID;
+        return mainID;
     }
 
 
     @Override
     public String toString() {
-        String sID = getID();
-        sID = sID.replaceAll("([a-z])([A-Z])", "$1 $2");
-        return sID;
+        String id = getID();
+        id = id.replaceAll("([a-z])([A-Z])", "$1 $2");
+        return id;
     }
 
 
-    public boolean matchesName(String sID) {
-        if (getMainID().replaceAll(".\\$\\(n\\)", "").equals(sID)) {
+    public boolean matchesName(String id) {
+        if (getMainID().replaceAll(".\\$\\(n\\)", "").equals(id)) {
             return true;
         }
-        if (getMainID().replaceAll("..:\\$\\(n\\)", "").equals(sID)) {
+        if (getMainID().replaceAll("..:\\$\\(n\\)", "").equals(id)) {
             return true;
         }
-        if (sShortClassName != null && sShortClassName.equals(sID)) {
+        if (shortClassName != null && shortClassName.equals(id)) {
             return true;
         }
         return false;
diff --git a/src/beast/app/beauti/ClockModelListInputEditor.java b/src/beast/app/beauti/ClockModelListInputEditor.java
index 92455f3..abbba2f 100644
--- a/src/beast/app/beauti/ClockModelListInputEditor.java
+++ b/src/beast/app/beauti/ClockModelListInputEditor.java
@@ -2,8 +2,6 @@ package beast.app.beauti;
 
 
 import java.awt.Color;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -13,13 +11,13 @@ import javax.swing.JTextField;
 
 import beast.app.draw.ListInputEditor;
 import beast.app.draw.SmallLabel;
+import beast.core.BEASTInterface;
 import beast.core.Input;
 import beast.core.MCMC;
 import beast.core.Operator;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 import beast.core.parameter.IntegerParameter;
 import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.branchratemodel.BranchRateModel;
 import beast.evolution.operators.DeltaExchangeOperator;
@@ -30,8 +28,8 @@ import beast.evolution.operators.DeltaExchangeOperator;
 
 public class ClockModelListInputEditor extends ListInputEditor {
     private static final long serialVersionUID = 1L;
-    List<JTextField> textFields = new ArrayList<JTextField>();
-    List<Operator> operators = new ArrayList<Operator>();
+    List<JTextField> textFields = new ArrayList<>();
+    List<Operator> operators = new ArrayList<>();
 
 	public ClockModelListInputEditor(BeautiDoc doc) {
 		super(doc);
@@ -55,34 +53,30 @@ public class ClockModelListInputEditor extends ListInputEditor {
     protected SmallLabel fixMeanRatesValidateLabel;
     
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
     	fixMeanRatesCheckBox = new JCheckBox("Fix mean rate of clock models");
     	m_buttonStatus = ButtonStatus.NONE;
-    	super.init(input, plugin, itemNr, bExpandOption, bAddButtons);
+    	super.init(input, beastObject, itemNr, isExpandOption, addButtons);
     	
 		List<Operator> operators = ((MCMC) doc.mcmc.get()).operatorsInput.get();
-    	fixMeanRatesCheckBox.addActionListener(new ActionListener() {
-			
-			@Override
-			public void actionPerformed(ActionEvent e) {
+    	fixMeanRatesCheckBox.addActionListener(e -> {
 				JCheckBox averageRatesBox = (JCheckBox) e.getSource();
 				boolean averageRates = averageRatesBox.isSelected();
-				List<Operator> operators = ((MCMC) doc.mcmc.get()).operatorsInput.get();
+				List<Operator> operators2 = ((MCMC) doc.mcmc.get()).operatorsInput.get();
 				if (averageRates) {
 					// connect DeltaExchangeOperator
-					if (!operators.contains(operator)) {
-						operators.add(operator);
+					if (!operators2.contains(operator)) {
+						operators2.add(operator);
 					}
 					// set up relative weights
 					setUpOperator();
 				} else {
-					operators.remove(operator);
+					operators2.remove(operator);
 					fixMeanRatesValidateLabel.setVisible(false);
 					repaint();
 				}
-			}
+			});
 
-		});
     	operator = (DeltaExchangeOperator) doc.pluginmap.get("FixMeanRatesOperator");
     	if (operator == null) {
     		operator = new DeltaExchangeOperator();
@@ -111,7 +105,7 @@ public class ClockModelListInputEditor extends ListInputEditor {
     @Override
     public void validateInput() {
     	super.validateInput();
-    	System.err.println("validateInput()");
+    	Log.warning.println("validateInput()");
     }
     
     /** set up relative weights and parameter input **/
@@ -120,7 +114,7 @@ public class ClockModelListInputEditor extends ListInputEditor {
     	List<RealParameter> parameters = operator.parameterInput.get();
     	parameters.clear();
     	double commonClockRate = -1;
-    	boolean bAllClocksAreEqual = true;
+    	boolean isAllClocksAreEqual = true;
 		try {
 	    	for (int i = 0; i < doc.alignments.size(); i++) {
 	    		Alignment data = doc.alignments.get(i); 
@@ -133,13 +127,13 @@ public class ClockModelListInputEditor extends ListInputEditor {
 	    				commonClockRate = clockRate.valuesInput.get().get(0);
 	    			} else {
 	    				if (Math.abs(commonClockRate - clockRate.valuesInput.get().get(0)) > 1e-10) {
-	    					bAllClocksAreEqual = false;
+	    					isAllClocksAreEqual = false;
 	    				}
 	    			}
     				weights += weight + " ";
 	    			parameters.add(clockRate);
 	    		}
-	    		//doc.bAutoSetClockRate = false;
+	    		//doc.autoSetClockRate = false;
 	    	}
 	    	if (!fixMeanRatesCheckBox.isSelected()) {
 	    		fixMeanRatesValidateLabel.setVisible(false);
@@ -156,7 +150,7 @@ public class ClockModelListInputEditor extends ListInputEditor {
 			weightParameter.setID("weightparameter");
 			weightParameter.isEstimatedInput.setValue(false, weightParameter);
 	    	operator.parameterWeightsInput.setValue(weightParameter, operator);
-	    	if (!bAllClocksAreEqual) {
+	    	if (!isAllClocksAreEqual) {
 	    		fixMeanRatesValidateLabel.setVisible(true);
 	    		fixMeanRatesValidateLabel.m_circleColor = Color.orange;
 	    		fixMeanRatesValidateLabel.setToolTipText("Not all clocks are equal. Are you sure this is what you want?");
@@ -172,7 +166,7 @@ public class ClockModelListInputEditor extends ListInputEditor {
 	    		fixMeanRatesValidateLabel.setVisible(false);
 	    	}
 			repaint();
-    		//doc.bAutoSetClockRate = true;
+    		//doc.autoSetClockRate = true;
 		} catch (Exception e) {
 			// TODO Auto-generated catch block
 			e.printStackTrace();
diff --git a/src/beast/app/beauti/ClonePartitionPanel.java b/src/beast/app/beauti/ClonePartitionPanel.java
index 81c3c03..29c1bf5 100644
--- a/src/beast/app/beauti/ClonePartitionPanel.java
+++ b/src/beast/app/beauti/ClonePartitionPanel.java
@@ -1,30 +1,36 @@
 package beast.app.beauti;
 
-import beast.app.beauti.guiutil.S11InitialSelection;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.DefaultListModel;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
 
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import beast.app.beauti.guiutil.S11InitialSelection;
 
 
 public class ClonePartitionPanel extends JPanel {
     private static final long serialVersionUID = 1L;
 
     final BeautiPanel beautiPanel;
-    final JComboBox cloneFromComboBox;
+    final JComboBox<Object> cloneFromComboBox;
     final JButton okButton = new JButton("OK");
 
 	public ClonePartitionPanel(BeautiPanel beautiPanel) {
         this.beautiPanel = beautiPanel;
 
-        DefaultListModel listModel = beautiPanel.listModel;
+        DefaultListModel<String> listModel = beautiPanel.listModel;
         Object[] models = new Object[listModel.getSize()];
         for(int i=0; i < listModel.getSize(); i++){
             models[i] = listModel.getElementAt(i);
         }
 
-        cloneFromComboBox = new JComboBox(models);
+        cloneFromComboBox = new JComboBox<>(models);
         // has to be editable
         cloneFromComboBox.setEditable(true);
         // change the editor's document
@@ -53,11 +59,9 @@ public class ClonePartitionPanel extends JPanel {
         okButton.setName("ok");
         okButton.setToolTipText("Click to clone configuration from the above selected partition " +
                 "into all selected partitions on the left.");
-        okButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+        okButton.addActionListener(e -> {
                 clonePartitions();
-            }
-        });
+            });
         add(okButton);
 
     } // init
@@ -65,7 +69,7 @@ public class ClonePartitionPanel extends JPanel {
     protected void clonePartitions() {
         String sourceId = cloneFromComboBox.getSelectedItem().toString();
 
-        for (Object targetId : beautiPanel.listOfPartitions.getSelectedValues()) {
+        for (Object targetId : beautiPanel.listOfPartitions.getSelectedValuesList()) {
              beautiPanel.cloneFrom(sourceId, targetId.toString());
         }
     }
diff --git a/src/beast/app/beauti/Fragment.java b/src/beast/app/beauti/Fragment.java
index 258bb6c..3bc63ec 100644
--- a/src/beast/app/beauti/Fragment.java
+++ b/src/beast/app/beauti/Fragment.java
@@ -9,10 +9,10 @@ import beast.core.Input;
 
 @Description("Dummy container for representing template fragment")
 public class Fragment extends BEASTObject {
-	public Input<String> valueInput = new Input<String>("value","for representing CDATA section");
-	public Input<List<BeautiConnector>> connectorsInput = new Input<List<BeautiConnector>>("connect", "for representing BEAUti connectors", new ArrayList<>());
+	final public Input<String> valueInput = new Input<>("value","for representing CDATA section");
+	final public Input<List<BeautiConnector>> connectorsInput = new Input<>("connect", "for representing BEAUti connectors", new ArrayList<>());
 
 	@Override
-	public void initAndValidate() throws Exception {
+	public void initAndValidate() {
 	}
 }
diff --git a/src/beast/app/beauti/FrequenciesInputEditor.java b/src/beast/app/beauti/FrequenciesInputEditor.java
index fc63075..3cc8ab9 100644
--- a/src/beast/app/beauti/FrequenciesInputEditor.java
+++ b/src/beast/app/beauti/FrequenciesInputEditor.java
@@ -1,18 +1,14 @@
 package beast.app.beauti;
 
 
-import java.awt.Component;
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 
-import javax.swing.Box;
 import javax.swing.JComboBox;
 import javax.swing.JComponent;
 
 import beast.app.draw.BEASTObjectInputEditor;
-import beast.core.Input;
-import beast.core.BEASTObject;
 import beast.core.BEASTInterface;
+import beast.core.Input;
 import beast.core.parameter.RealParameter;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.substitutionmodel.Frequencies;
@@ -24,7 +20,7 @@ public class FrequenciesInputEditor extends BEASTObjectInputEditor {
     Alignment alignment;
 
     private static final long serialVersionUID = 1L;
-    boolean bUseDefaultBehavior;
+    boolean useDefaultBehavior;
 
 	public FrequenciesInputEditor(BeautiDoc doc) {
 		super(doc);
@@ -37,17 +33,17 @@ public class FrequenciesInputEditor extends BEASTObjectInputEditor {
     }
 
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-        super.init(input, plugin, itemNr, bExpandOption, bAddButtons);
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+        super.init(input, beastObject, itemNr, isExpandOption, addButtons);
     } // init
 
 
     @Override
     /** suppress combobox **/
-    protected void addComboBox(JComponent box, Input<?> input, BEASTInterface plugin) {
+    protected void addComboBox(JComponent box, Input<?> input, BEASTInterface beastObject) {
         Frequencies freqs = (Frequencies) input.get();
 
-        JComboBox comboBox = new JComboBox(new String[]{"Estimated", "Empirical", "All equal"});
+        JComboBox<String> comboBox = new JComboBox<>(new String[]{"Estimated", "Empirical", "All equal"});
         if (freqs.frequenciesInput.get() != null) {
             comboBox.setSelectedIndex(0);
             freqsParameter = freqs.frequenciesInput.get();
@@ -61,14 +57,13 @@ public class FrequenciesInputEditor extends BEASTObjectInputEditor {
             alignment = freqs.dataInput.get();
             freqsParameter = (RealParameter) getCandidate(freqs.frequenciesInput, freqs);
         }
-        comboBox.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                JComboBox comboBox = (JComboBox) e.getSource();
-                int iSelected = comboBox.getSelectedIndex();
-                Frequencies freqs = (Frequencies) m_input.get();
+        comboBox.addActionListener(e -> {
+                //@SuppressWarnings("unchecked")
+				//JComboBox<String> comboBox = (JComboBox<String>) e.getSource();
+                int selected = comboBox.getSelectedIndex();
+                //Frequencies freqs = (Frequencies) m_input.get();
                 try {
-                    switch (iSelected) {
+                    switch (selected) {
                         case 0:
                             freqs.frequenciesInput.setValue(freqsParameter, freqs);
                             freqs.dataInput.setValue(null, freqs);
@@ -88,17 +83,16 @@ public class FrequenciesInputEditor extends BEASTObjectInputEditor {
                     e2.printStackTrace();
                 }
                 //System.err.println(freqs.frequencies.get() + " " + freqs.m_data.get() + " " + freqs.m_bEstimate.get());
-            }
-        });
+            });
         box.add(comboBox);
     }
 
     private BEASTInterface getCandidate(Input<?> input, Frequencies freqs) {
         return getDoc().getPartition(freqs);
-//		List<String> sCandidates = PluginPanel.getAvailablePlugins(input, freqs, null);
-//		String sID = sCandidates.get(0);
-//		Plugin plugin = PluginPanel.g_plugins.get(sID);
-//		return plugin;
+//		List<String> candidates = PluginPanel.getAvailablePlugins(input, freqs, null);
+//		String id = candidates.get(0);
+//		BEASTObject beastObject = PluginPanel.g_plugins.get(id);
+//		return beastObject;
     }
 
 
diff --git a/src/beast/app/beauti/GeneTreeForSpeciesTreeDistributionInputEditor.java b/src/beast/app/beauti/GeneTreeForSpeciesTreeDistributionInputEditor.java
index 4da95a0..d1b520b 100644
--- a/src/beast/app/beauti/GeneTreeForSpeciesTreeDistributionInputEditor.java
+++ b/src/beast/app/beauti/GeneTreeForSpeciesTreeDistributionInputEditor.java
@@ -1,16 +1,12 @@
 package beast.app.beauti;
 
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
 import javax.swing.Box;
 import javax.swing.JComboBox;
 import javax.swing.JLabel;
 
 import beast.app.draw.InputEditor;
-import beast.core.Input;
-import beast.core.BEASTObject;
 import beast.core.BEASTInterface;
+import beast.core.Input;
 import beast.evolution.speciation.GeneTreeForSpeciesTreeDistribution;
 
 
@@ -28,79 +24,77 @@ public class GeneTreeForSpeciesTreeDistributionInputEditor extends InputEditor.B
 	}
 
 	@Override
-	public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-        m_bAddButtons = bAddButtons;
+	public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+        m_bAddButtons = addButtons;
         m_input = input;
-        m_plugin = plugin;
+        m_beastObject = beastObject;
         this.itemNr= itemNr;
-        String sID = plugin.getID();
-        if (sID.contains(".t:")) {
-        	sID = sID.substring(sID.indexOf(".t:") + 3);
+        String id = beastObject.getID();
+        if (id.contains(".t:")) {
+        	id = id.substring(id.indexOf(".t:") + 3);
         }
-        add(new JLabel("Gene Tree " + sID));
+        add(new JLabel("Gene Tree " + id));
         add(Box.createGlue());
 	}
 	
 	static final int OTHER = 3;
-	String [] sValues = new String[]{"autosomal_nuclear", "X", "Y or mitochondrial", "other"};
-	Double [] fValues = new Double[]{2.0, 1.5, 0.5, -1.0};
-	JComboBox m_selectPluginBox;
+	String [] valuesString = new String[]{"autosomal_nuclear", "X", "Y or mitochondrial", "other"};
+	Double [] _values = new Double[]{2.0, 1.5, 0.5, -1.0};
+	JComboBox<String> m_selectBeastObjectBox;
 	
 	public InputEditor createPloidyEditor() {
 		InputEditor editor = new InputEditor.Base(doc) {
+			private static final long serialVersionUID = 1L;
+
 			@Override
 			public Class<?> type() {
-				// TODO Auto-generated method stub
 				return null;
 			}
 			
 			@Override
-			public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-				m_plugin = plugin;
+			public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+				m_beastObject = beastObject;
 				m_input = input;
-				m_bAddButtons = bAddButtons;
+				m_bAddButtons = addButtons;
 				this.itemNr = itemNr;
 				addInputLabel();
 				
-	            m_selectPluginBox = new JComboBox(sValues);
+	            m_selectBeastObjectBox = new JComboBox<>(valuesString);
 	            setSelection();
-	            String sSelectString = input.get().toString();
-	            m_selectPluginBox.setSelectedItem(sSelectString);
+	            String selectString = input.get().toString();
+	            m_selectBeastObjectBox.setSelectedItem(selectString);
 
-	            m_selectPluginBox.addActionListener(new ActionListener() {
-	                // implements ActionListener
-	                public void actionPerformed(ActionEvent e) {
-	                    int i = m_selectPluginBox.getSelectedIndex();
+	            m_selectBeastObjectBox.addActionListener(e -> {
+	                    int i = m_selectBeastObjectBox.getSelectedIndex();
 	                    if (i == OTHER) {
 	                    	setSelection();
 	                    	return;
 	                    }
 	                    try {
-	                    	setValue(fValues[i]);
-	                        //lm_input.setValue(sSelected, m_plugin);
+	                    	setValue(_values[i]);
+	                        //lm_input.setValue(selected, m_beastObject);
 	                    } catch (Exception e1) {
 	                        e1.printStackTrace();
 	                    }
-	                }
-	            });
-	            m_selectPluginBox.setToolTipText(input.getHTMLTipText());
-	            add(m_selectPluginBox);
+	                });
+	            m_selectBeastObjectBox.setToolTipText(input.getHTMLTipText());
+	            add(m_selectBeastObjectBox);
 	            add(Box.createGlue());
 			}
 
 			private void setSelection() {
 				Double value = (Double) m_input.get();
-				m_selectPluginBox.setSelectedIndex(OTHER);
-				for (int i = 0; i < fValues.length; i++) {
-					if (value.equals(fValues[i])) {
-						m_selectPluginBox.setSelectedIndex(i);
+				m_selectBeastObjectBox.setSelectedIndex(OTHER);
+				for (int i = 0; i < _values.length; i++) {
+					if (value.equals(_values[i])) {
+						m_selectBeastObjectBox.setSelectedIndex(i);
 					}
 				}
 			}
 			
 		};
-		editor.init(((GeneTreeForSpeciesTreeDistribution)m_plugin).ploidyInput, 
-			m_plugin, -1, ExpandOption.FALSE, true);
+		editor.init(((GeneTreeForSpeciesTreeDistribution)m_beastObject).ploidyInput, 
+			m_beastObject, -1, ExpandOption.FALSE, true);
 		return editor;
 	}
     
diff --git a/src/beast/app/beauti/GuessPatternDialog.java b/src/beast/app/beauti/GuessPatternDialog.java
index a880f12..48a54dc 100644
--- a/src/beast/app/beauti/GuessPatternDialog.java
+++ b/src/beast/app/beauti/GuessPatternDialog.java
@@ -1,14 +1,10 @@
 package beast.app.beauti;
 
-import beast.app.util.Utils;
-
-import javax.swing.*;
-import javax.swing.border.EmptyBorder;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
@@ -16,6 +12,24 @@ import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
+import javax.swing.ButtonGroup;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JSeparator;
+import javax.swing.JTextField;
+import javax.swing.border.EmptyBorder;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import beast.app.util.Utils;
+import beast.core.util.Log;
+
 
 public class GuessPatternDialog extends JDialog {
     private static final long serialVersionUID = 1L;
@@ -45,17 +59,17 @@ public class GuessPatternDialog extends JDialog {
     Component m_parent;
     JPanel guessPanel;
     ButtonGroup group;
-    JRadioButton bUseEverything = new JRadioButton("use everything");
-    JRadioButton bSplitOnChar = new JRadioButton("split on character");
-    JRadioButton bUseRegexp = new JRadioButton("use regular expression");
-    JRadioButton bReadFromFile = new JRadioButton("read from file");
+    JRadioButton useEverything = new JRadioButton("use everything");
+    JRadioButton isSplitOnChar = new JRadioButton("split on character");
+    JRadioButton useRegexp = new JRadioButton("use regular expression");
+    JRadioButton readFromFile = new JRadioButton("read from file");
 
     int m_location = 0;
     int m_splitlocation = 0;
     String m_sDelimiter = ".";
     JTextField textRegExp;
-    JComboBox combo;
-    JComboBox combo_1;
+    JComboBox<String> combo;
+    JComboBox<String> combo_1;
     String pattern;
 
     public String getPattern() {
@@ -90,39 +104,31 @@ public class GuessPatternDialog extends JDialog {
         guessPanel.setLayout(gbl_guessPanel);
 
         group = new ButtonGroup();
-        group.add(bUseEverything);
-        group.add(bSplitOnChar);
-        group.add(bUseRegexp);
-        group.add(bReadFromFile);
-        group.setSelected(bUseEverything.getModel(), true);
-        bUseEverything.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+        group.add(useEverything);
+        group.add(isSplitOnChar);
+        group.add(useRegexp);
+        group.add(readFromFile);
+        group.setSelected(useEverything.getModel(), true);
+        useEverything.addActionListener(e -> {
                 updateFields();
-            }
-        });
-        bUseEverything.setName(bUseEverything.getText());
-        bSplitOnChar.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+            });
+        useEverything.setName(useEverything.getText());
+        isSplitOnChar.addActionListener(e -> {
                 updateFields();
-            }
-        });
-        bSplitOnChar.setName(bSplitOnChar.getText());
-        bUseRegexp.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+            });
+        isSplitOnChar.setName(isSplitOnChar.getText());
+        useRegexp.addActionListener(e -> {
                 updateFields();
-            }
-        });
-        bUseRegexp.setName(bUseRegexp.getText());
-        bReadFromFile.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+            });
+        useRegexp.setName(useRegexp.getText());
+        readFromFile.addActionListener(e -> {
                 updateFields();
-            }
-        });
-        bReadFromFile.setName(bReadFromFile.getText());
+            });
+        readFromFile.setName(readFromFile.getText());
 
-        createDelimiterBox(bUseEverything);
-        createSplitBox(bSplitOnChar);
-        createRegExtpBox(bUseRegexp);
+        createDelimiterBox(useEverything);
+        createSplitBox(isSplitOnChar);
+        createRegExtpBox(useRegexp);
 
         textRegExp = new JTextField();
         textRegExp.setText(pattern);
@@ -139,17 +145,17 @@ public class GuessPatternDialog extends JDialog {
         textRegExp.getDocument().addDocumentListener(new DocumentListener() {
             @Override
             public void removeUpdate(DocumentEvent e) {
-                bUseRegexp.setSelected(true);
+                useRegexp.setSelected(true);
             }
 
             @Override
             public void insertUpdate(DocumentEvent e) {
-                bUseRegexp.setSelected(true);
+                useRegexp.setSelected(true);
             }
 
             @Override
             public void changedUpdate(DocumentEvent e) {
-                bUseRegexp.setSelected(true);
+                useRegexp.setSelected(true);
             }
         });
 
@@ -168,19 +174,17 @@ public class GuessPatternDialog extends JDialog {
         gbc_rdbtnReadFromFile.insets = new Insets(0, 0, 5, 5);
         gbc_rdbtnReadFromFile.gridx = 0;
         gbc_rdbtnReadFromFile.gridy = 10;
-        guessPanel.add(bReadFromFile, gbc_rdbtnReadFromFile);
+        guessPanel.add(readFromFile, gbc_rdbtnReadFromFile);
 
         btnBrowse = new JButton("Browse");
-        btnBrowse.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+        btnBrowse.addActionListener(e -> {
                 File file = Utils.getLoadFile("Load trait from file", new File(Beauti.g_sDir), "Select trait file", "dat","txt");
                 if (file != null) {
                     txtFile.setText(file.getPath());
-                    bReadFromFile.setSelected(true);
+                    readFromFile.setSelected(true);
                     updateFields();
                 }
-            }
-        });
+            });
 
         txtFile = new JTextField();
         txtFile.setText("File");
@@ -200,11 +204,9 @@ public class GuessPatternDialog extends JDialog {
 
         JButton btnHelp = new JButton("?");
         btnHelp.setToolTipText("Show format of trait file");
-        btnHelp.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+        btnHelp.addActionListener(e -> {
                 JOptionPane.showMessageDialog(m_parent, EXAMPLE_FORMAT);
-            }
-        });
+            });
         GridBagConstraints gbc_btnHelp = new GridBagConstraints();
         gbc_btnHelp.insets = new Insets(0, 0, 5, 5);
         gbc_btnHelp.gridx = 4;
@@ -214,11 +216,9 @@ public class GuessPatternDialog extends JDialog {
 
         chckbxAddFixedValue = new JCheckBox("Add fixed value");
         chckbxAddFixedValue.setName("Add fixed value");
-        chckbxAddFixedValue.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+        chckbxAddFixedValue.addActionListener(e -> {
                 updateFields();
-            }
-        });
+            });
 
         separator_5 = new JSeparator();
         separator_5.setPreferredSize(new Dimension(5,1));
@@ -248,11 +248,9 @@ public class GuessPatternDialog extends JDialog {
 
         chckbxUnlessLessThan = new JCheckBox("Unless less than...");
         chckbxUnlessLessThan.setName("Unless less than");
-        chckbxUnlessLessThan.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+        chckbxUnlessLessThan.addActionListener(e -> {
                 updateFields();
-            }
-        });
+            });
         GridBagConstraints gbc_chckbxUnlessLargerThan = new GridBagConstraints();
         gbc_chckbxUnlessLargerThan.anchor = GridBagConstraints.WEST;
         gbc_chckbxUnlessLargerThan.insets = new Insets(0, 0, 5, 5);
@@ -336,19 +334,19 @@ public class GuessPatternDialog extends JDialog {
         combo_1.setEnabled(false);
         lblAndTakeGroups.setEnabled(false);
         btnBrowse.setEnabled(false);
-        if (bUseEverything.isSelected()) {
+        if (useEverything.isSelected()) {
             textSplitChar.setEnabled(true);
             combo.setEnabled(true);
         }
-        if (bSplitOnChar.isSelected()) {
+        if (isSplitOnChar.isSelected()) {
             textSplitChar2.setEnabled(true);
             combo_1.setEnabled(true);
             lblAndTakeGroups.setEnabled(true);
         }
-        if (bUseRegexp.isSelected()) {
+        if (useRegexp.isSelected()) {
             textRegExp.setEnabled(true);
         }
-        if (bReadFromFile.isSelected()) {
+        if (readFromFile.isSelected()) {
             btnBrowse.setEnabled(true);
             txtFile.setEnabled(true);
         }
@@ -362,7 +360,7 @@ public class GuessPatternDialog extends JDialog {
         gbc.gridy = 1;
         guessPanel.add(b, gbc);
 
-        combo = new JComboBox(new String[] { "after first", "after last", "before first", "before last" });
+        combo = new JComboBox<>(new String[] { "after first", "after last", "before first", "before last" });
         combo.setName("delimiterCombo");
         GridBagConstraints gbc2 = new GridBagConstraints();
         gbc2.anchor = GridBagConstraints.WEST;
@@ -371,15 +369,13 @@ public class GuessPatternDialog extends JDialog {
         gbc2.gridx = 1;
         gbc2.gridy = 1;
         guessPanel.add(combo, gbc2);
-        combo.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                JComboBox combo = (JComboBox) e.getSource();
+        combo.addActionListener(e -> {
+                @SuppressWarnings("unchecked")
+				JComboBox<String> combo = (JComboBox<String>) e.getSource();
                 m_location = combo.getSelectedIndex();
-                bUseEverything.setSelected(true);
+                useEverything.setSelected(true);
                 updateFields();
-            }
-        });
+            });
     }
 
     private void createSplitBox(JRadioButton b) {
@@ -432,7 +428,7 @@ public class GuessPatternDialog extends JDialog {
         gbc_lblAndTakeGroups.gridy = 4;
         guessPanel.add(lblAndTakeGroups, gbc_lblAndTakeGroups);
 
-        combo_1 = new JComboBox(new String[] { "1", "2", "3", "4", "1-2", "2-3", "3-4", "1-3", "2-4" });
+        combo_1 = new JComboBox<>(new String[] { "1", "2", "3", "4", "1-2", "2-3", "3-4", "1-3", "2-4" });
         combo_1.setName("splitCombo");
         GridBagConstraints gbc_combo_1 = new GridBagConstraints();
         gbc_combo_1.anchor = GridBagConstraints.WEST;
@@ -440,15 +436,13 @@ public class GuessPatternDialog extends JDialog {
         gbc_combo_1.gridx = 4;
         gbc_combo_1.gridy = 4;
         guessPanel.add(combo_1, gbc_combo_1);
-        combo_1.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                JComboBox combo = (JComboBox) e.getSource();
+        combo_1.addActionListener(e -> {
+                @SuppressWarnings("unchecked")
+				JComboBox<String> combo = (JComboBox<String>) e.getSource();
                 m_splitlocation = combo.getSelectedIndex();
-                bSplitOnChar.setSelected(true);
+                isSplitOnChar.setSelected(true);
                 updateFields();
-            }
-        });
+            });
 
         separator_3 = new JSeparator();
         separator_3.setPreferredSize(new Dimension(5,1));
@@ -485,64 +479,64 @@ public class GuessPatternDialog extends JDialog {
             return Status.canceled;
         }
 
-        if (bUseEverything.getModel() == group.getSelection()) {
-            String sDelimiter = normalise(textSplitChar.getText());
+        if (useEverything.getModel() == group.getSelection()) {
+            String delimiter = normalise(textSplitChar.getText());
             switch (m_location) {
                 case 0: // "after first",
-                    pattern = "^[^" + sDelimiter + "]+" + sDelimiter + "(.*)$";
+                    pattern = "^[^" + delimiter + "]+" + delimiter + "(.*)$";
                     break;
                 case 1: // "after last",
-                    pattern = "^.*" + sDelimiter + "(.*)$";
+                    pattern = "^.*" + delimiter + "(.*)$";
                     break;
                 case 2: // "before first",
-                    pattern = "^([^" + sDelimiter + "]+)" + sDelimiter + ".*$";
+                    pattern = "^([^" + delimiter + "]+)" + delimiter + ".*$";
                     break;
                 case 3: // "before last"
-                    pattern = "^(.*)" + sDelimiter + ".*$";
+                    pattern = "^(.*)" + delimiter + ".*$";
                     break;
             }
         }
-        if (bSplitOnChar.getModel() == group.getSelection()) {
-            String sDelimiter = normalise(textSplitChar2.getText());
+        if (isSplitOnChar.getModel() == group.getSelection()) {
+            String delimiter = normalise(textSplitChar2.getText());
             switch (m_splitlocation) {
                 case 0: // "1"
-                    pattern = "^([^" + sDelimiter + "]+)" + ".*$";
+                    pattern = "^([^" + delimiter + "]+)" + ".*$";
                     break;
                 case 1: // "2"
-                    pattern = "^[^" + sDelimiter + "]+" + sDelimiter + "([^" + sDelimiter + "]+)" + ".*$";
+                    pattern = "^[^" + delimiter + "]+" + delimiter + "([^" + delimiter + "]+)" + ".*$";
                     break;
                 case 2: // "3"
-                    pattern = "^[^" + sDelimiter + "]+" + sDelimiter + "[^" + sDelimiter + "]+" + sDelimiter + "([^"
-                            + sDelimiter + "]+)" + ".*$";
+                    pattern = "^[^" + delimiter + "]+" + delimiter + "[^" + delimiter + "]+" + delimiter + "([^"
+                            + delimiter + "]+)" + ".*$";
                     break;
                 case 3: // "4"
-                    pattern = "^[^" + sDelimiter + "]+" + sDelimiter + "[^" + sDelimiter + "]+" + sDelimiter + "[^"
-                            + sDelimiter + "]+" + sDelimiter + "([^" + sDelimiter + "]+)" + ".*$";
+                    pattern = "^[^" + delimiter + "]+" + delimiter + "[^" + delimiter + "]+" + delimiter + "[^"
+                            + delimiter + "]+" + delimiter + "([^" + delimiter + "]+)" + ".*$";
                     break;
                 case 4: // "1-2"
-                    pattern = "^([^" + sDelimiter + "]+" + sDelimiter + "[^" + sDelimiter + "]+)" + ".*$";
+                    pattern = "^([^" + delimiter + "]+" + delimiter + "[^" + delimiter + "]+)" + ".*$";
                     break;
                 case 5: // "2-3"
-                    pattern = "^[^" + sDelimiter + "]+" + sDelimiter + "([^" + sDelimiter + "]+" + sDelimiter + "[^"
-                            + sDelimiter + "]+)" + ".*$";
+                    pattern = "^[^" + delimiter + "]+" + delimiter + "([^" + delimiter + "]+" + delimiter + "[^"
+                            + delimiter + "]+)" + ".*$";
                     break;
                 case 6: // "3-4"
-                    pattern = "^[^" + sDelimiter + "]+" + sDelimiter + "[^" + sDelimiter + "]+" + sDelimiter + "([^"
-                            + sDelimiter + "]+" + sDelimiter + "[^" + sDelimiter + "]+)" + ".*$";
+                    pattern = "^[^" + delimiter + "]+" + delimiter + "[^" + delimiter + "]+" + delimiter + "([^"
+                            + delimiter + "]+" + delimiter + "[^" + delimiter + "]+)" + ".*$";
                     break;
                 case 7: // "1-3"
-                    pattern = "^([^" + sDelimiter + "]+" + sDelimiter + "[^" + sDelimiter + "]+" + sDelimiter + "[^"
-                            + sDelimiter + "]+)" + ".*$";
+                    pattern = "^([^" + delimiter + "]+" + delimiter + "[^" + delimiter + "]+" + delimiter + "[^"
+                            + delimiter + "]+)" + ".*$";
                     break;
                 case 8: // "2-4"
-                    pattern = "^[^" + sDelimiter + "]+" + sDelimiter + "([^" + sDelimiter + "]+" + sDelimiter + "[^"
-                            + sDelimiter + "]+" + sDelimiter + "[^" + sDelimiter + "]+)" + ".*$";
+                    pattern = "^[^" + delimiter + "]+" + delimiter + "([^" + delimiter + "]+" + delimiter + "[^"
+                            + delimiter + "]+" + delimiter + "[^" + delimiter + "]+)" + ".*$";
             }
         }
-        if (bUseRegexp.getModel() == group.getSelection()) {
+        if (useRegexp.getModel() == group.getSelection()) {
             pattern = textRegExp.getText();
         }
-        if (bReadFromFile.getModel() == group.getSelection()) {
+        if (readFromFile.getModel() == group.getSelection()) {
             try {
                 BufferedReader fin = new BufferedReader(new FileReader(txtFile.getText()));
                 StringBuffer buf = new StringBuffer();
@@ -578,7 +572,7 @@ public class GuessPatternDialog extends JDialog {
         }
 
         if (optionPane.getValue() != null && optionPane.getValue().equals("OK")) {
-            System.err.println("Pattern = " + pattern);
+        	Log.warning.println("Pattern = " + pattern);
             return Status.pattern;
         } else {
             return Status.canceled;
@@ -586,20 +580,20 @@ public class GuessPatternDialog extends JDialog {
     }
 
     /**
-     * Converts the first character of sDelimiter into a substring suitable for
+     * Converts the first character of delimiter into a substring suitable for
      * inclusion in a regexp. This is done by expressing the character as an
      * octal escape.
      *
-     * @param sDelimiter first character of this string to be used as delimiter
+     * @param delimiter first character of this string to be used as delimiter
      * @return escaped octal representation of character
      */
-    private String normalise(String sDelimiter) {
+    private String normalise(String delimiter) {
 
-        if (sDelimiter.length() == 0) {
+        if (delimiter.length() == 0) {
             return ".";
         }
 
-        return String.format("\\0%o", (int)sDelimiter.charAt(0));
+        return String.format("\\0%o", (int)delimiter.charAt(0));
     }
 
     public String match(String s) {
diff --git a/src/beast/app/beauti/JPackageDialog.java b/src/beast/app/beauti/JPackageDialog.java
index ecf5407..61467c2 100644
--- a/src/beast/app/beauti/JPackageDialog.java
+++ b/src/beast/app/beauti/JPackageDialog.java
@@ -3,22 +3,20 @@ package beast.app.beauti;
 import beast.core.Description;
 import beast.util.AddOnManager;
 import beast.util.Package;
+import beast.util.PackageVersion;
 
 import javax.swing.*;
 import javax.swing.event.TableModelEvent;
 import javax.swing.table.AbstractTableModel;
-
-import com.sun.java.swing.SwingUtilities3;
-
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableModel;
 import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.io.File;
 import java.io.IOException;
-import java.util.ArrayList;
+import java.util.*;
 import java.util.List;
+import java.util.stream.Collectors;
 
 import static beast.util.AddOnManager.*;
 
@@ -35,11 +33,23 @@ public class JPackageDialog extends JPanel {
     JScrollPane scrollPane;
     JLabel jLabel;
     Box buttonBox;
-    JCheckBox allDepCheckBox = new JCheckBox("install/uninstall all dependencies", null, true);
     JFrame frame;
-    JTable dataTable = null;
-
-    List<Package> packages = new ArrayList<Package>();
+    PackageTable dataTable = null;
+
+    TreeMap<String, Package> packageMap = new TreeMap<>((s1,s2)->{
+    	if (s1.equals(AddOnManager.BEAST_PACKAGE)) {
+    		if (s2.equals(AddOnManager.BEAST_PACKAGE)) {
+    			return 0;
+    		}
+    		return -1;
+    	}
+    	if (s2.equals(AddOnManager.BEAST_PACKAGE)) {
+    		return 1;
+    	}
+    	return s1.compareToIgnoreCase(s2);
+    });
+
+    List<Package> packageList = null;
 
     boolean isRunning;
     Thread t;
@@ -50,17 +60,19 @@ public class JPackageDialog extends JPanel {
         setLayout(new BorderLayout());
 
 		createTable();
-        // update pacakges using a 30 second time out
+        // update packages using a 30 second time out
         isRunning = true;
         t = new Thread() {
-        	public void run() {
+        	@Override
+			public void run() {
                 resetPackages();
         		isRunning = false;
         	}
         };
         t.start();
     	Thread t2 = new Thread() {
-    		public void run() {
+    		@Override
+			public void run() {
     			try {
     				// wait 30 seconds
 					sleep(30000);
@@ -74,7 +86,7 @@ public class JPackageDialog extends JPanel {
 	    			}
 				} catch (InterruptedException e) {
 				}
-    		};
+    		}
     	};
     	t2.start();
         
@@ -100,13 +112,13 @@ public class JPackageDialog extends JPanel {
 
     private void createTable() {
         DataTableModel dataTableModel = new DataTableModel();
-        dataTable = new JTable(dataTableModel);
+        dataTable = new PackageTable(dataTableModel);
         
         double [] widths = new double[dataTable.getColumnCount()];
-        double total = 0;
+        //double total = 0;
         for (int i = 0; i < dataTable.getColumnCount(); i++) {
         	widths[i] = dataTable.getColumnModel().getColumn(i).getWidth();
-        	total += widths[i]; 
+        	//total += widths[i]; 
         }
         widths[2] /= 4.0;
         dataTable.getColumnModel().getColumn(2).setPreferredWidth((int) widths[2]);
@@ -122,9 +134,10 @@ public class JPackageDialog extends JPanel {
         //dataTable.setAutoCreateRowSorter(true);
         // ...if all processing was done based on the data in the table, 
         // instead of the row number alone.
-        dataTable.setSelectionMode(DefaultListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+        dataTable.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
         dataTable.addMouseListener(new MouseAdapter() {
-            public void mouseClicked(MouseEvent e) {
+            @Override
+			public void mouseClicked(MouseEvent e) {
                 if (e.getClickCount() == 2) {
                     Package selPackage = getSelectedPackage(dataTable.getSelectedRow());
                     showDetail(selPackage);
@@ -134,18 +147,25 @@ public class JPackageDialog extends JPanel {
     }
 
     private void resetPackages() {
-        packages.clear();
+        packageMap.clear();
         try {
-            packages = getPackages();
-        } catch (IOException e) {
-        	final String msg = "<html>" + NO_CONNECTION_MESSAGE.replaceAll("\\.", ".<br>") + "</html>";
+            addAvailablePackages(packageMap);
+            addInstalledPackages(packageMap);
+
+            // Create list of packages excluding beast2
+            packageList = new ArrayList<>();
+            for (Package pkg : packageMap.values())
+                if (!pkg.getName().equals("beast2"))
+                    packageList.add(pkg);
+
+        } catch (AddOnManager.PackageListRetrievalException e) {
+        	StringBuilder msgBuilder = new StringBuilder("<html>" + e.getMessage() + "<br>");
+            if (e.getCause() instanceof IOException)
+                msgBuilder.append(NO_CONNECTION_MESSAGE.replaceAll("\\.", ".<br>"));
+            msgBuilder.append("</html>");
+
         	try {
-        	SwingUtilities.invokeLater(new Runnable() {
-				@Override
-				public void run() {
-		        	JOptionPane.showMessageDialog(null, msg);
-				}
-			});
+        	SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(null, msgBuilder));
         	} catch (Exception e0) {
         		e0.printStackTrace();
         	}
@@ -161,216 +181,214 @@ public class JPackageDialog extends JPanel {
     }
 
     private Package getSelectedPackage(int selectedRow) {
-        if (packages.size() <= selectedRow)
+        if (packageList.size() <= selectedRow)
             throw new IllegalArgumentException("Incorrect row " + selectedRow +
-                    " is selected from package list, size = " + packages.size());
-        return packages.get(selectedRow);
+                    " is selected from package list, size = " + packageMap.size());
+        return packageList.get(selectedRow);
     }
 
     private void showDetail(Package aPackage) {
         //custom title, no icon
         JOptionPane.showMessageDialog(null,
                 aPackage.toHTML(),
-                aPackage.packageName,
+                aPackage.getName(),
                 JOptionPane.PLAIN_MESSAGE);
     }
 
     private Box createButtonBox() {
         Box box = Box.createHorizontalBox();
-        box.add(allDepCheckBox);
-        box.add(Box.createGlue());
         JButton installButton = new JButton("Install/Upgrade");
-        installButton.addActionListener(new ActionListener() {
+        installButton.addActionListener(e -> {
+            // first get rid of existing packages
+            int[] selectedRows = dataTable.getSelectedRows();
+            String installedPackageNames = "";
+
+            setCursor(new Cursor(Cursor.WAIT_CURSOR));
+
+            Map<Package, PackageVersion> packagesToInstall = new HashMap<>();
+            for (int selRow : selectedRows) {
+                Package selPackage = getSelectedPackage(selRow);
+                if (selPackage != null)
+                    packagesToInstall.put(selPackage, selPackage.getLatestVersion());
+            }
 
-            @Override
-            public void actionPerformed(ActionEvent e) {
-            	// first get rid of existing packages
-            	StringBuilder removedPackageNames = new StringBuilder();
-            	doUninstall(removedPackageNames);
-            	
-                int[] selectedRows = dataTable.getSelectedRows();
-                StringBuilder installedPackageNames = new StringBuilder();
-                                
-                for (int selRow : selectedRows) {
-                    Package selPackage = getSelectedPackage(selRow);
-                    if (selPackage != null) {
-                        try {
-//                            if (selPackage.isInstalled()) {
-//                                //TODO upgrade version
-//                            } else {
-                                setCursor(new Cursor(Cursor.WAIT_CURSOR));
-                                if (allDepCheckBox.isSelected()) {
-                                    installPackage(selPackage, false, null, packages);
-                                } else {
-                                    installPackage(selPackage, false, null, null);
-                                }
-                                if (installedPackageNames.length()>0)
-                                    installedPackageNames.append(", ");
-                                installedPackageNames.append("'")
-                                        .append(selPackage.packageName)
-                                        .append("'");
-                                
-                                setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
-//                            }
-                            resetPackages();
-                        } catch (Exception ex) {
-                            JOptionPane.showMessageDialog(null, "Install failed because: " + ex.getMessage());
-                            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
-                        }
-                    }
+            try {
+                populatePackagesToInstall(packageMap, packagesToInstall);
+
+                prepareForInstall(packagesToInstall, false, null);
+
+                if (getToDeleteListFile().exists()) {
+                    JOptionPane.showMessageDialog(frame,
+                            "<html><body><p style='width: 200px'>Upgrading packages on your machine requires BEAUti " +
+                                    "to restart. Shutting down now.</p></body></html>");
+                    System.exit(0);
                 }
-                
-                if (installedPackageNames.length()>0)
-                    JOptionPane.showMessageDialog(null, "Package(s) "
-                            + installedPackageNames.toString() + " installed. "
-                            + "Note that any changes to the BEAUti "
-                            + "interface will\n not appear until a "
-                            + "new document is created or BEAUti is "
-                            + "restarted.");
+
+                installPackages(packagesToInstall, false, null);
+
+                // Refresh classes:
+                loadExternalJars();
+
+                installedPackageNames = String.join(",",
+                        packagesToInstall.keySet().stream()
+                                .map(Package::toString)
+                                .collect(Collectors.toList()));
+
+                setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+
+            } catch (DependencyResolutionException | IOException ex) {
+                JOptionPane.showMessageDialog(null, "Install failed because: " + ex.getMessage());
+                setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
             }
+
+            resetPackages();
+            dataTable.setRowSelectionInterval(selectedRows[0], selectedRows[0]);
+
+            if (installedPackageNames.length()>0)
+                JOptionPane.showMessageDialog(null, "Package(s) "
+                        + installedPackageNames + " installed. "
+                        + "Note that any changes to the BEAUti "
+                        + "interface will\n not appear until a "
+                        + "new document is created or BEAUti is "
+                        + "restarted.");
         });
         box.add(installButton);
 
         JButton uninstallButton = new JButton("Uninstall");
-        uninstallButton.addActionListener(new ActionListener() {
+        uninstallButton.addActionListener(e -> {
+            StringBuilder removedPackageNames = new StringBuilder();
+            int[] selectedRows = dataTable.getSelectedRows();
+
+            for (int selRow : selectedRows) {
+                Package selPackage = getSelectedPackage(selRow);
+                if (selPackage != null) {
+                    try {
+                        if (selPackage.isInstalled()) {
+                            setCursor(new Cursor(Cursor.WAIT_CURSOR));
+                            List<String> deps = getInstalledDependencyNames(selPackage, packageMap);
+
+                            if (deps.isEmpty()) {
+                                String result = uninstallPackage(selPackage, false, null);
+
+                                if (result != null) {
+                                    if (removedPackageNames.length() > 0)
+                                        removedPackageNames.append(", ");
+                                    removedPackageNames.append("'")
+                                            .append(selPackage.getName())
+                                            .append("'");
+                                }
+                            } else {
+                                throw new DependencyResolutionException("package " + selPackage
+                                        + " is used by the following packages: "
+                                + String.join(", ", deps) + "\n"
+                                + "Remove those packages first.");
+                            }
 
-            @Override
-            public void actionPerformed(ActionEvent e) {
-            	StringBuilder removedPackageNames = new StringBuilder();
-            	boolean toDeleteFileExists = doUninstall(removedPackageNames);
-                resetPackages();
+                            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+                        }
 
-                if (toDeleteFileExists) {
-                    JOptionPane.showMessageDialog(null, "<html>To complete uninstalling the package, BEAUti need to be restarted<br><br>Exiting now.</html>");
-                    System.exit(0);
+                        resetPackages();
+                        dataTable.setRowSelectionInterval(selectedRows[0], selectedRows[0]);
+                    } catch (IOException | DependencyResolutionException ex) {
+                        JOptionPane.showMessageDialog(null, "Uninstall failed because: " + ex.getMessage());
+                        setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
+                    }
                 }
+            }
 
-                if (removedPackageNames.length()>0)
-                    JOptionPane.showMessageDialog(null, "Package(s) "
-                            + removedPackageNames.toString() + " removed. "
-                            + "Note that any changes to the BEAUti "
-                            + "interface will\n not appear until a "
-                            + "new document is created or BEAUti is "
-                            + "restarted.");
+            if (getToDeleteListFile().exists()) {
+                JOptionPane.showMessageDialog(frame,
+                        "<html><body><p style='width: 200px'>Removing packages on your machine requires BEAUti " +
+                                "to restart. Shutting down now.</p></body></html>");
+                System.exit(0);
             }
+
+            if (removedPackageNames.length()>0)
+                JOptionPane.showMessageDialog(null, "Package(s) "
+                        + removedPackageNames.toString() + " removed. "
+                        + "Note that any changes to the BEAUti "
+                        + "interface will\n not appear until a "
+                        + "new document is created or BEAUti is "
+                        + "restarted.");
         });
         box.add(uninstallButton);
-        
-        JButton packageRepoButton = new JButton("Package repositories");
-        packageRepoButton.addActionListener(new ActionListener() {
 
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        box.add(Box.createHorizontalGlue());
+
+        JButton packageRepoButton = new JButton("Package repositories");
+        packageRepoButton.addActionListener(e -> {
                 JPackageRepositoryDialog dlg = new JPackageRepositoryDialog(frame);
                 dlg.setVisible(true);
                 resetPackages();
-            }
-        });
+            });
         box.add(packageRepoButton);
 
+        box.add(Box.createGlue());
+
         JButton closeButton = new JButton("Close");
-        closeButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        closeButton.addActionListener(e -> {
             	if (dlg != null) {
             		dlg.setVisible(false);
             	} else {
             		setVisible(false);
             	}
-            }
-        });
-        box.add(Box.createGlue());
+            });
         box.add(closeButton);
-        box.add(Box.createGlue());
 
         JButton button = new JButton("?");
         button.setToolTipText(getPackageUserDir() + " " + getPackageSystemDir());
-        button.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+        button.addActionListener(e -> {
                 JOptionPane.showMessageDialog(scrollPane, "<html>By default, packages are installed in <br><br><em>" + getPackageUserDir() +
                         "</em><br><br>and are available only to you.<br>" +
                         "<br>Packages can also be moved manually to <br><br><em>" + getPackageSystemDir() +
                         "</em><br><br>which makes them available to all users<br>"
                         + "on your system.</html>");
-            }
-        });
+            });
         box.add(button);
         return box;
     }
 
-    protected boolean doUninstall(StringBuilder removedPackageNames) {
-        int[] selectedRows = dataTable.getSelectedRows();
-        
-        boolean toDeleteFileExists = false;
-        for (int selRow : selectedRows) {
-            Package selPackage = getSelectedPackage(selRow);
-            if (selPackage != null) {
-                try {
-                    if (selPackage.isInstalled()) {
-//                    if (JOptionPane.showConfirmDialog(null, "Are you sure you want to uninstall " +
-//                    AddOnManager.URL2PackageName(package.url) + "?", "Uninstall Add On",
-//                            JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
-                        setCursor(new Cursor(Cursor.WAIT_CURSOR));
-                        uninstallPackage(selPackage, false, null, packages, allDepCheckBox.isSelected());
-                        setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
-
-                        File toDeleteFile = getToDeleteListFile();
-                        if (toDeleteFile.exists()) {
-                            toDeleteFileExists = true;
-                        }
-
-                        if (removedPackageNames.length()>0)
-                            removedPackageNames.append(", ");
-                        removedPackageNames.append("'")
-                                .append(selPackage.packageName)
-                                .append("'");
-//                    }
-                    } else {
-                        //TODO ?
-                    }
-                } catch (Exception ex) {
-                    JOptionPane.showMessageDialog(null, "Uninstall failed because: " + ex.getMessage());
-                    setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
-                }
-            }
-        }	
-        return toDeleteFileExists;
-	}
-
 	class DataTableModel extends AbstractTableModel {
-        String[] columnNames = {"Name", "Status/Version", "Latest", "Dependencies", "Detail"};
+		private static final long serialVersionUID = 1L;
 
-        public int getColumnCount() {
+		String[] columnNames = {"Name", "Status/Version", "Latest", "Dependencies", "Detail"};
+
+        @Override
+		public int getColumnCount() {
             return columnNames.length;
         }
 
-        public int getRowCount() {
-            return packages.size();
+        @Override
+		public int getRowCount() {
+            return packageList.size();
         }
 
-        public Object getValueAt(int row, int col) {
-            Package aPackage = packages.get(row);
+        @Override
+		public Object getValueAt(int row, int col) {
+            Package aPackage = packageList.get(row);
             switch (col) {
                 case 0:
-                    return aPackage.packageName;
+                    return aPackage.getName();
                 case 1:
-                    return aPackage.getStatus();
+                    return aPackage.getStatusString();
                 case 2:
-                    return aPackage.getLatestVersion();
+                    return aPackage.isAvailable() ? aPackage.getLatestVersion() : "not available";
                 case 3:
                     return aPackage.getDependenciesString();
                 case 4:
-                    return aPackage.description;
+                    return aPackage.getDescription();
                 default:
                     throw new IllegalArgumentException("unknown column, " + col);
             }
         }
 
-        public String getColumnName(int column) {
+        @Override
+		public String getColumnName(int column) {
             return columnNames[column];
         }
 
-        public String toString() {
+        @Override
+		public String toString() {
             StringBuffer buffer = new StringBuffer();
 
             buffer.append(getColumnName(0));
@@ -393,8 +411,8 @@ public class JPackageDialog extends JPanel {
         }
     }
 
-	
-	
+
+
 	public JDialog asDialog(JFrame frame) {
 		if (frame == null) {
 	        frame = (JFrame) SwingUtilities.getWindowAncestor(this);
@@ -425,4 +443,49 @@ public class JPackageDialog extends JPanel {
 			super.setCursor(cursor);
 		}
 	}
+
+    class PackageTable extends JTable {
+		private static final long serialVersionUID = 1L;
+
+        Map<Package, PackageVersion> packagesToInstall = new HashMap<>();
+
+        public PackageTable(TableModel dm) {
+            super(dm);
+        }
+
+        @Override
+        public Component prepareRenderer(TableCellRenderer renderer, int row, int column) {
+            Component c =  super.prepareRenderer(renderer, row, column);
+
+            Font font = c.getFont();
+            font.getFamily();
+            Font boldFont = new Font(font.getName(), Font.BOLD | Font.ITALIC, font.getSize());
+
+            Package pkg = packageList.get(row);
+
+            if (! isRowSelected(row)) {
+                if (pkg.newVersionAvailable()) {
+                    if (pkg.isInstalled())
+                        c.setFont(boldFont);
+
+                    if (column == 2) {
+                        packagesToInstall.clear();
+                        packagesToInstall.put(pkg, pkg.getLatestVersion());
+                        try {
+                            populatePackagesToInstall(packageMap, packagesToInstall);
+                            c.setForeground(new Color(0, 150, 0));
+                        } catch (DependencyResolutionException ex) {
+                            c.setForeground(new Color(150, 0, 0));
+                        }
+                    } else {
+                        c.setForeground(Color.BLACK);
+                    }
+                } else {
+                    c.setForeground(Color.BLACK);
+                }
+            }
+
+            return c;
+        }
+    }
 }
diff --git a/src/beast/app/beauti/JPackageRepositoryDialog.java b/src/beast/app/beauti/JPackageRepositoryDialog.java
index 6f75297..5373d57 100644
--- a/src/beast/app/beauti/JPackageRepositoryDialog.java
+++ b/src/beast/app/beauti/JPackageRepositoryDialog.java
@@ -18,50 +18,52 @@
  */
 package beast.app.beauti;
 
-import beast.util.AddOnManager;
 import java.awt.BorderLayout;
 import java.awt.Dimension;
 import java.awt.Point;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.List;
-import javax.swing.Box;
-import javax.swing.JButton;
-import javax.swing.JDialog;
-import javax.swing.JFrame;
-import javax.swing.JOptionPane;
-import javax.swing.JScrollPane;
-import javax.swing.JTable;
+
+import javax.swing.*;
 import javax.swing.table.AbstractTableModel;
 
+import beast.util.AddOnManager;
+
 /**
  * @author Tim Vaughan <tgvaughan at gmail.com>
  */
 public class JPackageRepositoryDialog extends JDialog {
 
-    public JPackageRepositoryDialog(final JFrame frame) {
+	private static final long serialVersionUID = 1L;
+
+	public JPackageRepositoryDialog(final JFrame frame) {
         super(frame);
 
         setModal(true);
         setTitle("BEAST 2 Package Repository Manager");
         
         // Get current list of URLs:
-        List<String> URLs;
+        List<URL> urls;
         try {
-            URLs = AddOnManager.getPackagesURL();
+            urls = AddOnManager.getRepositoryURLs();
         } catch (MalformedURLException exception) {
-            URLs = new ArrayList<String>();
-            URLs.add(AddOnManager.PACKAGES_XML);
+            urls = new ArrayList<>();
+            try {
+                urls.add(new URL(AddOnManager.PACKAGES_XML));
+            } catch (MalformedURLException e) {
+                // Hard-coded URL is broken. Should never happen!
+                e.printStackTrace();
+            }
         }
 
         // Assemble table
-        final RepoTableModel repoTableModel = new RepoTableModel(URLs);
+        final RepoTableModel repoTableModel = new RepoTableModel(urls);
         final JTable repoTable = new JTable(repoTableModel);
+        repoTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
         JScrollPane scrollPane = new JScrollPane(repoTable);
         getContentPane().add(scrollPane, BorderLayout.CENTER);
         
@@ -70,75 +72,77 @@ public class JPackageRepositoryDialog extends JDialog {
         
         // ADD URL
         JButton addURLButton = new JButton("Add URL");
-        addURLButton.addActionListener(new ActionListener() {
-            
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                String newURL = (String)JOptionPane.showInputDialog(frame,
-                        "Enter package repository URL",
-                        "Add repository URL",JOptionPane.PLAIN_MESSAGE, null, null, "http://");
-                
-                if (newURL == null)
-                    return; // User canceled
-                
-                if (!repoTableModel.URLs.contains(newURL)) {
-                    
-                    // Check that URL is accessible:
-                    try {
-                        URL url = new URL(newURL);
-                        if (url.getHost() == null)
-                            return;
-                        
-                        InputStream is = url.openStream();
-                        is.close();
-                      
-                    } catch (MalformedURLException ex) {
-                        JOptionPane.showMessageDialog(frame, "Invalid URL.");
-                        return;
-                    } catch (IOException ex) {
-                        JOptionPane.showMessageDialog(frame, "Could not access URL.");
-                        return;
-                    }
-
-                    // Add to table:                        
-                    repoTableModel.URLs.add(newURL);
-                    repoTableModel.fireTableDataChanged();  
-                } else {
-                    JOptionPane.showMessageDialog(frame, "Repository already exists!");
-                }
+        addURLButton.addActionListener(e -> {
+            String newURLString = (String)JOptionPane.showInputDialog(frame,
+                    "Enter package repository URL",
+                    "Add repository URL",JOptionPane.PLAIN_MESSAGE, null, null, "http://");
+
+            if (newURLString == null)
+                return; // User canceled
+
+            URL newURL = null;
+            try {
+                newURL = new URL(newURLString);
+            } catch (MalformedURLException exception) {
+                JOptionPane.showMessageDialog(frame, "Invalid URL.");
+                return;
+            }
+
+            if (repoTableModel.urls.contains(newURL)) {
+                JOptionPane.showMessageDialog(frame, "Repository already exists!");
+                return;
             }
+
+            try {
+                if (newURL.getHost() == null)
+                    return;
+
+                InputStream is = newURL.openStream();
+                is.close();
+
+            } catch (IOException ex) {
+                JOptionPane.showMessageDialog(frame, "Could not access URL.");
+                return;
+            }
+
+            // Add to table:
+            repoTableModel.urls.add(newURL);
+            repoTableModel.fireTableDataChanged();
         });
         box.add(addURLButton);
         
         // DELETE URL
         JButton deleteURLButton = new JButton("Delete selected URL");
-        deleteURLButton.addActionListener(new ActionListener() {
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                if (repoTable.getSelectedRow()>0) {
-                    if (JOptionPane.showConfirmDialog(frame, "Really delete this repository?") ==JOptionPane.YES_OPTION) {
-                        repoTableModel.URLs.remove(repoTable.getSelectedRow());
-                        repoTableModel.fireTableDataChanged();
-                    }
-                }
+        deleteURLButton.addActionListener(e -> {
+            if (JOptionPane.showConfirmDialog(frame, "Really delete this repository?") ==JOptionPane.YES_OPTION) {
+                repoTableModel.urls.remove(repoTable.getSelectedRow());
+                repoTableModel.fireTableDataChanged();
             }
         });
+        deleteURLButton.setEnabled(false);
         box.add(deleteURLButton);
         
         // DONE
         JButton OKButton = new JButton("Done");
-        OKButton.addActionListener(new ActionListener() {
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                AddOnManager.savePackageURLs(repoTableModel.URLs);
-                setVisible(false);
-            }
+        OKButton.addActionListener(e -> {
+            AddOnManager.saveRepositoryURLs(repoTableModel.urls);
+            setVisible(false);
         });
         box.add(OKButton);
         getContentPane().add(box, BorderLayout.PAGE_END);
 
+        // Action listeners to disable/enable delete button
+        ListSelectionModel listSelectionModel = repoTable.getSelectionModel();
+        listSelectionModel.addListSelectionListener(e -> {
+            if (e.getValueIsAdjusting())
+                return;
+
+            if (listSelectionModel.isSelectedIndex(0))
+                deleteURLButton.setEnabled(false);
+            else
+                deleteURLButton.setEnabled(true);
+        });
+
         // Set size and location of dialog
         Dimension dim = scrollPane.getPreferredSize();
         Dimension dim2 = box.getPreferredSize();
@@ -153,16 +157,17 @@ public class JPackageRepositoryDialog extends JDialog {
      * Class of tables containing the current list of package repositories.
      */
     class RepoTableModel extends AbstractTableModel {
+		private static final long serialVersionUID = 1L;
+		
+		public List<URL> urls;
 
-        public List<String> URLs;
-
-        public RepoTableModel(List<String> URLs) {
-            this.URLs = URLs;
+        public RepoTableModel(List<URL> urls) {
+            this.urls = urls;
         }
 
         @Override
         public int getRowCount() {
-            return URLs.size();
+            return urls.size();
         }
 
         @Override
@@ -177,7 +182,7 @@ public class JPackageRepositoryDialog extends JDialog {
 
         @Override
         public Object getValueAt(int rowIndex, int columnIndex) {
-            return URLs.get(rowIndex);
+            return urls.get(rowIndex);
         }
     }
 
diff --git a/src/beast/app/beauti/LoggerListInputEditor.java b/src/beast/app/beauti/LoggerListInputEditor.java
index 495f084..eb7d589 100644
--- a/src/beast/app/beauti/LoggerListInputEditor.java
+++ b/src/beast/app/beauti/LoggerListInputEditor.java
@@ -8,10 +8,9 @@ import javax.swing.JTextField;
 import beast.app.draw.InputEditor;
 import beast.app.draw.ListInputEditor;
 import beast.app.draw.StringInputEditor;
+import beast.core.BEASTInterface;
 import beast.core.Input;
 import beast.core.Logger;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 
 
 
@@ -34,18 +33,18 @@ public class LoggerListInputEditor extends ListInputEditor {
     
 
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-    	super.init(input, plugin, itemNr, bExpandOption, bAddButtons);
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+    	super.init(input, beastObject, itemNr, isExpandOption, addButtons);
     }
     
     @Override
-    protected void addSingleItem(BEASTInterface plugin) {
-    	currentLogger = (Logger) plugin;
-    	super.addSingleItem(plugin);
+    protected void addSingleItem(BEASTInterface beastObject) {
+    	currentLogger = (Logger) beastObject;
+    	super.addSingleItem(beastObject);
     }
     
-    public InputEditor createFileNameEditor() throws Exception {
-        Input<?> input = currentLogger.fileNameInput;
+    public InputEditor createFileNameEditor() {
+        final Input<?> input = currentLogger.fileNameInput;
         StringInputEditor fileNameEditor = new StringInputEditor(doc);
         fileNameEditor.init(input, currentLogger, -1, ExpandOption.FALSE, true);
 
diff --git a/src/beast/app/beauti/MRCAPriorInputEditor.java b/src/beast/app/beauti/MRCAPriorInputEditor.java
index 20223bb..3f275f7 100644
--- a/src/beast/app/beauti/MRCAPriorInputEditor.java
+++ b/src/beast/app/beauti/MRCAPriorInputEditor.java
@@ -13,10 +13,12 @@ import javax.swing.JComboBox;
 
 import beast.app.draw.InputEditor;
 import beast.app.draw.SmallButton;
-import beast.core.Input;
 import beast.core.BEASTInterface;
+import beast.core.Input;
+import beast.core.util.Log;
 import beast.evolution.alignment.Taxon;
 import beast.evolution.alignment.TaxonSet;
+import beast.evolution.tree.Tree;
 import beast.math.distributions.MRCAPrior;
 import beast.math.distributions.OneOnX;
 
@@ -35,41 +37,38 @@ public class MRCAPriorInputEditor extends InputEditor.Base {
 	}
 
 	@Override
-	public void init(Input<?> input, BEASTInterface plugin, final int listItemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-        m_bAddButtons = bAddButtons;
+	public void init(Input<?> input, BEASTInterface beastObject, final int listItemNr, ExpandOption isExpandOption, boolean addButtons) {
+        m_bAddButtons = addButtons;
         m_input = input;
-        m_plugin = plugin;
+        m_beastObject = beastObject;
         this.itemNr= listItemNr;
 		
         Box itemBox = Box.createHorizontalBox();
 
-        MRCAPrior prior = (MRCAPrior) plugin;
-        String sText = prior.getID();
+        MRCAPrior prior = (MRCAPrior) beastObject;
+        String text = prior.getID();
 
-        JButton taxonButton = new JButton(sText);
-        taxonButton.setMinimumSize(PriorInputEditor.PREFERRED_SIZE);
-        taxonButton.setPreferredSize(PriorInputEditor.PREFERRED_SIZE);
+        JButton taxonButton = new JButton(text);
+        taxonButton.setMinimumSize(Base.PREFERRED_SIZE);
+        taxonButton.setPreferredSize(Base.PREFERRED_SIZE);
         itemBox.add(taxonButton);
-        taxonButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        taxonButton.addActionListener(e -> {
                 List<?> list = (List<?>) m_input.get();
-                MRCAPrior prior = (MRCAPrior) list.get(itemNr);
+                MRCAPrior prior2 = (MRCAPrior) list.get(itemNr);
                 try {
-                    TaxonSet taxonset = prior.taxonsetInput.get();
-                    Set<Taxon> candidates = getTaxonCandidates(prior);
+                    TaxonSet taxonset = prior2.taxonsetInput.get();
+                    Set<Taxon> candidates = getTaxonCandidates(prior2);
                     TaxonSetDialog dlg = new TaxonSetDialog(taxonset, candidates, doc);
                     if (dlg.showDialog()) {
-                        prior.setID(dlg.taxonSet.getID());
-                        prior.taxonsetInput.setValue(dlg.taxonSet, prior);
+                        prior2.setID(dlg.taxonSet.getID());
+                        prior2.taxonsetInput.setValue(dlg.taxonSet, prior2);
                     }
                 } catch (Exception e1) {
                     // TODO Auto-generated catch block
                     e1.printStackTrace();
                 }
                 refreshPanel();
-            }
-        });
+            });
 
 
         if (prior.distInput.getType() == null) {
@@ -82,16 +81,16 @@ public class MRCAPriorInputEditor extends InputEditor.Base {
 
         }
 
-        List<BeautiSubTemplate> sAvailablePlugins = doc.getInputEditorFactory().getAvailableTemplates(prior.distInput, prior, null, doc);
-        JComboBox comboBox = new JComboBox(sAvailablePlugins.toArray());
-        comboBox.setName(sText+".distr");
+        List<BeautiSubTemplate> availableBEASTObjects = doc.getInputEditorFactory().getAvailableTemplates(prior.distInput, prior, null, doc);
+        JComboBox<BeautiSubTemplate> comboBox = new JComboBox<>(availableBEASTObjects.toArray(new BeautiSubTemplate[]{}));
+        comboBox.setName(text+".distr");
 
         if (prior.distInput.get() != null) {
-            String sID = prior.distInput.get().getID();
-            //sID = BeautiDoc.parsePartition(sID);
-            sID = sID.substring(0, sID.indexOf('.'));
-            for (BeautiSubTemplate template : sAvailablePlugins) {
-                if (template.sClassInput.get() != null && template.sShortClassName.equals(sID)) {
+            String id = prior.distInput.get().getID();
+            //id = BeautiDoc.parsePartition(id);
+            id = id.substring(0, id.indexOf('.'));
+            for (BeautiSubTemplate template : availableBEASTObjects) {
+                if (template.classInput.get() != null && template.shortClassName.equals(id)) {
                     comboBox.setSelectedItem(template);
                 }
             }
@@ -101,20 +100,21 @@ public class MRCAPriorInputEditor extends InputEditor.Base {
         comboBox.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
-                JComboBox comboBox = (JComboBox) e.getSource();
+                @SuppressWarnings("unchecked")
+				JComboBox<BeautiSubTemplate> comboBox = (JComboBox<BeautiSubTemplate>) e.getSource();
                 BeautiSubTemplate template = (BeautiSubTemplate) comboBox.getSelectedItem();
                 List<?> list = (List<?>) m_input.get();
                 MRCAPrior prior = (MRCAPrior) list.get(itemNr);
 
-//System.err.println("PRIOR" + plugin2);
+//System.err.println("PRIOR" + beastObject2);
 //            	try {
-//					prior.m_distInput.setValue(plugin2, prior);
+//					prior.m_distInput.setValue(beastObject2, prior);
 //				} catch (Exception e1) {
 //					// TODO Auto-generated catch block
 //					e1.printStackTrace();
 //				}
                 try {
-                    //Plugin plugin2 =
+                    //BEASTObject beastObject2 =
                     template.createSubNet(new PartitionContext(""), prior, prior.distInput, true);
                 } catch (Exception e1) {
                     e1.printStackTrace();
@@ -125,7 +125,7 @@ public class MRCAPriorInputEditor extends InputEditor.Base {
         itemBox.add(comboBox);
 
         JCheckBox isMonophyleticdBox = new JCheckBox(doc.beautiConfig.getInputLabel(prior, prior.isMonophyleticInput.getName()));
-        isMonophyleticdBox.setName(sText+".isMonophyletic");
+        isMonophyleticdBox.setName(text+".isMonophyletic");
         isMonophyleticdBox.setSelected(prior.isMonophyleticInput.get());
         isMonophyleticdBox.setToolTipText(prior.isMonophyleticInput.getHTMLTipText());
         isMonophyleticdBox.addActionListener(new MRCAPriorActionListener(prior));
@@ -136,7 +136,7 @@ public class MRCAPriorInputEditor extends InputEditor.Base {
         deleteButton.addActionListener(new ActionListener() {
 			@Override
 			public void actionPerformed(ActionEvent e) {
-				System.err.println("Trying to delete a calibration");
+				Log.warning.println("Trying to delete a calibration");
 				List<?> list = (List<?>) m_input.get();
 				MRCAPrior prior = (MRCAPrior) list.get(itemNr);
 				doc.disconnect(prior, "prior", "distribution");
@@ -152,10 +152,23 @@ public class MRCAPriorInputEditor extends InputEditor.Base {
 	}
 	
     Set<Taxon> getTaxonCandidates(MRCAPrior prior) {
-        Set<Taxon> candidates = new HashSet<Taxon>();
-        for (String sTaxon : prior.treeInput.get().getTaxaNames()) {
-            Taxon taxon = doc.getTaxon(sTaxon);
-            candidates.add(taxon);
+        Set<Taxon> candidates = new HashSet<>();
+        Tree tree = prior.treeInput.get();
+        String [] taxa = null;
+        if (tree.m_taxonset.get() != null) {
+        	try {
+            	TaxonSet set = tree.m_taxonset.get();
+        		set.initAndValidate();
+            	taxa = set.asStringList().toArray(new String[0]);
+        	} catch (Exception e) {
+            	taxa = prior.treeInput.get().getTaxaNames();
+			}
+        } else {
+        	taxa = prior.treeInput.get().getTaxaNames();
+        }
+        
+        for (String taxon : taxa) {
+            candidates.add(doc.getTaxon(taxon));
         }
         return candidates;
     }
@@ -176,7 +189,7 @@ public class MRCAPriorInputEditor extends InputEditor.Base {
                 m_prior.isMonophyleticInput.setValue(((JCheckBox) e.getSource()).isSelected(), m_prior);
                 refreshPanel();
             } catch (Exception ex) {
-                System.err.println("PriorListInputEditor " + ex.getMessage());
+            	Log.warning.println("PriorListInputEditor " + ex.getMessage());
             }
         }
     }
diff --git a/src/beast/app/beauti/OperatorListInputEditor.java b/src/beast/app/beauti/OperatorListInputEditor.java
index 60fd5d6..a490b6a 100644
--- a/src/beast/app/beauti/OperatorListInputEditor.java
+++ b/src/beast/app/beauti/OperatorListInputEditor.java
@@ -1,6 +1,5 @@
 package beast.app.beauti;
 
-import java.awt.Color;
 import java.awt.Dimension;
 import java.util.ArrayList;
 import java.util.List;
@@ -13,18 +12,17 @@ import javax.swing.event.DocumentListener;
 
 import beast.app.draw.InputEditor;
 import beast.app.draw.ListInputEditor;
+import beast.core.BEASTInterface;
 import beast.core.Input;
 import beast.core.Operator;
 import beast.core.StateNode;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 
 
 
 public class OperatorListInputEditor extends ListInputEditor {
     private static final long serialVersionUID = 1L;
-    List<JTextField> textFields = new ArrayList<JTextField>();
-    List<Operator> operators = new ArrayList<Operator>();
+    List<JTextField> textFields = new ArrayList<>();
+    List<Operator> operators = new ArrayList<>();
 
 	public OperatorListInputEditor(BeautiDoc doc) {
 		super(doc);
@@ -41,7 +39,7 @@ public class OperatorListInputEditor extends ListInputEditor {
     }
 
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
     	Box box = Box.createHorizontalBox();
     	box.add(Box.createHorizontalStrut(25));
     	box.add(new JLabel("Operator"));
@@ -51,12 +49,12 @@ public class OperatorListInputEditor extends ListInputEditor {
     	add(box);
     	
     	m_buttonStatus = ButtonStatus.NONE;
-    	super.init(input, plugin, itemNr, bExpandOption, bAddButtons);
+    	super.init(input, beastObject, itemNr, isExpandOption, addButtons);
     }
     
     @Override
-    protected InputEditor addPluginItem(Box itemBox, BEASTInterface plugin) {
-        Operator operator = (Operator) plugin;
+    protected InputEditor addPluginItem(Box itemBox, BEASTInterface beastObject) {
+        Operator operator = (Operator) beastObject;
 
         JTextField entry = new JTextField(" " + getLabel(operator));
         entry.setMinimumSize(new Dimension(200, 16));
@@ -121,8 +119,8 @@ public class OperatorListInputEditor extends ListInputEditor {
 
         void processEntry() {
             try {
-                Double fWeight = Double.parseDouble(m_weightEntry.getText());
-                m_operator.m_pWeight.setValue(fWeight, m_operator);
+                Double weight = Double.parseDouble(m_weightEntry.getText());
+                m_operator.m_pWeight.setValue(weight, m_operator);
             } catch (Exception e) {
                 // ignore
             }
@@ -143,26 +141,26 @@ public class OperatorListInputEditor extends ListInputEditor {
     }
 
     String getLabel(Operator operator) {
-        String sName = operator.getClass().getName();
-        sName = sName.substring(sName.lastIndexOf('.') + 1);
-        sName = sName.replaceAll("Operator", "");
-        if (sName.matches(".*[A-Z].*")) {
-            sName = sName.replaceAll("(.)([A-Z])", "$1 $2");
+        String name = operator.getClass().getName();
+        name = name.substring(name.lastIndexOf('.') + 1);
+        name = name.replaceAll("Operator", "");
+        if (name.matches(".*[A-Z].*")) {
+            name = name.replaceAll("(.)([A-Z])", "$1 $2");
         }
-        sName += ": ";
+        name += ": ";
         try {
-            for (BEASTInterface plugin2 : operator.listActivePlugins()) {
-                if (plugin2 instanceof StateNode && ((StateNode) plugin2).isEstimatedInput.get()) {
-                    sName += plugin2.getID() + " ";
+            for (BEASTInterface beastObject2 : operator.listActiveBEASTObjects()) {
+                if (beastObject2 instanceof StateNode && ((StateNode) beastObject2).isEstimatedInput.get()) {
+                    name += beastObject2.getID() + " ";
                 }
             }
         } catch (Exception e) {
             // ignore
         }
-        String sTipText = getDoc().tipTextMap.get(operator.getID());
-        if (sTipText != null) {
-            sName += " " + sTipText;
+        String tipText = getDoc().tipTextMap.get(operator.getID());
+        if (tipText != null) {
+            name += " " + tipText;
         }
-        return sName;
+        return name;
     }
 } // OperatorListInputEditor
diff --git a/src/beast/app/beauti/ParametricDistributionInputEditor.java b/src/beast/app/beauti/ParametricDistributionInputEditor.java
index 59921bd..ef3a5c2 100644
--- a/src/beast/app/beauti/ParametricDistributionInputEditor.java
+++ b/src/beast/app/beauti/ParametricDistributionInputEditor.java
@@ -1,14 +1,13 @@
 package beast.app.beauti;
 
 
-import beast.app.draw.BEASTObjectInputEditor;
-import beast.core.BEASTInterface;
-import beast.core.Input;
-import beast.evolution.tree.TreeDistribution;
-import beast.math.distributions.MRCAPrior;
-import beast.math.distributions.ParametricDistribution;
-
-import java.awt.*;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 
@@ -19,6 +18,13 @@ import javax.swing.JPanel;
 
 import org.apache.commons.math.MathException;
 
+import beast.app.draw.BEASTObjectInputEditor;
+import beast.core.BEASTInterface;
+import beast.core.Input;
+import beast.evolution.tree.TreeDistribution;
+import beast.math.distributions.MRCAPrior;
+import beast.math.distributions.ParametricDistribution;
+
 public class ParametricDistributionInputEditor extends BEASTObjectInputEditor {
 
     public ParametricDistributionInputEditor(BeautiDoc doc) {
@@ -36,18 +42,18 @@ public class ParametricDistributionInputEditor extends BEASTObjectInputEditor {
     }
 
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-        useDefaultBehavior = !((plugin instanceof beast.math.distributions.Prior) || plugin instanceof MRCAPrior || plugin instanceof TreeDistribution);
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+        useDefaultBehavior = !((beastObject instanceof beast.math.distributions.Prior) || beastObject instanceof MRCAPrior || beastObject instanceof TreeDistribution);
 
 //    	if (useDefaultBehavior && false) {
-//    		super.init(input, plugin, bExpandOption, bAddButtons);
+//    		super.init(input, beastObject, isExpandOption, addButtons);
 //    	} else {
-        m_bAddButtons = bAddButtons;
+        m_bAddButtons = addButtons;
         m_input = input;
-        m_plugin = plugin;
+        m_beastObject = beastObject;
 		this.itemNr = itemNr;
         if (input.get() != null) {
-            super.init(input, plugin, itemNr, ExpandOption.TRUE, bAddButtons);
+            super.init(input, beastObject, itemNr, ExpandOption.TRUE, addButtons);
         }
         add(createGraph());
 //    	}
@@ -56,9 +62,9 @@ public class ParametricDistributionInputEditor extends BEASTObjectInputEditor {
 
     @Override
     /** suppress combobox **/
-    protected void addComboBox(JComponent box, Input<?> input, BEASTInterface plugin) {
+    protected void addComboBox(JComponent box, Input<?> input, BEASTInterface beastObject) {
         if (useDefaultBehavior) {
-            super.addComboBox(box, input, plugin);
+            super.addComboBox(box, input, beastObject);
         }
     }
 
@@ -113,20 +119,20 @@ public class ParametricDistributionInputEditor extends BEASTObjectInputEditor {
             }
 
             Font font = g.getFont();
-            double fMinValue = 0.1;
-            double fMaxValue = 1;
+            double minValue = 0.1;
+            double maxValue = 1;
             try {
-                fMinValue = m_distr.inverseCumulativeProbability(0.01);
-                fMaxValue = m_distr.inverseCumulativeProbability(0.99);
+                minValue = m_distr.inverseCumulativeProbability(0.01);
+                maxValue = m_distr.inverseCumulativeProbability(0.99);
             } catch (Exception e) {
                 // use defaults
             }
-            double fXRange = fMaxValue - fMinValue;
-            // adjust fYMax so that the ticks come out right
-            double fX0 = fMinValue;
+            double xRange = maxValue - minValue;
+            // adjust yMax so that the ticks come out right
+            double x0 = minValue;
             int k = 0;
-            double f = fXRange;
-            double f2 = fX0;
+            double f = xRange;
+            double f2 = x0;
             while (f > 10) {
                 f /= 10;
                 f2 /= 10;
@@ -148,36 +154,36 @@ public class ParametricDistributionInputEditor extends BEASTObjectInputEditor {
                 f /= 10;
                 f2 /= 10;
             }
-            //double fAdjXRange = f;
+            //double adjXRange = f;
 
-            fXRange = fXRange + fMinValue - f2;
-            fXRange = adjust(fXRange);
+            xRange = xRange + minValue - f2;
+            xRange = adjust(xRange);
             final int NR_OF_TICKS_X = m_nTicks;
 
-            fMinValue = f2; //fXRange = fAdjXRange;
+            minValue = f2; //xRange = adjXRange;
 
-            int nPoints;
+            int points;
             if (!m_distr.isIntegerDistribution()) {
-                nPoints = 100;
+                points = 100;
             } else {
-                nPoints = (int) (fXRange);
+                points = (int) (xRange);
             }
-            int[] xPoints = new int[nPoints];
-            int[] yPoints = new int[nPoints];
-            double[] fyPoints = new double[nPoints];
-            double fYMax = 0;
-            for (int i = 0; i < nPoints; i++) {
+            int[] xPoints = new int[points];
+            int[] yPoints = new int[points];
+            double[] fyPoints = new double[points];
+            double yMax = 0;
+            for (int i = 0; i < points; i++) {
                 //try {
-                    fyPoints[i] = getDensityForPlot(m_distr, fMinValue + (fXRange * i) / nPoints);
+                    fyPoints[i] = getDensityForPlot(m_distr, minValue + (xRange * i) / points);
                 //}
                 if (Double.isInfinite(fyPoints[i]) || Double.isNaN(fyPoints[i])) {
                     fyPoints[i] = 0;
                 }
-                //fyPoints[i] = Math.exp(m_distr.logDensity(fMinValue + (fXRange * i)/nPoints));
-                fYMax = Math.max(fYMax, fyPoints[i]);
+                //fyPoints[i] = Math.exp(m_distr.logDensity(minValue + (xRange * i)/points));
+                yMax = Math.max(yMax, fyPoints[i]);
             }
 
-            fYMax = adjust(fYMax);
+            yMax = adjust(yMax);
             final int NR_OF_TICKS_Y = m_nTicks;
 
             // draw ticks on edge
@@ -189,7 +195,7 @@ public class ParametricDistributionInputEditor extends BEASTObjectInputEditor {
             int maxLabelWidth = 0;
             FontMetrics sfm = getFontMetrics(smallFont);
             for (int i = 0; i <= NR_OF_TICKS_Y; i++) {
-                ylabels[i] = format(fYMax * i / NR_OF_TICKS_Y);
+                ylabels[i] = format(yMax * i / NR_OF_TICKS_Y);
                 int stringWidth = sfm.stringWidth(ylabels[i]);
                 if (stringWidth > maxLabelWidth) maxLabelWidth = stringWidth;
             }
@@ -197,46 +203,46 @@ public class ParametricDistributionInputEditor extends BEASTObjectInputEditor {
             // collect the xlabels
             String[] xlabels = new String[NR_OF_TICKS_X+1];
             for (int i = 0; i <= NR_OF_TICKS_X; i++) {
-                xlabels[i] = format(fMinValue + fXRange * i / NR_OF_TICKS_X);
+                xlabels[i] = format(minValue + xRange * i / NR_OF_TICKS_X);
             }
             int maxLabelHeight = sfm.getMaxAscent()+sfm.getMaxDescent();
 
             int leftMargin = maxLabelWidth + TICK_LENGTH + 1 + MARGIN_LEFT_OF_Y_LABELS;
             int bottomMargin = maxLabelHeight + TICK_LENGTH + 1;
 
-            int nGraphWidth = width - leftMargin - RIGHT_MARGIN;
-            int nGraphHeight = height - TOP_MARGIN - bottomMargin - labeloffset;
+            int graphWidth = width - leftMargin - RIGHT_MARGIN;
+            int graphHeight = height - TOP_MARGIN - bottomMargin - labeloffset;
 
             // DRAW GRAPH PAPER
             g.setColor(Color.WHITE);
-            g.fillRect(leftMargin, TOP_MARGIN, nGraphWidth, nGraphHeight);
+            g.fillRect(leftMargin, TOP_MARGIN, graphWidth, graphHeight);
             g.setColor(Color.BLACK);
-            g.drawRect(leftMargin, TOP_MARGIN, nGraphWidth, nGraphHeight);
+            g.drawRect(leftMargin, TOP_MARGIN, graphWidth, graphHeight);
 
-            for (int i = 0; i < nPoints; i++) {
-                xPoints[i] = leftMargin + nGraphWidth * i / nPoints;
-                yPoints[i] = 1 + (int) (TOP_MARGIN + nGraphHeight - nGraphHeight * fyPoints[i] / fYMax);
+            for (int i = 0; i < points; i++) {
+                xPoints[i] = leftMargin + graphWidth * i / points;
+                yPoints[i] = 1 + (int) (TOP_MARGIN + graphHeight - graphHeight * fyPoints[i] / yMax);
             }
             if (!m_distr.isIntegerDistribution()) {
-                g.drawPolyline(xPoints, yPoints, nPoints);
+                g.drawPolyline(xPoints, yPoints, points);
             } else {
-                int y0 = 1 + TOP_MARGIN + nGraphHeight;
-                int dotDiameter = nGraphHeight/20;
-                for (int i=0; i<nPoints; i++) {
+                int y0 = 1 + TOP_MARGIN + graphHeight;
+                int dotDiameter = graphHeight/20;
+                for (int i=0; i<points; i++) {
                     g.drawLine(xPoints[i], y0, xPoints[i], yPoints[i]);
                     g.fillOval(xPoints[i]-dotDiameter/2, yPoints[i]-dotDiameter/2, dotDiameter, dotDiameter);
                 }
             }
 
             for (int i = 0; i <= NR_OF_TICKS_X; i++) {
-                int x = leftMargin + i * nGraphWidth / NR_OF_TICKS_X;
-                g.drawLine(x, TOP_MARGIN + nGraphHeight, x, TOP_MARGIN + nGraphHeight + TICK_LENGTH);
-                g.drawString(xlabels[i], x-sfm.stringWidth(xlabels[i])/2, TOP_MARGIN + nGraphHeight + TICK_LENGTH + 1 + sfm.getMaxAscent());
+                int x = leftMargin + i * graphWidth / NR_OF_TICKS_X;
+                g.drawLine(x, TOP_MARGIN + graphHeight, x, TOP_MARGIN + graphHeight + TICK_LENGTH);
+                g.drawString(xlabels[i], x-sfm.stringWidth(xlabels[i])/2, TOP_MARGIN + graphHeight + TICK_LENGTH + 1 + sfm.getMaxAscent());
             }
 
             // draw the y labels and ticks
             for (int i = 0; i <= NR_OF_TICKS_Y; i++) {
-                int y = TOP_MARGIN + nGraphHeight - i * nGraphHeight / NR_OF_TICKS_Y;
+                int y = TOP_MARGIN + graphHeight - i * graphHeight / NR_OF_TICKS_Y;
                 g.drawLine(leftMargin - TICK_LENGTH, y, leftMargin, y);
                 g.drawString(ylabels[i], leftMargin - TICK_LENGTH - 1 - sfm.stringWidth(ylabels[i]), y + 3);
             }
@@ -244,29 +250,34 @@ public class ParametricDistributionInputEditor extends BEASTObjectInputEditor {
             g.setFont(new Font(font.getName(), font.getStyle(), 10));
             try {
                 FontMetrics fontMetrics = g.getFontMetrics();
-                String[] sStrs = new String[]{"2.5% Quantile", "5% Quantile", "Median", "95% Quantile", "97.5% Quantile"};
-                Double[] fQuantiles = new Double[]{0.025, 0.05, 0.5, 0.95, 0.975};
+                String[] strs = new String[]{"2.5% Quantile", "5% Quantile", "Median", "95% Quantile", "97.5% Quantile"};
+                Double[] quantiles = new Double[]{0.025, 0.05, 0.5, 0.95, 0.975};
             	mayBeUnstable = false;
                 for (k = 0; k < 5; k++) {
 
-                    int y = TOP_MARGIN + nGraphHeight + bottomMargin + g.getFontMetrics().getMaxAscent() + k * 10;
+                    int y = TOP_MARGIN + graphHeight + bottomMargin + g.getFontMetrics().getMaxAscent() + k * 10;
 
                 	try {
-                        g.drawString(format(m_distr.inverseCumulativeProbability(fQuantiles[k])), nGraphWidth / 2 + leftMargin, y);
+                        g.drawString(format(m_distr.inverseCumulativeProbability(quantiles[k])), graphWidth / 2 + leftMargin, y);
                     } catch (MathException e) {
-                        g.drawString("not available", nGraphWidth / 2 + leftMargin, y);
+                        g.drawString("not available", graphWidth / 2 + leftMargin, y);
                     }
-                    g.drawString(sStrs[k], nGraphWidth / 2 - fontMetrics.stringWidth(sStrs[k]) + leftMargin - 10, y);
+                    g.drawString(strs[k], graphWidth / 2 - fontMetrics.stringWidth(strs[k]) + leftMargin - 10, y);
                 }
                 if (mayBeUnstable) {
-                	int x = nGraphWidth * 3/ 4 + leftMargin; int y =TOP_MARGIN + nGraphHeight + bottomMargin + 10;
+                	int x = graphWidth * 3/ 4 + leftMargin; int y =TOP_MARGIN + graphHeight + bottomMargin + 10;
                     g.drawString("* numbers", x, y + 20); 
                     g.drawString("may not be", x, y + 30);                	
                     g.drawString("accurate", x, y + 40);                	
                 }
+                try {
+                	g.drawString("mean " + format(m_distr.getMean()), graphWidth * 3/ 4 + leftMargin, TOP_MARGIN + graphHeight + bottomMargin + 10);
+                } catch (RuntimeException e) {
+                	// catch in case it is not implemented.
+                }
             } catch (Exception e) {
                 // probably something wrong with the parameters of the parametric distribution
-                g.drawString("Improper parameters", leftMargin, TOP_MARGIN + nGraphHeight + bottomMargin + g.getFontMetrics().getMaxAscent());
+                g.drawString("Improper parameters", leftMargin, TOP_MARGIN + graphHeight + bottomMargin + g.getFontMetrics().getMaxAscent());
             }
         }
         
@@ -282,27 +293,27 @@ public class ParametricDistributionInputEditor extends BEASTObjectInputEditor {
             return writer.toString();
         }
         
-        private double adjust(double fYMax) {
-            // adjust fYMax so that the ticks come out right
+        private double adjust(double yMax) {
+            // adjust yMax so that the ticks come out right
             int k = 0;
-            double fY = fYMax;
-            while (fY > 10) {
-                fY /= 10;
+            double y = yMax;
+            while (y > 10) {
+                y /= 10;
                 k++;
             }
-            while (fY < 1 && fY > 0) {
-                fY *= 10;
+            while (y < 1 && y > 0) {
+                y *= 10;
                 k--;
             }
-            fY = Math.ceil(fY);
-            m_nTicks = NR_OF_TICKS[(int) fY];
+            y = Math.ceil(y);
+            m_nTicks = NR_OF_TICKS[(int) y];
             for (int i = 0; i < k; i++) {
-                fY *= 10;
+                y *= 10;
             }
             for (int i = k; i < 0; i++) {
-                fY /= 10;
+                y /= 10;
             }
-            return fY;
+            return y;
         }
     }
     
diff --git a/src/beast/app/beauti/PartitionContext.java b/src/beast/app/beauti/PartitionContext.java
index e402f2a..00f941c 100644
--- a/src/beast/app/beauti/PartitionContext.java
+++ b/src/beast/app/beauti/PartitionContext.java
@@ -1,7 +1,6 @@
 package beast.app.beauti;
 
 
-import beast.core.BEASTObject;
 import beast.core.BEASTInterface;
 import beast.evolution.likelihood.GenericTreeLikelihood;
 
@@ -32,20 +31,20 @@ public class PartitionContext {
 	}
 	
 	public PartitionContext(GenericTreeLikelihood treeLikelihood) {
-		String sID = treeLikelihood.dataInput.get().getID();
-		sID = BeautiDoc.parsePartition(sID);
-		this.partition = sID;
+		String id = treeLikelihood.dataInput.get().getID();
+		id = BeautiDoc.parsePartition(id);
+		this.partition = id;
 		if (treeLikelihood.branchRateModelInput.get() != null) {
-			sID = treeLikelihood.branchRateModelInput.get().getID();
-			sID = BeautiDoc.parsePartition(sID);
+			id = treeLikelihood.branchRateModelInput.get().getID();
+			id = BeautiDoc.parsePartition(id);
 		}
-		this.clockModel = sID;
-		sID = ((BEASTInterface) treeLikelihood.siteModelInput.get()).getID();
-		sID = BeautiDoc.parsePartition(sID);
-		this.siteModel = sID;
-		sID = treeLikelihood.treeInput.get().getID();
-		sID = BeautiDoc.parsePartition(sID);
-		this.tree = sID;
+		this.clockModel = id;
+		id = ((BEASTInterface) treeLikelihood.siteModelInput.get()).getID();
+		id = BeautiDoc.parsePartition(id);
+		this.siteModel = id;
+		id = treeLikelihood.treeInput.get().getID();
+		id = BeautiDoc.parsePartition(id);
+		this.tree = id;
 	}
 	
 	@Override
diff --git a/src/beast/app/beauti/PriorInputEditor.java b/src/beast/app/beauti/PriorInputEditor.java
index 09ba5fd..f74cfd3 100644
--- a/src/beast/app/beauti/PriorInputEditor.java
+++ b/src/beast/app/beauti/PriorInputEditor.java
@@ -1,8 +1,6 @@
 package beast.app.beauti;
 
 import java.awt.Dimension;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.util.Arrays;
 import java.util.List;
 
@@ -11,10 +9,10 @@ import javax.swing.JButton;
 import javax.swing.JComboBox;
 import javax.swing.JLabel;
 
-import beast.app.draw.InputEditor;
 import beast.app.draw.BEASTObjectDialog;
-import beast.core.Input;
+import beast.app.draw.InputEditor;
 import beast.core.BEASTInterface;
+import beast.core.Input;
 import beast.core.parameter.IntegerParameter;
 import beast.core.parameter.RealParameter;
 import beast.math.distributions.Prior;
@@ -32,41 +30,42 @@ public class PriorInputEditor extends InputEditor.Base {
 	}
 
 	@Override
-	public void init(Input<?> input, BEASTInterface plugin, int listItemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-        m_bAddButtons = bAddButtons;
+	public void init(Input<?> input, BEASTInterface beastObject, int listItemNr, ExpandOption isExpandOption, boolean addButtons) {
+        m_bAddButtons = addButtons;
         m_input = input;
-        m_plugin = plugin;
+        m_beastObject = beastObject;
         this.itemNr= listItemNr;
 		
         Box itemBox = Box.createHorizontalBox();
 
-        Prior prior = (Prior) plugin;
-        String sText = prior.getParameterName();
-        JLabel label = new JLabel(sText);
+        Prior prior = (Prior) beastObject;
+        String text = prior.getParameterName();
+        JLabel label = new JLabel(text);
         label.setMinimumSize(PREFERRED_SIZE);
         label.setPreferredSize(PREFERRED_SIZE);
         itemBox.add(label);
 
-        List<BeautiSubTemplate> sAvailablePlugins = doc.getInputEditorFactory().getAvailableTemplates(prior.distInput, prior, null, doc);
-        JComboBox comboBox = new JComboBox(sAvailablePlugins.toArray());
-        comboBox.setName(sText+".distr");
+        List<BeautiSubTemplate> availableBEASTObjects = doc.getInputEditorFactory().getAvailableTemplates(prior.distInput, prior, null, doc);
+        JComboBox<BeautiSubTemplate> comboBox = new JComboBox<BeautiSubTemplate>(availableBEASTObjects.toArray(new BeautiSubTemplate[]{}));
+        comboBox.setName(text+".distr");
 
-        String sID = prior.distInput.get().getID();
-        System.err.println("id=" + sID);
-        sID = sID.substring(0, sID.indexOf('.'));
-        for (BeautiSubTemplate template : sAvailablePlugins) {
-            if (template.sClassInput.get() != null && template.sShortClassName.equals(sID)) {
+        String id = prior.distInput.get().getID();
+        //Log.warning.println("id=" + id);
+        id = id.substring(0, id.indexOf('.'));
+        for (BeautiSubTemplate template : availableBEASTObjects) {
+            if (template.classInput.get() != null && template.shortClassName.equals(id)) {
                 comboBox.setSelectedItem(template);
             }
         }
         comboBox.addActionListener(e -> {
-            JComboBox comboBox1 = (JComboBox) e.getSource();
+            @SuppressWarnings("unchecked")
+			JComboBox<BeautiSubTemplate> comboBox1 = (JComboBox<BeautiSubTemplate>) e.getSource();
 
             List<?> list = (List<?>) m_input.get();
 
             BeautiSubTemplate template = (BeautiSubTemplate) comboBox1.getSelectedItem();
-            //String sID = ((Plugin) list.get(iItem)).getID();
-            //String sPartition = BeautiDoc.parsePartition(sID);
+            //String id = ((BEASTObject) list.get(item)).getID();
+            //String partition = BeautiDoc.parsePartition(id);
             PartitionContext context = doc.getContextFor((BEASTInterface) list.get(itemNr));
             Prior prior1 = (Prior) list.get(itemNr);
             try {
@@ -121,10 +120,10 @@ public class PriorInputEditor extends InputEditor.Base {
         }
         comboBox.setMaximumSize(new Dimension(1024, 24));
 
-        String sTipText = getDoc().tipTextMap.get(plugin.getID());
-        //System.out.println(plugin.getID());
-        if (sTipText != null) {
-            JLabel tipTextLabel = new JLabel(" " + sTipText);
+        String tipText = getDoc().tipTextMap.get(beastObject.getID());
+        //System.out.println(beastObject.getID());
+        if (tipText != null) {
+            JLabel tipTextLabel = new JLabel(" " + tipText);
             itemBox.add(tipTextLabel);
         }
         itemBox.add(Box.createGlue());
diff --git a/src/beast/app/beauti/PriorListInputEditor.java b/src/beast/app/beauti/PriorListInputEditor.java
index 6fdd118..bbe5c78 100644
--- a/src/beast/app/beauti/PriorListInputEditor.java
+++ b/src/beast/app/beauti/PriorListInputEditor.java
@@ -7,7 +7,6 @@ import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
@@ -15,20 +14,20 @@ import java.util.Set;
 import javax.swing.Box;
 import javax.swing.JButton;
 import javax.swing.JCheckBox;
-import javax.swing.JComboBox;
 import javax.swing.JOptionPane;
 
+import beast.app.draw.BEASTObjectPanel;
 import beast.app.draw.InputEditor;
 import beast.app.draw.ListInputEditor;
-import beast.app.draw.BEASTObjectPanel;
 import beast.app.draw.SmallButton;
+import beast.core.BEASTInterface;
 import beast.core.Distribution;
 import beast.core.Input;
 import beast.core.Logger;
 import beast.core.State;
 import beast.core.StateNode;
-import beast.core.BEASTInterface;
 import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
 import beast.evolution.alignment.Taxon;
 import beast.evolution.alignment.TaxonSet;
 import beast.evolution.tree.Tree;
@@ -43,9 +42,7 @@ import beast.math.distributions.Prior;
 public class PriorListInputEditor extends ListInputEditor {
     private static final long serialVersionUID = 1L;
 
-    List<JComboBox> comboBoxes;
     List<JButton> rangeButtons;
-    JComboBox currentComboBox;
 
     List<JButton> taxonButtons;
 
@@ -64,14 +61,12 @@ public class PriorListInputEditor extends ListInputEditor {
     }
 
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-    	List<?> list = (List) input.get();
-    	Collections.sort(list, new Comparator<Object>() {
-			@Override
-			public int compare(Object o1, Object o2) {
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+    	List<?> list = (List<?>) input.get();
+    	Collections.sort(list, (Object o1, Object o2) -> {
 				if (o1 instanceof BEASTInterface && o2 instanceof BEASTInterface) {
-					String sID1 = ((BEASTInterface)o1).getID();
-					String sID2 = ((BEASTInterface)o2).getID();
+					String d1 = ((BEASTInterface)o1).getID();
+					String id2 = ((BEASTInterface)o2).getID();
 					// first the tree priors
 					if (o1 instanceof TreeDistribution) {
 						if (o2 instanceof TreeDistribution) {
@@ -83,14 +78,14 @@ public class PriorListInputEditor extends ListInputEditor {
 							if (tree2 == null) {
 								tree2 = ((TreeDistribution)o2).treeIntervalsInput.get().treeInput.get();
 							}
-							return sID1.compareTo(sID2);
+							return d1.compareTo(id2);
 						} else {
 							return -1;
 						}
 					} else if (o1 instanceof MRCAPrior) {
 						// last MRCA priors
 						if (o2 instanceof MRCAPrior) {
-							return sID1.compareTo(sID2);
+							return d1.compareTo(id2);
 						} else {
 							return 1;
 						}
@@ -102,36 +97,33 @@ public class PriorListInputEditor extends ListInputEditor {
 							return -1;
 						}
 						if (o1 instanceof Prior) {
-							sID1 = ((Prior) o1).getParameterName(); 
+							d1 = ((Prior) o1).getParameterName(); 
 						}
 						if (o2 instanceof Prior) {
-							sID2 = ((Prior) o2).getParameterName(); 
+							id2 = ((Prior) o2).getParameterName(); 
 						}
-						return sID1.compareTo(sID2);
+						return d1.compareTo(id2);
 					}
 				}
 				return 0;
 			}
-		});
+		);
     	
     	
-        comboBoxes = new ArrayList<JComboBox>();
-        rangeButtons = new ArrayList<JButton>();
-        taxonButtons = new ArrayList<JButton>();
+        rangeButtons = new ArrayList<>();
+        taxonButtons = new ArrayList<>();
         
         //m_buttonStatus = ButtonStatus.NONE;
-        super.init(input, plugin, itemNr, bExpandOption, bAddButtons);
+        super.init(input, beastObject, itemNr, isExpandOption, addButtons);
 
         
         if (m_buttonStatus == ButtonStatus.ALL || m_buttonStatus == ButtonStatus.ADD_ONLY) {
 	        addButton = new SmallButton("+", true);
 	        addButton.setName("addItem");
 	        addButton.setToolTipText("Add item to the list");
-	        addButton.addActionListener(new ActionListener() {
-	            public void actionPerformed(ActionEvent e) {
+	        addButton.addActionListener(e -> {
 	                addItem();
-	            }
-	        });
+	            });
 	        buttonBox.add(addButton);
             buttonBox.add(Box.createHorizontalGlue());
         }
@@ -139,17 +131,17 @@ public class PriorListInputEditor extends ListInputEditor {
 
 
     /**
-     * add components to box that are specific for the plugin.
-     * By default, this just inserts a label with the plugin ID
+     * add components to box that are specific for the beastObject.
+     * By default, this just inserts a label with the beastObject ID
      *
      * @param itemBox box to add components to
-     * @param plugin  plugin to add
+     * @param beastObject  beastObject to add
      */
     @Override
-    protected InputEditor addPluginItem(Box itemBox, BEASTInterface plugin) {
+    protected InputEditor addPluginItem(Box itemBox, BEASTInterface beastObject) {
 		try {
-	    	int listItemNr = ((List) m_input.get()).indexOf(plugin);
-	    	InputEditor editor = doc.getInputEditorFactory().createInputEditor(m_input, listItemNr, plugin, false, ExpandOption.FALSE, ButtonStatus.NONE, null, doc);
+	    	int listItemNr = ((List<?>) m_input.get()).indexOf(beastObject);
+	    	InputEditor editor = doc.getInputEditorFactory().createInputEditor(m_input, listItemNr, beastObject, false, ExpandOption.FALSE, ButtonStatus.NONE, null, doc);
 	    	itemBox.add((Component) editor);
 	    	return editor;
 		} catch (Exception e) {
@@ -169,7 +161,7 @@ public class PriorListInputEditor extends ListInputEditor {
     }
 
     Set<Taxon> getTaxonCandidates(MRCAPrior prior) {
-        Set<Taxon> candidates = new HashSet<Taxon>();
+        Set<Taxon> candidates = new HashSet<>();
         Tree tree = prior.treeInput.get();
         String [] taxa = null;
         if (tree.m_taxonset.get() != null) {
@@ -184,8 +176,8 @@ public class PriorListInputEditor extends ListInputEditor {
         	taxa = prior.treeInput.get().getTaxaNames();
         }
         
-        for (String sTaxon : taxa) {
-            candidates.add(doc.getTaxon(sTaxon));
+        for (String taxon : taxa) {
+            candidates.add(doc.getTaxon(taxon));
         }
         return candidates;
     }
@@ -206,7 +198,7 @@ public class PriorListInputEditor extends ListInputEditor {
                 m_prior.isMonophyleticInput.setValue(((JCheckBox) e.getSource()).isSelected(), m_prior);
                 refreshPanel();
             } catch (Exception ex) {
-                System.err.println("PriorListInputEditor " + ex.getMessage());
+                Log.err.println("PriorListInputEditor " + ex.getMessage());
             }
         }
     }
@@ -218,11 +210,12 @@ public class PriorListInputEditor extends ListInputEditor {
         refreshPanel();
     } // addItem
 
-    protected List<BEASTInterface> pluginSelector(Input<?> input, BEASTInterface parent, List<String> tabooList) {
+    @Override
+	protected List<BEASTInterface> pluginSelector(Input<?> input, BEASTInterface parent, List<String> tabooList) {
         MRCAPrior prior = new MRCAPrior();
         try {
 
-            List<Tree> trees = new ArrayList<Tree>();
+            List<Tree> trees = new ArrayList<>();
             getDoc().scrubAll(true, false);
             State state = (State) doc.pluginmap.get("state");
             for (StateNode node : state.stateNodeInput.get()) {
@@ -230,20 +223,20 @@ public class PriorListInputEditor extends ListInputEditor {
                     trees.add((Tree) node);
                 }
             }
-            int iTree = 0;
+            int treeIndex = 0;
             if (trees.size() > 1) {
-                String[] sTreeIDs = new String[trees.size()];
-                for (int j = 0; j < sTreeIDs.length; j++) {
-                    sTreeIDs[j] = trees.get(j).getID();
+                String[] treeIDs = new String[trees.size()];
+                for (int j = 0; j < treeIDs.length; j++) {
+                    treeIDs[j] = trees.get(j).getID();
                 }
-                iTree = JOptionPane.showOptionDialog(null, "Select a tree", "MRCA selector",
+                treeIndex = JOptionPane.showOptionDialog(null, "Select a tree", "MRCA selector",
                         JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null,
-                        sTreeIDs, trees.get(0));
+                        treeIDs, trees.get(0));
             }
-            if (iTree < 0) {
+            if (treeIndex < 0) {
                 return null;
             }
-            prior.treeInput.setValue(trees.get(iTree), prior);
+            prior.treeInput.setValue(trees.get(treeIndex), prior);
             TaxonSet taxonSet = new TaxonSet();
 
             TaxonSetDialog dlg = new TaxonSetDialog(taxonSet, getTaxonCandidates(prior), doc);
@@ -264,7 +257,7 @@ public class PriorListInputEditor extends ListInputEditor {
         } catch (Exception e) {
             // TODO: handle exception
         }
-        List<BEASTInterface> selectedPlugins = new ArrayList<BEASTInterface>();
+        List<BEASTInterface> selectedPlugins = new ArrayList<>();
         selectedPlugins.add(prior);
         g_collapsedIDs.add(prior.getID());
         return selectedPlugins;
diff --git a/src/beast/app/beauti/SiteModelInputEditor.java b/src/beast/app/beauti/SiteModelInputEditor.java
index 7db776b..9fdf56c 100644
--- a/src/beast/app/beauti/SiteModelInputEditor.java
+++ b/src/beast/app/beauti/SiteModelInputEditor.java
@@ -1,8 +1,7 @@
 package beast.app.beauti;
 
 import java.awt.Color;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -13,16 +12,16 @@ import javax.swing.JTextField;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
 
+import beast.app.draw.BEASTObjectInputEditor;
 import beast.app.draw.InputEditor;
 import beast.app.draw.IntegerInputEditor;
 import beast.app.draw.ParameterInputEditor;
 import beast.app.draw.SmallLabel;
-import beast.app.draw.BEASTObjectInputEditor;
+import beast.core.BEASTInterface;
 import beast.core.Distribution;
 import beast.core.Input;
 import beast.core.MCMC;
 import beast.core.Operator;
-import beast.core.BEASTInterface;
 import beast.core.parameter.IntegerParameter;
 import beast.core.parameter.RealParameter;
 import beast.core.util.CompoundDistribution;
@@ -55,24 +54,21 @@ public class SiteModelInputEditor extends BEASTObjectInputEditor {
     }
     
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr,
-    		ExpandOption bExpandOption, boolean bAddButtons) {
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr,
+    		ExpandOption isExpandOption, boolean addButtons) {
     	fixMeanRatesCheckBox = new JCheckBox("Fix mean substitution rate");
     	fixMeanRatesCheckBox.setName("FixMeanMutationRate");
-    	fixMeanRatesCheckBox.setEnabled(!doc.bAutoUpdateFixMeanSubstRate);
-    	super.init(input, plugin, itemNr, bExpandOption, bAddButtons);
+    	fixMeanRatesCheckBox.setEnabled(!doc.autoUpdateFixMeanSubstRate);
+    	super.init(input, beastObject, itemNr, isExpandOption, addButtons);
 
 		List<Operator> operators = ((MCMC) doc.mcmc.get()).operatorsInput.get();
-    	fixMeanRatesCheckBox.addActionListener(new ActionListener() {			
-			@Override
-			public void actionPerformed(ActionEvent e) {
+    	fixMeanRatesCheckBox.addActionListener(e -> {
 				JCheckBox averageRatesBox = (JCheckBox) e.getSource();
 				doFixMeanRates(averageRatesBox.isSelected());
 				if (averageRatesBox.isSelected())
 					// set up relative weights
 					setUpOperator();
-			}
-		});
+			});
     	operator = (DeltaExchangeOperator) doc.pluginmap.get("FixMeanMutationRatesOperator");
     	if (operator == null) {
     		operator = new DeltaExchangeOperator();
@@ -119,25 +115,26 @@ public class SiteModelInputEditor extends BEASTObjectInputEditor {
 		}
 	}
 
-    public InputEditor createMutationRateEditor() throws Exception {
+    public InputEditor createMutationRateEditor() {
     	SiteModel sitemodel = ((SiteModel) m_input.get()); 
-        Input<?> input = sitemodel.muParameterInput;
+        final Input<?> input = sitemodel.muParameterInput;
         ParameterInputEditor mutationRateEditor = new ParameterInputEditor(doc);
         mutationRateEditor.init(input, sitemodel, -1, ExpandOption.FALSE, true);
-        mutationRateEditor.getEntry().setEnabled(!doc.bAutoUpdateFixMeanSubstRate);
+        mutationRateEditor.getEntry().setEnabled(!doc.autoUpdateFixMeanSubstRate);
         return mutationRateEditor;
     }
 	
-	public InputEditor createGammaCategoryCountEditor() throws Exception {
+	public InputEditor createGammaCategoryCountEditor() {
     	SiteModel sitemodel = ((SiteModel) m_input.get()); 
-        Input<?> input = sitemodel.gammaCategoryCount;
+        final Input<?> input = sitemodel.gammaCategoryCount;
         categoryCountEditor = new IntegerInputEditor(doc) {
 			private static final long serialVersionUID = 1L;
 
+			@Override
 			public void validateInput() {
         		super.validateInput();
-            	SiteModel sitemodel = (SiteModel) m_plugin; 
-                if (sitemodel.gammaCategoryCount.get() < 2 && ((RealParameter)sitemodel.shapeParameterInput.get()).isEstimatedInput.get()) {
+            	SiteModel sitemodel = (SiteModel) m_beastObject; 
+                if (sitemodel.gammaCategoryCount.get() < 2 && sitemodel.shapeParameterInput.get().isEstimatedInput.get()) {
                 	m_validateLabel.m_circleColor = Color.orange;
                 	m_validateLabel.setToolTipText("shape parameter is estimated, but not used");
                 	m_validateLabel.setVisible(true);
@@ -169,25 +166,25 @@ public class SiteModelInputEditor extends BEASTObjectInputEditor {
     }
 
     void processEntry2() {
-        String sCategories = categoryCountEntry.getText();
+        String categories = categoryCountEntry.getText();
         try {
-            int nCategories = Integer.parseInt(sCategories);
-            gammaShapeEditor.getComponent().setVisible(nCategories >= 2);
+            int categoryCount = Integer.parseInt(categories);
+            gammaShapeEditor.getComponent().setVisible(categoryCount >= 2);
             repaint();
         } catch (java.lang.NumberFormatException e) {
             // ignore.
         }
     }
 
-    public InputEditor createShapeEditor() throws Exception {
-        Input<?> input = ((SiteModel) m_input.get()).shapeParameterInput;
+    public InputEditor createShapeEditor() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+        final Input<?> input = ((SiteModel) m_input.get()).shapeParameterInput;
         gammaShapeEditor = doc.getInputEditorFactory().createInputEditor(input, (BEASTInterface) m_input.get(), doc);
         gammaShapeEditor.getComponent().setVisible(((SiteModel) m_input.get()).gammaCategoryCount.get() >= 2);
         return gammaShapeEditor;
     }
 
-    public InputEditor createProportionInvariantEditor() throws Exception {
-        Input<?> input = ((SiteModel) m_input.get()).invarParameterInput;
+    public InputEditor createProportionInvariantEditor() {
+        final Input<?> input = ((SiteModel) m_input.get()).invarParameterInput;
         inVarEditor = new ParameterInputEditor(doc) {
 			private static final long serialVersionUID = 1L;
 
@@ -275,10 +272,10 @@ public class SiteModelInputEditor extends BEASTObjectInputEditor {
     
     /** set up relative weights and parameter input **/
     public void setUpOperator() {
-    	boolean bAllClocksAreEqual = true;
+    	boolean isAllClocksAreEqual = true;
     	try {
     		boolean hasOneEstimatedRate = customConnector(doc);
-		    if (doc.bAutoUpdateFixMeanSubstRate) {
+		    if (doc.autoUpdateFixMeanSubstRate) {
 		    	fixMeanRatesCheckBox.setSelected(hasOneEstimatedRate);
 		    	doFixMeanRates(hasOneEstimatedRate);
 		    }
@@ -298,7 +295,7 @@ public class SiteModelInputEditor extends BEASTObjectInputEditor {
     		    				commonClockRate = mutationRate.valuesInput.get().get(0);
     		    			} else {
     		    				if (Math.abs(commonClockRate - mutationRate.valuesInput.get().get(0)) > 1e-10) {
-    		    					bAllClocksAreEqual = false;
+    		    					isAllClocksAreEqual = false;
     		    				}
     		    			}
     		    		}
@@ -322,7 +319,7 @@ public class SiteModelInputEditor extends BEASTObjectInputEditor {
 				repaint();
 	    		return;
 	    	}
-	    	if (!bAllClocksAreEqual) {
+	    	if (!isAllClocksAreEqual) {
 	    		fixMeanRatesValidateLabel.setVisible(true);
 	    		fixMeanRatesValidateLabel.m_circleColor = Color.orange;
 	    		fixMeanRatesValidateLabel.setToolTipText("Not all clocks are equal. Are you sure this is what you want?");
diff --git a/src/beast/app/beauti/SpeciesTreePriorInputEditor.java b/src/beast/app/beauti/SpeciesTreePriorInputEditor.java
index 35f46a0..c2c4c72 100644
--- a/src/beast/app/beauti/SpeciesTreePriorInputEditor.java
+++ b/src/beast/app/beauti/SpeciesTreePriorInputEditor.java
@@ -4,9 +4,8 @@ import javax.swing.Box;
 import javax.swing.JComponent;
 
 import beast.app.draw.BEASTObjectInputEditor;
-import beast.core.Input;
-import beast.core.BEASTObject;
 import beast.core.BEASTInterface;
+import beast.core.Input;
 import beast.evolution.speciation.SpeciesTreePrior;
 
 
@@ -24,11 +23,12 @@ public class SpeciesTreePriorInputEditor extends BEASTObjectInputEditor {
 	}
 	
 	@Override
-	public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-		super.init(input, plugin, itemNr, bExpandOption, bAddButtons);
+	public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+		super.init(input, beastObject, itemNr, isExpandOption, addButtons);
 	}
 
-    protected void addComboBox(JComponent box, Input<?> input, BEASTInterface plugin) {
+    @Override
+	protected void addComboBox(JComponent box, Input<?> input, BEASTInterface beastObject) {
     	m_bAddButtons = true;
     	String label = "Species Tree Population Size";
     	addInputLabel(label, label);
diff --git a/src/beast/app/beauti/StateNodeListInputEditor.java b/src/beast/app/beauti/StateNodeListInputEditor.java
index 97f2498..ad265f1 100644
--- a/src/beast/app/beauti/StateNodeListInputEditor.java
+++ b/src/beast/app/beauti/StateNodeListInputEditor.java
@@ -3,10 +3,9 @@ package beast.app.beauti;
 import java.util.List;
 
 import beast.app.draw.ListInputEditor;
+import beast.core.BEASTInterface;
 import beast.core.Input;
 import beast.core.StateNode;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 
 
 
@@ -28,9 +27,9 @@ public class StateNodeListInputEditor extends ListInputEditor {
 	}
 	
 	@Override
-	public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
+	public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
 		m_buttonStatus = ButtonStatus.NONE;
-		super.init(input, plugin, itemNr, bExpandOption, bAddButtons);
+		super.init(input, beastObject, itemNr, isExpandOption, addButtons);
 	}
 
 }
diff --git a/src/beast/app/beauti/TaxonSetDialog.java b/src/beast/app/beauti/TaxonSetDialog.java
index 186b3a4..d654bfa 100644
--- a/src/beast/app/beauti/TaxonSetDialog.java
+++ b/src/beast/app/beauti/TaxonSetDialog.java
@@ -3,8 +3,6 @@ package beast.app.beauti;
 import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Frame;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Comparator;
@@ -22,7 +20,6 @@ import javax.swing.JList;
 import javax.swing.JOptionPane;
 import javax.swing.JScrollPane;
 import javax.swing.JTextField;
-import javax.swing.ListCellRenderer;
 import javax.swing.border.EmptyBorder;
 import javax.swing.border.EtchedBorder;
 import javax.swing.event.DocumentEvent;
@@ -37,17 +34,17 @@ public class TaxonSetDialog extends JDialog {
     private static final long serialVersionUID = 1L;
     public boolean isOK = false;
     TaxonSet taxonSet;
-    String sID;
+    String id;
     List<Taxon> _candidates;
 
     JTextField idEntry;
 
     JTextField filterEntry;
 
-    JList listOfTaxonCandidates;
-    DefaultListModel listModel1;
-    JList listOfTaxonSet;
-    DefaultListModel listModel2;
+    JList<Taxon> listOfTaxonCandidates;
+    DefaultListModel<Taxon> listModel1;
+    JList<Taxon> listOfTaxonSet;
+    DefaultListModel<Taxon> listModel2;
 
 
     Box box;
@@ -57,7 +54,7 @@ public class TaxonSetDialog extends JDialog {
         // initialize state
         this.taxonSet = taxonSet;
         this.doc = doc;
-        sID = taxonSet.getID();
+        id = taxonSet.getID();
         // create components
         box = Box.createVerticalBox();
         box.add(createIDBox());
@@ -111,13 +108,13 @@ public class TaxonSetDialog extends JDialog {
         }
         isOK =  (result != JOptionPane.CANCEL_OPTION);
         if (isOK) {
-            taxonSet.setID(sID);
+            taxonSet.setID(id);
             List<Taxon> taxa = taxonSet.taxonsetInput.get();
             while (taxa.size() > 0) {
                 taxa.remove(0);
             }
             for (int i = 0; i < listModel2.size(); i++) {
-                taxa.add((Taxon) listModel2.get(i));
+                taxa.add(listModel2.get(i));
             }
             isOK = true;
             dispose();
@@ -162,11 +159,11 @@ public class TaxonSetDialog extends JDialog {
     }
 
     private void processEntry() {
-        String sFilter = ".*" + filterEntry.getText() + ".*";
+        String filter = ".*" + filterEntry.getText() + ".*";
 
         listModel1.clear();
         for (Taxon taxon : _candidates) {
-            if (taxon.getID().matches(sFilter)) {
+            if (taxon.getID().matches(filter)) {
                 listModel1.addElement(taxon);
             }
         }
@@ -180,22 +177,22 @@ public class TaxonSetDialog extends JDialog {
         box.add(new JLabel("Taxon set label:"));
         idEntry = new JTextField();
         idEntry.setName("idEntry");
-        idEntry.setText(sID);
+        idEntry.setText(id);
         box.add(idEntry);
         idEntry.getDocument().addDocumentListener(new DocumentListener() {
             @Override
             public void removeUpdate(DocumentEvent e) {
-                sID = idEntry.getText();
+                id = idEntry.getText();
             }
 
             @Override
             public void insertUpdate(DocumentEvent e) {
-                sID = idEntry.getText();
+                id = idEntry.getText();
             }
 
             @Override
             public void changedUpdate(DocumentEvent e) {
-                sID = idEntry.getText();
+                id = idEntry.getText();
             }
         });
 
@@ -204,8 +201,10 @@ public class TaxonSetDialog extends JDialog {
     }
     
     class TaxonCellRenderer extends DefaultListCellRenderer {
+		private static final long serialVersionUID = 1L;
+
 		@Override
-		public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
+		public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
 				boolean cellHasFocus) {
 			JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
 			label.setText(((Taxon)value).getID());
@@ -217,8 +216,8 @@ public class TaxonSetDialog extends JDialog {
         Box box = Box.createHorizontalBox();
 
         // list of taxa to select from
-        listModel1 = new DefaultListModel();
-        listOfTaxonCandidates = new JList(listModel1);
+        listModel1 = new DefaultListModel<>();
+        listOfTaxonCandidates = new JList<>(listModel1);
         listOfTaxonCandidates.setName("listOfTaxonCandidates");
         listOfTaxonCandidates.setBorder(BorderFactory.createEtchedBorder());
         listOfTaxonCandidates.setCellRenderer(new TaxonCellRenderer());
@@ -231,38 +230,34 @@ public class TaxonSetDialog extends JDialog {
         buttonBox.add(Box.createGlue());
         JButton selectButton = new JButton(">>");
         selectButton.setName(">>");
-        selectButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                int[] nSelected = listOfTaxonCandidates.getSelectedIndices();
-                for (int i : nSelected) {
+        selectButton.addActionListener(e -> {
+                int[] selected = listOfTaxonCandidates.getSelectedIndices();
+                for (int i : selected) {
                     listModel2.addElement(listModel1.get(i));
                 }
                 for (int i = 0; i < listModel2.size(); i++) {
                     listModel1.removeElement(listModel2.get(i));
                 }
-            }
-        });
+            });
         buttonBox.add(selectButton);
         JButton deselectButton = new JButton("<<");
         deselectButton.setName("<<");
-        deselectButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                int[] nSelected = listOfTaxonSet.getSelectedIndices();
-                for (int i : nSelected) {
+        deselectButton.addActionListener(e -> {
+                int[] selected = listOfTaxonSet.getSelectedIndices();
+                for (int i : selected) {
                     listModel1.addElement(listModel2.get(i));
                 }
                 for (int i = 0; i < listModel1.size(); i++) {
                     listModel2.removeElement(listModel1.get(i));
                 }
-            }
-        });
+            });
         buttonBox.add(deselectButton);
         buttonBox.add(Box.createGlue());
         box.add(buttonBox);
 
         // list of taxa in taxon set
-        listModel2 = new DefaultListModel();
-        listOfTaxonSet = new JList(listModel2);
+        listModel2 = new DefaultListModel<>();
+        listOfTaxonSet = new JList<>(listModel2);
         listOfTaxonSet.setBorder(BorderFactory.createEtchedBorder());
         listOfTaxonSet.setCellRenderer(new TaxonCellRenderer());
 
@@ -276,27 +271,23 @@ public class TaxonSetDialog extends JDialog {
         cancelOkBox.setBorder(new EtchedBorder());
         JButton okButton = new JButton("Ok");
         okButton.setName("OK");
-        okButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                taxonSet.setID(sID);
+        okButton.addActionListener(e -> {
+                taxonSet.setID(id);
                 List<Taxon> taxa = taxonSet.taxonsetInput.get();
                 while (taxa.size() > 0) {
                     taxa.remove(0);
                 }
                 for (int i = 0; i < listModel2.size(); i++) {
-                    taxa.add((Taxon) listModel2.get(i));
+                    taxa.add(listModel2.get(i));
                 }
                 isOK = true;
                 dispose();
-            }
-        });
+            });
         JButton cancelButton = new JButton("Cancel");
         cancelButton.setName("Cancel");
-        cancelButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+        cancelButton.addActionListener(e -> {
                 dispose();
-            }
-        });
+            });
         cancelOkBox.add(Box.createHorizontalGlue());
         cancelOkBox.add(okButton);
         cancelOkBox.add(Box.createHorizontalGlue());
diff --git a/src/beast/app/beauti/TaxonSetInputEditor.java b/src/beast/app/beauti/TaxonSetInputEditor.java
index 27a615c..baf4dbe 100644
--- a/src/beast/app/beauti/TaxonSetInputEditor.java
+++ b/src/beast/app/beauti/TaxonSetInputEditor.java
@@ -3,16 +3,27 @@ package beast.app.beauti;
 import java.awt.Color;
 import java.awt.Component;
 import java.awt.Dimension;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.EventObject;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.regex.PatternSyntaxException;
 
-import javax.swing.*;
+import javax.swing.Box;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
 import javax.swing.event.CellEditorListener;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
@@ -22,9 +33,8 @@ import javax.swing.table.TableCellEditor;
 import javax.swing.table.TableCellRenderer;
 
 import beast.app.draw.InputEditor;
-import beast.core.Input;
-import beast.core.BEASTObject;
 import beast.core.BEASTInterface;
+import beast.core.Input;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.alignment.FilteredAlignment;
 import beast.evolution.alignment.Sequence;
@@ -56,19 +66,19 @@ public class TaxonSetInputEditor extends InputEditor.Base {
     }
 
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
         m_input = input;
-        m_plugin = plugin;
+        m_beastObject = beastObject;
 		this.itemNr = itemNr;
         TaxonSet taxonset = (TaxonSet) m_input.get();
         if (taxonset == null) {
             return;
         }
-        List<Taxon> taxonsets = new ArrayList<Taxon>();
+        List<Taxon> taxonsets = new ArrayList<>();
 
         List<Taxon> taxa = taxonset.taxonsetInput.get();
         for (Taxon taxon : taxa) {
-            taxonsets.add((TaxonSet) taxon);
+            taxonsets.add(taxon);
         }
         add(getContent(taxonsets));
         if (taxa.size() == 1 && taxa.get(0).getID().equals("Beauti2DummyTaxonSet") || taxa.size() == 0) {
@@ -92,8 +102,8 @@ public class TaxonSetInputEditor extends InputEditor.Base {
 
     private Component getContent(List<Taxon> taxonset) {
         m_taxonset = taxonset;
-        m_taxonMap = new HashMap<String, String>();
-        m_lineageset = new ArrayList<Taxon>();
+        m_taxonMap = new HashMap<>();
+        m_lineageset = new ArrayList<>();
         for (Taxon taxonset2 : m_taxonset) {
             for (Taxon taxon : ((TaxonSet) taxonset2).taxonsetInput.get()) {
                 m_lineageset.add(taxon);
@@ -139,17 +149,19 @@ public class TaxonSetInputEditor extends InputEditor.Base {
             @Override
             public boolean stopCellEditing() {
                 m_table.removeEditor();
-                String sText = m_textField.getText();
-                System.err.println(sText);
-                m_model.setValueAt(sText, m_iRow, m_iCol);
+                String text = m_textField.getText();
+                //Log.warning.println(text);
+                m_model.setValueAt(text, m_iRow, m_iCol);
+
                 // try {
-                // Double.parseDouble(sText);
+                // Double.parseDouble(text);
                 // } catch (Exception e) {
                 // return false;
                 // }
                 modelToTaxonset();
                 return true;
             }
+            
 
             @Override
             public boolean isCellEditable(EventObject anEvent) {
@@ -157,13 +169,13 @@ public class TaxonSetInputEditor extends InputEditor.Base {
             }
 
             @Override
-            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int iRow,
-                                                         int iCol) {
+            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int rowNr,
+                                                         int colNr) {
                 if (!isSelected) {
                     return null;
                 }
-                m_iRow = iRow;
-                m_iCol = iCol;
+                m_iRow = rowNr;
+                m_iCol = colNr;
                 m_textField.setText((String) value);
                 return m_textField;
             }
@@ -191,6 +203,7 @@ public class TaxonSetInputEditor extends InputEditor.Base {
             }
 
         });
+        m_table.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
         m_table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
         m_table.getColumnModel().getColumn(0).setPreferredWidth(250);
         m_table.getColumnModel().getColumn(1).setPreferredWidth(250);
@@ -217,30 +230,23 @@ public class TaxonSetInputEditor extends InputEditor.Base {
         JButton fillDownButton = new JButton("Fill down");
         fillDownButton.setName("Fill down");
         fillDownButton.setToolTipText("replaces all taxons in selection with the one that is selected at the top");
-        fillDownButton.addActionListener(new ActionListener() {
-
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        fillDownButton.addActionListener(e -> {
                 int[] rows = m_table.getSelectedRows();
                 if (rows.length < 2) {
                     return;
                 }
-                String sTaxon = (String) ((Vector<?>) m_model.getDataVector().elementAt(rows[0])).elementAt(1);
+                String taxon = (String) ((Vector<?>) m_model.getDataVector().elementAt(rows[0])).elementAt(1);
                 for (int i = 1; i < rows.length; i++) {
-                    m_model.setValueAt(sTaxon, rows[i], 1);
+                    m_model.setValueAt(taxon, rows[i], 1);
                 }
                 modelToTaxonset();
-            }
-        });
+            });
 
         JButton guessButton = new JButton("Guess");
         guessButton.setName("Guess");
-        guessButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        guessButton.addActionListener(e -> {
                 guess();
-            }
-        });
+            });
 
         buttonBox.add(Box.createHorizontalGlue());
         buttonBox.add(fillDownButton);
@@ -251,7 +257,8 @@ public class TaxonSetInputEditor extends InputEditor.Base {
     }
 
     public class ColumnHeaderListener extends MouseAdapter {
-        public void mouseClicked(MouseEvent evt) {
+        @Override
+		public void mouseClicked(MouseEvent evt) {
             // The index of the column whose header was clicked
             int vColIndex = m_table.getColumnModel().getColumnIndexAtX(evt.getX());
             if (vColIndex == -1) {
@@ -272,10 +279,10 @@ public class TaxonSetInputEditor extends InputEditor.Base {
         switch(dlg.showDialog("Guess taxon sets")) {
         case canceled: return;
         case pattern: 
-        String sPattern = dlg.getPattern();
+        String pattern = dlg.getPattern();
             try {
-                guessTaxonSets(sPattern, 0);
-                m_sPattern = sPattern;
+                guessTaxonSets(pattern, 0);
+                m_sPattern = pattern;
                 break;
             } catch (Exception e) {
                 e.printStackTrace();
@@ -297,27 +304,27 @@ public class TaxonSetInputEditor extends InputEditor.Base {
     }
 
     /**
-     * guesses taxon sets based on pattern in sRegExp based on the taxa in
+     * guesses taxon sets based on pattern in regExp based on the taxa in
      * m_rawData
      */
-    public int guessTaxonSets(String sRegexp, int nMinSize) throws Exception {
+    public int guessTaxonSets(String regexp, int minSize) {
         m_taxonset.clear();
-        HashMap<String, TaxonSet> map = new HashMap<String, TaxonSet>();
-        Pattern m_pattern = Pattern.compile(sRegexp);
-        Set<Taxon> taxa = new HashSet<Taxon>();
-        Set<String> taxonIDs = new HashSet<String>();
+        HashMap<String, TaxonSet> map = new HashMap<>();
+        Pattern m_pattern = Pattern.compile(regexp);
+        Set<Taxon> taxa = new HashSet<>();
+        Set<String> taxonIDs = new HashSet<>();
         for (Alignment alignment : getDoc().alignments) {
-        	for (String sID : alignment.getTaxaNames()) {
-                if (!taxonIDs.contains(sID)) {
+        	for (String id : alignment.getTaxaNames()) {
+                if (!taxonIDs.contains(id)) {
 	                Taxon taxon = new Taxon();
-	                taxon.setID(sID);
+	                taxon.setID(id);
 	                taxa.add(taxon);
-	                taxonIDs.add(sID);
+	                taxonIDs.add(id);
         		}
         	}
             for (Sequence sequence : alignment.sequenceInput.get()) {
-                String sID = sequence.taxonInput.get();
-                if (!taxonIDs.contains(sID)) {
+                String id = sequence.taxonInput.get();
+                if (!taxonIDs.contains(id)) {
                     Taxon taxon = new Taxon();
                     // ensure sequence and taxon do not get same ID
                     if (sequence.getID().equals(sequence.taxonInput.get())) {
@@ -325,7 +332,7 @@ public class TaxonSetInputEditor extends InputEditor.Base {
                     }
                     taxon.setID(sequence.taxonInput.get());
                     taxa.add(taxon);
-                    taxonIDs.add(sID);
+                    taxonIDs.add(id);
                 }
             }
         }
@@ -334,16 +341,16 @@ public class TaxonSetInputEditor extends InputEditor.Base {
             if (!(taxon instanceof TaxonSet)) {
                 Matcher matcher = m_pattern.matcher(taxon.getID());
                 if (matcher.find()) {
-                    String sMatch = matcher.group(1);
+                    String match = matcher.group(1);
                     try {
-                        if (map.containsKey(sMatch)) {
-                            TaxonSet set = map.get(sMatch);
+                        if (map.containsKey(match)) {
+                            TaxonSet set = map.get(match);
                             set.taxonsetInput.setValue(taxon, set);
                         } else {
                             TaxonSet set = new TaxonSet();
-                            set.setID(sMatch);
+                            set.setID(match);
                             set.taxonsetInput.setValue(taxon, set);
-                            map.put(sMatch, set);
+                            map.put(match, set);
                         }
                     } catch (Exception ex) {
                         ex.printStackTrace();
@@ -352,19 +359,19 @@ public class TaxonSetInputEditor extends InputEditor.Base {
             }
         }
         // add taxon sets
-        int nIgnored = 0;
+        int ignored = 0;
         for (TaxonSet set : map.values()) {
-            if (set.taxonsetInput.get().size() > nMinSize) {
+            if (set.taxonsetInput.get().size() > minSize) {
                 m_taxonset.add(set);
             } else {
-                nIgnored += set.taxonsetInput.get().size();
+                ignored += set.taxonsetInput.get().size();
             }
         }
-        return nIgnored;
+        return ignored;
     }
 
     void parseTrait(String trait) {
-    	Map<String,String> traitmap = new HashMap<String, String>();
+    	Map<String,String> traitmap = new HashMap<>();
     	for (String line : trait.split(",")) {
     		String [] strs = line.split("=");
     		if (strs.length == 2) {
@@ -374,15 +381,15 @@ public class TaxonSetInputEditor extends InputEditor.Base {
     	
         m_taxonset.clear();
 
-        Set<Taxon> taxa = new HashSet<Taxon>();
-        Set<String> taxonIDs = new HashSet<String>();
+        Set<Taxon> taxa = new HashSet<>();
+        Set<String> taxonIDs = new HashSet<>();
         for (Alignment alignment : getDoc().alignments) {
         	if (alignment instanceof FilteredAlignment) {
         		alignment = ((FilteredAlignment)alignment).alignmentInput.get();
         	}
             for (Sequence sequence : alignment.sequenceInput.get()) {
-                String sID = sequence.taxonInput.get();
-                if (!taxonIDs.contains(sID)) {
+                String id = sequence.taxonInput.get();
+                if (!taxonIDs.contains(id)) {
                     Taxon taxon = new Taxon();
                     // ensure sequence and taxon do not get same ID
                     if (sequence.getID().equals(sequence.taxonInput.get())) {
@@ -390,25 +397,25 @@ public class TaxonSetInputEditor extends InputEditor.Base {
                     }
                     taxon.setID(sequence.taxonInput.get());
                     taxa.add(taxon);
-                    taxonIDs.add(sID);
+                    taxonIDs.add(id);
                 }
             }
         }
 
-        HashMap<String, TaxonSet> map = new HashMap<String, TaxonSet>();
+        HashMap<String, TaxonSet> map = new HashMap<>();
         for (Taxon taxon : taxa) {
             if (!(taxon instanceof TaxonSet)) {
-                String sMatch = traitmap.get(taxon.getID());
-                if (sMatch != null) {
+                String match = traitmap.get(taxon.getID());
+                if (match != null) {
                     try {
-                        if (map.containsKey(sMatch)) {
-                            TaxonSet set = map.get(sMatch);
+                        if (map.containsKey(match)) {
+                            TaxonSet set = map.get(match);
                             set.taxonsetInput.setValue(taxon, set);
                         } else {
                             TaxonSet set = new TaxonSet();
-                            set.setID(sMatch);
+                            set.setID(match);
                             set.taxonsetInput.setValue(taxon, set);
-                            map.put(sMatch, set);
+                            map.put(match, set);
                         }
                     } catch (Exception ex) {
                         ex.printStackTrace();
@@ -417,7 +424,6 @@ public class TaxonSetInputEditor extends InputEditor.Base {
             }
         }
         // add taxon sets
-        int nIgnored = 0;
         for (TaxonSet set : map.values()) {
              m_taxonset.add(set);
         }
@@ -456,11 +462,11 @@ public class TaxonSetInputEditor extends InputEditor.Base {
             }
 
             private void processFilter() {
-                String sFilter = ".*" + filterEntry.getText() + ".*";
+                String filter = ".*" + filterEntry.getText() + ".*";
                 try {
                     // sanity check: make sure the filter is legit
-                    sFilter.matches(sFilter);
-                    m_sFilter = sFilter;
+                    filter.matches(filter);
+                    m_sFilter = filter;
                     taxonSetToModel();
                     m_table.repaint();
                 } catch (PatternSyntaxException e) {
@@ -476,34 +482,24 @@ public class TaxonSetInputEditor extends InputEditor.Base {
      */
     @SuppressWarnings("unchecked")
     private void taxonSetToModel() {
-        // count number of lineages that match the filter
-        int i = 0;
-        for (String sLineageID : m_taxonMap.keySet()) {
-            if (sLineageID.matches(m_sFilter)) {
-                i++;
-            }
-        }
-
         // clear table model
         while (m_model.getRowCount() > 0) {
             m_model.removeRow(0);
         }
 
         // fill table model with lineages matching the filter
-        for (String sLineageID : m_taxonMap.keySet()) {
-            if (sLineageID.matches(m_sFilter)) {
+        for (String lineageID : m_taxonMap.keySet()) {
+            if (lineageID.matches(m_sFilter)) {
                 Object[] rowData = new Object[2];
-                rowData[0] = sLineageID;
-                rowData[1] = m_taxonMap.get(sLineageID);
+                rowData[0] = lineageID;
+                rowData[1] = m_taxonMap.get(lineageID);
                 m_model.addRow(rowData);
             }
         }
 
         @SuppressWarnings("rawtypes")
         Vector data = m_model.getDataVector();
-        Collections.sort(data, new Comparator<Vector<?>>() {
-            @Override
-            public int compare(Vector<?> v1, Vector<?> v2) {
+        Collections.sort(data, (Vector<?> v1, Vector<?> v2) -> {
                 String o1 = (String) v1.get(m_sortByColumn);
                 String o2 = (String) v2.get(m_sortByColumn);
                 if (o1.equals(o2)) {
@@ -517,7 +513,7 @@ public class TaxonSetInputEditor extends InputEditor.Base {
                 }
             }
 
-        });
+        );
         m_model.fireTableRowsInserted(0, m_model.getRowCount());
     }
 
@@ -525,19 +521,20 @@ public class TaxonSetInputEditor extends InputEditor.Base {
      * for convert table model to taxon sets *
      */
     private void modelToTaxonset() {
+
         // update map
         for (int i = 0; i < m_model.getRowCount(); i++) {
-            String sLineageID = (String) ((Vector<?>) m_model.getDataVector().elementAt(i)).elementAt(0);
-            String sTaxonSetID = (String) ((Vector<?>) m_model.getDataVector().elementAt(i)).elementAt(1);
+            String lineageID = (String) ((Vector<?>) m_model.getDataVector().elementAt(i)).elementAt(0);
+            String taxonSetID = (String) ((Vector<?>) m_model.getDataVector().elementAt(i)).elementAt(1);
 
             // new taxon set?
-            if (!m_taxonMap.containsValue(sTaxonSetID)) {
+            if (!m_taxonMap.containsValue(taxonSetID)) {
                 // create new taxon set
                 TaxonSet taxonset = new TaxonSet();
-                taxonset.setID(sTaxonSetID);
+                taxonset.setID(taxonSetID);
                 m_taxonset.add(taxonset);
             }
-            m_taxonMap.put(sLineageID, sTaxonSetID);
+            m_taxonMap.put(lineageID, taxonSetID);
         }
 
         // clear old taxon sets
@@ -548,13 +545,13 @@ public class TaxonSetInputEditor extends InputEditor.Base {
         }
 
         // group lineages with their taxon sets
-        for (String sLineageID : m_taxonMap.keySet()) {
+        for (String lineageID : m_taxonMap.keySet()) {
             for (Taxon taxon : m_lineageset) {
-                if (taxon.getID().equals(sLineageID)) {
-                    String sTaxonSet = m_taxonMap.get(sLineageID);
+                if (taxon.getID().equals(lineageID)) {
+                    String taxonSet = m_taxonMap.get(lineageID);
                     for (Taxon taxon2 : m_taxonset) {
                         TaxonSet set = (TaxonSet) taxon2;
-                        if (set.getID().equals(sTaxonSet)) {
+                        if (set.getID().equals(taxonSet)) {
                             try {
                                 set.taxonsetInput.setValue(taxon, set);
                             } catch (Exception e) {
diff --git a/src/beast/app/beauti/TipDatesInputEditor.java b/src/beast/app/beauti/TipDatesInputEditor.java
index 3cd5eb3..6e611ee 100644
--- a/src/beast/app/beauti/TipDatesInputEditor.java
+++ b/src/beast/app/beauti/TipDatesInputEditor.java
@@ -1,14 +1,14 @@
 package beast.app.beauti;
 
-import java.awt.Color;
-import java.awt.Component;
+import java.awt.*;
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.text.DateFormat;
-import java.text.FieldPosition;
-import java.text.ParseException;
-import java.text.ParsePosition;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.EventObject;
+import java.util.GregorianCalendar;
+import java.util.List;
 
 import javax.swing.Box;
 import javax.swing.JButton;
@@ -23,8 +23,9 @@ import javax.swing.table.TableCellEditor;
 import javax.swing.table.TableCellRenderer;
 
 import beast.app.draw.BEASTObjectInputEditor;
-import beast.core.Input;
 import beast.core.BEASTInterface;
+import beast.core.Input;
+import beast.core.util.Log;
 import beast.evolution.alignment.Taxon;
 import beast.evolution.alignment.TaxonSet;
 import beast.evolution.operators.TipDatesRandomWalker;
@@ -46,9 +47,9 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
     }
     Tree tree;
     TraitSet traitSet;
-    JComboBox unitsComboBox;
-    JComboBox relativeToComboBox;
-    List<String> sTaxa;
+    JComboBox<TraitSet.Units> unitsComboBox;
+    JComboBox<String> relativeToComboBox;
+    List<String> taxa;
     Object[][] tableData;
     JTable table;
     String m_sPattern = ".*(\\d\\d\\d\\d).*";
@@ -56,8 +57,8 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
     List<Taxon> taxonsets;
 
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-        m_bAddButtons = bAddButtons;
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+        m_bAddButtons = addButtons;
         this.itemNr = itemNr;
         if (itemNr >= 0) {
             tree = (Tree) ((List<?>) input.get()).get(itemNr);
@@ -71,15 +72,13 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
                 // TODO Auto-generated catch block
                 e1.printStackTrace();
             }
-            m_plugin = (BEASTInterface) tree;
+            m_beastObject = tree;
             traitSet = tree.getDateTrait();
 
             Box box = Box.createVerticalBox();
 
             JCheckBox useTipDates = new JCheckBox("Use tip dates", traitSet != null);
-            useTipDates.addActionListener(new ActionListener() {
-                @Override
-                public void actionPerformed(ActionEvent e) {
+            useTipDates.addActionListener(e -> {
                     JCheckBox checkBox = (JCheckBox) e.getSource();
                     try {
                         if (checkBox.isSelected()) {
@@ -100,11 +99,10 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
                         ex.printStackTrace();
                     }
 
-                }
-            });
+                });
             Box box2 = Box.createHorizontalBox();
             box2.add(useTipDates);
-            box2.add(Box.createGlue());
+            box2.add(Box.createHorizontalGlue());
             box.add(box2);
 
             if (traitSet != null) {
@@ -123,7 +121,9 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
 
     private Component createSamplingBox() {
         Box samplingBox = Box.createHorizontalBox();
-        JComboBox comboBox = new JComboBox(new String[]{"no tips sampling", "sample tips from taxon set:"});// ,"sample tips with individual priors"});
+        JComboBox<String> comboBox = new JComboBox<>(new String[]{"no tips sampling", "sample tips from taxon set:"});// ,"sample tips with individual priors"});
+
+        comboBox.setMaximumSize(new Dimension(Integer.MAX_VALUE, comboBox.getPreferredSize().height));
 
         // determine mode
         m_iMode = NO_TIP_SAMPLING;
@@ -137,19 +137,14 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
 
         m_iMode = Math.min(m_iMode, 2);
         comboBox.setSelectedIndex(m_iMode);
-        comboBox.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                selectMode(e);
-            }
-        });
+        comboBox.addActionListener(this::selectMode);
         samplingBox.add(comboBox);
 
-        taxonsets = new ArrayList<Taxon>();
+        taxonsets = new ArrayList<>();
         Taxon allTaxa = new Taxon();
         allTaxa.setID(ALL_TAXA);
         taxonsets.add(allTaxa);
-        List<String> taxonSetIDs = new ArrayList<String>();
+        List<String> taxonSetIDs = new ArrayList<>();
         taxonSetIDs.add(ALL_TAXA);
         for (Taxon taxon : doc.taxaset.values()) {
             if (taxon instanceof TaxonSet) {
@@ -157,7 +152,9 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
                 taxonSetIDs.add(taxon.getID());
             }
         }
-        JComboBox comboBox2 = new JComboBox(taxonSetIDs.toArray());
+        JComboBox<String> comboBox2 = new JComboBox<>(taxonSetIDs.toArray(new String[]{}));
+
+        comboBox2.setMaximumSize(new Dimension(Integer.MAX_VALUE, comboBox2.getPreferredSize().height));
         
         if (operator == null) {
         	comboBox.setEnabled(false);
@@ -170,12 +167,7 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
 	            comboBox2.setSelectedIndex(i);
 	        }
 	
-	        comboBox2.addActionListener(new ActionListener() {
-	            @Override
-	            public void actionPerformed(ActionEvent e) {
-	                selectTaxonSet(e);
-	            }
-	        });
+	        comboBox2.addActionListener(this::selectTaxonSet);
         }
         samplingBox.add(comboBox2);
 
@@ -183,7 +175,8 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
     }
 
     private void selectTaxonSet(ActionEvent e) {
-        JComboBox comboBox = (JComboBox) e.getSource();
+        @SuppressWarnings("unchecked")
+		JComboBox<String> comboBox = (JComboBox<String>) e.getSource();
         String taxonSetID = (String) comboBox.getSelectedItem();
         Taxon taxonset = null;;
         for (Taxon taxon : taxonsets) {
@@ -202,16 +195,16 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
             String treeID = tree.getID();
             String operatorID = "allTipDatesRandomWalker.t:" + treeID.substring(treeID.lastIndexOf(":") + 1);
             TipDatesRandomWalker operator = (TipDatesRandomWalker) doc.pluginmap.get(operatorID);
-            System.err.println("treeID = " + treeID);
-            System.err.println("operatorID = " + operatorID);
-            System.err.println("operator = " + operator);
+            Log.warning.println("treeID = " + treeID);
+            Log.warning.println("operatorID = " + operatorID);
+            Log.warning.println("operator = " + operator);
             operator.m_taxonsetInput.setValue(taxonset, operator);
 
-//            for (Plugin plugin : traitSet.outputs) {
-//                if (plugin instanceof Tree) {
-//                    for (Plugin plugin2 : plugin.outputs) {
-//                        if (plugin2 instanceof TipDatesScaler) {
-//                            TipDatesScaler operator = (TipDatesScaler) plugin2;
+//            for (BEASTObject beastObject : traitSet.outputs) {
+//                if (beastObject instanceof Tree) {
+//                    for (BEASTObject beastObject2 : beastObject.outputs) {
+//                        if (beastObject2 instanceof TipDatesScaler) {
+//                            TipDatesScaler operator = (TipDatesScaler) beastObject2;
 //                            operator.m_taxonsetInput.setValue(taxonset, operator);
 //                        }
 //                    }
@@ -219,11 +212,11 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
 //            }
 //
 //            // TODO: find MRACPriors and set TaxonSet inputs
-//            for (Plugin plugin : traitSet.outputs) {
-//                if (plugin instanceof Tree) {
-//                    for (Plugin plugin2 : plugin.outputs) {
-//                        if (plugin2 instanceof MRCAPrior) {
-//                            MRCAPrior prior = (MRCAPrior) plugin2;
+//            for (BEASTObject beastObject : traitSet.outputs) {
+//                if (beastObject instanceof Tree) {
+//                    for (BEASTObject beastObject2 : beastObject.outputs) {
+//                        if (beastObject2 instanceof MRCAPrior) {
+//                            MRCAPrior prior = (MRCAPrior) beastObject2;
 //                            if (prior.m_bOnlyUseTipsInput.get()) {
 //                                prior.m_taxonset.setValue(taxonset, prior);
 //                            }
@@ -238,15 +231,15 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
     }
 
     private void selectMode(ActionEvent e) {
-        JComboBox comboBox = (JComboBox) e.getSource();
+        JComboBox<?> comboBox = (JComboBox<?>) e.getSource();
         m_iMode = comboBox.getSelectedIndex();
         try {
             // clear
-            for (Object plugin : traitSet.getOutputs()) {
-                if (plugin instanceof Tree) {
-                    for (Object plugin2 : BEASTInterface.getOutputs(plugin)) {
-                        if (plugin2 instanceof TipDatesRandomWalker) {
-                            TipDatesRandomWalker operator = (TipDatesRandomWalker) plugin2;
+            for (Object beastObject : traitSet.getOutputs()) {
+                if (beastObject instanceof Tree) {
+                    for (Object beastObject2 : BEASTInterface.getOutputs(beastObject)) {
+                        if (beastObject2 instanceof TipDatesRandomWalker) {
+                            TipDatesRandomWalker operator = (TipDatesRandomWalker) beastObject2;
                             switch (m_iMode) {
                                 case NO_TIP_SAMPLING:
                                     operator.m_pWeight.setValue(0.0, operator);
@@ -276,9 +269,9 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
     }
 
     private Component createListBox() {
-        sTaxa = traitSet.taxaInput.get().asStringList();
+        taxa = traitSet.taxaInput.get().asStringList();
         String[] columnData = new String[]{"Name", "Date", "Height"};
-        tableData = new Object[sTaxa.size()][3];
+        tableData = new Object[taxa.size()][3];
         convertTraitToTableData();
         // set up table.
         // special features: background shading of rows
@@ -312,17 +305,17 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
             @Override
             public boolean stopCellEditing() {
                 table.removeEditor();
-                String sText = m_textField.getText();
+                String text = m_textField.getText();
 //                try {
-//                    Double.parseDouble(sText);
+//                    Double.parseDouble(text);
 //                } catch (Exception e) {
 //                	try {
-//                		Date.parse(sText);
+//                		Date.parse(text);
 //                	} catch (Exception e2) {
 //                        return false;
 //					}
 //                }
-                tableData[m_iRow][m_iCol] = sText;
+                tableData[m_iRow][m_iCol] = text;
                 convertTableDataToTrait();
                 convertTraitToTableData();
                 return true;
@@ -334,12 +327,12 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
             }
 
             @Override
-            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int iRow, int iCol) {
+            public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int rowNr, int colNr) {
                 if (!isSelected) {
                     return null;
                 }
-                m_iRow = iRow;
-                m_iCol = iCol;
+                m_iRow = rowNr;
+                m_iCol = colNr;
                 m_textField.setText((String) value);
                 return m_textField;
             }
@@ -403,48 +396,48 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
         return scrollPane;
     } // createListBox
 
-    /* synchronise table with data from traitSet Plugin */
+    /* synchronise table with data from traitSet BEASTObject */
     private void convertTraitToTableData() {
         for (int i = 0; i < tableData.length; i++) {
-            tableData[i][0] = sTaxa.get(i);
+            tableData[i][0] = taxa.get(i);
             tableData[i][1] = "0";
             tableData[i][2] = "0";
         }
-        String[] sTraits = traitSet.traitsInput.get().split(",");
-        for (String sTrait : sTraits) {
-            sTrait = sTrait.replaceAll("\\s+", " ");
-            String[] sStrs = sTrait.split("=");
-            if (sStrs.length != 2) {
+        String[] traits = traitSet.traitsInput.get().split(",");
+        for (String trait : traits) {
+            trait = trait.replaceAll("\\s+", " ");
+            String[] strs = trait.split("=");
+            if (strs.length != 2) {
                 break;
-                //throw new Exception("could not parse trait: " + sTrait);
+                //throw new Exception("could not parse trait: " + trait);
             }
-            String sTaxonID = normalize(sStrs[0]);
-            int taxonIndex = sTaxa.indexOf(sTaxonID);
-//            if (iTaxon < 0) {
-//                throw new Exception("Trait (" + sTaxonID + ") is not a known taxon. Spelling error perhaps?");
+            String taxonID = normalize(strs[0]);
+            int taxonIndex = taxa.indexOf(taxonID);
+//            if (taxonIndex < 0) {
+//                throw new Exception("Trait (" + taxonID + ") is not a known taxon. Spelling error perhaps?");
 //            }
             if (taxonIndex >= 0) {
-                tableData[taxonIndex][1] = normalize(sStrs[1]);
-                tableData[taxonIndex][0] = sTaxonID;
+                tableData[taxonIndex][1] = normalize(strs[1]);
+                tableData[taxonIndex][0] = taxonID;
             } else {
-                System.err.println("WARNING: File contains taxon " + sTaxonID + " that cannot be found in alignment");
+            	Log.warning.println("WARNING: File contains taxon " + taxonID + " that cannot be found in alignment");
             }
         }
         if (traitSet.traitNameInput.get().equals(TraitSet.DATE_BACKWARD_TRAIT)) {
-            Double fMinDate = Double.MAX_VALUE;
+            Double minDate = Double.MAX_VALUE;
             for (int i = 0; i < tableData.length; i++) {
-                fMinDate = Math.min(fMinDate, parseDate((String) tableData[i][1]));
+                minDate = Math.min(minDate, parseDate((String) tableData[i][1]));
             }
             for (int i = 0; i < tableData.length; i++) {
-                tableData[i][2] = parseDate((String) tableData[i][1]) - fMinDate;
+                tableData[i][2] = parseDate((String) tableData[i][1]) - minDate;
             }
         } else {
-            Double fMaxDate = 0.0;
+            Double maxDate = 0.0;
             for (int i = 0; i < tableData.length; i++) {
-                fMaxDate = Math.max(fMaxDate, parseDate((String) tableData[i][1]));
+                maxDate = Math.max(maxDate, parseDate((String) tableData[i][1]));
             }
             for (int i = 0; i < tableData.length; i++) {
-                tableData[i][2] = fMaxDate - parseDate((String) tableData[i][1]);
+                tableData[i][2] = maxDate - parseDate((String) tableData[i][1]);
             }
         }
 
@@ -456,20 +449,20 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
         }
     } // convertTraitToTableData
 
-    private double parseDate(String sStr) {
+    private double parseDate(String str) {
         // default, try to interpret the string as a number
         try {
-            return Double.parseDouble(sStr);
+            return Double.parseDouble(str);
         } catch (NumberFormatException e) {
             // does not look like a number, try parsing it as a date
-                if (sStr.matches(".*[a-zA-Z].*")) {
-                    sStr = sStr.replace('/', '-');
+                if (str.matches(".*[a-zA-Z].*")) {
+                    str = str.replace('/', '-');
                 }
 
             //try {
 
                 // unfortunately this deprecated date parser is the most flexible around at the moment...
-                long time = Date.parse(sStr);
+                long time = Date.parse(str);
                 Date date = new Date(time);
 
                 // AJD
@@ -477,7 +470,7 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
                 // far less support for different date formats.
                 // for example it fails on "12-Oct-2014"
                 //dateFormat.setLenient(true);
-                //Date date = dateFormat.parse(sStr);
+                //Date date = dateFormat.parse(str);
 
                 Calendar calendar = dateFormat.getCalendar();
                 calendar.setTime(date);
@@ -497,35 +490,35 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
                 return dateAsDecimal;
             //}
             //catch (ParseException e1) {
-            //    System.err.println("*** WARNING: Failed to parse '" + sStr + "' as date using dateFormat " + dateFormat);
+            //    System.err.println("*** WARNING: Failed to parse '" + str + "' as date using dateFormat " + dateFormat);
             //}
         }
         //return 0;
     } // parseStrings
 
-    private String normalize(String sStr) {
-        if (sStr.charAt(0) == ' ') {
-            sStr = sStr.substring(1);
+    private String normalize(String str) {
+        if (str.charAt(0) == ' ') {
+            str = str.substring(1);
         }
-        if (sStr.endsWith(" ")) {
-            sStr = sStr.substring(0, sStr.length() - 1);
+        if (str.endsWith(" ")) {
+            str = str.substring(0, str.length() - 1);
         }
-        return sStr;
+        return str;
     }
 
     /**
-     * synchronise traitSet Plugin with table data
+     * synchronise traitSet BEAST object with table data
      */
     private void convertTableDataToTrait() {
-        String sTrait = "";
+        String trait = "";
         for (int i = 0; i < tableData.length; i++) {
-            sTrait += sTaxa.get(i) + "=" + tableData[i][1];
+            trait += taxa.get(i) + "=" + tableData[i][1];
             if (i < tableData.length - 1) {
-                sTrait += ",\n";
+                trait += ",\n";
             }
         }
         try {
-            traitSet.traitsInput.setValue(sTrait, traitSet);
+            traitSet.traitsInput.setValue(trait, traitSet);
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -538,104 +531,93 @@ public class TipDatesInputEditor extends BEASTObjectInputEditor {
         Box buttonBox = Box.createHorizontalBox();
 
         JLabel label = new JLabel("Dates specified as: ");
-        label.setMaximumSize(MAX_SIZE);//new Dimension(1024, 22));
+        label.setMaximumSize(label.getPreferredSize());
         buttonBox.add(label);
-        unitsComboBox = new JComboBox(TraitSet.Units.values());
+        unitsComboBox = new JComboBox<>(TraitSet.Units.values());
         unitsComboBox.setSelectedItem(traitSet.unitsInput.get());
-        unitsComboBox.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                String sSelected = (String) unitsComboBox.getSelectedItem().toString();
+        unitsComboBox.addActionListener(e -> {
+                String selected = unitsComboBox.getSelectedItem().toString();
                 try {
-                    traitSet.unitsInput.setValue(sSelected, traitSet);
+                    traitSet.unitsInput.setValue(selected, traitSet);
                     //System.err.println("Traitset is now: " + m_traitSet.m_sUnits.get());
                 } catch (Exception ex) {
                     ex.printStackTrace();
                 }
-            }
-        });
-        unitsComboBox.setMaximumSize(MAX_SIZE);//new Dimension(1024, 22));
+            });
+        unitsComboBox.setMaximumSize(new Dimension(Integer.MAX_VALUE, unitsComboBox.getPreferredSize().height));
         buttonBox.add(unitsComboBox);
 
-        relativeToComboBox = new JComboBox(new String[]{"Since some time in the past", "Before the present"});
+        relativeToComboBox = new JComboBox<>(new String[]{"Since some time in the past", "Before the present"});
         if (traitSet.traitNameInput.get().equals(TraitSet.DATE_BACKWARD_TRAIT)) {
             relativeToComboBox.setSelectedIndex(1);
         } else {
             relativeToComboBox.setSelectedIndex(0);
         }
-        relativeToComboBox.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                String sSelected = TraitSet.DATE_BACKWARD_TRAIT;
+        relativeToComboBox.addActionListener(e -> {
+                String selected = TraitSet.DATE_BACKWARD_TRAIT;
                 if (relativeToComboBox.getSelectedIndex() == 0) {
-                    sSelected = TraitSet.DATE_FORWARD_TRAIT;
+                    selected = TraitSet.DATE_FORWARD_TRAIT;
                 }
                 try {
-                    traitSet.traitNameInput.setValue(sSelected, traitSet);
-                    System.err.println("Relative position is now: " + traitSet.traitNameInput.get());
+                    traitSet.traitNameInput.setValue(selected, traitSet);
+                    Log.warning.println("Relative position is now: " + traitSet.traitNameInput.get());
                 } catch (Exception ex) {
                     ex.printStackTrace();
                 }
                 convertTraitToTableData();
-            }
-        });
-        relativeToComboBox.setMaximumSize(MAX_SIZE);//new Dimension(1024, 20));
+            });
+        relativeToComboBox.setMaximumSize(new Dimension(Integer.MAX_VALUE, relativeToComboBox.getPreferredSize().height));
         buttonBox.add(relativeToComboBox);
-        buttonBox.add(Box.createGlue());
+
+        buttonBox.add(Box.createHorizontalGlue());
 
         JButton guessButton = new JButton("Guess");
         guessButton.setName("Guess");
-        guessButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        guessButton.addActionListener(e -> {
                 GuessPatternDialog dlg = new GuessPatternDialog(null, m_sPattern);
                 dlg.allowAddingValues();
-                String sTrait = "";
+                String trait = "";
                 switch (dlg.showDialog("Guess dates")) {
                     case canceled:
                         return;
                     case trait:
-                        sTrait = dlg.getTrait();
+                        trait = dlg.getTrait();
                         break;
                     case pattern:
-                        for (String sTaxon : sTaxa) {
-                            String sMatch = dlg.match(sTaxon);
-                            if (sMatch == null) {
+                        for (String taxon : taxa) {
+                            String match = dlg.match(taxon);
+                            if (match == null) {
                                 return;
                             }
-                            double nDate = parseDate(sMatch);
-                            if (sTrait.length() > 0) {
-                                sTrait += ",";
+                            double date = parseDate(match);
+                            if (trait.length() > 0) {
+                                trait += ",";
                             }
-                            sTrait += sTaxon + "=" + nDate;
+                            trait += taxon + "=" + date;
                         }
                         break;
                 }
                 try {
-                    traitSet.traitsInput.setValue(sTrait, traitSet);
+                    traitSet.traitsInput.setValue(trait, traitSet);
                     convertTraitToTableData();
                     convertTableDataToTrait();
                 } catch (Exception ex) {
                     // TODO: handle exception
                 }
                 refreshPanel();
-            }
-        });
+            });
         buttonBox.add(guessButton);
 
 
         JButton clearButton = new JButton("Clear");
-        clearButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        clearButton.addActionListener(e -> {
                 try {
                     traitSet.traitsInput.setValue("", traitSet);
                 } catch (Exception ex) {
                     // TODO: handle exception
                 }
                 refreshPanel();
-            }
-        });
+            });
         buttonBox.add(clearButton);
 
         return buttonBox;
diff --git a/src/beast/app/beauti/TreeDistributionInputEditor.java b/src/beast/app/beauti/TreeDistributionInputEditor.java
index ce725e5..528eebc 100644
--- a/src/beast/app/beauti/TreeDistributionInputEditor.java
+++ b/src/beast/app/beauti/TreeDistributionInputEditor.java
@@ -2,7 +2,6 @@ package beast.app.beauti;
 
 import java.awt.Color;
 import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.util.List;
 
 import javax.swing.Box;
@@ -12,8 +11,8 @@ import javax.swing.SwingUtilities;
 
 import beast.app.draw.InputEditor;
 import beast.app.draw.SmallLabel;
-import beast.core.Input;
 import beast.core.BEASTInterface;
+import beast.core.Input;
 import beast.evolution.tree.Tree;
 import beast.evolution.tree.TreeDistribution;
 
@@ -33,7 +32,7 @@ public class TreeDistributionInputEditor extends InputEditor.Base {
     }
 //	@Override
 //	public Class<?>[] types() {
-//		ArrayList<Class> types = new ArrayList<Class>();
+//		ArrayList<Class> types = new ArrayList<>();
 //		types.add(TreeDistribution.class);
 //		types.add(BirthDeathGernhard08Model.class);
 //		types.add(YuleModel.class);
@@ -44,74 +43,73 @@ public class TreeDistributionInputEditor extends InputEditor.Base {
     ActionEvent m_e;
 
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int listItemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-        m_bAddButtons = bAddButtons;
+    public void init(Input<?> input, BEASTInterface beastObject, int listItemNr, ExpandOption isExpandOption, boolean addButtons) {
+        m_bAddButtons = addButtons;
         m_input = input;
-        m_plugin = plugin;
+        m_beastObject = beastObject;
         this.itemNr = listItemNr;
 
         Box itemBox = Box.createHorizontalBox();
 
-        TreeDistribution distr = (TreeDistribution) plugin;
-        String sText = ""/* plugin.getID() + ": " */;
+        TreeDistribution distr = (TreeDistribution) beastObject;
+        String text = ""/* beastObject.getID() + ": " */;
         if (distr.treeInput.get() != null) {
-            sText += distr.treeInput.get().getID();
+            text += distr.treeInput.get().getID();
         } else {
-            sText += distr.treeIntervalsInput.get().treeInput.get().getID();
+            text += distr.treeIntervalsInput.get().treeInput.get().getID();
         }
-        JLabel label = new JLabel(sText);
-        label.setMinimumSize(PriorListInputEditor.PREFERRED_SIZE);
-        label.setPreferredSize(PriorListInputEditor.PREFERRED_SIZE);
+        JLabel label = new JLabel(text);
+        label.setMinimumSize(Base.PREFERRED_SIZE);
+        label.setPreferredSize(Base.PREFERRED_SIZE);
         itemBox.add(label);
-        // List<String> sAvailablePlugins =
-        // PluginPanel.getAvailablePlugins(m_input, m_plugin, null);
+        // List<String> availableBEASTObjects =
+        // PluginPanel.getAvailablePlugins(m_input, m_beastObject, null);
 
-        List<BeautiSubTemplate> sAvailablePlugins = doc.getInputEditorFactory().getAvailableTemplates(m_input, m_plugin,
+        List<BeautiSubTemplate> availableBEASTObjects = doc.getInputEditorFactory().getAvailableTemplates(m_input, m_beastObject,
                 null, doc); 
         // make sure we are dealing with a TreeDistribution
-        for (int i = sAvailablePlugins.size() - 1; i >= 0; i--) {
-        	BeautiSubTemplate t = sAvailablePlugins.get(i);
+        for (int i = availableBEASTObjects.size() - 1; i >= 0; i--) {
+        	BeautiSubTemplate t = availableBEASTObjects.get(i);
         	Class<?> c = t._class;
         	if (!(TreeDistribution.class.isAssignableFrom(c))) {
-        		sAvailablePlugins.remove(i);
+        		availableBEASTObjects.remove(i);
         	}
         }
         
-        JComboBox comboBox = new JComboBox(sAvailablePlugins.toArray());
+        JComboBox<BeautiSubTemplate> comboBox = new JComboBox<>(availableBEASTObjects.toArray(new BeautiSubTemplate[]{}));
         comboBox.setName("TreeDistribution");
 
-        for (int i = sAvailablePlugins.size() - 1; i >= 0; i--) {
-            if (!TreeDistribution.class.isAssignableFrom(sAvailablePlugins.get(i)._class)) {
-                sAvailablePlugins.remove(i);
+        for (int i = availableBEASTObjects.size() - 1; i >= 0; i--) {
+            if (!TreeDistribution.class.isAssignableFrom(availableBEASTObjects.get(i)._class)) {
+                availableBEASTObjects.remove(i);
             }
         }
 
-        String sID = distr.getID();
+        String id = distr.getID();
         try {
-            // sID = BeautiDoc.parsePartition(sID);
-            sID = sID.substring(0, sID.indexOf('.'));
+            // id = BeautiDoc.parsePartition(id);
+            id = id.substring(0, id.indexOf('.'));
         } catch (Exception e) {
             throw new RuntimeException("Improperly formatted ID: " + distr.getID());
         }
-        for (BeautiSubTemplate template : sAvailablePlugins) {
-            if (template.matchesName(sID)) { // getMainID().replaceAll(".\\$\\(n\\)",
-                // "").equals(sID)) {
+        for (BeautiSubTemplate template : availableBEASTObjects) {
+            if (template.matchesName(id)) { // getMainID().replaceAll(".\\$\\(n\\)",
+                // "").equals(id)) {
                 comboBox.setSelectedItem(template);
             }
         }
 
-        comboBox.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        comboBox.addActionListener(e -> {
                 m_e = e;
                 SwingUtilities.invokeLater(new Runnable() {
-                    @Override
+					@Override
                     public void run() {
-                        JComboBox currentComboBox = (JComboBox) m_e.getSource();
+						@SuppressWarnings("unchecked")
+						JComboBox<BeautiSubTemplate> currentComboBox = (JComboBox<BeautiSubTemplate>) m_e.getSource();
                         @SuppressWarnings("unchecked")
-                        List<BEASTInterface> list = (List<BEASTInterface>) m_input.get();
+						List<BEASTInterface> list = (List<BEASTInterface>) m_input.get();
                         BeautiSubTemplate template = (BeautiSubTemplate) currentComboBox.getSelectedItem();
-                        PartitionContext partitionContext = doc.getContextFor((BEASTInterface) list.get(itemNr));
+                        PartitionContext partitionContext = doc.getContextFor(list.get(itemNr));
                         try {
                             template.createSubNet(partitionContext, list, itemNr, true);
                         } catch (Exception ex) {
@@ -121,8 +119,7 @@ public class TreeDistributionInputEditor extends InputEditor.Base {
                         refreshPanel();
                     }
                 });
-            }
-        });
+            });
         itemBox.add(comboBox);
         itemBox.add(Box.createGlue());
 
@@ -135,7 +132,7 @@ public class TreeDistributionInputEditor extends InputEditor.Base {
 
     @Override
     public void validateInput() {
-        TreeDistribution distr = (TreeDistribution) m_plugin;
+        TreeDistribution distr = (TreeDistribution) m_beastObject;
         // TODO: robustify for the case the tree is not a simple binary tree
         Tree tree = (Tree) distr.treeInput.get();
         if (tree == null) {
diff --git a/src/beast/app/beauti/guiutil/S11InitialSelection.java b/src/beast/app/beauti/guiutil/S11InitialSelection.java
index 29a044b..15de4ee 100644
--- a/src/beast/app/beauti/guiutil/S11InitialSelection.java
+++ b/src/beast/app/beauti/guiutil/S11InitialSelection.java
@@ -1,5 +1,8 @@
 package beast.app.beauti.guiutil;
 
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+
 //http://www.java2s.com/Code/Java/Swing-Components/JComboBoxaddingautomaticcompletionHandlingtheinitialselection.htm
 //Code from: http://www.orbital-computer.de/JComboBox/
 /*
@@ -15,36 +18,36 @@ Handling the initial selection
 It is a quiet annoying that the initially selected item is not shown in the combo box. This
 can be easily changed in the constructor of the auto completing document.
 */
-import javax.swing.*;
+import javax.swing.ComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.JFrame;
 import javax.swing.text.AttributeSet;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.JTextComponent;
 import javax.swing.text.PlainDocument;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
 
 public class S11InitialSelection extends PlainDocument {
-    JComboBox comboBox;
-    ComboBoxModel model;
+	private static final long serialVersionUID = 1L;
+
+	JComboBox<Object> comboBox;
+    ComboBoxModel<Object> model;
     JTextComponent editor;
+    
     // flag to indicate if setSelectedItem has been called
     // subsequent calls to remove/insertString should be ignored
     boolean selecting=false;
 
-    public S11InitialSelection(final JComboBox comboBox) {
+    public S11InitialSelection(final JComboBox<Object> comboBox) {
         this.comboBox = comboBox;
         model = comboBox.getModel();
         editor = (JTextComponent) comboBox.getEditor().getEditorComponent();
         editor.setDocument(this);
-        comboBox.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+        comboBox.addActionListener(e -> {
                 if (!selecting) highlightCompletedText(0);
-            }
-        });
+            });
         editor.addKeyListener(new KeyAdapter() {
-            public void keyPressed(KeyEvent e) {
+            @Override
+			public void keyPressed(KeyEvent e) {
                 if (comboBox.isDisplayable()) comboBox.setPopupVisible(true);
             }
         });
@@ -54,13 +57,15 @@ public class S11InitialSelection extends PlainDocument {
         highlightCompletedText(0);
     }
 
-    public void remove(int offs, int len) throws BadLocationException {
+    @Override
+	public void remove(int offs, int len) throws BadLocationException {
         // return immediately when selecting an item
         if (selecting) return;
         super.remove(offs, len);
     }
 
-    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
+    @Override
+	public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
         // return immediately when selecting an item
         if (selecting) return;
         // insert the string into the document
@@ -129,7 +134,7 @@ public class S11InitialSelection extends PlainDocument {
 
     private static void createAndShowGUI() {
         // the combo box (add/modify items if you like to)
-        JComboBox comboBox = new JComboBox(new Object[] {"Ester", "Jordi", "Jordina", "Jorge", "Sergi"});
+        JComboBox<Object> comboBox = new JComboBox<>(new Object[] {"Ester", "Jordi", "Jordina", "Jorge", "Sergi"});
         // has to be editable
         comboBox.setEditable(true);
         // change the editor's document
@@ -145,7 +150,8 @@ public class S11InitialSelection extends PlainDocument {
 
     public static void main(String[] args) {
         javax.swing.SwingUtilities.invokeLater(new Runnable() {
-            public void run() {
+            @Override
+			public void run() {
                 createAndShowGUI();
             }
         });
diff --git a/src/beast/app/draw/Arrow.java b/src/beast/app/draw/Arrow.java
index fb3c759..78d59da 100644
--- a/src/beast/app/draw/Arrow.java
+++ b/src/beast/app/draw/Arrow.java
@@ -36,6 +36,8 @@ import javax.swing.JPanel;
 
 import org.w3c.dom.Node;
 
+import beast.core.util.Log;
+
 public class Arrow extends Shape {
     String m_sHeadID;
     String m_sTailID;
@@ -44,8 +46,8 @@ public class Arrow extends Shape {
 //	String m_sPenStyle;
 
     /* c'tor for creating arrow while parsing XDL format XML **/
-    public Arrow(Node node, Document doc, boolean bReconstructPlugins) {
-        parse(node, doc, bReconstructPlugins);
+    public Arrow(Node node, Document doc, boolean reconstructBEASTObjects) {
+        parse(node, doc, reconstructBEASTObjects);
     }
 
     /* c'tor for creating arrow when starting to draw new one **/
@@ -60,12 +62,12 @@ public class Arrow extends Shape {
 
     /* c'tor for creating arrow with all fields set properly
       * Used when arrows are created by Document.recalcArrows */
-    public Arrow(BEASTObjectShape tailShape, BEASTObjectShape headShape, String sInputName) {
+    public Arrow(BEASTObjectShape tailShape, BEASTObjectShape headShape, String inputName) {
 	        m_sTailID = tailShape.getID();
 	        m_tailShape = tailShape;
-	        InputShape input = headShape.getInputShape(sInputName);
+	        InputShape input = headShape.getInputShape(inputName);
 	        if (input == null) {
-	        	System.err.println("Arrow from " + tailShape.m_plugin.getID() + " to " + headShape.m_plugin.getID() + "." + sInputName + " skipped");	        	
+	        	Log.warning.println("Arrow from " + tailShape.m_beastObject.getID() + " to " + headShape.m_beastObject.getID() + "." + inputName + " skipped");	        	
 	        }
 	        m_sHeadID = input.getID();
 	        m_headShape = input;
@@ -96,19 +98,19 @@ public class Arrow extends Shape {
     }
 
     /* set all parameters properly at end of dragging when mouse is released */
-    public boolean setHead(InputShape shape, List<Shape> objects, Document doc) throws Exception {
+    public boolean setHead(InputShape shape, List<Shape> objects, Document doc) {
         m_sHeadID = shape.getID();
         m_headShape = shape;
         adjustCoordinates();
-        String sInputName = m_headShape.getInputName();
-        m_headShape.getPlugin().setInputValue(sInputName, m_tailShape.m_plugin);
+        String inputName = m_headShape.getInputName();
+        m_headShape.getBEASTObject().setInputValue(inputName, m_tailShape.m_beastObject);
         return true;//setFunctionInput(objects, doc);
     }
 
     /* parse arrow in XDL format XML **/
     @Override
-    void parse(Node node, Document doc, boolean bReconstructPlugins) {
-        super.parse(node, doc, bReconstructPlugins);
+    void parse(Node node, Document doc, boolean reconstructBEASTObjects) {
+        super.parse(node, doc, reconstructBEASTObjects);
         if (node.getAttributes().getNamedItem("headid") != null) {
             m_sHeadID = node.getAttributes().getNamedItem("headid").getNodeValue();
         }
@@ -207,23 +209,23 @@ public class Arrow extends Shape {
         double ar, br, ga, gb, A, B, C, p, q;
 
         if (p1.x > p0.x)
-            p = (double) (p0.x + w - a);
+            p = p0.x + w - a;
         else
-            p = (double) (p0.x - w + a);
+            p = p0.x - w + a;
         if (p1.y > p0.y)
-            q = (double) (p0.y + h - b);
+            q = p0.y + h - b;
         else
-            q = (double) (p0.y - h + b);
+            q = p0.y - h + b;
 
-        ar = (double) a;
-        br = (double) b;
+        ar = a;
+        br = b;
         if (p1.x == p0.x) // cheat to prevent divsion by zero
         {
             ga = (double) (p1.y - p0.y) / 1;
         } else {
             ga = (double) (p1.y - p0.y) / (double) (p1.x - p0.x);
         }
-        gb = (double) (p0.y - ga * p0.x);
+        gb = p0.y - ga * p0.x;
         A = 1 / (ar * ar) + (ga * ga) / (br * br);
         B = -2.0 * p / (ar * ar) + 2.0 * ga * gb / (br * br) - 2.0 * ga * q / (br * br);
         C = p * p / (ar * ar) + gb * gb / (br * br) - 2.0 * gb * q / (br * br) + q * q / (br * br) - 1.0;
@@ -245,11 +247,12 @@ public class Arrow extends Shape {
         return m_sID;
     }
 
-    public void setID(String sID) {
-        m_sID = sID;
+    public void setID(String id) {
+        m_sID = id;
     }
 
-    public String toString() {
+    @Override
+	public String toString() {
         return m_sTailID + "-->" + m_sHeadID;
     }
 
diff --git a/src/beast/app/draw/BEASTObjectDialog.java b/src/beast/app/draw/BEASTObjectDialog.java
index 2873afb..289a120 100644
--- a/src/beast/app/draw/BEASTObjectDialog.java
+++ b/src/beast/app/draw/BEASTObjectDialog.java
@@ -1,28 +1,30 @@
 package beast.app.draw;
 
 
-import javax.swing.*;
+import java.awt.BorderLayout;
+import java.awt.Frame;
+import java.io.File;
+import java.net.URL;
+import java.util.List;
+import java.util.Scanner;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JDialog;
+import javax.swing.JOptionPane;
 import javax.swing.border.EmptyBorder;
 
 import beast.app.beauti.BeautiDoc;
+import beast.core.BEASTInterface;
 import beast.core.Input;
 import beast.core.MCMC;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 import beast.util.XMLProducer;
 
-
-import java.awt.*;
-import java.io.File;
-import java.net.URL;
-import java.util.List;
-import java.util.Scanner;
-
 /**
- * Dialog for editing Plugins.
+ * Dialog for editing BEASTObjects.
  * <p/>
  * This dynamically creates a dialog consisting of
- * InputEditors associated with the inputs of a Plugin.
+ * InputEditors associated with the inputs of a BEASTObject.
  * *
  */
 
@@ -48,12 +50,12 @@ public class BEASTObjectDialog extends JDialog {
         this.doc = doc;
     }
 
-    public BEASTObjectDialog(BEASTInterface plugin, Class<? extends BEASTInterface> aClass, List<BEASTInterface> plugins, BeautiDoc doc) {
-        this(new BEASTObjectPanel(plugin, aClass, plugins, doc), doc);
+    public BEASTObjectDialog(BEASTInterface beastObject, Class<? extends BEASTInterface> aClass, List<BEASTInterface> beastObjects, BeautiDoc doc) {
+        this(new BEASTObjectPanel(beastObject, aClass, beastObjects, doc), doc);
     }
 
-    public BEASTObjectDialog(BEASTInterface plugin, Class<?> type, BeautiDoc doc) {
-        this(new BEASTObjectPanel(plugin, type, doc), doc);
+    public BEASTObjectDialog(BEASTInterface beastObject, Class<?> type, BeautiDoc doc) {
+        this(new BEASTObjectPanel(beastObject, type, doc), doc);
     }
 
     
@@ -84,20 +86,20 @@ public class BEASTObjectDialog extends JDialog {
     }
     
     /* to be called when OK is pressed **/
-    public void accept(BEASTInterface plugin, BeautiDoc doc) {
+    public void accept(BEASTInterface beastObject, BeautiDoc doc) {
         try {
-            for (Input<?> input : m_panel.m_plugin.listInputs()) {
+            for (Input<?> input : m_panel.m_beastObject.listInputs()) {
             	if (input.get() != null && (input.get() instanceof List)) {
                     // setInpuValue (below) on lists does not lead to expected result
             		// it appends values to the list instead, so we have to clear it first
-                    List list = (List)plugin.getInput(input.getName()).get();
+                    List<?> list = (List<?>)beastObject.getInput(input.getName()).get();
                     list.clear();
             	}
-            	plugin.setInputValue(input.getName(), input.get());
+            	beastObject.setInputValue(input.getName(), input.get());
             }
-            plugin.setID(m_panel.m_plugin.getID());
+            beastObject.setID(m_panel.m_beastObject.getID());
             if (doc != null) {
-            	doc.addPlugin(plugin);
+            	doc.addPlugin(beastObject);
             }
         } catch (Exception e) {
             e.printStackTrace();
@@ -111,7 +113,7 @@ public class BEASTObjectDialog extends JDialog {
 
         add(BorderLayout.CENTER, panel);
 
-        setTitle(panel.m_plugin.getID() + " Editor");
+        setTitle(panel.m_beastObject.getID() + " Editor");
 
 
 //        /* add cancel and ok buttons at the bottom */
@@ -152,10 +154,10 @@ public class BEASTObjectDialog extends JDialog {
         //PluginDialog.m_position.x -= 30;
         //PluginDialog.m_position.y -= 30;
         if (m_bOK) {
-            String sOldID = m_panel.m_plugin.getID();
-            BEASTObjectPanel.g_plugins.remove(sOldID);
-            m_panel.m_plugin.setID(m_panel.m_identry.getText());
-            BEASTObjectPanel.registerPlugin(m_panel.m_plugin.getID(), m_panel.m_plugin, doc);
+            String oldID = m_panel.m_beastObject.getID();
+            BEASTObjectPanel.g_plugins.remove(oldID);
+            m_panel.m_beastObject.setID(m_panel.m_identry.getText());
+            BEASTObjectPanel.registerPlugin(m_panel.m_beastObject.getID(), m_panel.m_beastObject, doc);
         }
         return m_bOK;
     }
@@ -179,29 +181,29 @@ public class BEASTObjectDialog extends JDialog {
                 } finally {
                     scanner.close();
                 }
-                BEASTInterface plugin = new beast.util.XMLParser().parseBareFragment(text.toString(), false);
-                dlg = new BEASTObjectDialog(new BEASTObjectPanel(plugin, plugin.getClass(), null), null);
+                BEASTInterface beastObject = new beast.util.XMLParser().parseBareFragment(text.toString(), false);
+                dlg = new BEASTObjectDialog(new BEASTObjectPanel(beastObject, beastObject.getClass(), null), null);
             } else if (args.length == 1) {
                 dlg = new BEASTObjectDialog(new BEASTObjectPanel((BEASTInterface) Class.forName(args[0]).newInstance(), Class.forName(args[0]), null), null);
             } else if (args.length == 2) {
                 dlg = new BEASTObjectDialog(new BEASTObjectPanel((BEASTInterface) Class.forName(args[0]).newInstance(), Class.forName(args[1]), null), null);
             } else {
-                throw new Exception("Incorrect number of arguments");
+                throw new IllegalArgumentException("Incorrect number of arguments");
             }
         } catch (Exception e) {
             e.printStackTrace();
             System.err.println("Usage: " + BEASTObjectDialog.class.getName() + " [-x file ] [class [type]]\n" +
-                    "where [class] (optional, default MCMC) is a Plugin to edit\n" +
-                    "and [type] (optional only if class is specified, default Runnable) the type of the Plugin.\n" +
+                    "where [class] (optional, default MCMC) is a BEASTObject to edit\n" +
+                    "and [type] (optional only if class is specified, default Runnable) the type of the BEASTObject.\n" +
                     "for example\n" +
                     "");
-            System.exit(0);
+            System.exit(1);
         }
         dlg.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
         if (dlg.showDialog()) {
-            BEASTInterface plugin = dlg.m_panel.m_plugin;
-            String sXML = new XMLProducer().modelToXML(plugin);
-            System.out.println(sXML);
+            BEASTInterface beastObject = dlg.m_panel.m_beastObject;
+            String xml = new XMLProducer().modelToXML(beastObject);
+            System.out.println(xml);
         }
     } // main
 } // class PluginDialog
diff --git a/src/beast/app/draw/BEASTObjectInputEditor.java b/src/beast/app/draw/BEASTObjectInputEditor.java
index 3838a05..4f7942f 100644
--- a/src/beast/app/draw/BEASTObjectInputEditor.java
+++ b/src/beast/app/draw/BEASTObjectInputEditor.java
@@ -2,29 +2,29 @@ package beast.app.draw;
 
 
 
-import javax.swing.*;
+import java.awt.Dimension;
+import java.util.List;
+
+import javax.swing.Box;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
 import javax.swing.border.EtchedBorder;
 
 import beast.app.beauti.BeautiDoc;
 import beast.app.beauti.BeautiSubTemplate;
-import beast.core.Input;
 import beast.core.BEASTInterface;
+import beast.core.Input;
 import beast.util.AddOnManager;
 
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.Arrays;
-import java.util.List;
-
 public class BEASTObjectInputEditor extends InputEditor.Base {
     private static final long serialVersionUID = 1L;
-    JComboBox m_selectPluginBox;
-    SmallButton m_editPluginButton;
+    JComboBox<Object> m_selectBEASTObjectBox;
+    SmallButton m_editBEASTObjectButton;
 
     BEASTObjectInputEditor _this;
 
-    //public PluginInputEditor() {}
     public BEASTObjectInputEditor(BeautiDoc doc) {
         super(doc);
         _this = this;
@@ -43,41 +43,41 @@ public class BEASTObjectInputEditor extends InputEditor.Base {
      * o validation label -- optional, if input is not valid
      */
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
     	//box.setAlignmentY(LEFT_ALIGNMENT);
     	
-        m_bAddButtons = bAddButtons;
+        m_bAddButtons = addButtons;
         m_input = input;
-        m_plugin = plugin;
+        m_beastObject = beastObject;
 		this.itemNr = itemNr;
-        if (bExpandOption == ExpandOption.FALSE) {
-            simpleInit(input, plugin);
+        if (isExpandOption == ExpandOption.FALSE) {
+            simpleInit(input, beastObject);
         } else {
-            expandedInit(input, plugin);
+            expandedInit(input, beastObject);
         }
     } // init
 
     /**
-     * add combobox with available plugins
-     * a button to edit that plugin +
+     * add combobox with available beastObjects
+     * a button to edit that beastObject +
      * a validation icon
      * *
      */
-    void simpleInit(Input<?> input, BEASTInterface plugin) {
+    void simpleInit(Input<?> input, BEASTInterface beastObject) {
 
         addInputLabel();
 
-        addComboBox(this, input, plugin);
+        addComboBox(this, input, beastObject);
 
         if (m_bAddButtons) {
             if (BEASTObjectPanel.countInputs((BEASTInterface) m_input.get(), doc) > 0) {
-                m_editPluginButton = new SmallButton("e", true);
+                m_editBEASTObjectButton = new SmallButton("e", true);
                 if (input.get() == null) {
-                    m_editPluginButton.setEnabled(false);
+                    m_editBEASTObjectButton.setEnabled(false);
                 }
-                m_editPluginButton.setToolTipText("Edit " + m_inputLabel.getText());
+                m_editBEASTObjectButton.setToolTipText("Edit " + m_inputLabel.getText());
 
-                m_editPluginButton.addActionListener(e -> {
+                m_editBEASTObjectButton.addActionListener(e -> {
                     BEASTObjectDialog dlg = new BEASTObjectDialog((BEASTInterface) m_input.get(), m_input.getType(), doc);
                     if (dlg.showDialog()) {
                         try {
@@ -90,20 +90,20 @@ public class BEASTObjectInputEditor extends InputEditor.Base {
                     validateInput();
                     refreshPanel();
                 });
-                add(m_editPluginButton);
+                add(m_editBEASTObjectButton);
             }
         }
         addValidationLabel();
     } // init
 
     void refresh() {
-    	if (m_selectPluginBox != null) {
-	        String sOldID = (String) m_selectPluginBox.getSelectedItem();
-	        String sID = ((BEASTInterface) m_input.get()).getID();
-	        if (!sID.equals(sOldID)) {
-	            m_selectPluginBox.addItem(sID);
-	            m_selectPluginBox.setSelectedItem(sID);
-	            m_selectPluginBox.removeItem(sOldID);
+    	if (m_selectBEASTObjectBox != null) {
+	        String oldID = (String) m_selectBEASTObjectBox.getSelectedItem();
+	        String id = ((BEASTInterface) m_input.get()).getID();
+	        if (!id.equals(oldID)) {
+	            m_selectBEASTObjectBox.addItem(id);
+	            m_selectBEASTObjectBox.setSelectedItem(id);
+	            m_selectBEASTObjectBox.removeItem(oldID);
 	        }
     	}
         super.refreshPanel();
@@ -117,33 +117,33 @@ public class BEASTObjectInputEditor extends InputEditor.Base {
     }
 
     void initSelectPluginBox() {
-        List<String> sAvailablePlugins = doc.getInputEditorFactory().getAvailablePlugins(m_input, m_plugin, null, doc);
-        if (sAvailablePlugins.size() > 0) {
-            sAvailablePlugins.add(NO_VALUE);
-            for (int i = 0; i < sAvailablePlugins.size(); i++) {
-                String sPlugin = sAvailablePlugins.get(i);
-                if (sPlugin.startsWith("new ")) {
-                    sPlugin = sPlugin.substring(sPlugin.lastIndexOf('.'));
-                    sAvailablePlugins.set(i, sPlugin);
+        List<String> availableBEASTObjects = doc.getInputEditorFactory().getAvailablePlugins(m_input, m_beastObject, null, doc);
+        if (availableBEASTObjects.size() > 0) {
+            availableBEASTObjects.add(NO_VALUE);
+            for (int i = 0; i < availableBEASTObjects.size(); i++) {
+                String beastObjectName = availableBEASTObjects.get(i);
+                if (beastObjectName.startsWith("new ")) {
+                    beastObjectName = beastObjectName.substring(beastObjectName.lastIndexOf('.'));
+                    availableBEASTObjects.set(i, beastObjectName);
                 }
 
             }
-            m_selectPluginBox.removeAllItems();
-            for (String sStr : sAvailablePlugins.toArray(new String[0])) {
-                m_selectPluginBox.addItem(sStr);
+            m_selectBEASTObjectBox.removeAllItems();
+            for (String str : availableBEASTObjects.toArray(new String[0])) {
+                m_selectBEASTObjectBox.addItem(str);
             }
-            m_selectPluginBox.setSelectedItem(m_plugin.getID());
+            m_selectBEASTObjectBox.setSelectedItem(m_beastObject.getID());
         }
     }
 
     Box m_expansionBox = null;
 
-    void expandedInit(Input<?> input, BEASTInterface plugin) {
+    void expandedInit(Input<?> input, BEASTInterface beastObject) {
         addInputLabel();
         Box box = Box.createVerticalBox();
-        // add horizontal box with combobox of Plugins to select from
+        // add horizontal box with combobox of BEASTObjects to select from
         Box combobox = Box.createHorizontalBox();
-        addComboBox(combobox, input, plugin);
+        addComboBox(combobox, input, beastObject);
         box.add(combobox);
 
         doc.getInputEditorFactory().addInputs(box, (BEASTInterface) input.get(), this, this, doc);
@@ -157,243 +157,237 @@ public class BEASTObjectInputEditor extends InputEditor.Base {
 
 
     /**
-     * add combobox with Plugins to choose from
-     * On choosing a new value, create plugin (if is not already an object)
+     * add combobox with BEASTObjects to choose from
+     * On choosing a new value, create beastObject (if is not already an object)
      * Furthermore, if expanded, update expanded inputs
      */
-    protected void addComboBox(JComponent box, Input<?> input, BEASTInterface plugin) {
+    protected void addComboBox(JComponent box, Input<?> input, BEASTInterface beastObject0) {
     	if (itemNr >= 0) {
-    		box.add(new JLabel(plugin.getID()));
+    		box.add(new JLabel(beastObject0.getID()));
     		box.add(Box.createGlue());
     		return;
     	}
     	
-        List<BeautiSubTemplate> availableTemplates = doc.getInputEditorFactory().getAvailableTemplates(m_input, m_plugin, null, doc);
+        List<BeautiSubTemplate> availableTemplates = doc.getInputEditorFactory().getAvailableTemplates(m_input, m_beastObject, null, doc);
         if (availableTemplates.size() > 0) {
-//        	if (m_input.getRule() != Validate.REQUIRED || plugin == null) {
-//        		sAvailablePlugins.add(NO_VALUE);
+//        	if (m_input.getRule() != Validate.REQUIRED || beastObject == null) {
+//        		availableBEASTObjects.add(NO_VALUE);
 //        	}
-//        	for (int i = 0; i < sAvailablePlugins.size(); i++) {
-//        		String sPlugin = sAvailablePlugins.get(i);
-//        		if (sPlugin.startsWith("new ")) {
-//        			sPlugin = sPlugin.substring(sPlugin.lastIndexOf('.'));
-//        			sAvailablePlugins.set(i, sPlugin);
+//        	for (int i = 0; i < availableBEASTObjects.size(); i++) {
+//        		String beastObjectName = availableBEASTObjects.get(i);
+//        		if (beastObjectName.startsWith("new ")) {
+//        			beastObjectName = beastObjectName.substring(beastObjectName.lastIndexOf('.'));
+//        			availableBEASTObjects.set(i, beastObjectName);
 //        		}
 //
 //        	}
-            m_selectPluginBox = new JComboBox(availableTemplates.toArray());
-            m_selectPluginBox.setName(input.getName());
+            m_selectBEASTObjectBox = new JComboBox<>(availableTemplates.toArray());
+            m_selectBEASTObjectBox.setName(input.getName());
 
             Object o = input.get();
             if (itemNr >= 0) {
-            	o = ((List)o).get(itemNr);
+            	o = ((List<?>)o).get(itemNr);
             }
-            String sID;
+            String id2;
             if (o == null) {
-                sID = plugin.getID();
+                id2 = beastObject0.getID();
             } else {
-                sID = ((BEASTInterface) o).getID();
+                id2 = ((BEASTInterface) o).getID();
             }
-            if (sID.indexOf('.')>=0) {
-            	sID = sID.substring(0, sID.indexOf('.'));
+            if (id2.indexOf('.')>=0) {
+            	id2 = id2.substring(0, id2.indexOf('.'));
             }
             for (BeautiSubTemplate template : availableTemplates) {
-                if (template.matchesName(sID)) {
-                    m_selectPluginBox.setSelectedItem(template);
+                if (template.matchesName(id2)) {
+                    m_selectBEASTObjectBox.setSelectedItem(template);
                 }
             }
 
-            m_selectPluginBox.addActionListener(new ActionListener() {
-                // implements ActionListener
-                public void actionPerformed(ActionEvent e) {
-
-//                	SwingUtilities.invokeLater(new Runnable() {
-//						
-//						@Override
-//						public void run() {
-
-                    // get a handle of the selected plugin
-                    BeautiSubTemplate sSelected = (BeautiSubTemplate) m_selectPluginBox.getSelectedItem();
-                    BEASTInterface plugin = (BEASTInterface) m_input.get();
-                    String sID = plugin.getID();
-                    String sPartition = sID.substring(sID.indexOf('.') + 1);
-                    if (sPartition.indexOf(':') >= 0) {
-                    	sPartition = sID.substring(sID.indexOf(':') + 1);
-                    }
-                    //String sNewID = sSelected.getMainID().replaceAll("\\$\\(n\\)", sPartition);
+            m_selectBEASTObjectBox.addActionListener(e -> {
 
-                    if (sSelected.equals(NO_VALUE)) {
-                        plugin = null;
-//                    } else if (PluginPanel.g_plugins.containsKey(sNewID)) {
-//                    	plugin = PluginPanel.g_plugins.get(sNewID);
-                    } else {
-                        try {
-                            plugin = sSelected.createSubNet(doc.getContextFor(plugin), m_plugin, m_input, true);
-                            //PluginPanel.addPluginToMap(plugin);
-                            // tricky: try to connect up new inputs with old inputs of existing name
-//                            Plugin oldPlugin = (Plugin) m_input.get();
-//                            for (Input<?> oldInput: oldPlugin.listInputs()) {
-//                            	String sName = oldInput.getName();
-//                            	try {
-//                            		Input<?> newInput = plugin.getInput(sName);
-//                            		if (newInput.get() instanceof List) {
-//                            			List<?> values = (List<?>) oldInput.get();
-//                            			for (Object value: values) {
-//                                			newInput.setValue(value, plugin);
-//                            			}
-//                            		} else {
-//                            			newInput.setValue(oldInput.get(), plugin);
-//                            		}
-//                            	} catch (Exception ex) {
-//									// ignore
-//								}
-//                            }
-                        } catch (Exception ex) {
-                            JOptionPane.showMessageDialog(null, "Could not select plugin: " +
-                                    ex.getClass().getName() + " " +
-                                    ex.getMessage()
-                            );
-                        }
-                    }
+//            	SwingUtilities.invokeLater(new Runnable() {
+//					
+//					@Override
+//					public void run() {
 
+                // get a handle of the selected beastObject
+                BeautiSubTemplate selected = (BeautiSubTemplate) m_selectBEASTObjectBox.getSelectedItem();
+                BEASTInterface beastObject = (BEASTInterface) m_input.get();
+                String id = beastObject.getID();
+                String partition = id.substring(id.indexOf('.') + 1);
+                if (partition.indexOf(':') >= 0) {
+                	partition = id.substring(id.indexOf(':') + 1);
+                }
+                //String newID = selected.getMainID().replaceAll("\\$\\(n\\)", partition);
 
+                if (selected.equals(NO_VALUE)) {
+                    beastObject = null;
+//                } else if (PluginPanel.g_plugins.containsKey(newID)) {
+//                	beastObject = PluginPanel.g_plugins.get(newID);
+                } else {
                     try {
-                        if (plugin == null) {
-                            m_selectPluginBox.setSelectedItem(NO_VALUE);
-                            // is this input expanded?
-                            if (m_expansionBox != null) {
-                                // remove items from Expansion Box, if any
-                                for (int i = 1; i < m_expansionBox.getComponentCount(); i++) {
-                                    m_expansionBox.remove(i);
-                                }
-                            } else { // not expanded
-                                if (m_bAddButtons && m_editPluginButton != null) {
-                                    m_editPluginButton.setEnabled(false);
-                                }
-                            }
-                        } else {
-                            if (!m_input.canSetValue(plugin, m_plugin)) {
-                                throw new Exception("Cannot set input to this value");
-                            }
-//                        	// get handle on ID of the plugin, and add to combobox if necessary
-//                            String sID = plugin.getID();
-//                            // TODO RRB: have to remove ID first, then add it
-//                            // The addition is necessary to make the items in the expansionBox scale and show up
-//                            // Is there another way?
-//                            m_selectPluginBox.removeItem(sID);
-//                            m_selectPluginBox.addItem(sID);
-//                            m_selectPluginBox.setSelectedItem(sID);
-                            sID = plugin.getID();
-                            sID = sID.substring(0, sID.indexOf('.'));
-                             for (int i = 0; i < m_selectPluginBox.getItemCount(); i++) {
-                                BeautiSubTemplate template = (BeautiSubTemplate) m_selectPluginBox.getItemAt(i);
-                                if (template.getMainID().replaceAll(".\\$\\(n\\)", "").equals(sID) ||
-                                		template.getMainID().replaceAll(".s:\\$\\(n\\)", "").equals(sID) || 
-                                		template.getMainID().replaceAll(".c:\\$\\(n\\)", "").equals(sID) || 
-                                		template.getMainID().replaceAll(".t:\\$\\(n\\)", "").equals(sID)) {
-                                    m_selectPluginBox.setSelectedItem(template);
-                                }
-                            }
-                        }
+                        beastObject = selected.createSubNet(doc.getContextFor(beastObject), m_beastObject, m_input, true);
+                        //PluginPanel.addPluginToMap(beastObject);
+                        // tricky: try to connect up new inputs with old inputs of existing name
+//                        beastObject oldPlugin = (beastObject) m_input.get();
+//                        for (Input<?> oldInput: oldPlugin.listInputs()) {
+//                        	String name = oldInput.getName();
+//                        	try {
+//                        		Input<?> newInput = beastObject.getInput(name);
+//                        		if (newInput.get() instanceof List) {
+//                        			List<?> values = (List<?>) oldInput.get();
+//                        			for (Object value: values) {
+//                            			newInput.setValue(value, beastObject);
+//                        			}
+//                        		} else {
+//                        			newInput.setValue(oldInput.get(), beastObject);
+//                        		}
+//                        	} catch (Exception ex) {
+//								// ignore
+//							}
+//                        }
+                    } catch (Exception ex) {
+                        JOptionPane.showMessageDialog(null, "Could not select beastObject: " +
+                                ex.getClass().getName() + " " +
+                                ex.getMessage()
+                        );
+                    }
+                }
 
-                        setValue(plugin);
-                        //m_input.setValue(plugin, m_plugin);
 
+                try {
+                    if (beastObject == null) {
+                        m_selectBEASTObjectBox.setSelectedItem(NO_VALUE);
+                        // is this input expanded?
                         if (m_expansionBox != null) {
-                            // remove items from Expansion Box
-                            for (int i = 1; i < m_expansionBox.getComponentCount(); ) {
+                            // remove items from Expansion Box, if any
+                            for (int i = 1; i < m_expansionBox.getComponentCount(); i++) {
                                 m_expansionBox.remove(i);
                             }
-                            // add new items to Expansion Box
-                            if (plugin != null) {
-                            	doc.getInputEditorFactory().addInputs(m_expansionBox, plugin, _this, _this, doc);
+                        } else { // not expanded
+                            if (m_bAddButtons && m_editBEASTObjectButton != null) {
+                                m_editBEASTObjectButton.setEnabled(false);
                             }
-                        } else {
-                            // it is not expanded, enable the edit button
-                            if (m_bAddButtons && m_editPluginButton != null) {
-                                m_editPluginButton.setEnabled(true);
+                        }
+                    } else {
+                        if (!m_input.canSetValue(beastObject, m_beastObject)) {
+                            throw new IllegalArgumentException("Cannot set input to this value");
+                        }
+//                    	// get handle on ID of the beastObject, and add to combobox if necessary
+//                        String id = beastObject.getID();
+//                        // TODO RRB: have to remove ID first, then add it
+//                        // The addition is necessary to make the items in the expansionBox scale and show up
+//                        // Is there another way?
+//                        m_selectPluginBox.removeItem(id);
+//                        m_selectPluginBox.addItem(id);
+//                        m_selectPluginBox.setSelectedItem(id);
+                        id = beastObject.getID();
+                        id = id.substring(0, id.indexOf('.'));
+                         for (int i = 0; i < m_selectBEASTObjectBox.getItemCount(); i++) {
+                            BeautiSubTemplate template = (BeautiSubTemplate) m_selectBEASTObjectBox.getItemAt(i);
+                            if (template.getMainID().replaceAll(".\\$\\(n\\)", "").equals(id) ||
+                            		template.getMainID().replaceAll(".s:\\$\\(n\\)", "").equals(id) || 
+                            		template.getMainID().replaceAll(".c:\\$\\(n\\)", "").equals(id) || 
+                            		template.getMainID().replaceAll(".t:\\$\\(n\\)", "").equals(id)) {
+                                m_selectBEASTObjectBox.setSelectedItem(template);
                             }
-                            validateInput();
                         }
-                        sync();
-                        refreshPanel();
-                    } catch (Exception ex) {
-                        sID = ((BEASTInterface) m_input.get()).getID();
-                        m_selectPluginBox.setSelectedItem(sID);
-                        ex.printStackTrace();
-                        JOptionPane.showMessageDialog(null, "Could not change plugin: " +
-                                ex.getClass().getName() + " " +
-                                ex.getMessage() 
-                        );
                     }
+
+                    setValue(beastObject);
+                    //m_input.setValue(beastObject, m_beastObject);
+
+                    if (m_expansionBox != null) {
+                        // remove items from Expansion Box
+                        for (int i = 1; i < m_expansionBox.getComponentCount(); ) {
+                            m_expansionBox.remove(i);
+                        }
+                        // add new items to Expansion Box
+                        if (beastObject != null) {
+                        	doc.getInputEditorFactory().addInputs(m_expansionBox, beastObject, _this, _this, doc);
+                        }
+                    } else {
+                        // it is not expanded, enable the edit button
+                        if (m_bAddButtons && m_editBEASTObjectButton != null) {
+                            m_editBEASTObjectButton.setEnabled(true);
+                        }
+                        validateInput();
+                    }
+                    sync();
+                    refreshPanel();
+                } catch (Exception ex) {
+                    id = ((BEASTInterface) m_input.get()).getID();
+                    m_selectBEASTObjectBox.setSelectedItem(id);
+                    ex.printStackTrace();
+                    JOptionPane.showMessageDialog(null, "Could not change beastObject: " +
+                            ex.getClass().getName() + " " +
+                            ex.getMessage() 
+                    );
                 }
+            });
 
-            }
-            );
-//            }
-//            });
-            m_selectPluginBox.setToolTipText(input.getHTMLTipText());
-            m_selectPluginBox.setMaximumSize(new Dimension(1024, 200));
-            box.add(m_selectPluginBox);
+            m_selectBEASTObjectBox.setToolTipText(input.getHTMLTipText());
+            m_selectBEASTObjectBox.setMaximumSize(new Dimension(1024, 200));
+            box.add(m_selectBEASTObjectBox);
         }
     }
 
-//    protected void addComboBox2(Box box, Input <?> input, Plugin plugin) {
-//        List<String> sAvailablePlugins = PluginPanel.getAvailablePlugins(m_input, m_plugin, null);
-//        if (sAvailablePlugins.size() > 0) {
-//        	if (m_input.getRule() != Validate.REQUIRED || plugin == null) {
-//        		sAvailablePlugins.add(NO_VALUE);
+//    protected void addComboBox2(Box box, Input <?> input, BEASTObject beastObject) {
+//        List<String> availableBEASTObjects = PluginPanel.getAvailablePlugins(m_input, m_beastObject, null);
+//        if (availableBEASTObjects.size() > 0) {
+//        	if (m_input.getRule() != Validate.REQUIRED || beastObject == null) {
+//        		availableBEASTObjects.add(NO_VALUE);
 //        	}
-//        	for (int i = 0; i < sAvailablePlugins.size(); i++) {
-//        		String sPlugin = sAvailablePlugins.get(i);
-//        		if (sPlugin.startsWith("new ")) {
-//        			sPlugin = sPlugin.substring(sPlugin.lastIndexOf('.'));
-//        			sAvailablePlugins.set(i, sPlugin);
+//        	for (int i = 0; i < availableBEASTObjects.size(); i++) {
+//        		String beastObjectName = availableBEASTObjects.get(i);
+//        		if (beastObjectName.startsWith("new ")) {
+//        			beastObjectName = beastObjectName.substring(beastObjectName.lastIndexOf('.'));
+//        			availableBEASTObjects.set(i, beastObjectName);
 //        		}
 //
 //        	}
-//            m_selectPluginBox = new JComboBox(sAvailablePlugins.toArray(new String[0]));
-//            String sSelectString = NO_VALUE;
+//            m_selectPluginBox = new JComboBox(availableBEASTObjects.toArray(new String[0]));
+//            String selectString = NO_VALUE;
 //            if (input.get() != null) {
-//                sSelectString = ((Plugin) input.get()).getID();
+//                selectString = ((BEASTObject) input.get()).getID();
 //            }
-//            m_selectPluginBox.setSelectedItem(sSelectString);
+//            m_selectPluginBox.setSelectedItem(selectString);
 //
 //            m_selectPluginBox.addActionListener(new ActionListener() {
 //                // implements ActionListener
 //                public void actionPerformed(ActionEvent e) {
 //                	
-//                	// get a handle of the selected plugin
-//                    String sSelected = (String) m_selectPluginBox.getSelectedItem();
-//                    Plugin plugin = (Plugin) m_input.get();
-//                    if (sSelected.equals(NO_VALUE)) {
-//                        plugin = null;
-//                    } else if (!sSelected.startsWith(".")) {
-//                        plugin = PluginPanel.g_plugins.get(sSelected);
+//                	// get a handle of the selected beastObject
+//                    String selected = (String) m_selectPluginBox.getSelectedItem();
+//                    BEASTObject beastObject = (BEASTObject) m_input.get();
+//                    if (selected.equals(NO_VALUE)) {
+//                        beastObject = null;
+//                    } else if (!selected.startsWith(".")) {
+//                        beastObject = PluginPanel.g_plugins.get(selected);
 //                    } else {
-//                        List<String> sAvailablePlugins = PluginPanel.getAvailablePlugins(m_input, m_plugin, null);
+//                        List<String> availableBEASTObjects = PluginPanel.getAvailablePlugins(m_input, m_beastObject, null);
 //                        int i = 0;                     
-//                        while (!sAvailablePlugins.get(i).matches(".*\\"+sSelected+"$")) {
+//                        while (!availableBEASTObjects.get(i).matches(".*\\"+selected+"$")) {
 //                        	i++;
 //                        }
-//                    	sSelected = sAvailablePlugins.get(i);                       
-//                        /* create new plugin */
+//                    	selected = availableBEASTObjects.get(i);                       
+//                        /* create new beastObject */
 //                        try {
-//                            plugin = (Plugin) Class.forName(sSelected.substring(4)).newInstance();
-//                            PluginPanel.addPluginToMap(plugin);
+//                            beastObject = (BEASTObject) Class.forName(selected.substring(4)).newInstance();
+//                            PluginPanel.addPluginToMap(beastObject);
 //                            // tricky: try to connect up new inputs with old inputs of existing name
-//                            Plugin oldPlugin = (Plugin) m_input.get();
+//                            BEASTObject oldPlugin = (BEASTObject) m_input.get();
 //                            for (Input<?> oldInput: oldPlugin.listInputs()) {
-//                            	String sName = oldInput.getName();
+//                            	String name = oldInput.getName();
 //                            	try {
-//                            		Input<?> newInput = plugin.getInput(sName);
+//                            		Input<?> newInput = beastObject.getInput(name);
 //                            		if (newInput.get() instanceof List) {
 //                            			List<?> values = (List<?>) oldInput.get();
 //                            			for (Object value: values) {
-//                                			newInput.setValue(value, plugin);
+//                                			newInput.setValue(value, beastObject);
 //                            			}
 //                            		} else {
-//                            			newInput.setValue(oldInput.get(), plugin);
+//                            			newInput.setValue(oldInput.get(), beastObject);
 //                            		}
 //                            	} catch (Exception ex) {
 //									// ignore
@@ -401,7 +395,7 @@ public class BEASTObjectInputEditor extends InputEditor.Base {
 //                            }
 //                            
 //                        } catch (Exception ex) {
-//                            JOptionPane.showMessageDialog(null, "Could not select plugin: " +
+//                            JOptionPane.showMessageDialog(null, "Could not select beastObject: " +
 //                                    ex.getClass().getName() + " " +
 //                                    ex.getMessage()
 //                            );
@@ -410,7 +404,7 @@ public class BEASTObjectInputEditor extends InputEditor.Base {
 //
 //                    
 //                    try {
-//                        if (plugin == null) {
+//                        if (beastObject == null) {
 //                            m_selectPluginBox.setSelectedItem(NO_VALUE);
 //                            // is this input expanded?
 //                            if (m_expansionBox != null) {
@@ -424,20 +418,20 @@ public class BEASTObjectInputEditor extends InputEditor.Base {
 //                            	}
 //                            }
 //                        } else {
-//                            if (!m_input.canSetValue(plugin, m_plugin)) {
+//                            if (!m_input.canSetValue(beastObject, m_beastObject)) {
 //                            	throw new Exception("Cannot set input to this value");
 //                            }
-//                        	// get handle on ID of the plugin, and add to combobox if necessary
-//                            String sID = plugin.getID();
+//                        	// get handle on ID of the beastObject, and add to combobox if necessary
+//                            String id = beastObject.getID();
 //                            // TODO RRB: have to remove ID first, then add it
 //                            // The addition is necessary to make the items in the expansionBox scale and show up
 //                            // Is there another way?
-//                            m_selectPluginBox.removeItem(sID);
-//                            m_selectPluginBox.addItem(sID);
-//                            m_selectPluginBox.setSelectedItem(sID);
+//                            m_selectPluginBox.removeItem(id);
+//                            m_selectPluginBox.addItem(id);
+//                            m_selectPluginBox.setSelectedItem(id);
 //                        }
 //                        
-//                        m_input.setValue(plugin, m_plugin);
+//                        m_input.setValue(beastObject, m_beastObject);
 //                        
 //                        if (m_expansionBox != null) {
 //                        	// remove items from Expansion Box
@@ -445,8 +439,8 @@ public class BEASTObjectInputEditor extends InputEditor.Base {
 //                        		m_expansionBox.remove(i);
 //                        	}
 //                        	// add new items to Expansion Box
-//                        	if (plugin != null) {
-//                        		PluginPanel.addInputs(m_expansionBox, plugin, _this, _this);
+//                        	if (beastObject != null) {
+//                        		PluginPanel.addInputs(m_expansionBox, beastObject, _this, _this);
 //                        	}
 //                        } else {
 //                        	// it is not expanded, enable the edit button
@@ -457,10 +451,10 @@ public class BEASTObjectInputEditor extends InputEditor.Base {
 //                        }
 //                        
 //                    } catch (Exception ex) {
-//                        String sID = ((Plugin)m_input.get()).getID();
-//                        m_selectPluginBox.setSelectedItem(sID);
+//                        String id = ((BEASTObject)m_input.get()).getID();
+//                        m_selectPluginBox.setSelectedItem(id);
 //                    	//ex.printStackTrace();
-//                        JOptionPane.showMessageDialog(null, "Could not change plugin: " +
+//                        JOptionPane.showMessageDialog(null, "Could not change beastObject: " +
 //                                ex.getClass().getName() + " " +
 //                                ex.getMessage()
 //                        );
@@ -474,8 +468,8 @@ public class BEASTObjectInputEditor extends InputEditor.Base {
 //    }
 
     String[] getAvailablePlugins() {
-        List<String> sPlugins = AddOnManager.find(m_input.getType(), "beast");
-        return sPlugins.toArray(new String[0]);
+        List<String> beastObjectNames = AddOnManager.find(m_input.getType(), "beast");
+        return beastObjectNames.toArray(new String[0]);
     } // getAvailablePlugins
 
 } // class PluginInputEditor
diff --git a/src/beast/app/draw/BEASTObjectPanel.java b/src/beast/app/draw/BEASTObjectPanel.java
index b565d86..2cbd1f5 100644
--- a/src/beast/app/draw/BEASTObjectPanel.java
+++ b/src/beast/app/draw/BEASTObjectPanel.java
@@ -3,26 +3,33 @@ package beast.app.draw;
 
 
 
-import javax.swing.*;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Scanner;
+
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
 
 import beast.app.beauti.BeautiDoc;
+import beast.core.BEASTInterface;
 import beast.core.Input;
 import beast.core.MCMC;
-import beast.core.BEASTInterface;
-import beast.evolution.alignment.Taxon;
+import beast.core.util.Log;
 import beast.util.XMLProducer;
 
-
-import java.awt.*;
-import java.io.File;
-import java.util.*;
-import java.util.List;
-
 /**
- * Panel for editing Plugins.
+ * Panel for editing BEASTObjects.
  * <p/>
  * This dynamically creates a Panel consisting of
- * InputEditors associated with the inputs of a Plugin.
+ * InputEditors associated with the inputs of a BEASTObject.
  * *
  */
 
@@ -31,18 +38,18 @@ public class BEASTObjectPanel extends JPanel {
     /**
      * plug in to be edited *
      */
-    public BEASTInterface m_plugin;
+    public BEASTInterface m_beastObject;
     /**
      * (super) class of plug-in, this determines the super-class
-     * that is allowable if the plugin class is changed.
+     * that is allowable if the beastObject class is changed.
      */
-    Class<?> m_pluginClass;
-    JLabel m_pluginButton;
+    Class<?> m_beastObjectClass;
+    JLabel m_beastObjectButton;
     JTextField m_identry;
 
     private boolean m_bOK = false;
-    /* Set of plugins in the system.
-      * These are the plugins that an input can be connected to **/
+    /* Set of beastObjects in the system.
+      * These are the beastObjects that an input can be connected to **/
     static public HashMap<String, BEASTInterface> g_plugins = null;
     //    static public Set<Operator> g_operators = null;
 //    static public Set<StateNode> g_stateNodes = null;
@@ -64,112 +71,112 @@ public class BEASTObjectPanel extends JPanel {
 
     public static void init() {
 //        // register input editors
-//        g_inputEditorMap = new HashMap<Class<?>, String>();
-//        g_listInputEditorMap = new HashMap<Class<?>, String>();
+//        g_inputEditorMap = new HashMap<>, String>();
+//        g_listInputEditorMap = new HashMap<>, String>();
 //
-////        String [] sKnownEditors = new String [] {"beast.app.draw.DataInputEditor","beast.app.beauti.AlignmentListInputEditor", "beast.app.beauti.FrequenciesInputEditor", "beast.app.beauti.OperatorListInputEditor", "beast.app.beauti.ParametricDistributionInputEditor", "beast.app.beauti.PriorListInputEditor", "beast.app.beauti.SiteModelInputEditor", "beast.app.beauti.TaxonSetInputEditor", "beast.app.beauti.TipDatesInputEditor", "beast.app.draw.BooleanInputEditor", "beast.app.draw.Doubl [...]
+////        String [] knownEditors = new String [] {"beast.app.draw.DataInputEditor","beast.app.beauti.AlignmentListInputEditor", "beast.app.beauti.FrequenciesInputEditor", "beast.app.beauti.OperatorListInputEditor", "beast.app.beauti.ParametricDistributionInputEditor", "beast.app.beauti.PriorListInputEditor", "beast.app.beauti.SiteModelInputEditor", "beast.app.beauti.TaxonSetInputEditor", "beast.app.beauti.TipDatesInputEditor", "beast.app.draw.BooleanInputEditor", "beast.app.draw.Double [...]
 ////        		"beast.app.draw.ParameterInputEditor", "beast.app.draw.PluginInputEditor", "beast.app.draw.StringInputEditor"};
-////        registerInputEditors(sKnownEditors);
+////        registerInputEditors(knownEditors);
 //        String[] PACKAGE_DIRS = {"beast.app",};
-//        for (String sPackage : PACKAGE_DIRS) {
-//            List<String> sInputEditors = AddOnManager.find("beast.app.draw.InputEditor", sPackage);
-//            registerInputEditors(sInputEditors.toArray(new String[0]));
+//        for (String packageName : PACKAGE_DIRS) {
+//            List<String> inputEditors = AddOnManager.find("beast.app.draw.InputEditor", packageName);
+//            registerInputEditors(inputEditors.toArray(new String[0]));
 //        }
 
         m_position = new Point(0, 0);
-        g_plugins = new HashMap<String, BEASTInterface>();
-//        g_operators = new HashSet<Operator>();
-//        g_stateNodes = new HashSet<StateNode>();
-//        g_loggers = new HashSet<Loggable>();
-//        g_distributions = new HashSet<Distribution>();
+        g_plugins = new HashMap<>();
+//        g_operators = new HashSet<>();
+//        g_stateNodes = new HashSet<>();
+//        g_loggers = new HashSet<>();
+//        g_distributions = new HashSet<>();
     }
 
 
-    public BEASTObjectPanel(BEASTInterface plugin, Class<?> _pluginClass, List<BEASTInterface> plugins, BeautiDoc doc) {
-        //g_plugins = new HashMap<String, Plugin>();
-        for (BEASTInterface plugin2 : plugins) {
-            String sID = getID(plugin2);
+    public BEASTObjectPanel(BEASTInterface beastObject, Class<?> _pluginClass, List<BEASTInterface> beastObjects, BeautiDoc doc) {
+        //g_plugins = new HashMap<>();
+        for (BEASTInterface beastObject2 : beastObjects) {
+            String id = getID(beastObject2);
             // ensure IDs are unique
-            if (g_plugins.containsKey(sID)) {
-                plugin2.setID(null);
-                sID = getID(plugin2);
+            if (g_plugins.containsKey(id)) {
+                beastObject2.setID(null);
+                id = getID(beastObject2);
             }
-            registerPlugin(getID(plugin2), plugin2, doc);
+            registerPlugin(getID(beastObject2), beastObject2, doc);
         }
-        init(plugin, _pluginClass, true, doc);
+        init(beastObject, _pluginClass, true, doc);
     }
 
     /**
-     * add plugin to plugin map and update related maps
+     * add beastObject to beastObject map and update related maps
      *
      * @return true if it was already registered *
      */
-    static public boolean registerPlugin(String sID, BEASTInterface plugin, BeautiDoc doc) {
+    static public boolean registerPlugin(String id, BEASTInterface beastObject, BeautiDoc doc) {
         if (doc != null) {
-            doc.registerPlugin(plugin);
+            doc.registerPlugin(beastObject);
         }
-//    	if (plugin instanceof Operator) {
-//    		g_operators.add((Operator)plugin);
+//    	if (beastObject instanceof Operator) {
+//    		g_operators.add((Operator)beastObject);
 //    	}
-//    	if (plugin instanceof StateNode) {
-//    		g_stateNodes.add((StateNode)plugin);
+//    	if (beastObject instanceof StateNode) {
+//    		g_stateNodes.add((StateNode)beastObject);
 //    	}
-//    	if (plugin instanceof Loggable) {
-//    		g_loggers.add((Loggable)plugin);
+//    	if (beastObject instanceof Loggable) {
+//    		g_loggers.add((Loggable)beastObject);
 //    	}
-//    	if (plugin instanceof Distribution) {
-//    		g_distributions.add((Distribution)plugin);
+//    	if (beastObject instanceof Distribution) {
+//    		g_distributions.add((Distribution)beastObject);
 //    	}
-        if (g_plugins.containsKey(sID) && g_plugins.get(sID) == plugin) {
+        if (g_plugins.containsKey(id) && g_plugins.get(id) == beastObject) {
             return true;
         }
-        g_plugins.put(sID, plugin);
+        g_plugins.put(id, beastObject);
         return false;
     }
 
-    public static void renamePluginID(BEASTInterface plugin, String sOldID, String sID, BeautiDoc doc) {
+    public static void renamePluginID(BEASTInterface beastObject, String oldID, String id, BeautiDoc doc) {
         if (doc != null) {
-            doc.unregisterPlugin(plugin);
+            doc.unregisterPlugin(beastObject);
         }
-        g_plugins.remove(sOldID);
-//		g_operators.remove(sOldID);
-//		g_stateNodes.remove(sOldID);
-//		g_loggers.remove(sOldID);
-//		g_distributions.remove(sOldID);
-        registerPlugin(sID, plugin, doc);
+        g_plugins.remove(oldID);
+//		g_operators.remove(oldID);
+//		g_stateNodes.remove(oldID);
+//		g_loggers.remove(oldID);
+//		g_distributions.remove(oldID);
+        registerPlugin(id, beastObject, doc);
     }
 
-    public BEASTObjectPanel(BEASTInterface plugin, Class<?> _pluginClass, BeautiDoc doc) {
-        this(plugin, _pluginClass, true, doc);
+    public BEASTObjectPanel(BEASTInterface beastObject, Class<?> _pluginClass, BeautiDoc doc) {
+        this(beastObject, _pluginClass, true, doc);
     }
 
-    public BEASTObjectPanel(BEASTInterface plugin, Class<?> _pluginClass, boolean bShowHeader, BeautiDoc doc) {
-        initPlugins(plugin, doc);
-        init(plugin, _pluginClass, bShowHeader, doc);
+    public BEASTObjectPanel(BEASTInterface beastObject, Class<?> _pluginClass, boolean isShowHeader, BeautiDoc doc) {
+        initPlugins(beastObject, doc);
+        init(beastObject, _pluginClass, isShowHeader, doc);
     }
 
-    void init(BEASTInterface plugin, Class<?> _pluginClass, boolean showHeader, BeautiDoc doc) {
+    void init(BEASTInterface beastObject, Class<?> _pluginClass, boolean showHeader, BeautiDoc doc) {
         try {
-            m_plugin = plugin.getClass().newInstance();
-            for (Input<?> input : plugin.listInputs()) {
-                m_plugin.setInputValue(input.getName(), input.get());
+            m_beastObject = beastObject.getClass().newInstance();
+            for (Input<?> input : beastObject.listInputs()) {
+                m_beastObject.setInputValue(input.getName(), input.get());
             }
-            m_plugin.setID(plugin.getID());
+            m_beastObject.setID(beastObject.getID());
         } catch (Exception e) {
             e.printStackTrace();
         }
 
 
         //setModal(true);
-        //m_plugin = plugin;
-        m_pluginClass = _pluginClass;
-        //setTitle(m_plugin.getID() + " Editor");
+        //m_beastObject = beastObject;
+        m_beastObjectClass = _pluginClass;
+        //setTitle(m_beastObject.getID() + " Editor");
 
         Box mainBox = Box.createVerticalBox();
         mainBox.add(Box.createVerticalStrut(5));
 
         if (showHeader) {
-            /* add plugin + help button at the top */
+            /* add beastObject + help button at the top */
             Box pluginBox = createPluginBox();
             mainBox.add(pluginBox);
             mainBox.add(Box.createVerticalStrut(5));
@@ -179,7 +186,7 @@ public class BEASTObjectPanel extends JPanel {
             }
         }
 
-        doc.getInputEditorFactory().addInputs(mainBox, m_plugin, null, null, doc);
+        doc.getInputEditorFactory().addInputs(mainBox, m_beastObject, null, null, doc);
 
 
         mainBox.add(Box.createVerticalStrut(5));
@@ -200,61 +207,61 @@ public class BEASTObjectPanel extends JPanel {
     }
 
     /**
-     * add all inputs of a plugin to a box *
+     * add all inputs of a beastObject to a box *
      */
-    public static int countInputs(BEASTInterface plugin, BeautiDoc doc) {
-        int nInputs = 0;
+    public static int countInputs(BEASTInterface beastObject, BeautiDoc doc) {
+        int inputCount = 0;
         try {
-            List<Input<?>> inputs = plugin.listInputs();
+            List<Input<?>> inputs = beastObject.listInputs();
             for (Input<?> input : inputs) {
-                String sFullInputName = plugin.getClass().getName() + "." + input.getName();
-                if (!doc.beautiConfig.suppressPlugins.contains(sFullInputName)) {
-                    nInputs++;
+                String fullInputName = beastObject.getClass().getName() + "." + input.getName();
+                if (!doc.beautiConfig.suppressBEASTObjects.contains(fullInputName)) {
+                    inputCount++;
                 }
             }
         } catch (Exception e) {
             // ignore
         }
-        return nInputs;
+        return inputCount;
     } // addInputs
 
 
 
     /**
-     * create box for manipulating the plugin, or ask for help *
+     * create box for manipulating the beastObject, or ask for help *
      */
     Box createPluginBox() {
         Box box = Box.createHorizontalBox();
-        JLabel icon = new JLabel();
+        //jLabel icon = new JLabel();
         box.add(Box.createHorizontalGlue());
 
-        JLabel label = new JLabel(m_pluginClass.getName().replaceAll(".*\\.", "") + ":");
+        JLabel label = new JLabel(m_beastObjectClass.getName().replaceAll(".*\\.", "") + ":");
         box.add(label);
 
-//        m_pluginButton = new JLabel(m_plugin.getID());
-//        m_pluginButton.setToolTipText(m_plugin.getID() + " is of type " + m_plugin.getClass().getName() + " Click to change.");
-        label.setToolTipText(m_plugin.getID() + " is of type " + m_plugin.getClass().getName() + " Click to change.");
+//        m_pluginButton = new JLabel(m_beastObject.getID());
+//        m_pluginButton.setToolTipText(m_beastObject.getID() + " is of type " + m_beastObject.getClass().getName() + " Click to change.");
+        label.setToolTipText(m_beastObject.getID() + " is of type " + m_beastObject.getClass().getName() + " Click to change.");
 
 //		m_pluginButton.addActionListener(new ActionListener() {
 //			@Override
 //			public void actionPerformed(ActionEvent e) {
-//				List<String> sClasses = ClassDiscovery.find(m_pluginClass, "beast"); 
-//				String sClassName = (String) JOptionPane.showInputDialog(null,
+//				List<String> classes = ClassDiscovery.find(m_pluginClass, "beast"); 
+//				String className = (String) JOptionPane.showInputDialog(null,
 //						"Select another type of " + m_pluginClass.getName().replaceAll(".*\\.", ""), 
 //						"Select",
 //						JOptionPane.PLAIN_MESSAGE, null,
-//						sClasses.toArray(new String[0]),
+//						classes.toArray(new String[0]),
 //						null);
-//				if (sClassName.equals(m_plugin.getClass().getName())) {
+//				if (className.equals(m_beastObject.getClass().getName())) {
 //					return;
 //				}
 //				try {
-//					m_plugin = (Plugin) Class.forName(sClassName).newInstance();
-//					m_pluginButton.setText(sClassName.replaceAll(".*\\.", ""));
+//					m_beastObject = (BEASTObject) Class.forName(className).newInstance();
+//					m_pluginButton.setText(className.replaceAll(".*\\.", ""));
 //					// TODO: replace InputEditors where appropriate.
 //					
 //				} catch (Exception ex) {
-//					JOptionPane.showMessageDialog(null, "Could not change plugin: " +
+//					JOptionPane.showMessageDialog(null, "Could not change beastObject: " +
 //							ex.getClass().getName() + " " +
 //							ex.getMessage()
 //							);
@@ -265,10 +272,10 @@ public class BEASTObjectPanel extends JPanel {
 //        box.add(m_pluginButton);
 
 
-        box.add(new JLabel(" " + m_plugin.getID()));
+        box.add(new JLabel(" " + m_beastObject.getID()));
         
 //        m_identry = new JTextField();
-//        m_identry.setText(m_plugin.getID());
+//        m_identry.setText(m_beastObject.getID());
 //        m_identry.setToolTipText("Name/ID that uniquely identifies this item");
 //
 //        m_identry.getDocument().addDocumentListener(new DocumentListener() {
@@ -300,33 +307,33 @@ public class BEASTObjectPanel extends JPanel {
     } // createPluginBox
 
     void processID() {
-//		PluginPanel.g_plugins.remove(m_plugin.getID());
-//		m_plugin.setID(m_identry.getText());
-//		PluginPanel.g_plugins.put(m_plugin.getID(), m_plugin);
+//		PluginPanel.g_plugins.remove(m_beastObject.getID());
+//		m_beastObject.setID(m_identry.getText());
+//		PluginPanel.g_plugins.put(m_beastObject.getID(), m_beastObject);
     }
 
 
 
     /**
-     * collect all plugins that can reach this input (actually, it's parent)
+     * collect all beastObjects that can reach this input (actually, it's parent)
      * and add them to the tabu list.
      */
-    static List<BEASTInterface> listAscendants(BEASTInterface parent, Collection<BEASTInterface> plugins) {
-        /* First, calculate outputs for each plugin */
-        HashMap<BEASTInterface, List<BEASTInterface>> outputs = getOutputs(plugins);
+    static List<BEASTInterface> listAscendants(BEASTInterface parent, Collection<BEASTInterface> beastObjects) {
+        /* First, calculate outputs for each beastObject */
+        HashMap<BEASTInterface, List<BEASTInterface>> outputs = getOutputs(beastObjects);
         /* process outputs */
-        List<BEASTInterface> ascendants = new ArrayList<BEASTInterface>();
+        List<BEASTInterface> ascendants = new ArrayList<>();
         ascendants.add(parent);
-        boolean bProgress = true;
-        while (bProgress) {
-            bProgress = false;
+        boolean progress = true;
+        while (progress) {
+            progress = false;
             for (int i = 0; i < ascendants.size(); i++) {
                 BEASTInterface ascendant = ascendants.get(i);
                 if (outputs.containsKey(ascendant)) {
                     for (BEASTInterface parent2 : outputs.get(ascendant)) {
                         if (!ascendants.contains(parent2)) {
                             ascendants.add(parent2);
-                            bProgress = true;
+                            progress = true;
                         }
                     }
                 }
@@ -335,19 +342,19 @@ public class BEASTObjectPanel extends JPanel {
         return ascendants;
     }
 
-    /* calculate outputs for each plugin
+    /* calculate outputs for each beastObject
       * and put them as ArrayLists in a Map
-      * so they can be retrieved indexed by plugin like this:
-      * ArrayList<Plugin> output = outputs.get(plugin)*/
+      * so they can be retrieved indexed by beastObject like this:
+      * ArrayList<BEASTObject> output = outputs.get(beastObject)*/
 
-    static HashMap<BEASTInterface, List<BEASTInterface>> getOutputs(Collection<BEASTInterface> plugins) {
-        HashMap<BEASTInterface, List<BEASTInterface>> outputs = new HashMap<BEASTInterface, List<BEASTInterface>>();
-        for (BEASTInterface plugin : plugins) {
-            outputs.put(plugin, new ArrayList<BEASTInterface>());
+    static HashMap<BEASTInterface, List<BEASTInterface>> getOutputs(Collection<BEASTInterface> beastObjects) {
+        HashMap<BEASTInterface, List<BEASTInterface>> outputs = new HashMap<>();
+        for (BEASTInterface beastObject : beastObjects) {
+            outputs.put(beastObject, new ArrayList<>());
         }
-        for (BEASTInterface plugin : plugins) {
+        for (BEASTInterface beastObject : beastObjects) {
             try {
-                for (Input<?> input2 : plugin.listInputs()) {
+                for (Input<?> input2 : beastObject.listInputs()) {
                     Object o = input2.get();
                     if (o != null && o instanceof BEASTInterface) {
                         List<BEASTInterface> list = outputs.get(o);
@@ -355,18 +362,15 @@ public class BEASTObjectPanel extends JPanel {
 //                    		int h = 3;
 //                    		h++;
 //                    	} else {
-                        list.add(plugin);
+                        list.add(beastObject);
 //                    	}
                     }
                     if (o != null && o instanceof List<?>) {
                         for (Object o2 : (List<?>) o) {
                             if (o2 != null && o2 instanceof BEASTInterface) {
                                 List<BEASTInterface> list = outputs.get(o2);
-                                if (list == null) {
-                                    int h = 3;
-                                    h++;
-                                } else {
-                                    list.add(plugin);
+                                if (list != null) {
+                                    list.add(beastObject);
                                 }
                             }
                         }
@@ -379,17 +383,17 @@ public class BEASTObjectPanel extends JPanel {
         return outputs;
     } // getOutputs
 
-    public void initPlugins(BEASTInterface plugin, BeautiDoc doc) {
-        //g_plugins = new HashMap<String, Plugin>();
-        addPluginToMap(plugin, doc);
+    public void initPlugins(BEASTInterface beastObject, BeautiDoc doc) {
+        //g_plugins = new HashMap<>();
+        addPluginToMap(beastObject, doc);
     }
 
-    static public void addPluginToMap(BEASTInterface plugin, BeautiDoc doc) {
-        if (registerPlugin(getID(plugin), plugin, doc)) {
+    static public void addPluginToMap(BEASTInterface beastObject, BeautiDoc doc) {
+        if (registerPlugin(getID(beastObject), beastObject, doc)) {
             return;
         }
         try {
-            for (Input<?> input : plugin.listInputs()) {
+            for (Input<?> input : beastObject.listInputs()) {
                 if (input.get() != null) {
                     if (input.get() instanceof BEASTInterface) {
                         addPluginToMap((BEASTInterface) input.get(), doc);
@@ -405,23 +409,23 @@ public class BEASTObjectPanel extends JPanel {
             }
         } catch (Exception e) {
             // ignore
-            System.err.println(e.getClass().getName() + " " + e.getMessage());
+            Log.warning.println(e.getClass().getName() + " " + e.getMessage());
         }
     } // addPluginToMap
 
     /**
-     * return ID of plugin, if no ID is specified, generate an appropriate ID first
+     * return ID of beastObject, if no ID is specified, generate an appropriate ID first
      */
-    public static String getID(BEASTInterface plugin) {
-        if (plugin.getID() == null || plugin.getID().length() == 0) {
-            String sID = plugin.getClass().getName().replaceAll(".*\\.", "");
+    public static String getID(BEASTInterface beastObject) {
+        if (beastObject.getID() == null || beastObject.getID().length() == 0) {
+            String id = beastObject.getClass().getName().replaceAll(".*\\.", "");
             int i = 0;
-            while (g_plugins.containsKey(sID + i)) {
+            while (g_plugins.containsKey(id + i)) {
                 i++;
             }
-            plugin.setID(sID + "." + i);
+            beastObject.setID(id + "." + i);
         }
-        return plugin.getID();
+        return beastObject.getID();
     }
 
     /**
@@ -444,29 +448,29 @@ public class BEASTObjectPanel extends JPanel {
                 } finally {
                     scanner.close();
                 }
-                BEASTInterface plugin = new beast.util.XMLParser().parseBareFragment(text.toString(), false);
-                pluginPanel = new BEASTObjectPanel(plugin, plugin.getClass(), null);
+                BEASTInterface beastObject = new beast.util.XMLParser().parseBareFragment(text.toString(), false);
+                pluginPanel = new BEASTObjectPanel(beastObject, beastObject.getClass(), null);
             } else if (args.length == 1) {
                 pluginPanel = new BEASTObjectPanel((BEASTInterface) Class.forName(args[0]).newInstance(), Class.forName(args[0]), null);
             } else if (args.length == 2) {
                 pluginPanel = new BEASTObjectPanel((BEASTInterface) Class.forName(args[0]).newInstance(), Class.forName(args[1]), null);
             } else {
-                throw new Exception("Incorrect number of arguments");
+                throw new IllegalArgumentException("Incorrect number of arguments");
             }
         } catch (Exception e) {
             e.printStackTrace();
             System.err.println("Usage: " + BEASTObjectPanel.class.getName() + " [-x file ] [class [type]]\n" +
-                    "where [class] (optional, default MCMC) is a Plugin to edit\n" +
-                    "and [type] (optional only if class is specified, default Runnable) the type of the Plugin.\n" +
+                    "where [class] (optional, default MCMC) is a BEASTObject to edit\n" +
+                    "and [type] (optional only if class is specified, default Runnable) the type of the BEASTObject.\n" +
                     "for example\n" +
                     "");
-            System.exit(0);
+            System.exit(1);
         }
         pluginPanel.setVisible(true);
         if (pluginPanel.m_bOK) {
-            BEASTInterface plugin = pluginPanel.m_plugin;
-            String sXML = new XMLProducer().modelToXML(plugin);
-            System.out.println(sXML);
+            BEASTInterface beastObject = pluginPanel.m_beastObject;
+            String xml = new XMLProducer().modelToXML(beastObject);
+            System.out.println(xml);
         }
     } // main
 
diff --git a/src/beast/app/draw/BEASTObjectSet.java b/src/beast/app/draw/BEASTObjectSet.java
index d5b1f9f..0e8fe00 100644
--- a/src/beast/app/draw/BEASTObjectSet.java
+++ b/src/beast/app/draw/BEASTObjectSet.java
@@ -3,16 +3,16 @@ package beast.app.draw;
 import java.util.ArrayList;
 import java.util.List;
 
+import beast.core.BEASTInterface;
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 
 
 
- at Description("Set of plugins to represent partially finished models in GUIs")
+ at Description("Set of beastObjects to represent partially finished models in GUIs")
 public class BEASTObjectSet extends BEASTObject {
-    public Input<List<BEASTInterface>> m_plugins = new Input<List<BEASTInterface>>("plugin", "set of the plugins in this collection", new ArrayList<BEASTInterface>());
+    final public Input<List<BEASTInterface>> m_plugins = new Input<>("beastObject", "set of the beastObjects in this collection", new ArrayList<>());
 
     @Override
     public void initAndValidate() {
diff --git a/src/beast/app/draw/BEASTObjectShape.java b/src/beast/app/draw/BEASTObjectShape.java
index febaac2..0802ce0 100644
--- a/src/beast/app/draw/BEASTObjectShape.java
+++ b/src/beast/app/draw/BEASTObjectShape.java
@@ -32,16 +32,15 @@ import java.awt.GradientPaint;
 import java.awt.Graphics2D;
 import java.awt.Point;
 import java.io.PrintStream;
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
 
 import javax.swing.JPanel;
 
 import org.w3c.dom.Node;
 
+import beast.core.BEASTInterface;
 import beast.core.Input;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 import beast.util.Randomizer;
 
 
@@ -50,7 +49,7 @@ import beast.util.Randomizer;
 
 public class BEASTObjectShape extends Shape {
     static Font g_PluginFont = new Font("arial", Font.PLAIN, 11);
-    public beast.core.BEASTInterface m_plugin;
+    public beast.core.BEASTInterface m_beastObject;
     List<InputShape> m_inputs;
 
 
@@ -59,35 +58,32 @@ public class BEASTObjectShape extends Shape {
         m_fillcolor = new Color(Randomizer.nextInt(256), 128 + Randomizer.nextInt(128), Randomizer.nextInt(128));
     }
 
-    public BEASTObjectShape(BEASTInterface plugin, Document doc) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+    public BEASTObjectShape(BEASTInterface beastObject, Document doc) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
         super();
-        m_plugin = plugin;
+        m_beastObject = beastObject;
         m_fillcolor = new Color(Randomizer.nextInt(256), 128 + Randomizer.nextInt(128), Randomizer.nextInt(128));
-        init(plugin.getClass().getName(), doc);
+        init(beastObject.getClass().getName(), doc);
     }
 
-    public BEASTObjectShape(Node node, Document doc, boolean bReconstructPlugins) {
-        parse(node, doc, bReconstructPlugins);
+    public BEASTObjectShape(Node node, Document doc, boolean reconstructBEASTObjects) {
+        parse(node, doc, reconstructBEASTObjects);
     }
 
-    public void init(String sClassName, Document doc) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+    public void init(String className, Document doc) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
     	m_doc = doc;
-        if (m_plugin == null) {
-            m_plugin = (beast.core.BEASTInterface) Class.forName(sClassName).newInstance();
-        }
-        m_inputs = new ArrayList<InputShape>();
-        if (m_plugin.getID() == null) {
-        	String sID = m_plugin.getClass().getName();
-        	sID = sID.substring(sID.lastIndexOf('.') + 1);
-        	m_plugin.setID(sID);
+        if (m_beastObject == null) {
+            m_beastObject = (beast.core.BEASTInterface) Class.forName(className).newInstance();
         }
-        //System.err.println("\n>>>>" + m_plugin.getID());        
-        if (m_plugin.getID().equals("mcmc")) {
-        	int h = 3;
+        m_inputs = new ArrayList<>();
+        if (m_beastObject.getID() == null) {
+        	String id = m_beastObject.getClass().getName();
+        	id = id.substring(id.lastIndexOf('.') + 1);
+        	m_beastObject.setID(id);
         }
-        List<Input<?>> sInputs = m_plugin.listInputs();
-        for (Input<?> input_ : sInputs) {
-			String longInputName = m_plugin.getClass().getName() + "." + input_.getName(); 
+        //System.err.println("\n>>>>" + m_beastObject.getID());        
+        List<Input<?>> inputs = m_beastObject.listInputs();
+        for (Input<?> input_ : inputs) {
+			String longInputName = m_beastObject.getClass().getName() + "." + input_.getName(); 
 			//System.err.print(longInputName);
         	if (doc.showAllInputs() ||
         			!doc.tabulist.contains(longInputName) && 
@@ -109,15 +105,15 @@ public class BEASTObjectShape extends Shape {
         adjustInputs();
     } // setClassName
 
-    // find input shape associated with input with name sLabel
-    InputShape getInputShape(String sLabel) {
+    // find input shape associated with input with name label
+    InputShape getInputShape(String label) {
         for (InputShape shape : m_inputs) {
-            String sLabel2 = shape.getLabel();
-            if (sLabel2 != null) {
-                if (sLabel2.contains("=")) {
-                    sLabel2 = sLabel2.substring(0, sLabel2.indexOf('='));
+            String label2 = shape.getLabel();
+            if (label2 != null) {
+                if (label2.contains("=")) {
+                    label2 = label2.substring(0, label2.indexOf('='));
                 }
-                if (sLabel2.equals(sLabel)) {
+                if (label2.equals(label)) {
                     return shape;
                 }
             }
@@ -129,15 +125,15 @@ public class BEASTObjectShape extends Shape {
      * set coordinates of inputs based on location of this PluginShape
      */
     void adjustInputs() {
-        if (m_plugin != null) {
+        if (m_beastObject != null) {
             try {
-                List<Input<?>> inputs = m_plugin.listInputs();
+                //List<Input<?>> inputs = m_beastObject.listInputs();
                 for (int i = 0; i < m_inputs.size(); i++) {
                     InputShape input = m_inputs.get(i);
                     //input.m_input = inputs.get(i);
-                    int nOffset = i * m_h / (m_inputs.size()) + m_h / (2 * (m_inputs.size()));
+                    int offset = i * m_h / (m_inputs.size()) + m_h / (2 * (m_inputs.size()));
                     input.m_x = m_x - input.m_w;
-                    input.m_y = m_y + nOffset;
+                    input.m_y = m_y + offset;
                     //input.m_w = 10;
                     input.m_h = 10;
                     input.m_fillcolor = m_fillcolor;
@@ -173,26 +169,26 @@ public class BEASTObjectShape extends Shape {
     }
 
     @Override
-    void parse(Node node, Document doc, boolean bReconstructPlugins) {
-        super.parse(node, doc, bReconstructPlugins);
-        if (bReconstructPlugins) {
+    void parse(Node node, Document doc, boolean reconstructBEASTObjects) {
+        super.parse(node, doc, reconstructBEASTObjects);
+        if (reconstructBEASTObjects) {
             if (node.getAttributes().getNamedItem("class") != null) {
-                String sClassName = node.getAttributes().getNamedItem("class").getNodeValue();
+                String className = node.getAttributes().getNamedItem("class").getNodeValue();
                 try {
-                    m_plugin = (beast.core.BEASTInterface) Class.forName(sClassName).newInstance();
-                    m_plugin.setID(m_sID);
+                    m_beastObject = (beast.core.BEASTInterface) Class.forName(className).newInstance();
+                    m_beastObject.setID(m_sID);
                 } catch (Exception e) {
                     // TODO: handle exception
                 }
             }
             if (node.getAttributes().getNamedItem("inputids") != null) {
-                String sInputIDs = node.getAttributes().getNamedItem("inputids").getNodeValue();
-                String[] sInputID = sInputIDs.split(" ");
-                m_inputs = new ArrayList<InputShape>();
+                String inputIDs = node.getAttributes().getNamedItem("inputids").getNodeValue();
+                String[] inputID = inputIDs.split(" ");
+                m_inputs = new ArrayList<>();
                 try {
-                    List<Input<?>> inputs = m_plugin.listInputs();
-                    for (int i = 0; i < sInputID.length; i++) {
-                        InputShape ellipse = (InputShape) doc.findObjectWithID(sInputID[i]);
+                    //List<Input<?>> inputs = m_beastObject.listInputs();
+                    for (int i = 0; i < inputID.length; i++) {
+                        InputShape ellipse = (InputShape) doc.findObjectWithID(inputID[i]);
                         m_inputs.add(ellipse);
                         ellipse.setPluginShape(this);
                         //ellipse.m_input = inputs.get(i);
@@ -209,7 +205,7 @@ public class BEASTObjectShape extends Shape {
         StringBuffer buf = new StringBuffer();
         buf.append("<" + Document.PLUGIN_SHAPE_ELEMENT);
         buf.append(" class='");
-        buf.append(m_plugin.getClass().getName());
+        buf.append(m_beastObject.getClass().getName());
         buf.append("'");
         buf.append(" inputids='");
         for (int i = 0; i < m_inputs.size(); i++) {
@@ -227,12 +223,12 @@ public class BEASTObjectShape extends Shape {
     @Override
     void assignFrom(Shape other) {
         super.assignFrom(other);
-        m_plugin.setID(other.m_sID);
+        m_beastObject.setID(other.m_sID);
     }
 
     @Override
-    boolean intersects(int nX, int nY) {
-        return super.intersects(nX, nY);
+    boolean intersects(int x, int y) {
+        return super.intersects(x, y);
     }
 
     @Override
@@ -242,10 +238,10 @@ public class BEASTObjectShape extends Shape {
 
     @Override
     String getID() {
-        if (m_plugin == null) {
+        if (m_beastObject == null) {
             return null;
         }
-        return m_plugin.getID();
+        return m_beastObject.getID();
     }
 
     @Override
diff --git a/src/beast/app/draw/BooleanInputEditor.java b/src/beast/app/draw/BooleanInputEditor.java
index 927676a..643b904 100644
--- a/src/beast/app/draw/BooleanInputEditor.java
+++ b/src/beast/app/draw/BooleanInputEditor.java
@@ -1,15 +1,12 @@
 package beast.app.draw;
 
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
 import javax.swing.Box;
 import javax.swing.JCheckBox;
 
 import beast.app.beauti.BeautiDoc;
-import beast.core.Input;
-import beast.core.BEASTObject;
 import beast.core.BEASTInterface;
+import beast.core.Input;
+import beast.core.util.Log;
 
 
 
@@ -32,9 +29,9 @@ public class BooleanInputEditor extends InputEditor.Base {
      * create input editor containing a check box *
      */
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-        m_bAddButtons = bAddButtons;
-        m_plugin = plugin;
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+        m_bAddButtons = addButtons;
+        m_beastObject = beastObject;
         m_input = input;
 		this.itemNr = itemNr;
         m_entry = new JCheckBox(formatName(m_input.getName()));
@@ -42,18 +39,15 @@ public class BooleanInputEditor extends InputEditor.Base {
             m_entry.setSelected((Boolean) input.get());
         }
         m_entry.setToolTipText(input.getHTMLTipText());
-        m_entry.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        m_entry.addActionListener(e -> {
                 try {
                 	setValue(m_entry.isSelected());
                     validateInput();
-                    //m_input.setValue(m_entry.isSelected(), m_plugin);
+                    //m_input.setValue(m_entry.isSelected(), m_beastObject);
                 } catch (Exception ex) {
-                    System.err.println("BooleanInputEditor " + ex.getMessage());
+                    Log.err.println("BooleanInputEditor " + ex.getMessage());
                 }
-            }
-        });
+            });
         add(m_entry);
         add(Box.createHorizontalGlue());
     } // c'tor
diff --git a/src/beast/app/draw/Document.java b/src/beast/app/draw/Document.java
index e3a9bd3..b876bd5 100644
--- a/src/beast/app/draw/Document.java
+++ b/src/beast/app/draw/Document.java
@@ -26,26 +26,34 @@ package beast.app.draw;
 
 
 
+import java.awt.Color;
+import java.io.File;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Properties;
+import java.util.Random;
+import java.util.Scanner;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
+import beast.core.BEASTInterface;
 import beast.core.Input;
 import beast.core.Runnable;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
+import beast.core.util.Log;
 import beast.util.AddOnManager;
 import beast.util.XMLParser;
 import beast.util.XMLProducer;
 
-
-import javax.xml.parsers.DocumentBuilderFactory;
-import java.awt.*;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.StringReader;
-import java.util.*;
-import java.util.List;
-
 /**
  * The Document class is the Document part in the doc-view pattern of
  * the Beast ModelBuilder application.
@@ -55,13 +63,13 @@ public class Document {
     /**
      * list of PluginShapes, InputShapes and connecting Arrows *
      */
-    public List<Shape> m_objects = new ArrayList<Shape>();
+    public List<Shape> m_objects = new ArrayList<>();
     public List<Shape> m_tmpobjects;
 
     /**
      * undo/redo related stuff *
      */
-    List<UndoAction> m_undoStack = new ArrayList<UndoAction>();
+    List<UndoAction> m_undoStack = new ArrayList<>();
     int m_nCurrentEditAction = -1;
 
 
@@ -74,7 +82,7 @@ public class Document {
         m_bIsSaved = true;
     }
 
-    void iSChanged() {
+    void sChanged() {
         m_bIsSaved = false;
     }
 
@@ -96,9 +104,9 @@ public class Document {
 
     public Document() {
         // load all parsers
-        List<String> sPlugInNames = AddOnManager.find(beast.core.BEASTInterface.class, AddOnManager.IMPLEMENTATION_DIR);
-        m_sPlugInNames = sPlugInNames.toArray(new String[0]);
-        tabulist = new HashSet<String>();
+        List<String> plugInNames = AddOnManager.find(beast.core.BEASTInterface.class, AddOnManager.IMPLEMENTATION_DIR);
+        m_sPlugInNames = plugInNames.toArray(new String[0]);
+        tabulist = new HashSet<>();
         Properties properties = new Properties();
         try {
         	
@@ -116,8 +124,8 @@ public class Document {
 
 //    /** change order of shapes to ensure arrows are drawn before the rest **/
 //    void moveArrowsToBack() {
-//        ArrayList<Shape> arrows = new ArrayList<Shape>();
-//        List<Shape> others = new ArrayList<Shape>();
+//        ArrayList<Shape> arrows = new ArrayList<>();
+//        List<Shape> others = new ArrayList<>();
 //
 //        for (Shape shape : m_objects) {
 //            if (shape instanceof Arrow) {
@@ -174,63 +182,59 @@ public class Document {
     /**
      * edit actions on shapes *
      */
-    public void moveShape(int nX, int nY, int nToX, int nToY, int nPosition) {
-        boolean bNeedsUndoAction = true;
+    public void moveShape(int x, int y, int toX, int toY, int position) {
+        boolean needsUndoAction = true;
         if (m_nCurrentEditAction == m_undoStack.size() - 1 && m_nCurrentEditAction >= 0) {
             UndoAction undoAction = m_undoStack.get(m_nCurrentEditAction);
-            if (undoAction.m_nActionType == UndoAction.MOVE_ACTION && undoAction.isSingleSelection(nPosition)) {
-                bNeedsUndoAction = false;
+            if (undoAction.m_nActionType == UndoAction.MOVE_ACTION && undoAction.isSingleSelection(position)) {
+                needsUndoAction = false;
             }
         }
-        if (bNeedsUndoAction) {
-            addUndoAction(new UndoAction(nPosition, UndoAction.MOVE_ACTION));
+        if (needsUndoAction) {
+            addUndoAction(new UndoAction(position, UndoAction.MOVE_ACTION));
         }
-        Shape shape = (Shape) m_objects.get(nPosition);
-        shape.movePosition(nX, nY, nToX, nToY);
+        Shape shape = m_objects.get(position);
+        shape.movePosition(x, y, toX, toY);
         adjustArrows();
     } // moveShape
 
-    public void moveShapes(int dX, int dY, List<Integer> nPositions) {
-        boolean bNeedsUndoAction = true;
+    public void moveShapes(int dX, int dY, List<Integer> positions) {
+        boolean needsUndoAction = true;
         if (m_nCurrentEditAction == m_undoStack.size() - 1 && m_nCurrentEditAction >= 0) {
             UndoAction undoAction = m_undoStack.get(m_nCurrentEditAction);
-            if (undoAction.m_nActionType == UndoAction.MOVE_ACTION && undoAction.isSelection(nPositions)) {
-                bNeedsUndoAction = false;
+            if (undoAction.m_nActionType == UndoAction.MOVE_ACTION && undoAction.isSelection(positions)) {
+                needsUndoAction = false;
             }
         }
-        if (bNeedsUndoAction) {
-            addUndoAction(new UndoAction(nPositions, UndoAction.MOVE_ACTION));
+        if (needsUndoAction) {
+            addUndoAction(new UndoAction(positions, UndoAction.MOVE_ACTION));
         }
     } // moveShape
 
-    public void movePoint(int nPoint, int nX, int nY, int nToX, int nToY, int nPosition) {
-        boolean bNeedsUndoAction = true;
+    public void movePoint(int point, int x, int y, int toX, int toY, int position) {
+        boolean needsUndoAction = true;
         if (m_nCurrentEditAction == m_undoStack.size() - 1 && m_nCurrentEditAction >= 0) {
             UndoAction undoAction = m_undoStack.get(m_nCurrentEditAction);
-            if (undoAction.m_nActionType == UndoAction.RESHAPE_ACTION && undoAction.isSingleSelection(nPosition)) {
-                bNeedsUndoAction = false;
+            if (undoAction.m_nActionType == UndoAction.RESHAPE_ACTION && undoAction.isSingleSelection(position)) {
+                needsUndoAction = false;
             }
         }
-        if (bNeedsUndoAction) {
-            addUndoAction(new UndoAction(nPosition, UndoAction.RESHAPE_ACTION));
+        if (needsUndoAction) {
+            addUndoAction(new UndoAction(position, UndoAction.RESHAPE_ACTION));
         }
-        Shape shape = (Shape) m_objects.get(nPosition);
-        shape.movePoint(nPoint, nX, nY, nToX, nToY);
+        Shape shape = m_objects.get(position);
+        shape.movePoint(point, x, y, toX, toY);
         adjustArrows();
     } // movePoint
 
-    boolean containsID(String sID, List<Shape> objects, List<String> tabulist) {
+    boolean containsID(String id, List<Shape> objects, List<String> tabulist) {
         for (Shape shape : m_objects) {
-            if (shape.getID() == null) {
-                int h = 3;
-                h++;
-            }
-            if (shape.getID().equals(sID)) {
+            if (shape.getID().equals(id)) {
                 return true;
             }
 //            if (shape instanceof Group) {
 //                Group group = (Group) shape;
-//                if (containsID(sID, group.m_objects, tabulist)) {
+//                if (containsID(id, group.m_objects, tabulist)) {
 //                    return true;
 //                }
 //            }
@@ -238,8 +242,8 @@ public class Document {
         if (tabulist == null) {
             return false;
         }
-        for (String sTabuID : tabulist) {
-            if (sTabuID.equals(sID)) {
+        for (String tabuID : tabulist) {
+            if (tabuID.equals(id)) {
                 return true;
             }
         }
@@ -247,31 +251,31 @@ public class Document {
     }
 
     String getNewID(List<String> tabulist) {
-        int nID = m_objects.size();
-        String sID = "id" + nID;
-        while (containsID(sID, m_objects, tabulist)) {
-            nID++;
-            sID = "id" + nID;
+        int _id = m_objects.size();
+        String id = "id" + _id;
+        while (containsID(id, m_objects, tabulist)) {
+            _id++;
+            id = "id" + _id;
         }
-        return sID;
+        return id;
     }
 
     void setPluginID(BEASTObjectShape shape) {
-        if (shape.m_plugin.getID() != null && shape.m_plugin.getID().length() > 0) {
+        if (shape.m_beastObject.getID() != null && shape.m_beastObject.getID().length() > 0) {
             return;
         }
-        BEASTInterface plugin = shape.m_plugin;
-        String sBase = plugin.getClass().getName().replaceAll(".*\\.", "");
-        int nID = 0;
-        while (containsID(sBase + nID, m_objects, null)) {
-            nID++;
+        BEASTInterface beastObject = shape.m_beastObject;
+        String base = beastObject.getClass().getName().replaceAll(".*\\.", "");
+        int _id = 0;
+        while (containsID(base + _id, m_objects, null)) {
+            _id++;
         }
-        plugin.setID(sBase + nID);
+        beastObject.setID(base + _id);
     }
 
-    Shape getShapeByID(String sID) {
+    Shape getShapeByID(String id) {
         for (Shape shape : m_objects) {
-            if (shape.getID().equals(sID)) {
+            if (shape.getID().equals(id)) {
                 return shape;
             }
         }
@@ -291,39 +295,39 @@ public class Document {
         }
         m_objects.add(shape);
         if (shape instanceof BEASTObjectShape) {
-            List<Integer> iObjects = new ArrayList<Integer>();
-            iObjects.add(m_objects.size() - 1);
-            checkForOtherPluginShapes(iObjects, (BEASTObjectShape) shape);
-            if (iObjects.size() == 1) {
+            List<Integer> objects = new ArrayList<>();
+            objects.add(m_objects.size() - 1);
+            checkForOtherPluginShapes(objects, (BEASTObjectShape) shape);
+            if (objects.size() == 1) {
                 addUndoAction(new PluginAction(m_objects.size() - 1, UndoAction.ADD_PLUGIN_ACTION));
             } else {
-                addUndoAction(new MultiObjectAction(iObjects, UndoAction.ADD_GROUP_ACTION));
+                addUndoAction(new MultiObjectAction(objects, UndoAction.ADD_GROUP_ACTION));
             }
         } else if (shape instanceof Arrow) {
             addUndoAction(new ArrowAction(m_objects.size() - 1, UndoAction.ADD_ARROW_ACTION));
         }
     } // addNewShape
 
-    void checkForOtherPluginShapes(List<Integer> iObjects, BEASTObjectShape shape) {
-        // check whether we need to create any input plugins
+    void checkForOtherPluginShapes(List<Integer> objects, BEASTObjectShape shape) {
+        // check whether we need to create any input beastObjects
         try {
-            List<Input<?>> inputs = ((BEASTObjectShape) shape).m_plugin.listInputs();
+            List<Input<?>> inputs = shape.m_beastObject.listInputs();
             for (Input<?> input : inputs) {
                 if (input.get() instanceof BEASTInterface) {
-                    BEASTInterface plugin = (BEASTInterface) input.get();
-                    BEASTObjectShape pluginShape = new BEASTObjectShape(plugin, this);
-                    pluginShape.m_x = Math.max(shape.m_x - DX, 0);
-                    pluginShape.m_y = shape.m_y;
-                    pluginShape.m_w = 100;
-                    pluginShape.m_h = 80;
-                    setPluginID(pluginShape);
-                    m_objects.add(pluginShape);
-                    iObjects.add(m_objects.size() - 1);
-                    Arrow arrow = new Arrow(pluginShape, (BEASTObjectShape) shape, input.getName());
+                    BEASTInterface beastObject = (BEASTInterface) input.get();
+                    BEASTObjectShape beastObjectShape = new BEASTObjectShape(beastObject, this);
+                    beastObjectShape.m_x = Math.max(shape.m_x - DX, 0);
+                    beastObjectShape.m_y = shape.m_y;
+                    beastObjectShape.m_w = 100;
+                    beastObjectShape.m_h = 80;
+                    setPluginID(beastObjectShape);
+                    m_objects.add(beastObjectShape);
+                    objects.add(m_objects.size() - 1);
+                    Arrow arrow = new Arrow(beastObjectShape, shape, input.getName());
                     m_objects.add(arrow);
-                    iObjects.add(m_objects.size() - 1);
+                    objects.add(m_objects.size() - 1);
                     // recurse
-                    checkForOtherPluginShapes(iObjects, pluginShape);
+                    checkForOtherPluginShapes(objects, beastObjectShape);
                 }
             }
         } catch (Exception e) {
@@ -331,13 +335,13 @@ public class Document {
         }
     }
 
-    List<Integer> getConnectedArrows(List<String> sIDs, List<Integer> selection) {
+    List<Integer> getConnectedArrows(List<String> ids, List<Integer> selection) {
         for (int i = 0; i < m_objects.size(); i++) {
-            Shape shape = (Shape) m_objects.get(i);
+            Shape shape = m_objects.get(i);
             if (shape instanceof Arrow) {
                 Arrow arrow = (Arrow) shape;
-                for (int j = 0; j < sIDs.size(); j++) {
-                    if (arrow.m_sHeadID.startsWith(sIDs.get(j)) || arrow.m_sTailID.equals(sIDs.get(j))) {
+                for (int j = 0; j < ids.size(); j++) {
+                    if (arrow.m_sHeadID.startsWith(ids.get(j)) || arrow.m_sTailID.equals(ids.get(j))) {
                         if (!selection.contains(new Integer(i))) {
                             selection.add(new Integer(i));
                         }
@@ -348,14 +352,14 @@ public class Document {
         return selection;
     }
 
-    List<String> getIncomingArrows(List<String> sIDs) {
-        List<String> selection = new ArrayList<String>();
+    List<String> getIncomingArrows(List<String> ids) {
+        List<String> selection = new ArrayList<>();
         for (int i = 0; i < m_objects.size(); i++) {
-            Shape shape = (Shape) m_objects.get(i);
+            Shape shape = m_objects.get(i);
             if (shape instanceof Arrow) {
                 Arrow arrow = (Arrow) shape;
-                for (int j = 0; j < sIDs.size(); j++) {
-                    if (arrow.m_sHeadID.equals(sIDs.get(j))) {
+                for (int j = 0; j < ids.size(); j++) {
+                    if (arrow.m_sHeadID.equals(ids.get(j))) {
                         if (!selection.contains(arrow.m_sTailID)) {
                             selection.add(arrow.m_sTailID);
                         }
@@ -366,14 +370,14 @@ public class Document {
         return selection;
     }
 
-    List<String> getOutgoingArrows(List<String> sIDs) {
-        List<String> selection = new ArrayList<String>();
+    List<String> getOutgoingArrows(List<String> ids) {
+        List<String> selection = new ArrayList<>();
         for (int i = 0; i < m_objects.size(); i++) {
-            Shape shape = (Shape) m_objects.get(i);
+            Shape shape = m_objects.get(i);
             if (shape instanceof Arrow) {
                 Arrow arrow = (Arrow) shape;
-                for (int j = 0; j < sIDs.size(); j++) {
-                    if (arrow.m_sTailID.equals(sIDs.get(j))) {
+                for (int j = 0; j < ids.size(); j++) {
+                    if (arrow.m_sTailID.equals(ids.get(j))) {
                         if (!selection.contains(arrow.m_sTailID)) {
                             selection.add(arrow.m_sTailID);
                         }
@@ -385,12 +389,12 @@ public class Document {
     }
 
     public void deleteShapes(List<Integer> selection) {
-        List<String> sIDs = new ArrayList<String>();
+        List<String> ids = new ArrayList<>();
         for (int j = 0; j < selection.size(); j++) {
-            sIDs.add(((Shape) m_objects.get(((Integer) selection.get(j)).intValue())).getID());
+            ids.add(m_objects.get(selection.get(j).intValue()).getID());
 
         }
-        selection = getConnectedArrows(sIDs, selection);
+        selection = getConnectedArrows(ids, selection);
         UndoAction action = new MultiObjectAction(selection, UndoAction.DEL_GROUP_ACTION);
         addUndoAction(action);
         action.redo();
@@ -410,39 +414,39 @@ public class Document {
         tabulist.add(shape.getID());
     } // ensureUniqueID
 
-    public void pasteShape(String sXML) {
-        List<Shape> shapes = XML2Shapes(sXML, true);
+    public void pasteShape(String xml) {
+        List<Shape> shapes = XML2Shapes(xml, true);
         if (shapes.size() == 0) {
             return;
         }
-        List<Integer> nPositions = new ArrayList<Integer>();
+        List<Integer> positions = new ArrayList<>();
         for (Shape shape : shapes) {
             if (shape instanceof Arrow) {
                 ((Arrow) shape).setID(getNewID(null));
             }
             if (shape instanceof BEASTObjectShape) {
-                ((BEASTObjectShape) shape).m_plugin.setID(null);
+                ((BEASTObjectShape) shape).m_beastObject.setID(null);
                 setPluginID((BEASTObjectShape) shape);
                 // ensure the new shape does not overlap exactly with an existing shape
-                int nOffset = 0;
-                boolean bMatch = false;
+                int offset = 0;
+                boolean isMatch = false;
                 do {
-                    bMatch = false;
+                    isMatch = false;
                     for (Shape shape2 : m_objects) {
-                        if (shape2.m_x == shape.m_x + nOffset && shape2.m_y == shape.m_y + nOffset &&
+                        if (shape2.m_x == shape.m_x + offset && shape2.m_y == shape.m_y + offset &&
                                 shape2.m_w == shape.m_w && shape2.m_h == shape.m_h) {
-                            bMatch = true;
-                            nOffset += 10;
+                            isMatch = true;
+                            offset += 10;
                         }
                     }
-                } while (bMatch);
-                shape.m_x += nOffset;
-                shape.m_y += nOffset;
+                } while (isMatch);
+                shape.m_x += offset;
+                shape.m_y += offset;
             }
             m_objects.add(shape);
-            nPositions.add(m_objects.size() - 1);
+            positions.add(m_objects.size() - 1);
         }
-        addUndoAction(new MultiObjectAction(nPositions, UndoAction.ADD_GROUP_ACTION));
+        addUndoAction(new MultiObjectAction(positions, UndoAction.ADD_GROUP_ACTION));
     } // pasteShape
 
     /**
@@ -455,20 +459,20 @@ public class Document {
 //                selection.m_Selection.remove(i);
 //            }
 //        }
-//        int nNrOfPrimePositions = selection.m_Selection.size();
-//        if (nNrOfPrimePositions == 0) {
+//        int nrOfPrimePositions = selection.m_Selection.size();
+//        if (nrOfPrimePositions == 0) {
 //            return;
 //        }
-//        for (int i = 0; i < nNrOfPrimePositions; i++) {
+//        for (int i = 0; i < nrOfPrimePositions; i++) {
 //        	Shape shape = m_objects.get(((Integer) selection.m_Selection.get(i)).intValue());
 //        	findAffectedShapes(shape, selection.m_Selection);
 //        }
-//        if (selection.m_Selection.size() == nNrOfPrimePositions) {
+//        if (selection.m_Selection.size() == nrOfPrimePositions) {
 //        	// nothing to collapse
 //        	return;
 //        }
 //        
-//        UndoAction action = new UndoMultiSelectionAction(selection.m_Selection, nNrOfPrimePositions);
+//        UndoAction action = new UndoMultiSelectionAction(selection.m_Selection, nrOfPrimePositions);
 //        addUndoAction(action);
 //        action.redo();
 //        selection.clear();
@@ -502,9 +506,9 @@ public class Document {
             if (shape instanceof Arrow) {
                 Arrow arrow = (Arrow) shape;
                 if (arrow.m_sHeadID.equals(ellipse.getID())) {
-                    String sTailID = arrow.m_sTailID;
+                    String tailID = arrow.m_sTailID;
                     for (int i = 0; i < m_objects.size(); i++) {
-                        if (m_objects.get(i).getID().equals(sTailID)) {
+                        if (m_objects.get(i).getID().equals(tailID)) {
                             selection.add(i);
                         }
                     }
@@ -517,9 +521,9 @@ public class Document {
 //        UngroupAction action = new UngroupAction(selection);
 //        addUndoAction(action);
 //        action.redo();
-//        int nSize = action.getGroupSize();
+//        int size = action.getGroupSize();
 //        selection.clear();
-//        for (int i = 0; i < nSize; i++) {
+//        for (int i = 0; i < size; i++) {
 //            selection.m_Selection.add(new Integer(m_objects.size() - i - 1));
 //        }
 //    } // ungroup
@@ -531,8 +535,8 @@ public class Document {
             addUndoAction(new UndoAction(selection.m_Selection, UndoAction.MOVE_ACTION));
         }
         for (int i = 0; i < selection.m_Selection.size(); i++) {
-            int iSelection = ((Integer) selection.m_Selection.get(i)).intValue();
-            Shape shape = (Shape) m_objects.get(iSelection);
+            int selectionIndex = selection.m_Selection.get(i).intValue();
+            Shape shape = m_objects.get(selectionIndex);
             shape.setFillColor(color);
         }
     } // setFillColor
@@ -544,8 +548,8 @@ public class Document {
             addUndoAction(new UndoAction(selection.m_Selection, UndoAction.MOVE_ACTION));
         }
         for (int i = 0; i < selection.m_Selection.size(); i++) {
-            int iSelection = ((Integer) selection.m_Selection.get(i)).intValue();
-            Shape shape = (Shape) m_objects.get(iSelection);
+            int selectionIndex = selection.m_Selection.get(i).intValue();
+            Shape shape = m_objects.get(selectionIndex);
             shape.setPenColor(color);
         }
     } // setPenColor
@@ -554,91 +558,94 @@ public class Document {
 //        addUndoAction(new UndoAction(selection.m_Selection));
 //    }
 
-    int getPositionX(int iShape) {
-        Shape shape = (Shape) m_objects.get(iShape);
+    int getPositionX(int shapeIndex) {
+        Shape shape = m_objects.get(shapeIndex);
         return shape.getX();
     }
 
-    int getPositionY(int iShape) {
-        Shape shape = (Shape) m_objects.get(iShape);
+    int getPositionY(int shapeIndex) {
+        Shape shape = m_objects.get(shapeIndex);
         return shape.getY();
     }
 
-    int getPositionX2(int iShape) {
-        Shape shape = (Shape) m_objects.get(iShape);
+    int getPositionX2(int shapeIndex) {
+        Shape shape = m_objects.get(shapeIndex);
         return shape.getX2();
     }
 
-    int getPositionY2(int iShape) {
-        Shape shape = (Shape) m_objects.get(iShape);
+    int getPositionY2(int shapeIndex) {
+        Shape shape = m_objects.get(shapeIndex);
         return shape.getY2();
     }
 
-    void setPositionX(int nX, int iShape) {
-        Shape shape = (Shape) m_objects.get(iShape);
-        shape.setX(nX);
+    void setPositionX(int x, int shapeIndex) {
+        Shape shape = m_objects.get(shapeIndex);
+        shape.setX(x);
     }
 
-    void setPositionY(int nY, int iShape) {
-        Shape shape = (Shape) m_objects.get(iShape);
-        shape.setY(nY);
+    void setPositionY(int y, int shapeIndex) {
+        Shape shape = m_objects.get(shapeIndex);
+        shape.setY(y);
     }
 
-    void setPositionX2(int nX, int iShape) {
-        Shape shape = (Shape) m_objects.get(iShape);
-        shape.setX2(nX);
+    void setPositionX2(int x, int shapeIndex) {
+        Shape shape = m_objects.get(shapeIndex);
+        shape.setX2(x);
     }
 
-    void setPositionY2(int nY, int iShape) {
-        Shape shape = (Shape) m_objects.get(iShape);
-        shape.setY2(nY);
+    void setPositionY2(int y, int shapeIndex) {
+        Shape shape = m_objects.get(shapeIndex);
+        shape.setY2(y);
     }
 
-    public void setID(String sID, int iObject) {
-        addUndoAction(new UndoAction(iObject, UndoAction.SET_LABEL_ACTION));
-        Shape shape = (Shape) m_objects.get(iObject);
-        ((BEASTObjectShape) shape).m_plugin.setID(sID);
+    public void setID(String id, int object) {
+        addUndoAction(new UndoAction(object, UndoAction.SET_LABEL_ACTION));
+        Shape shape = m_objects.get(object);
+        ((BEASTObjectShape) shape).m_beastObject.setID(id);
     }
 
-    public void toggleFilled(int iObject) {
-        addUndoAction(new UndoAction(iObject, UndoAction.TOGGLE_FILL_ACTION));
-        Shape shape = (Shape) m_objects.get(iObject);
+    public void toggleFilled(int object) {
+        addUndoAction(new UndoAction(object, UndoAction.TOGGLE_FILL_ACTION));
+        Shape shape = m_objects.get(object);
         shape.toggleFilled();
     }
 
-    void setInputValue(BEASTObjectShape pluginShape, String sInput, String sValue) throws Exception {
-        addUndoAction(new SetInputAction(pluginShape, sInput, sValue));
-        //pluginShape.m_plugin.setInputValue(sInput, sValue);
+    void setInputValue(BEASTObjectShape beastObjectShape, String input, String valueString) {
+        addUndoAction(new SetInputAction(beastObjectShape, input, valueString));
+        //beastObjectShape.m_beastObject.setInputValue(input, valueString);
     }
 
     /**
      * action representing assignment of value to a primitive input *
      */
     class SetInputAction extends UndoAction {
-        BEASTObjectShape m_pluginShape;
+        BEASTObjectShape m_beastObjectShape;
         String m_sInput;
         String m_sValue;
 
-        SetInputAction(BEASTObjectShape pluginShape, String sInput, String sValue) {
-            m_pluginShape = pluginShape;
-            m_sInput = sInput;
-            m_sValue = sValue;
+        SetInputAction(BEASTObjectShape beastObjectShape, String input, String valueString) {
+            m_beastObjectShape = beastObjectShape;
+            m_sInput = input;
+            m_sValue = valueString;
             doit();
         }
 
-        void redo() {
+        @Override
+		void redo() {
             doit();
         }
 
-        void undo() {
+        @Override
+		void undo() {
             doit();
         }
 
-        void doit() {
+        @Override
+		void doit() {
             try {
-                String sValue = m_pluginShape.m_plugin.getInput(m_sInput).get().toString();
-                m_pluginShape.m_plugin.setInputValue(m_sInput, m_sValue);
-                m_sValue = sValue;
+                String valueString = m_beastObjectShape.m_beastObject.getInput(m_sInput).get().toString();
+                m_beastObjectShape.m_beastObject.setInputValue(m_sInput, m_sValue);
+                m_sValue = valueString;
             } catch (Exception e) {
                 e.printStackTrace();
             }
@@ -655,7 +662,7 @@ public class Document {
         }
         int[] order = new int[selection.m_Selection.size()];
         for (int i = 0; i < order.length; i++) {
-            order[i] = ((Integer) selection.m_Selection.get(i)).intValue();
+            order[i] = selection.m_Selection.get(i).intValue();
         }
         Arrays.sort(order);
         int[] oldOrder = new int[selection.m_Selection.size()];
@@ -678,7 +685,7 @@ public class Document {
         }
         int[] oldOrder = new int[selection.m_Selection.size()];
         for (int i = 0; i < oldOrder.length; i++) {
-            oldOrder[i] = ((Integer) selection.m_Selection.get(i)).intValue();
+            oldOrder[i] = selection.m_Selection.get(i).intValue();
         }
         Arrays.sort(oldOrder);
         ReorderAction reorderAction = new ReorderAction(oldOrder, newOrder);
@@ -693,7 +700,7 @@ public class Document {
         }
         int[] order = new int[selection.m_Selection.size()];
         for (int i = 0; i < order.length; i++) {
-            order[i] = ((Integer) selection.m_Selection.get(i)).intValue();
+            order[i] = selection.m_Selection.get(i).intValue();
         }
         Arrays.sort(order);
         int[] oldOrder = new int[selection.m_Selection.size()];
@@ -720,7 +727,7 @@ public class Document {
         }
         int[] oldOrder = new int[selection.m_Selection.size()];
         for (int i = 0; i < oldOrder.length; i++) {
-            oldOrder[i] = ((Integer) selection.m_Selection.get(i)).intValue();
+            oldOrder[i] = selection.m_Selection.get(i).intValue();
         }
         Arrays.sort(oldOrder);
         int[] newOrder = new int[selection.m_Selection.size()];
@@ -745,16 +752,16 @@ public class Document {
         addUndoAction(new UndoAction(selection.m_Selection, UndoAction.MOVE_ACTION));
 
         List<Integer> nodes = selection.m_Selection;
-        int nMinX = -1;
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nX = getPositionX(((Integer) nodes.get(iNode)).intValue());
-            if (nX < nMinX || iNode == 0) {
-                nMinX = nX;
+        int minX = -1;
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int x = getPositionX(nodes.get(nodeIndex).intValue());
+            if (x < minX || nodeIndex == 0) {
+                minX = x;
             }
         }
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nNode = ((Integer) nodes.get(iNode)).intValue();
-            setPositionX(nMinX, nNode);
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int node = nodes.get(nodeIndex).intValue();
+            setPositionX(minX, node);
         }
         adjustArrows();
     } // alignLeft
@@ -768,17 +775,17 @@ public class Document {
         // update undo stack
         addUndoAction(new UndoAction(selection.m_Selection, UndoAction.MOVE_ACTION));
         List<Integer> nodes = selection.m_Selection;
-        int nMaxX = -1;
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nX = getPositionX2(((Integer) nodes.get(iNode)).intValue());
-            if (nX > nMaxX || iNode == 0) {
-                nMaxX = nX;
+        int maxX = -1;
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int x = getPositionX2(nodes.get(nodeIndex).intValue());
+            if (x > maxX || nodeIndex == 0) {
+                maxX = x;
             }
         }
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nNode = ((Integer) nodes.get(iNode)).intValue();
-            int dX = getPositionX2(nNode) - getPositionX(nNode);
-            setPositionX(nMaxX - dX, nNode);
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int node = nodes.get(nodeIndex).intValue();
+            int dX = getPositionX2(node) - getPositionX(node);
+            setPositionX(maxX - dX, node);
         }
         adjustArrows();
     } // alignRight
@@ -792,16 +799,16 @@ public class Document {
         // update undo stack
         addUndoAction(new UndoAction(selection.m_Selection, UndoAction.MOVE_ACTION));
         List<Integer> nodes = selection.m_Selection;
-        int nMinY = -1;
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nY = getPositionY(((Integer) nodes.get(iNode)).intValue());
-            if (nY < nMinY || iNode == 0) {
-                nMinY = nY;
+        int minY = -1;
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int y = getPositionY(nodes.get(nodeIndex).intValue());
+            if (y < minY || nodeIndex == 0) {
+                minY = y;
             }
         }
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nNode = ((Integer) nodes.get(iNode)).intValue();
-            setPositionY(nMinY, nNode);
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int node = nodes.get(nodeIndex).intValue();
+            setPositionY(minY, node);
         }
         adjustArrows();
     } // alignTop
@@ -815,17 +822,17 @@ public class Document {
         // update undo stack
         addUndoAction(new UndoAction(selection.m_Selection, UndoAction.MOVE_ACTION));
         List<Integer> nodes = selection.m_Selection;
-        int nMaxY = -1;
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nY = getPositionY2(((Integer) nodes.get(iNode)).intValue());
-            if (nY > nMaxY || iNode == 0) {
-                nMaxY = nY;
+        int maxY = -1;
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int y = getPositionY2(nodes.get(nodeIndex).intValue());
+            if (y > maxY || nodeIndex == 0) {
+                maxY = y;
             }
         }
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nNode = ((Integer) nodes.get(iNode)).intValue();
-            int dY = getPositionY2(nNode) - getPositionY(nNode);
-            setPositionY(nMaxY - dY, nNode);
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int node = nodes.get(nodeIndex).intValue();
+            int dY = getPositionY2(node) - getPositionY(node);
+            setPositionY(maxY - dY, node);
         }
         adjustArrows();
     } // alignBottom
@@ -839,22 +846,22 @@ public class Document {
         // update undo stack
         addUndoAction(new UndoAction(selection.m_Selection, UndoAction.MOVE_ACTION));
         List<Integer> nodes = selection.m_Selection;
-        int nMinY = -1;
-        int nMaxY = -1;
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nY = (getPositionY(((Integer) nodes.get(iNode)).intValue()) +
-                    getPositionY2(((Integer) nodes.get(iNode)).intValue())) / 2;
-            if (nY < nMinY || iNode == 0) {
-                nMinY = nY;
+        int minY = -1;
+        int maxY = -1;
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int y = (getPositionY(nodes.get(nodeIndex).intValue()) +
+                    getPositionY2(nodes.get(nodeIndex).intValue())) / 2;
+            if (y < minY || nodeIndex == 0) {
+                minY = y;
             }
-            if (nY > nMaxY || iNode == 0) {
-                nMaxY = nY;
+            if (y > maxY || nodeIndex == 0) {
+                maxY = y;
             }
         }
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nNode = ((Integer) nodes.get(iNode)).intValue();
-            int dY = (getPositionY2(nNode) - getPositionY(nNode)) / 2;
-            setPositionY((nMinY + nMaxY) / 2 - dY, nNode);
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int node = nodes.get(nodeIndex).intValue();
+            int dY = (getPositionY2(node) - getPositionY(node)) / 2;
+            setPositionY((minY + maxY) / 2 - dY, node);
         }
         adjustArrows();
     } // centreHorizontal
@@ -868,22 +875,22 @@ public class Document {
         // update undo stack
         addUndoAction(new UndoAction(selection.m_Selection, UndoAction.MOVE_ACTION));
         List<Integer> nodes = selection.m_Selection;
-        int nMinX = -1;
-        int nMaxX = -1;
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nX = (getPositionX(((Integer) nodes.get(iNode)).intValue()) +
-                    getPositionX2(((Integer) nodes.get(iNode)).intValue())) / 2;
-            if (nX < nMinX || iNode == 0) {
-                nMinX = nX;
+        int minX = -1;
+        int maxX = -1;
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int x = (getPositionX(nodes.get(nodeIndex).intValue()) +
+                    getPositionX2(nodes.get(nodeIndex).intValue())) / 2;
+            if (x < minX || nodeIndex == 0) {
+                minX = x;
             }
-            if (nX > nMaxX || iNode == 0) {
-                nMaxX = nX;
+            if (x > maxX || nodeIndex == 0) {
+                maxX = x;
             }
         }
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nNode = ((Integer) nodes.get(iNode)).intValue();
-            int dX = (getPositionX2(nNode) - getPositionX(nNode)) / 2;
-            setPositionX((nMinX + nMaxX) / 2 - dX, nNode);
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int node = nodes.get(nodeIndex).intValue();
+            int dX = (getPositionX2(node) - getPositionX(node)) / 2;
+            setPositionX((minX + maxX) / 2 - dX, node);
         }
         adjustArrows();
     } // centreVertical
@@ -897,20 +904,20 @@ public class Document {
         // update undo stack
         addUndoAction(new UndoAction(selection.m_Selection, UndoAction.MOVE_ACTION));
         List<Integer> nodes = selection.m_Selection;
-        int nMinX = -1;
-        int nMaxX = -1;
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nX = getPositionX(((Integer) nodes.get(iNode)).intValue());
-            if (nX < nMinX || iNode == 0) {
-                nMinX = nX;
+        int minX = -1;
+        int maxX = -1;
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int x = getPositionX(nodes.get(nodeIndex).intValue());
+            if (x < minX || nodeIndex == 0) {
+                minX = x;
             }
-            if (nX > nMaxX || iNode == 0) {
-                nMaxX = nX;
+            if (x > maxX || nodeIndex == 0) {
+                maxX = x;
             }
         }
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nNode = ((Integer) nodes.get(iNode)).intValue();
-            setPositionX((int) (nMinX + iNode * (nMaxX - nMinX) / (nodes.size() - 1.0)), nNode);
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int node = nodes.get(nodeIndex).intValue();
+            setPositionX((int) (minX + nodeIndex * (maxX - minX) / (nodes.size() - 1.0)), node);
         }
         adjustArrows();
     } // spaceHorizontal
@@ -924,20 +931,20 @@ public class Document {
         // update undo stack
         addUndoAction(new UndoAction(selection.m_Selection, UndoAction.MOVE_ACTION));
         List<Integer> nodes = selection.m_Selection;
-        int nMinY = -1;
-        int nMaxY = -1;
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nY = getPositionY(((Integer) nodes.get(iNode)).intValue());
-            if (nY < nMinY || iNode == 0) {
-                nMinY = nY;
+        int minY = -1;
+        int maxY = -1;
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int y = getPositionY(nodes.get(nodeIndex).intValue());
+            if (y < minY || nodeIndex == 0) {
+                minY = y;
             }
-            if (nY > nMaxY || iNode == 0) {
-                nMaxY = nY;
+            if (y > maxY || nodeIndex == 0) {
+                maxY = y;
             }
         }
-        for (int iNode = 0; iNode < nodes.size(); iNode++) {
-            int nNode = ((Integer) nodes.get(iNode)).intValue();
-            setPositionY((int) (nMinY + iNode * (nMaxY - nMinY) / (nodes.size() - 1.0)), nNode);
+        for (int nodeIndex = 0; nodeIndex < nodes.size(); nodeIndex++) {
+            int node = nodes.get(nodeIndex).intValue();
+            setPositionY((int) (minY + nodeIndex * (maxY - minY) / (nodes.size() - 1.0)), node);
         }
         adjustArrows();
     } // spaceVertical
@@ -965,23 +972,23 @@ public class Document {
 
         /* single selection undo actions **/
 
-        public UndoAction(int nSelection, int nActionType) {
-            if (!(m_objects.get(nSelection) instanceof BEASTObjectShape)) {
+        public UndoAction(int selection, int actionType) {
+            if (!(m_objects.get(selection) instanceof BEASTObjectShape)) {
                 return;
             }
-            m_nActionType = nActionType;
-            m_nPositions = new ArrayList<Integer>();
-            m_nPositions.add(nSelection);
+            m_nActionType = actionType;
+            m_nPositions = new ArrayList<>();
+            m_nPositions.add(selection);
             init();
         }
         /* multiple selection undo actions **/
 
-        public UndoAction(List<Integer> selection, int nActionType) {
-            m_nActionType = nActionType;
-            m_nPositions = new ArrayList<Integer>();
+        public UndoAction(List<Integer> selection, int actionType) {
+            m_nActionType = actionType;
+            m_nPositions = new ArrayList<>();
             for (int i = 0; i < selection.size(); i++) {
                 if (m_objects.get(selection.get(i)) instanceof BEASTObjectShape) {
-                    m_nPositions.add(new Integer(((Integer) selection.get(i)).intValue()));
+                    m_nPositions.add(new Integer(selection.get(i).intValue()));
                 }
             }
             init();
@@ -992,29 +999,29 @@ public class Document {
         public UndoAction() {
         }
 
-        boolean isSingleSelection(int nPosition) {
-            return (m_nPositions.size() == 1 && m_nPositions.get(0) == nPosition);
+        boolean isSingleSelection(int position) {
+            return (m_nPositions.size() == 1 && m_nPositions.get(0) == position);
         }
 
-        boolean isSelection(List<Integer> nPositions) {
-            int nMatches = 0;
-            for (Integer i : nPositions) {
+        boolean isSelection(List<Integer> positions) {
+            int matches = 0;
+            for (Integer i : positions) {
                 if (m_objects.get(i) instanceof BEASTObjectShape) {
                     if (m_nPositions.contains(i)) {
-                        nMatches++;
+                        matches++;
                     } else {
                         return false;
                     }
                 }
             }
-            return nMatches == m_nPositions.size();
+            return matches == m_nPositions.size();
         }
 
         void init() {
             m_sXML = "<doc>";
             for (int i = 0; i < m_nPositions.size(); i++) {
-                int iShape = ((Integer) m_nPositions.get(i)).intValue();
-                Shape shape = (Shape) m_objects.get(iShape);
+                int shapeIndex = m_nPositions.get(i).intValue();
+                Shape shape = m_objects.get(shapeIndex);
                 m_sXML += shape.getXML();
             }
             m_sXML += "</doc>";
@@ -1029,42 +1036,42 @@ public class Document {
         }
 
         void doit() {
-            String sXML = "<doc>";
+            String xml = "<doc>";
             for (int i = 0; i < m_nPositions.size(); i++) {
-                int iShape = ((Integer) m_nPositions.get(i)).intValue();
-                Shape shape = (Shape) m_objects.get(iShape);
-                sXML += shape.getXML();
+                int shapeIndex = m_nPositions.get(i).intValue();
+                Shape shape = m_objects.get(shapeIndex);
+                xml += shape.getXML();
             }
-            sXML += "</doc>";
+            xml += "</doc>";
             List<Shape> shapes = XML2Shapes(m_sXML, false);
             for (int i = 0; i < m_nPositions.size(); i++) {
-                int iShape = ((Integer) m_nPositions.get(i)).intValue();
-                Shape originalShape = m_objects.get(iShape);
-                Shape shape = (Shape) shapes.get(i);
-                ((BEASTObjectShape) shape).m_plugin = ((BEASTObjectShape) originalShape).m_plugin;
+                int shapeIndex = m_nPositions.get(i).intValue();
+                Shape originalShape = m_objects.get(shapeIndex);
+                Shape shape = shapes.get(i);
+                ((BEASTObjectShape) shape).m_beastObject = ((BEASTObjectShape) originalShape).m_beastObject;
                 originalShape.assignFrom(shape);
             }
-            m_sXML = sXML;
+            m_sXML = xml;
         }
     } // class UndoAction
 
     /**
-     * action representing addition/deletion of a single plugin.
+     * action representing addition/deletion of a single beastObject.
      * This does not take connecting arrows in account.
-     * Use MultiObjectAction to add/delete plugin with its connecting arrows.
+     * Use MultiObjectAction to add/delete beastObject with its connecting arrows.
      */
     class PluginAction extends UndoAction {
-        public PluginAction(int nPosition, int nActionType) {
-            // assumes pluginShape + all its inputs has just been added
-            m_nActionType = nActionType;
-            BEASTObjectShape pluginShape = (BEASTObjectShape) m_objects.get(nPosition);
-            m_nPositions = new ArrayList<Integer>();
-            m_nPositions.add(nPosition);
-            nPosition--;
-            while (nPosition >= 0 &&
-                    m_objects.get(nPosition) instanceof InputShape &&
-                    ((InputShape) m_objects.get(nPosition)).getPluginShape() == pluginShape) {
-                m_nPositions.add(0, nPosition--);
+        public PluginAction(int position, int actionType) {
+            // assumes beastObjectShape + all its inputs has just been added
+            m_nActionType = actionType;
+            BEASTObjectShape beastObjectShape = (BEASTObjectShape) m_objects.get(position);
+            m_nPositions = new ArrayList<>();
+            m_nPositions.add(position);
+            position--;
+            while (position >= 0 &&
+                    m_objects.get(position) instanceof InputShape &&
+                    ((InputShape) m_objects.get(position)).getPluginShape() == beastObjectShape) {
+                m_nPositions.add(0, position--);
             }
             // creat XML
             init();
@@ -1080,7 +1087,7 @@ public class Document {
                     addPlugin();
                     return;
             }
-            System.err.println("Error 101: action type not set properly");
+            Log.err.println("Error 101: action type not set properly");
         }
 
         @Override
@@ -1093,7 +1100,7 @@ public class Document {
                     removePlugin();
                     return;
             }
-            System.err.println("Error 102: action type not set properly");
+            Log.err.println("Error 102: action type not set properly");
         }
 
         void removePlugin() {
@@ -1115,10 +1122,10 @@ public class Document {
      * action representing addition/deletion of a single arrow.
      */
     class ArrowAction extends UndoAction {
-        public ArrowAction(int nPosition, int nArrowAction) {
-            m_nActionType = nArrowAction;
-            m_nPositions = new ArrayList<Integer>();
-            m_nPositions.add(nPosition);
+        public ArrowAction(int position, int arrowAction) {
+            m_nActionType = arrowAction;
+            m_nPositions = new ArrayList<>();
+            m_nPositions.add(position);
             init();
         }
 
@@ -1132,7 +1139,7 @@ public class Document {
                     addArrow();
                     return;
             }
-            System.err.println("Error 103: action type not set properly");
+            Log.err.println("Error 103: action type not set properly");
         }
 
         @Override
@@ -1145,19 +1152,19 @@ public class Document {
                     removeArrow();
                     return;
             }
-            System.err.println("Error 104: action type not set properly");
+            Log.err.println("Error 104: action type not set properly");
         }
 
         void removeArrow() {
-            Arrow arrow = (Arrow) m_objects.get((int) m_nPositions.get(0));
+            Arrow arrow = (Arrow) m_objects.get(m_nPositions.get(0));
             m_objects.remove((int) m_nPositions.get(0));
             // unconnect plug-in and input
-            Input<?> input = arrow.m_headShape.m_input;
+            final Input<?> input = arrow.m_headShape.m_input;
             if (input instanceof List<?>) {
-                ((List<?>) input.get()).remove(arrow.m_tailShape.m_plugin);
+                ((List<?>) input.get()).remove(arrow.m_tailShape.m_beastObject);
             } else {
                 try {
-                    input.setValue(null, arrow.m_headShape.getPlugin());
+                    input.setValue(null, arrow.m_headShape.getBEASTObject());
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
@@ -1167,12 +1174,12 @@ public class Document {
         void addArrow() {
             List<Shape> shapes = XML2Shapes(m_sXML, true);
             Arrow arrow = (Arrow) shapes.get(0);
-            m_objects.add((int) m_nPositions.get(0), arrow);
+            m_objects.add(m_nPositions.get(0), arrow);
             // reconnect plug-in with input
             arrow.m_tailShape = getPluginShapeWithLabel(arrow.m_sTailID);
             arrow.m_headShape = getInputShapeWithID(arrow.m_sHeadID);
             try {
-                arrow.m_headShape.m_input.setValue(arrow.m_tailShape.m_plugin, arrow.m_headShape.getPlugin());
+                arrow.m_headShape.m_input.setValue(arrow.m_tailShape.m_beastObject, arrow.m_headShape.getBEASTObject());
             } catch (Exception e) {
                 e.printStackTrace();
             }
@@ -1180,58 +1187,56 @@ public class Document {
     } // class ArrowAction
 
     /**
-     * action representing addition or deletion of multiple plugins/arrows
+     * action representing addition or deletion of multiple beastObjects/arrows
      */
     class MultiObjectAction extends UndoAction {
         List<UndoAction> m_actions;
 
-        MultiObjectAction(List<Integer> nPositions, int nActionType) {
-            m_nActionType = nActionType;
-            m_actions = new ArrayList<UndoAction>();
+        MultiObjectAction(List<Integer> positions, int actionType) {
+            m_nActionType = actionType;
+            m_actions = new ArrayList<>();
             // remove duplicates, if any
-            Collections.sort(nPositions, new Comparator<Integer>() {
-                @Override
-                public int compare(Integer o1, Integer o2) {
+            Collections.sort(positions, (Integer o1, Integer o2) -> {
                     return (o2 - o1);
                 }
-            });
-            for (int i = 1; i < nPositions.size(); i++) {
-                if ((int) nPositions.get(i) == (int) nPositions.get(i - 1)) {
-                    nPositions.remove(i);
+            );
+            for (int i = 1; i < positions.size(); i++) {
+                if (positions.get(i) == positions.get(i - 1)) {
+                    positions.remove(i);
                     i--;
                 }
             }
-            // split in plugins and arrows
-            List<Integer> iArrows = new ArrayList<Integer>();
-            List<Integer> iPluginsShapes = new ArrayList<Integer>();
-            for (int i : nPositions) {
+            // split in beastObjects and arrows
+            List<Integer> arrows = new ArrayList<>();
+            List<Integer> pluginsShapes = new ArrayList<>();
+            for (int i : positions) {
                 Shape shape = m_objects.get(i);
                 if (shape instanceof BEASTObjectShape) {
-                    iPluginsShapes.add(i);
+                    pluginsShapes.add(i);
                 } else if (shape instanceof Arrow) {
-                    iArrows.add(i);
+                    arrows.add(i);
                 }
             }
             // create appropriate set of undo actions
-            switch (nActionType) {
+            switch (actionType) {
                 case ADD_GROUP_ACTION:
-                    for (int i : iPluginsShapes) {
+                    for (int i : pluginsShapes) {
                         m_actions.add(new PluginAction(i, ADD_PLUGIN_ACTION));
                     }
-                    for (int i : iArrows) {
+                    for (int i : arrows) {
                         m_actions.add(new ArrowAction(i, ADD_ARROW_ACTION));
                     }
                     break;
                 case DEL_GROUP_ACTION:
-                    for (int i : iArrows) {
+                    for (int i : arrows) {
                         m_actions.add(new ArrowAction(i, DEL_ARROW_ACTION));
                     }
-                    for (int i : iPluginsShapes) {
+                    for (int i : pluginsShapes) {
                         m_actions.add(new PluginAction(i, DEL_PLUGIN_ACTION));
                     }
                     break;
                 default:
-                    System.err.println("Error 105: unrecognized action type");
+                    Log.err.println("Error 105: unrecognized action type");
             }
         }
 
@@ -1261,24 +1266,26 @@ public class Document {
             m_newOrder = newOrder;
         }
 
-        void undo() {
+        @Override
+		void undo() {
             reorder(m_oldOrder, m_newOrder);
         }
 
-        void redo() {
+        @Override
+		void redo() {
             for (int i = m_newOrder.length - 1; i >= 0; i--) {
-                int iSelection = m_newOrder[i];
-                Shape shape = (Shape) m_objects.get(iSelection);
-                m_objects.remove(iSelection);
+                int selectionIndex = m_newOrder[i];
+                Shape shape = m_objects.get(selectionIndex);
+                m_objects.remove(selectionIndex);
                 m_objects.add(m_oldOrder[i], shape);
             }
         }
 
         void reorder(int[] oldOrder, int[] newOrder) {
             for (int i = 0; i < oldOrder.length; i++) {
-                int iSelection = oldOrder[i];
-                Shape shape = (Shape) m_objects.get(iSelection);
-                m_objects.remove(iSelection);
+                int selectionIndex = oldOrder[i];
+                Shape shape = m_objects.get(selectionIndex);
+                m_objects.remove(selectionIndex);
                 m_objects.add(newOrder[i], shape);
             }
         }
@@ -1291,9 +1298,9 @@ public class Document {
      * @param action operation that needs to be added to the undo stack
      */
     void addUndoAction(UndoAction action) {
-        int iAction = m_undoStack.size() - 1;
-        while (iAction > m_nCurrentEditAction) {
-            m_undoStack.remove(iAction--);
+        int actionIndex = m_undoStack.size() - 1;
+        while (actionIndex > m_nCurrentEditAction) {
+            m_undoStack.remove(actionIndex--);
         }
         m_undoStack.add(action);
         m_nCurrentEditAction++;
@@ -1303,7 +1310,7 @@ public class Document {
      * remove all actions from the undo stack
      */
     public void clearUndoStack() {
-        m_undoStack = new ArrayList<UndoAction>();
+        m_undoStack = new ArrayList<>();
         m_nCurrentEditAction = -1;
     } // clearUndoStack
 
@@ -1340,10 +1347,10 @@ public class Document {
     } // redo
 
 
-    BEASTObjectShape getPluginShapeWithLabel(String sLabel) {
+    BEASTObjectShape getPluginShapeWithLabel(String label) {
         for (Shape shape : m_objects) {
             if (shape instanceof BEASTObjectShape) {
-                if (shape.getLabel() != null && shape.getLabel().equals(sLabel)) {
+                if (shape.getLabel() != null && shape.getLabel().equals(label)) {
                     return (BEASTObjectShape) shape;
                 }
             }
@@ -1351,10 +1358,10 @@ public class Document {
         return null;
     }
 
-    InputShape getInputShapeWithID(String sLabel) {
+    InputShape getInputShapeWithID(String label) {
         for (Shape shape : m_objects) {
             if (shape instanceof InputShape) {
-                if (shape.getID() != null && shape.getID().equals(sLabel)) {
+                if (shape.getID() != null && shape.getID().equals(label)) {
                     return (InputShape) shape;
                 }
             }
@@ -1365,33 +1372,33 @@ public class Document {
     final static int DX = 120;
     final static int DY = 80;
 
-    void addInput(BEASTObjectShape shape, Object o2, int nDepth, String sInput) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
+    void addInput(BEASTObjectShape shape, Object o2, int depth, String input) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
         if (o2 instanceof BEASTInterface) {
             BEASTObjectShape shape2 = getPluginShapeWithLabel(((BEASTInterface) o2).getID());
             if (shape2 == null) {
                 shape2 = new BEASTObjectShape((BEASTInterface) o2, this);
-                shape2.m_x = nDepth * DX;
+                shape2.m_x = depth * DX;
                 shape2.m_w = DY;
-                shape2.m_plugin = (BEASTInterface) o2;
+                shape2.m_beastObject = (BEASTInterface) o2;
                 setPluginID(shape2);
                 m_objects.add(shape2);
             }
-            process(shape2, nDepth);
+            process(shape2, depth);
         }
     }
 
-    void process(BEASTObjectShape shape, int nDepth) throws IllegalArgumentException, IllegalAccessException, InstantiationException, ClassNotFoundException {
-        BEASTInterface plugin = shape.m_plugin;
-        List<Input<?>> sInputs = plugin.listInputs();
-        for (Input<?> input_ : sInputs) {
+    void process(BEASTObjectShape shape, int depth) throws IllegalArgumentException, IllegalAccessException, InstantiationException, ClassNotFoundException {
+        BEASTInterface beastObject = shape.m_beastObject;
+        List<Input<?>> inputs = beastObject.listInputs();
+        for (Input<?> input_ : inputs) {
             Object o = input_.get();
             if (o != null) {
                 if (o instanceof List<?>) {
                     for (Object o2 : (List<?>) o) {
-                        addInput(shape, o2, nDepth + 1, input_.getName());
+                        addInput(shape, o2, depth + 1, input_.getName());
                     }
                 } else if (o instanceof BEASTInterface) {
-                    addInput(shape, o, nDepth + 1, input_.getName());
+                    addInput(shape, o, depth + 1, input_.getName());
                     // } else {
                     // it is a primitive type
                 }
@@ -1400,22 +1407,22 @@ public class Document {
     }
 
 
-    public void loadFile(String sFileName) {
+    public void loadFile(String fileName) {
         m_objects.clear();
         XMLParser parser = new XMLParser();
         try {
-            //sFileName;
-            StringBuilder sXML = new StringBuilder();
+            //fileName;
+            StringBuilder xml = new StringBuilder();
             String NL = System.getProperty("line.separator");
-            Scanner scanner = new Scanner(new File(sFileName));
+            Scanner scanner = new Scanner(new File(fileName));
             try {
                 while (scanner.hasNextLine()) {
-                    sXML.append(scanner.nextLine() + NL);
+                    xml.append(scanner.nextLine() + NL);
                 }
             } finally {
                 scanner.close();
             }
-            BEASTInterface plugin0 = parser.parseBareFragment(sXML.toString(), false);
+            BEASTInterface plugin0 = parser.parseBareFragment(xml.toString(), false);
             init(plugin0);
         } catch (Exception e) {
             e.printStackTrace();
@@ -1424,11 +1431,11 @@ public class Document {
     }
     
     void reinit() {
-    	String sXML = toXML();
+    	String xml = toXML();
         m_objects.clear();
         try {
             XMLParser parser = new XMLParser();
-            BEASTInterface plugin0 = parser.parseBareFragment(sXML, false);
+            BEASTInterface plugin0 = parser.parseBareFragment(xml, false);
             init(plugin0);
         } catch (Exception e) {
             e.printStackTrace();
@@ -1443,9 +1450,9 @@ public class Document {
                 if (set == null) {
                     return;
                 }
-                for (BEASTInterface plugin : set) {
-                    BEASTObjectShape shape = new BEASTObjectShape(plugin, this);
-                    shape.m_plugin = plugin;
+                for (BEASTInterface beastObject : set) {
+                    BEASTObjectShape shape = new BEASTObjectShape(beastObject, this);
+                    shape.m_beastObject = beastObject;
                     setPluginID(shape);
                     m_objects.add(shape);
                     process(shape, 1);
@@ -1457,7 +1464,7 @@ public class Document {
                 }
             } else {
                 BEASTObjectShape shape = new BEASTObjectShape(plugin0, this);
-                shape.m_plugin = plugin0;
+                shape.m_beastObject = plugin0;
                 setPluginID(shape);
                 m_objects.add(shape);
                 process(shape, 1);
@@ -1480,19 +1487,19 @@ public class Document {
         adjustArrows();
     } // init
 
-    List<Shape> XML2Shapes(String sXML, boolean bReconstructPlugins) {
-        List<Shape> shapes = new ArrayList<Shape>();
+    List<Shape> XML2Shapes(String xml, boolean reconstructBEASTObjects) {
+        List<Shape> shapes = new ArrayList<>();
         m_tmpobjects = shapes;
         try {
             DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
             factory.setValidating(false);
-            org.w3c.dom.Document doc = factory.newDocumentBuilder().parse(new org.xml.sax.InputSource(new StringReader(sXML)));
+            org.w3c.dom.Document doc = factory.newDocumentBuilder().parse(new org.xml.sax.InputSource(new StringReader(xml)));
             doc.normalize();
             NodeList nodes = doc.getDocumentElement().getChildNodes();
-            for (int iNode = 0; iNode < nodes.getLength(); iNode++) {
-                Node node = nodes.item(iNode);
+            for (int nodeIndex = 0; nodeIndex < nodes.getLength(); nodeIndex++) {
+                Node node = nodes.item(nodeIndex);
                 if (node.getNodeType() == Node.ELEMENT_NODE) {
-                    shapes.add(parseNode(node, this, bReconstructPlugins));
+                    shapes.add(parseNode(node, this, reconstructBEASTObjects));
                 }
             }
         } catch (Throwable t) {
@@ -1508,14 +1515,14 @@ public class Document {
     /**
      * parse XDL xml format *
      */
-    static Shape parseNode(Node node, Document doc, boolean bReconstructPlugins) {
+    static Shape parseNode(Node node, Document doc, boolean reconstructBEASTObjects) {
         Shape shape = null;
-        if (node.getNodeName().equals(INPUT_SHAPE_ELEMENT) && bReconstructPlugins) {
-            shape = new InputShape(node, doc, bReconstructPlugins);
-        } else if (node.getNodeName().equals(ARROW_ELEMENT) && bReconstructPlugins) {
-            shape = new Arrow(node, doc, bReconstructPlugins);
+        if (node.getNodeName().equals(INPUT_SHAPE_ELEMENT) && reconstructBEASTObjects) {
+            shape = new InputShape(node, doc, reconstructBEASTObjects);
+        } else if (node.getNodeName().equals(ARROW_ELEMENT) && reconstructBEASTObjects) {
+            shape = new Arrow(node, doc, reconstructBEASTObjects);
         } else if (node.getNodeName().equals(PLUGIN_SHAPE_ELEMENT)) {
-            shape = new BEASTObjectShape(node, doc, bReconstructPlugins);
+            shape = new BEASTObjectShape(node, doc, reconstructBEASTObjects);
         }
         return shape;
     } // parseNode
@@ -1531,19 +1538,19 @@ public class Document {
 
 
     /**
-     * collect all objects and put all top-level plugins in a PluginSet
+     * collect all objects and put all top-level beastObjects in a PluginSet
      */
     BEASTObjectSet calcPluginSet() {
         // collect all plug-ins
-        Collection<BEASTInterface> plugins = getPlugins();
+        Collection<BEASTInterface> beastObjects = getPlugins();
         // calc outputs
-        HashMap<BEASTInterface, List<BEASTInterface>> outputs = BEASTObjectPanel.getOutputs(plugins);
-        // put all plugins with no ouputs in the PluginSet
+        HashMap<BEASTInterface, List<BEASTInterface>> outputs = BEASTObjectPanel.getOutputs(beastObjects);
+        // put all beastObjects with no ouputs in the PluginSet
         BEASTObjectSet pluginSet = new BEASTObjectSet();
-        for (BEASTInterface plugin : outputs.keySet()) {
-            if (outputs.get(plugin).size() == 0) {
+        for (BEASTInterface beastObject : outputs.keySet()) {
+            if (outputs.get(beastObject).size() == 0) {
                 try {
-                    pluginSet.setInputValue("plugin", plugin);
+                    pluginSet.setInputValue("beastObject", beastObject);
                 } catch (Exception e) {
                     e.printStackTrace();
                 }
@@ -1553,37 +1560,37 @@ public class Document {
     } // calcPluginSet
 
     /**
-     * convert m_objects in set of plugins *
+     * convert m_objects in set of beastObjects *
      */
     Collection<BEASTInterface> getPlugins() {
-        Collection<BEASTInterface> plugins = new HashSet<BEASTInterface>();
+        Collection<BEASTInterface> beastObjects = new HashSet<>();
         for (Shape shape : m_objects) {
             if (shape instanceof BEASTObjectShape) {
-                plugins.add(((BEASTObjectShape) shape).m_plugin);
+                beastObjects.add(((BEASTObjectShape) shape).m_beastObject);
             }
         }
-        return plugins;
+        return beastObjects;
     }
 
     /**
      * return true if source is ascendant of target *
      */
     boolean isAscendant(BEASTInterface source, BEASTInterface target) {
-        Collection<BEASTInterface> plugins = getPlugins();
-        List<BEASTInterface> ascendants = BEASTObjectPanel.listAscendants(target, plugins);
+        Collection<BEASTInterface> beastObjects = getPlugins();
+        List<BEASTInterface> ascendants = BEASTObjectPanel.listAscendants(target, beastObjects);
         return ascendants.contains(source);
     }
 
-    Shape findObjectWithID(String sID) {
+    Shape findObjectWithID(String id) {
         if (m_tmpobjects != null) {
             for (int i = 0; i < m_tmpobjects.size(); i++) {
-                if (m_tmpobjects.get(i).getID().equals(sID)) {
+                if (m_tmpobjects.get(i).getID().equals(id)) {
                     return m_tmpobjects.get(i);
                 }
             }
         }
         for (int i = 0; i < m_objects.size(); i++) {
-            if (m_objects.get(i).getID().equals(sID)) {
+            if (m_objects.get(i).getID().equals(id)) {
                 return m_objects.get(i);
             }
         }
@@ -1596,21 +1603,21 @@ public class Document {
      */
     void layout() {
         // first construct input map for ease of navigation
-        HashMap<BEASTObjectShape, List<BEASTObjectShape>> inputMap = new HashMap<BEASTObjectShape, List<BEASTObjectShape>>();
-        HashMap<BEASTObjectShape, List<BEASTObjectShape>> outputMap = new HashMap<BEASTObjectShape, List<BEASTObjectShape>>();
+        HashMap<BEASTObjectShape, List<BEASTObjectShape>> inputMap = new HashMap<>();
+        HashMap<BEASTObjectShape, List<BEASTObjectShape>> outputMap = new HashMap<>();
         for (Shape shape : m_objects) {
             if (shape instanceof BEASTObjectShape && shape.m_bNeedsDrawing) {
-                inputMap.put((BEASTObjectShape) shape, new ArrayList<BEASTObjectShape>());
-                outputMap.put((BEASTObjectShape) shape, new ArrayList<BEASTObjectShape>());
+                inputMap.put((BEASTObjectShape) shape, new ArrayList<>());
+                outputMap.put((BEASTObjectShape) shape, new ArrayList<>());
             }
         }
         for (Shape shape : m_objects) {
             if (shape instanceof Arrow && shape.m_bNeedsDrawing) {
                 Shape headShape = ((Arrow) shape).m_headShape;
-                BEASTObjectShape pluginShape = ((InputShape) headShape).m_pluginShape;
+                BEASTObjectShape beastObjectShape = ((InputShape) headShape).m_beastObjectShape;
                 BEASTObjectShape inputShape = ((Arrow) shape).m_tailShape;
-                inputMap.get(pluginShape).add(inputShape);
-                outputMap.get(inputShape).add(pluginShape);
+                inputMap.get(beastObjectShape).add(inputShape);
+                outputMap.get(inputShape).add(beastObjectShape);
             }
         }
         // reset all x-coords to minimal x-value
@@ -1618,32 +1625,32 @@ public class Document {
             shape.m_x = DX;
         }
         // move inputs rightward till they exceed x-coord of their inputs
-        boolean bProgress = true;
-        while (bProgress) {
-            bProgress = false;
+        boolean progress = true;
+        while (progress) {
+            progress = false;
             for (Shape shape : inputMap.keySet()) {
-                int nMaxInputX = -DX;
+                int maxInputX = -DX;
                 for (Shape input : inputMap.get(shape)) {
-                    nMaxInputX = Math.max(nMaxInputX, input.m_x);
+                    maxInputX = Math.max(maxInputX, input.m_x);
                 }
-                if (shape.m_x < nMaxInputX + DX) {
-                    shape.m_x = nMaxInputX + DX;
-                    bProgress = true;
+                if (shape.m_x < maxInputX + DX) {
+                    shape.m_x = maxInputX + DX;
+                    progress = true;
                 }
             }
         }
         // move inputs rightward till they are stopped by their outputs
-        bProgress = true;
-        while (bProgress) {
-            bProgress = false;
+        progress = true;
+        while (progress) {
+            progress = false;
             for (Shape shape : outputMap.keySet()) {
-                int nMinOutputX = Integer.MAX_VALUE;
+                int minOutputX = Integer.MAX_VALUE;
                 for (Shape input : outputMap.get(shape)) {
-                    nMinOutputX = Math.min(nMinOutputX, input.m_x);
+                    minOutputX = Math.min(minOutputX, input.m_x);
                 }
-                if (nMinOutputX < Integer.MAX_VALUE && shape.m_x < nMinOutputX - DX) {
-                    shape.m_x = nMinOutputX - DX;
-                    bProgress = true;
+                if (minOutputX < Integer.MAX_VALUE && shape.m_x < minOutputX - DX) {
+                    shape.m_x = minOutputX - DX;
+                    progress = true;
                 }
             }
         }
@@ -1651,11 +1658,11 @@ public class Document {
 
         layoutAdjustY(inputMap);
         // relax a bit
-        System.err.print("Relax...");
+        Log.warning.print("Relax...");
         for (int i = 0; i < 250; i++) {
             relax(false);
         }
-        System.err.println("Done");
+        Log.warning.println("Done");
         layoutAdjustY(inputMap);
 
         adjustInputs();
@@ -1667,18 +1674,18 @@ public class Document {
      */
     void layoutAdjustY(HashMap<BEASTObjectShape, List<BEASTObjectShape>> inputMap) {
         // next, optimise top down order
-        boolean bProgress = true;
-        int iX = DX;
-        while (bProgress) {
-            List<BEASTObjectShape> shapes = new ArrayList<BEASTObjectShape>();
+        boolean progress = true;
+        int x = DX;
+        while (progress) {
+            List<BEASTObjectShape> shapes = new ArrayList<>();
             // find shapes with same x-coordinate
             for (BEASTObjectShape shape : inputMap.keySet()) {
-                if (shape.m_x == iX) {
+                if (shape.m_x == x) {
                     shapes.add(shape);
                 }
             }
             int k = 1;
-            HashMap<Integer, BEASTObjectShape> ycoordMap = new HashMap<Integer, BEASTObjectShape>();
+            HashMap<Integer, BEASTObjectShape> ycoordMap = new HashMap<>();
             // set y-coordinate as mean of inputs
             // if there are no inputs, order them top to bottom at DY intervals
             for (BEASTObjectShape shape : shapes) {
@@ -1699,18 +1706,18 @@ public class Document {
                 k++;
             }
             // ensure shapes are sufficiently far apart - at least DY between them
-            int nPrevY = 0;
-            ArrayList<Integer> yCoords = new ArrayList<Integer>();
+            int prevY = 0;
+            ArrayList<Integer> yCoords = new ArrayList<>();
             yCoords.addAll(ycoordMap.keySet());
             Collections.sort(yCoords);
             int dY = 0;
             for (Integer i : yCoords) {
                 BEASTObjectShape shape = ycoordMap.get(i);
-                if (shape.m_y < nPrevY + DY) {
-                    dY = nPrevY + DY - shape.m_y;
-                    shape.m_y = nPrevY + DY;
+                if (shape.m_y < prevY + DY) {
+                    dY = prevY + DY - shape.m_y;
+                    shape.m_y = prevY + DY;
                 }
-                nPrevY = shape.m_y;
+                prevY = shape.m_y;
             }
             // upwards correction
             if (dY > 0) {
@@ -1721,16 +1728,16 @@ public class Document {
             }
 
 
-            bProgress = (shapes.size() > 0);
-            iX += DX;
+            progress = (shapes.size() > 0);
+            x += DX;
         }
     } // layoutAdjustY
 
     /**
      * apply spring model algorithm to the placement of plug-in shapes *
      */
-    public void relax(boolean bAllowXToMove) {
-        List<Shape> objects = new ArrayList<Shape>();
+    public void relax(boolean allowXToMove) {
+        List<Shape> objects = new ArrayList<>();
         for (Shape shape : m_objects) {
             if (shape.m_bNeedsDrawing) {
                 objects.add(shape);
@@ -1738,23 +1745,23 @@ public class Document {
         }
 
         // Step 0: determine degrees
-        HashMap<String, Integer> degreeMap = new HashMap<String, Integer>();
+        HashMap<String, Integer> degreeMap = new HashMap<>();
         for (Shape shape : objects) {
 
             if (shape instanceof Arrow) {
                 Arrow arrow = (Arrow) shape;
-                String sID = arrow.m_tailShape.getID();
+                String id = arrow.m_tailShape.getID();
                 if (arrow.m_headShape instanceof InputShape) {
-                    String sID2 = ((InputShape) arrow.m_headShape).m_pluginShape.getID();
-                    if (degreeMap.containsKey(sID)) {
-                        degreeMap.put(sID, degreeMap.get(sID) + 1);
+                    String id2 = arrow.m_headShape.m_beastObjectShape.getID();
+                    if (degreeMap.containsKey(id)) {
+                        degreeMap.put(id, degreeMap.get(id) + 1);
                     } else {
-                        degreeMap.put(sID, 1);
+                        degreeMap.put(id, 1);
                     }
-                    if (degreeMap.containsKey(sID2)) {
-                        degreeMap.put(sID2, degreeMap.get(sID2) + 1);
+                    if (degreeMap.containsKey(id2)) {
+                        degreeMap.put(id2, degreeMap.get(id2) + 1);
                     } else {
-                        degreeMap.put(sID2, 1);
+                        degreeMap.put(id2, 1);
                     }
                 }
             }
@@ -1768,7 +1775,7 @@ public class Document {
                 int p1x = source.m_x + source.m_w / 2;
                 int p1y = source.m_y + source.m_h / 2;
                 if (arrow.m_headShape instanceof InputShape) {
-                    Shape target = ((InputShape) arrow.m_headShape).m_pluginShape;
+                    Shape target = arrow.m_headShape.m_beastObjectShape;
                     int p2x = target.m_x + target.m_w / 2;
                     int p2y = target.m_y + target.m_h / 2;
 
@@ -1783,11 +1790,11 @@ public class Document {
 
                     double f = 1.0 / 3.0 * (desiredLen - len) / len;
 
-                    int nDegree1 = degreeMap.get(source.getID());
-                    int nDegree2 = degreeMap.get(target.getID());
+                    int degree1 = degreeMap.get(source.getID());
+                    int degree2 = degreeMap.get(target.getID());
 
 
-                    f = f * Math.pow(0.99, (nDegree1 + nDegree2 - 2));
+                    f = f * Math.pow(0.99, (degree1 + degree2 - 2));
 
 
                     // the actual movement distance 'dx' is the force multiplied by the
@@ -1798,9 +1805,9 @@ public class Document {
                         dx = -dx;
                         //f *= Math.abs((vx+200))/40;
                     }
-                    if (bAllowXToMove) source.m_x = (int) Math.max(100, source.m_x + dx);
+                    if (allowXToMove) source.m_x = (int) Math.max(100, source.m_x + dx);
                     source.m_y = (int) Math.max(10, source.m_y + dy);
-                    if (bAllowXToMove) target.m_x = (int) Math.max(100, target.m_x - dx);
+                    if (allowXToMove) target.m_x = (int) Math.max(100, target.m_x - dx);
                     target.m_y = (int) Math.max(10, target.m_y - dy);
 
                 }
@@ -1830,7 +1837,7 @@ public class Document {
                         }
                     }
                 }
-                if (bAllowXToMove) shape1.m_x = (int) Math.min(800, Math.max(10, shape1.m_x + dx));
+                if (allowXToMove) shape1.m_x = (int) Math.min(800, Math.max(10, shape1.m_x + dx));
                 shape1.m_y = (int) Math.min(800, Math.max(10, shape1.m_y + dy));
             }
         }
@@ -1861,8 +1868,8 @@ public class Document {
             return STATUS_ORPHANS_IN_MODEL;
         }
         boolean hasRunable = false;
-        for (BEASTInterface plugin : pluginSet.m_plugins.get()) {
-            if (plugin instanceof Runnable) {
+        for (BEASTInterface beastObject : pluginSet.m_plugins.get()) {
+            if (beastObject instanceof Runnable) {
                 hasRunable = true;
             }
         }
@@ -1873,7 +1880,7 @@ public class Document {
     } // isValidModel
 
     /**
-     * remove all arrows, then add based on the plugin inputs *
+     * remove all arrows, then add based on the beastObject inputs *
      */
     void recalcArrows() {
         // remove all arrows
@@ -1884,10 +1891,10 @@ public class Document {
             }
         }
         // build map for quick resolution of PluginShapes
-        HashMap<BEASTInterface, BEASTObjectShape> map = new HashMap<BEASTInterface, BEASTObjectShape>();
+        HashMap<BEASTInterface, BEASTObjectShape> map = new HashMap<>();
         for (Shape shape : m_objects) {
             if (shape instanceof BEASTObjectShape) {
-                map.put(((BEASTObjectShape) shape).m_plugin, (BEASTObjectShape) shape);
+                map.put(((BEASTObjectShape) shape).m_beastObject, (BEASTObjectShape) shape);
             }
         }
         // re-insert arrows, if any
@@ -1895,13 +1902,13 @@ public class Document {
             Shape shape = m_objects.get(i);
             if (shape instanceof BEASTObjectShape) {
                 BEASTObjectShape headShape = ((BEASTObjectShape) shape);
-                BEASTInterface plugin = headShape.m_plugin;
+                BEASTInterface beastObject = headShape.m_beastObject;
                 try {
-                    List<Input<?>> inputs = plugin.listInputs();
+                    List<Input<?>> inputs = beastObject.listInputs();
                     for (Input<?> input : inputs) {
                         if (input.get() != null) {
                             if (input.get() instanceof BEASTInterface) {
-                                BEASTObjectShape tailShape = map.get((BEASTInterface) input.get());
+                                BEASTObjectShape tailShape = map.get(input.get());
                                 try {
 	                                Arrow arrow = new Arrow(tailShape, headShape, input.getName());
 	                                arrow.setID(getNewID(null));
@@ -1913,7 +1920,7 @@ public class Document {
                             if (input.get() instanceof List<?>) {
                                 for (Object o : (List<?>) input.get()) {
                                     if (o != null && o instanceof BEASTInterface) {
-                                        BEASTObjectShape tailShape = map.get((BEASTInterface) o);
+                                        BEASTObjectShape tailShape = map.get(o);
                                         try {
 	                                        Arrow arrow = new Arrow(tailShape, headShape, input.getName());
 	                                        arrow.setID(getNewID(null));
diff --git a/src/beast/app/draw/DoubleListInputEditor.java b/src/beast/app/draw/DoubleListInputEditor.java
index 974afc4..9fe6495 100644
--- a/src/beast/app/draw/DoubleListInputEditor.java
+++ b/src/beast/app/draw/DoubleListInputEditor.java
@@ -12,6 +12,7 @@ import javax.swing.BorderFactory;
 import javax.swing.Box;
 import javax.swing.JLabel;
 import javax.swing.JTextField;
+import javax.swing.SwingConstants;
 import javax.swing.border.Border;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
@@ -22,6 +23,7 @@ import beast.app.beauti.BeautiPanel;
 import beast.app.beauti.BeautiPanelConfig;
 import beast.core.BEASTInterface;
 import beast.core.Input;
+import beast.core.util.Log;
 
 
 public class DoubleListInputEditor extends ListInputEditor {
@@ -39,7 +41,8 @@ public class DoubleListInputEditor extends ListInputEditor {
     /**
      * return type of the list *
      */
-    public Class<?> baseType() {
+    @Override
+	public Class<?> baseType() {
         return Double.class;
     }
     
@@ -64,9 +67,9 @@ public class DoubleListInputEditor extends ListInputEditor {
         protected Input<?> m_input;
 
         /**
-         * parent plugin *
+         * parent beastObject *
          */
-        protected BEASTInterface m_plugin;
+        protected BEASTInterface m_beastObject;
 
         /**
          * text field used for primitive input editors *
@@ -75,7 +78,8 @@ public class DoubleListInputEditor extends ListInputEditor {
         
         protected int itemNr;
 
-        public JTextField getEntry() {
+        @Override
+		public JTextField getEntry() {
             return m_entry;
         }
 
@@ -103,14 +107,16 @@ public class DoubleListInputEditor extends ListInputEditor {
          */
         List<InputEditor> m_validateListeners;
 
-        public void addValidationListener(InputEditor validateListener) {
+        @Override
+		public void addValidationListener(InputEditor validateListener) {
             if (m_validateListeners == null) {
-                m_validateListeners = new ArrayList<InputEditor>();
+                m_validateListeners = new ArrayList<>();
             }
             m_validateListeners.add(validateListener);
         }
 
-        public void notifyValidationListeners(ValidationStatus state) {
+        @Override
+		public void notifyValidationListeners(ValidationStatus state) {
             if (m_validateListeners != null) {
                 for (InputEditor listener : m_validateListeners) {
                     listener.startValidating(state);
@@ -118,7 +124,8 @@ public class DoubleListInputEditor extends ListInputEditor {
             }
         }
 
-    	protected BeautiDoc getDoc() {
+    	@Override
+		protected BeautiDoc getDoc() {
             if (doc == null) {
                 Component c = this;
                 while (c.getParent() != null) {
@@ -132,7 +139,8 @@ public class DoubleListInputEditor extends ListInputEditor {
         }
 
 
-        public Class<?>[] types() {
+        @Override
+		public Class<?>[] types() {
             Class<?>[] types = new Class<?>[1];
             types[0] = type();
             return types;
@@ -141,10 +149,11 @@ public class DoubleListInputEditor extends ListInputEditor {
         /**
          * construct an editor consisting of a label and input entry *
          */
-        public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-            m_bAddButtons = bAddButtons;
+        @Override
+		public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+            m_bAddButtons = addButtons;
             m_input = input;
-            m_plugin = plugin;
+            m_beastObject = beastObject;
             this.itemNr= itemNr;
             
             addInputLabel();
@@ -156,7 +165,8 @@ public class DoubleListInputEditor extends ListInputEditor {
             addValidationLabel();
         } // init
 
-        void setUpEntry() {
+        @Override
+		void setUpEntry() {
             m_entry = new JTextField();
             m_entry.setName(m_input.getName());
             m_entry.setMinimumSize(PREFERRED_SIZE);
@@ -184,27 +194,29 @@ public class DoubleListInputEditor extends ListInputEditor {
             });
         }
 
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-    	protected void setValue(Object o) throws Exception {
+        @Override
+		@SuppressWarnings({ "unchecked", "rawtypes" })
+    	protected void setValue(Object o) {
         	if (itemNr < 0) {
-        		m_input.setValue(o, m_plugin);
+        		m_input.setValue(o, m_beastObject);
         	} else {
         		// set value of an item in a list
         		List list = (List) m_input.get();
         		Object other = list.get(itemNr);
         		if (other != o) {
         			if (other instanceof BEASTInterface) {
-        				BEASTInterface.getOutputs(other).remove(m_plugin);
+        				BEASTInterface.getOutputs(other).remove(m_beastObject);
         			}
         			list.set(itemNr, o);
         			if (o instanceof BEASTInterface) {
-        				BEASTInterface.getOutputs(o).add(m_plugin);
+        				BEASTInterface.getOutputs(o).add(m_beastObject);
         			}
         		}
         	}
         }
         
-        protected void processEntry() {
+        @Override
+		protected void processEntry() {
             try {
             	setValue(m_entry.getText());
                 validateInput();
@@ -222,28 +234,31 @@ public class DoubleListInputEditor extends ListInputEditor {
             }
         }
 
-        protected void addInputLabel() {
+        @Override
+		protected void addInputLabel() {
             if (m_bAddButtons) {
-                String sName = formatName(m_input.getName());
-                addInputLabel(sName, m_input.getHTMLTipText());
+                String name = formatName(m_input.getName());
+                addInputLabel(name, m_input.getHTMLTipText());
             }
         }
 
-        protected String formatName(String sName) {
-    	    if (doc.beautiConfig.inputLabelMap.containsKey(m_plugin.getClass().getName() + "." + sName)) {
-    	        sName = doc.beautiConfig.inputLabelMap.get(m_plugin.getClass().getName() + "." + sName);
+        @Override
+		protected String formatName(String name) {
+    	    if (doc.beautiConfig.inputLabelMap.containsKey(m_beastObject.getClass().getName() + "." + name)) {
+    	        name = doc.beautiConfig.inputLabelMap.get(m_beastObject.getClass().getName() + "." + name);
     	    } else {
-    	        sName = sName.replaceAll("([a-z])([A-Z])", "$1 $2");
-    	        sName = sName.substring(0, 1).toUpperCase() + sName.substring(1);
+    	        name = name.replaceAll("([a-z])([A-Z])", "$1 $2");
+    	        name = name.substring(0, 1).toUpperCase() + name.substring(1);
     	    }
-    	    return sName;
+    	    return name;
         }
 
-        protected void addInputLabel(String sLabel, String sTipText) {
+        @Override
+		protected void addInputLabel(String label, String tipText) {
             if (m_bAddButtons) {
-                m_inputLabel = new JLabel(sLabel);
-                m_inputLabel.setToolTipText(sTipText);
-                m_inputLabel.setHorizontalTextPosition(JLabel.RIGHT);
+                m_inputLabel = new JLabel(label);
+                m_inputLabel.setToolTipText(tipText);
+                m_inputLabel.setHorizontalTextPosition(SwingConstants.RIGHT);
                 //Dimension size = new Dimension(g_nLabelWidth, 20);
                 Dimension size = new Dimension(200, 20);
                 m_inputLabel.setMaximumSize(size);
@@ -259,7 +274,8 @@ public class DoubleListInputEditor extends ListInputEditor {
             }
         }
 
-        protected void addValidationLabel() {
+        @Override
+		protected void addValidationLabel() {
             if (m_bAddButtons) {
                 m_validateLabel = new SmallLabel("x", new Color(200, 0, 0));
                 add(m_validateLabel);
@@ -269,7 +285,8 @@ public class DoubleListInputEditor extends ListInputEditor {
         }
 
         /* check the input is valid, continue checking recursively */
-        protected void validateAllEditors() {
+        @Override
+		protected void validateAllEditors() {
             for (InputEditor editor : doc.currentInputEditors) {
                 editor.validateInput();
             }
@@ -279,12 +296,12 @@ public class DoubleListInputEditor extends ListInputEditor {
         public void validateInput() {
             try {
                 m_input.validate();
-                if (m_entry != null && !m_input.canSetValue(m_entry.getText(), m_plugin)) {
-                    throw new Exception("invalid value");
+                if (m_entry != null && !m_input.canSetValue(m_entry.getText(), m_beastObject)) {
+                    throw new IllegalArgumentException("invalid value");
                 }
                 // recurse
                 try {
-                    validateRecursively(m_input, new HashSet<Input<?>>());
+                    validateRecursively(m_input, new HashSet<>());
                 } catch (Exception e) {
                     notifyValidationListeners(ValidationStatus.HAS_INVALIDMEMBERS);
                     if (m_validateLabel != null) {
@@ -300,7 +317,7 @@ public class DoubleListInputEditor extends ListInputEditor {
                 }
                 notifyValidationListeners(ValidationStatus.IS_VALID);
             } catch (Exception e) {
-                System.err.println("Validation message: " + e.getMessage());
+            	Log.warning.println("Validation message: " + e.getMessage());
                 if (m_validateLabel != null) {
                     m_validateLabel.setToolTipText(e.getMessage());
                     m_validateLabel.m_circleColor = Color.red;
@@ -311,9 +328,10 @@ public class DoubleListInputEditor extends ListInputEditor {
             repaint();
         }
 
-        /* Recurse in any of the input plugins
+        /* Recurse in any of the input beastObjects
           * and validate its inputs */
-        void validateRecursively(Input<?> input, Set<Input<?>> done) throws Exception {
+        @Override
+		void validateRecursively(Input<?> input, Set<Input<?>> done) {
             if (done.contains(input)) {
                 // this prevent cycles to lock up validation
                 return;
@@ -322,12 +340,12 @@ public class DoubleListInputEditor extends ListInputEditor {
             }
             if (input.get() != null) {
                 if (input.get() instanceof BEASTInterface) {
-                    BEASTInterface plugin = ((BEASTInterface) input.get());
-                    for (Input<?> input2 : plugin.listInputs()) {
+                    BEASTInterface beastObject = ((BEASTInterface) input.get());
+                    for (Input<?> input2 : beastObject.listInputs()) {
                         try {
                             input2.validate();
                         } catch (Exception e) {
-                            throw new Exception(((BEASTInterface) input.get()).getID() + "</p><p> " + e.getMessage());
+                            throw new IllegalArgumentException(((BEASTInterface) input.get()).getID() + "</p><p> " + e.getMessage());
                         }
                         validateRecursively(input2, done);
                     }
@@ -335,12 +353,12 @@ public class DoubleListInputEditor extends ListInputEditor {
                 if (input.get() instanceof List<?>) {
                     for (Object o : (List<?>) input.get()) {
                         if (o != null && o instanceof BEASTInterface) {
-                            BEASTInterface plugin = (BEASTInterface) o;
-                            for (Input<?> input2 : plugin.listInputs()) {
+                            BEASTInterface beastObject = (BEASTInterface) o;
+                            for (Input<?> input2 : beastObject.listInputs()) {
                                 try {
                                     input2.validate();
                                 } catch (Exception e) {
-                                    throw new Exception(((BEASTInterface) o).getID() + " " + e.getMessage());
+                                    throw new IllegalArgumentException(((BEASTInterface) o).getID() + " " + e.getMessage());
                                 }
                                 validateRecursively(input2, done);
                             }
@@ -356,7 +374,8 @@ public class DoubleListInputEditor extends ListInputEditor {
         }
 
 
-        public void refreshPanel() {
+        @Override
+		public void refreshPanel() {
             Component c = this;
             while (c.getParent() != null) {
                 c = c.getParent();
@@ -369,20 +388,22 @@ public class DoubleListInputEditor extends ListInputEditor {
         /**
          * synchronise values in panel with current network *
          */
-        protected void sync() {
+        @Override
+		protected void sync() {
             Component c = this;
             while (c.getParent() != null) {
                 c = c.getParent();
                 if (c instanceof BeautiPanel) {
                     BeautiPanel panel = (BeautiPanel) c;
                     BeautiPanelConfig cfgPanel = panel.config;
-                    cfgPanel.sync(panel.iPartition);
+                    cfgPanel.sync(panel.partitionIndex);
                 }
             }
         }
 
         // we should leave it to the component to set its own border
-        @Deprecated
+        @Override
+		@Deprecated
         public void setBorder(Border border) {
     		super.setBorder(border);
         }
@@ -393,13 +414,15 @@ public class DoubleListInputEditor extends ListInputEditor {
         }
 
         // what is this method for? We should leave repainting to the standard mechanism
-        @Deprecated
+        @Override
+		@Deprecated
     	public void repaint() {
     	this.repaint(0);
     		super.repaint();
     	}
 
-    	public Component getComponent() {
+    	@Override
+		public Component getComponent() {
     		return this;
     	}
 
diff --git a/src/beast/app/draw/EnumInputEditor.java b/src/beast/app/draw/EnumInputEditor.java
index 080ee73..73869d3 100644
--- a/src/beast/app/draw/EnumInputEditor.java
+++ b/src/beast/app/draw/EnumInputEditor.java
@@ -1,7 +1,5 @@
 package beast.app.draw;
 
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -9,9 +7,8 @@ import javax.swing.Box;
 import javax.swing.JComboBox;
 
 import beast.app.beauti.BeautiDoc;
-import beast.core.Input;
-import beast.core.BEASTObject;
 import beast.core.BEASTInterface;
+import beast.core.Input;
 
 
 
@@ -25,7 +22,7 @@ public class EnumInputEditor extends InputEditor.Base {
     //public EnumInputEditor() {}
 
 	private static final long serialVersionUID = 1L;
-    JComboBox m_selectPluginBox;
+    JComboBox<String> m_selectPluginBox;
 
     @Override
     public Class<?> type() {
@@ -38,34 +35,31 @@ public class EnumInputEditor extends InputEditor.Base {
      * o a combo box for selecting another value in the enumeration
      */
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-        m_bAddButtons = bAddButtons;
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+        m_bAddButtons = addButtons;
         m_input = input;
-        m_plugin = plugin;
+        m_beastObject = beastObject;
 		this.itemNr = itemNr;
 
         addInputLabel();
-        List<String> sAvailableValues = new ArrayList<String>();
+        List<String> availableValues = new ArrayList<>();
         for (int i = 0; i < input.possibleValues.length; i++) {
-            sAvailableValues.add(input.possibleValues[i].toString());
+            availableValues.add(input.possibleValues[i].toString());
         }
-        if (sAvailableValues.size() > 1) {
-            m_selectPluginBox = new JComboBox(sAvailableValues.toArray(new String[0]));
-            String sSelectString = input.get().toString();
-            m_selectPluginBox.setSelectedItem(sSelectString);
+        if (availableValues.size() > 1) {
+            m_selectPluginBox = new JComboBox<>(availableValues.toArray(new String[0]));
+            String selectString = input.get().toString();
+            m_selectPluginBox.setSelectedItem(selectString);
 
-            m_selectPluginBox.addActionListener(new ActionListener() {
-                // implements ActionListener
-                public void actionPerformed(ActionEvent e) {
-                    String sSelected = (String) m_selectPluginBox.getSelectedItem();
+            m_selectPluginBox.addActionListener(e -> {
+                    String selected = (String) m_selectPluginBox.getSelectedItem();
                     try {
-                    	setValue(sSelected);
-                        //lm_input.setValue(sSelected, m_plugin);
+                    	setValue(selected);
+                        //lm_input.setValue(selected, m_beastObject);
                     } catch (Exception e1) {
                         e1.printStackTrace();
                     }
-                }
-            });
+                });
             m_selectPluginBox.setToolTipText(input.getHTMLTipText());
             add(m_selectPluginBox);
             add(Box.createGlue());
diff --git a/src/beast/app/draw/ExtensionFileFilter.java b/src/beast/app/draw/ExtensionFileFilter.java
index 54e9c90..f88be05 100644
--- a/src/beast/app/draw/ExtensionFileFilter.java
+++ b/src/beast/app/draw/ExtensionFileFilter.java
@@ -46,7 +46,8 @@ public class ExtensionFileFilter extends FileFilter implements FilenameFilter {
      *
      * @return the description.
      */
-    public String getDescription() {
+    @Override
+	public String getDescription() {
 
         return m_Description;
     }
@@ -57,7 +58,7 @@ public class ExtensionFileFilter extends FileFilter implements FilenameFilter {
      * @return the accepted extensions
      */
     public String[] getExtensions() {
-        return (String[]) m_Extension.clone();
+        return m_Extension.clone();
     }
 
     /**
@@ -67,7 +68,8 @@ public class ExtensionFileFilter extends FileFilter implements FilenameFilter {
      * @param file the file of interest.
      * @return true if the file is accepted by the filter.
      */
-    public boolean accept(File file) {
+    @Override
+	public boolean accept(File file) {
 
         String name = file.getName().toLowerCase();
         if (file.isDirectory()) {
@@ -89,7 +91,8 @@ public class ExtensionFileFilter extends FileFilter implements FilenameFilter {
      * @param name the name of the file.
      * @return true if the file is accepted.
      */
-    public boolean accept(File dir, String name) {
+    @Override
+	public boolean accept(File dir, String name) {
         return accept(new File(dir, name));
     }
 }
diff --git a/src/beast/app/draw/HelpBrowser.java b/src/beast/app/draw/HelpBrowser.java
index b522144..586d32e 100644
--- a/src/beast/app/draw/HelpBrowser.java
+++ b/src/beast/app/draw/HelpBrowser.java
@@ -25,8 +25,6 @@
 
 package beast.app.draw;
 
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -39,12 +37,13 @@ import javax.swing.event.HyperlinkEvent;
 import javax.swing.event.HyperlinkListener;
 
 import beast.app.DocMaker;
+import beast.core.util.Log;
 
 
 
 /**
  * Dialog for showing HTML help, with hyperlinks and some browser
- * functionality to navigate around the Plugin help facilities.
+ * functionality to navigate around the BEASTObject help facilities.
  */
 public class HelpBrowser extends JDialog implements HyperlinkListener {
     /**
@@ -58,7 +57,7 @@ public class HelpBrowser extends JDialog implements HyperlinkListener {
     /**
      * browser stack *
      */
-    List<String> m_sPlugins = new ArrayList<String>();
+    List<String> m_sPlugins = new ArrayList<>();
     int m_iCurrentPlugin = 0;
 
     /**
@@ -69,7 +68,7 @@ public class HelpBrowser extends JDialog implements HyperlinkListener {
     JButton m_backwardButton;
 
 
-    public HelpBrowser(String sPlugin) {
+    public HelpBrowser(String beastObjectName) {
         if (m_docMaker == null) {
             m_docMaker = new DocMaker();
         }
@@ -88,31 +87,22 @@ public class HelpBrowser extends JDialog implements HyperlinkListener {
         buttonBox.setAlignmentX(LEFT_ALIGNMENT);
         m_forwardButton = new JButton(">");
         m_forwardButton.setToolTipText("Browse forward");
-        m_forwardButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        m_forwardButton.addActionListener(e -> {
                 browseForward();
-            }
-        });
+            });
 
         m_backwardButton = new JButton("<");
         m_backwardButton.setToolTipText("Browse backward");
-        m_backwardButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        m_backwardButton.addActionListener(e -> {
                 browseBackward();
-            }
-        });
+            });
 
 
         JButton closeButton = new JButton("x");
         closeButton.setToolTipText("Close Help");
-        closeButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        closeButton.addActionListener(e -> {
                 dispose();
-            }
-        });
+            });
 //		m_backwardButton.setMnemonic(KeyEvent.VK_RIGHT);
 //		m_forwardButton.setMnemonic(KeyEvent.VK_LEFT);
 
@@ -125,7 +115,7 @@ public class HelpBrowser extends JDialog implements HyperlinkListener {
         box.add(scroller);
 
 
-        m_sPlugins.add(sPlugin);
+        m_sPlugins.add(beastObjectName);
         updateState();
         this.add(box);
     } // c'tor
@@ -149,19 +139,19 @@ public class HelpBrowser extends JDialog implements HyperlinkListener {
         try {
             HyperlinkEvent.EventType type = link.getEventType();
             if (type == HyperlinkEvent.EventType.ACTIVATED) {
-                String sPlugin = link.getDescription();
-                sPlugin = sPlugin.replaceAll(".html", "");
+                String beastObjectName = link.getDescription();
+                beastObjectName = beastObjectName.replaceAll(".html", "");
                 // update browser stack
                 m_iCurrentPlugin++;
                 while (m_iCurrentPlugin < m_sPlugins.size()) {
                     m_sPlugins.remove(m_iCurrentPlugin);
                 }
-                m_sPlugins.add(sPlugin);
+                m_sPlugins.add(beastObjectName);
                 updateState();
             }
         } catch (Exception e) {
             // ignore
-            System.err.println(e.getMessage());
+            Log.err.println(e.getMessage());
         }
     } // hyperlinkUpdate
 
@@ -170,13 +160,13 @@ public class HelpBrowser extends JDialog implements HyperlinkListener {
      * change html text and enable/disable buttons (where appropriate) *
      */
     void updateState() {
-        String sPlugin = m_sPlugins.get(m_iCurrentPlugin);
+        String beastObjectName = m_sPlugins.get(m_iCurrentPlugin);
         try {
-            String sHTML = m_docMaker.getHTML(sPlugin, false);
-            m_editorPane.setText(sHTML);
+            String hTML = m_docMaker.getHTML(beastObjectName, false);
+            m_editorPane.setText(hTML);
         } catch (Exception e) {
             // ignore
-            System.err.println("HelpBrowser: Something is wrong: " + e.getClass().getName() + " " + e.getMessage());
+            Log.err.println("HelpBrowser: Something is wrong: " + e.getClass().getName() + " " + e.getMessage());
         }
         m_backwardButton.setEnabled(m_iCurrentPlugin > 0);
         m_forwardButton.setEnabled(m_iCurrentPlugin < m_sPlugins.size() - 1);
diff --git a/src/beast/app/draw/InputEditor.java b/src/beast/app/draw/InputEditor.java
index f05b4ee..1c255d0 100644
--- a/src/beast/app/draw/InputEditor.java
+++ b/src/beast/app/draw/InputEditor.java
@@ -14,6 +14,7 @@ import javax.swing.BoxLayout;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 import javax.swing.JTextField;
+import javax.swing.SwingConstants;
 import javax.swing.border.Border;
 import javax.swing.event.DocumentEvent;
 import javax.swing.event.DocumentListener;
@@ -22,18 +23,19 @@ import javax.swing.event.ListSelectionListener;
 import beast.app.beauti.BeautiDoc;
 import beast.app.beauti.BeautiPanel;
 import beast.app.beauti.BeautiPanelConfig;
-import beast.core.Input;
 import beast.core.BEASTInterface;
+import beast.core.Input;
+import beast.core.util.Log;
 
 /**
- * Base class for editors that provide a GUI for manipulating an Input for a Plugin.
+ * Base class for editors that provide a GUI for manipulating an Input for a BEASTObject.
  * The idea is that for every type of Input there will be a dedicated editor, e.g.
  * for a String Input, there will be an edit field, for a Boolean Input, there will
  * be a checkbox in the editor.
  * <p/>
  * The default just provides an edit field and uses toString() on Input to get its value.
  * To change the behaviour, override
- * public void init(Input<?> input, Plugin plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons)
+ * public void init(Input<?> input, BEASTObject beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons)
  */
 /** note that it is assumed that any InputEditor is a java.awt.Component **/
 public interface InputEditor {
@@ -50,20 +52,20 @@ public interface InputEditor {
         HAS_INVALIDMEMBERS
     }
 
-    /** type of Plugin to which this editor can be used **/ 
+    /** type of BEASTObject to which this editor can be used **/ 
     Class<?> type();
 
-    /** list of types of Plugins to which this editor can be used **/ 
+    /** list of types of BEASTObjects to which this editor can be used **/ 
     Class<?>[] types();
 
     /** initialise InputEditor
      * @param input to be edited
-     * @param plugin parent plugin containing the input
+     * @param beastObject parent beastObject containing the input
      * @param itemNr if the input is a list, itemNr indicates which item to edit in the list
-     * @param bExpandOption start state of input editor
-     * @param bAddButtons button status of input editor
+     * @param isExpandOption start state of input editor
+     * @param addButtons button status of input editor
      */
-    void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons);
+    void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons);
 
     /** set document with the model containing the input **/
     void setDoc(BeautiDoc doc);
@@ -71,8 +73,8 @@ public interface InputEditor {
     /**
      * set decoration. This method is deprecated, because decoration can be handled by the JComponent with setBorder method on
      **/
-    @Deprecated
-    void setBorder(Border border);
+    //@Deprecated
+    //void setBorder(Border border);
 
     /** prepare to validate input **/
     void startValidating(ValidationStatus state);
@@ -83,7 +85,7 @@ public interface InputEditor {
     /** add input editor to listen for changes **/
     void addValidationListener(InputEditor validateListener);
     
-    /** propagate status of predecessor inputs through list of plugins **/
+    /** propagate status of predecessor inputs through list of beastObjects **/
     void notifyValidationListeners(ValidationStatus state);
     
     Component getComponent();
@@ -98,9 +100,9 @@ public abstract class Base extends JPanel implements InputEditor {
     protected Input<?> m_input;
 
     /**
-     * parent plugin *
+     * parent beastObject *
      */
-    protected BEASTInterface m_plugin;
+    protected BEASTInterface m_beastObject;
 
     /**
      * text field used for primitive input editors *
@@ -137,14 +139,16 @@ public abstract class Base extends JPanel implements InputEditor {
      */
     List<InputEditor> m_validateListeners;
 
-    public void addValidationListener(InputEditor validateListener) {
+    @Override
+	public void addValidationListener(InputEditor validateListener) {
         if (m_validateListeners == null) {
-            m_validateListeners = new ArrayList<InputEditor>();
+            m_validateListeners = new ArrayList<>();
         }
         m_validateListeners.add(validateListener);
     }
 
-    public void notifyValidationListeners(ValidationStatus state) {
+    @Override
+	public void notifyValidationListeners(ValidationStatus state) {
         if (m_validateListeners != null) {
             for (InputEditor listener : m_validateListeners) {
                 listener.startValidating(state);
@@ -182,9 +186,11 @@ public abstract class Base extends JPanel implements InputEditor {
      * Either implement type() or types() if multiple
      * types are supported *
      */
-    abstract public Class<?> type();
+    @Override
+	abstract public Class<?> type();
 
-    public Class<?>[] types() {
+    @Override
+	public Class<?>[] types() {
         Class<?>[] types = new Class<?>[1];
         types[0] = type();
         return types;
@@ -193,10 +199,11 @@ public abstract class Base extends JPanel implements InputEditor {
     /**
      * construct an editor consisting of a label and input entry *
      */
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-        m_bAddButtons = bAddButtons;
+    @Override
+	public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+        m_bAddButtons = addButtons;
         m_input = input;
-        m_plugin = plugin;
+        m_beastObject = beastObject;
         this.itemNr= itemNr;
         
         addInputLabel();
@@ -245,20 +252,20 @@ public abstract class Base extends JPanel implements InputEditor {
     }
 
     @SuppressWarnings({ "unchecked", "rawtypes" })
-	protected void setValue(Object o) throws Exception {
+	protected void setValue(Object o) {
     	if (itemNr < 0) {
-    		m_input.setValue(o, m_plugin);
+    		m_input.setValue(o, m_beastObject);
     	} else {
     		// set value of an item in a list
     		List list = (List) m_input.get();
     		Object other = list.get(itemNr);
     		if (other != o) {
     			if (other instanceof BEASTInterface) {
-    				BEASTInterface.getOutputs(other).remove(m_plugin);
+    				BEASTInterface.getOutputs(other).remove(m_beastObject);
     			}
     			list.set(itemNr, o);
     			if (o instanceof BEASTInterface) {
-    				BEASTInterface.getOutputs(o).add(m_plugin);
+    				BEASTInterface.getOutputs(o).add(m_beastObject);
     			}
     		}
     	}
@@ -284,26 +291,26 @@ public abstract class Base extends JPanel implements InputEditor {
 
     protected void addInputLabel() {
         if (m_bAddButtons) {
-            String sName = formatName(m_input.getName());
-            addInputLabel(sName, m_input.getHTMLTipText());
+            String name = formatName(m_input.getName());
+            addInputLabel(name, m_input.getHTMLTipText());
         }
     }
 
-    protected String formatName(String sName) {
-	    if (doc.beautiConfig.inputLabelMap.containsKey(m_plugin.getClass().getName() + "." + sName)) {
-	        sName = doc.beautiConfig.inputLabelMap.get(m_plugin.getClass().getName() + "." + sName);
+    protected String formatName(String name) {
+	    if (doc.beautiConfig.inputLabelMap.containsKey(m_beastObject.getClass().getName() + "." + name)) {
+	        name = doc.beautiConfig.inputLabelMap.get(m_beastObject.getClass().getName() + "." + name);
 	    } else {
-	        sName = sName.replaceAll("([a-z])([A-Z])", "$1 $2");
-	        sName = sName.substring(0, 1).toUpperCase() + sName.substring(1);
+	        name = name.replaceAll("([a-z])([A-Z])", "$1 $2");
+	        name = name.substring(0, 1).toUpperCase() + name.substring(1);
 	    }
-	    return sName;
+	    return name;
     }
 
-    protected void addInputLabel(String sLabel, String sTipText) {
+    protected void addInputLabel(String label, String tipText) {
         if (m_bAddButtons) {
-            m_inputLabel = new JLabel(sLabel);
-            m_inputLabel.setToolTipText(sTipText);
-            m_inputLabel.setHorizontalTextPosition(JLabel.RIGHT);
+            m_inputLabel = new JLabel(label);
+            m_inputLabel.setToolTipText(tipText);
+            m_inputLabel.setHorizontalTextPosition(SwingConstants.RIGHT);
             //Dimension size = new Dimension(g_nLabelWidth, 20);
             Dimension size = new Dimension(200, 20);
             m_inputLabel.setMaximumSize(size);
@@ -315,10 +322,6 @@ public abstract class Base extends JPanel implements InputEditor {
 //            m_inputLabel.setBorder(BorderFactory.createLineBorder(Color.RED, 2));
             // RRB: temporary
             //m_inputLabel.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
-            if (sLabel.equals("Subst Model")) {
-            	int h = 3;
-            	h++;
-            }
             add(m_inputLabel);
         }
     }
@@ -343,12 +346,12 @@ public abstract class Base extends JPanel implements InputEditor {
     public void validateInput() {
         try {
             m_input.validate();
-            if (m_entry != null && !m_input.canSetValue(m_entry.getText(), m_plugin)) {
-                throw new Exception("invalid value");
+            if (m_entry != null && !m_input.canSetValue(m_entry.getText(), m_beastObject)) {
+                throw new IllegalArgumentException("invalid value");
             }
             // recurse
             try {
-                validateRecursively(m_input, new HashSet<Input<?>>());
+                validateRecursively(m_input, new HashSet<>());
             } catch (Exception e) {
                 notifyValidationListeners(ValidationStatus.HAS_INVALIDMEMBERS);
                 if (m_validateLabel != null) {
@@ -364,7 +367,7 @@ public abstract class Base extends JPanel implements InputEditor {
             }
             notifyValidationListeners(ValidationStatus.IS_VALID);
         } catch (Exception e) {
-            System.err.println("Validation message: " + e.getMessage());
+            Log.err.println("Validation message: " + e.getMessage());
             if (m_validateLabel != null) {
                 m_validateLabel.setToolTipText(e.getMessage());
                 m_validateLabel.m_circleColor = Color.red;
@@ -375,9 +378,9 @@ public abstract class Base extends JPanel implements InputEditor {
         repaint();
     }
 
-    /* Recurse in any of the input plugins
+    /* Recurse in any of the input beastObjects
       * and validate its inputs */
-    void validateRecursively(Input<?> input, Set<Input<?>> done) throws Exception {
+    void validateRecursively(Input<?> input, Set<Input<?>> done) {
         if (done.contains(input)) {
             // this prevent cycles to lock up validation
             return;
@@ -386,12 +389,12 @@ public abstract class Base extends JPanel implements InputEditor {
         }
         if (input.get() != null) {
             if (input.get() instanceof BEASTInterface) {
-                BEASTInterface plugin = ((BEASTInterface) input.get());
-                for (Input<?> input2 : plugin.listInputs()) {
+                BEASTInterface beastObject = ((BEASTInterface) input.get());
+                for (Input<?> input2 : beastObject.listInputs()) {
                     try {
                         input2.validate();
                     } catch (Exception e) {
-                        throw new Exception(((BEASTInterface) input.get()).getID() + "</p><p> " + e.getMessage());
+                        throw new IllegalArgumentException(((BEASTInterface) input.get()).getID() + "</p><p> " + e.getMessage());
                     }
                     validateRecursively(input2, done);
                 }
@@ -399,12 +402,12 @@ public abstract class Base extends JPanel implements InputEditor {
             if (input.get() instanceof List<?>) {
                 for (Object o : (List<?>) input.get()) {
                     if (o != null && o instanceof BEASTInterface) {
-                        BEASTInterface plugin = (BEASTInterface) o;
-                        for (Input<?> input2 : plugin.listInputs()) {
+                        BEASTInterface beastObject = (BEASTInterface) o;
+                        for (Input<?> input2 : beastObject.listInputs()) {
                             try {
                                 input2.validate();
                             } catch (Exception e) {
-                                throw new Exception(((BEASTInterface) o).getID() + " " + e.getMessage());
+                                throw new IllegalArgumentException(((BEASTInterface) o).getID() + " " + e.getMessage());
                             }
                             validateRecursively(input2, done);
                         }
@@ -440,13 +443,14 @@ public abstract class Base extends JPanel implements InputEditor {
             if (c instanceof BeautiPanel) {
                 BeautiPanel panel = (BeautiPanel) c;
                 BeautiPanelConfig cfgPanel = panel.config;
-                cfgPanel.sync(panel.iPartition);
+                cfgPanel.sync(panel.partitionIndex);
             }
         }
     }
 
     // we should leave it to the component to set its own border
-    @Deprecated
+    @Override
+	@Deprecated
     public void setBorder(Border border) {
 		super.setBorder(border);
     }
@@ -457,12 +461,18 @@ public abstract class Base extends JPanel implements InputEditor {
     }
 
     // what is this method for? We should leave repainting to the standard mechanism
-    @Deprecated
+    // RRB: Did not always work in the past. The following should suffice (though perhaps
+    // slightly less efficient to also revalidate, but have not noticed any difference)
+	@Override
 	public void repaint() {
-	this.repaint(0);
+		// tell Swing that an area of the window is dirty
 		super.repaint();
+		
+		// tell the layout manager to recalculate the layout
+		super.revalidate();
 	}
 
+	@Override
 	public Component getComponent() {
 		return this;
 	}
diff --git a/src/beast/app/draw/InputEditorFactory.java b/src/beast/app/draw/InputEditorFactory.java
index 15fd3a1..711ea6c 100644
--- a/src/beast/app/draw/InputEditorFactory.java
+++ b/src/beast/app/draw/InputEditorFactory.java
@@ -2,6 +2,7 @@ package beast.app.draw;
 
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -9,6 +10,7 @@ import java.util.List;
 
 import javax.swing.BorderFactory;
 import javax.swing.Box;
+import javax.swing.JComponent;
 import javax.swing.JOptionPane;
 
 import beast.app.beauti.BeautiConfig;
@@ -16,17 +18,15 @@ import beast.app.beauti.BeautiDoc;
 import beast.app.beauti.BeautiSubTemplate;
 import beast.app.draw.InputEditor.ButtonStatus;
 import beast.app.draw.InputEditor.ExpandOption;
-import beast.core.Input;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 import beast.core.BEASTInterface;
+import beast.core.Input;
 import beast.core.Input.Validate;
 import beast.core.util.Log;
 import beast.util.AddOnManager;
 
 
 
-/** Can create InputEditors for inputs of Plugins 
+/** Can create InputEditors for inputs of BEASTObjects 
  * and there are some associated utility methods **/
 public class InputEditorFactory {
     /**
@@ -43,26 +43,26 @@ public class InputEditorFactory {
 
     public void init() {
         // register input editors
-        inputEditorMap = new HashMap<Class<?>, String>();
-        listInputEditorMap = new HashMap<Class<?>, String>();
+        inputEditorMap = new HashMap<>();
+        listInputEditorMap = new HashMap<>();
 
-//        String [] sKnownEditors = new String [] {"beast.app.draw.DataInputEditor","beast.app.beauti.AlignmentListInputEditor", "beast.app.beauti.FrequenciesInputEditor", "beast.app.beauti.OperatorListInputEditor", "beast.app.beauti.ParametricDistributionInputEditor", "beast.app.beauti.PriorListInputEditor", "beast.app.beauti.SiteModelInputEditor", "beast.app.beauti.TaxonSetInputEditor", "beast.app.beauti.TipDatesInputEditor", "beast.app.draw.BooleanInputEditor", "beast.app.draw.DoubleI [...]
+//        String [] knownEditors = new String [] {"beast.app.draw.DataInputEditor","beast.app.beauti.AlignmentListInputEditor", "beast.app.beauti.FrequenciesInputEditor", "beast.app.beauti.OperatorListInputEditor", "beast.app.beauti.ParametricDistributionInputEditor", "beast.app.beauti.PriorListInputEditor", "beast.app.beauti.SiteModelInputEditor", "beast.app.beauti.TaxonSetInputEditor", "beast.app.beauti.TipDatesInputEditor", "beast.app.draw.BooleanInputEditor", "beast.app.draw.DoubleIn [...]
 //        		"beast.app.draw.ParameterInputEditor", "beast.app.draw.PluginInputEditor", "beast.app.draw.StringInputEditor"};
-//        registerInputEditors(sKnownEditors);
+//        registerInputEditors(knownEditors);
         String[] PACKAGE_DIRS = {"beast.app",};
-        for (String sPackage : PACKAGE_DIRS) {
-            List<String> sInputEditors = AddOnManager.find("beast.app.draw.InputEditor", sPackage);
-            registerInputEditors(sInputEditors.toArray(new String[0]));
+        for (String packageName : PACKAGE_DIRS) {
+            List<String> inputEditors = AddOnManager.find("beast.app.draw.InputEditor", packageName);
+            registerInputEditors(inputEditors.toArray(new String[0]));
         }
     }
 
-    private void registerInputEditors(String[] sInputEditors) {
+    private void registerInputEditors(String[] inputEditors) {
     	//BeautiDoc doc = new BeautiDoc();
-        for (String sInputEditor : sInputEditors) {
+        for (String inputEditor : inputEditors) {
         	// ignore inner classes, which are marked with $
-        	if (!sInputEditor.contains("$")) {
+        	if (!inputEditor.contains("$")) {
 	            try {
-	                Class<?> _class = Class.forName(sInputEditor);
+	                Class<?> _class = Class.forName(inputEditor);
 	                
 	                
 	                Constructor<?> con = _class.getConstructor(BeautiDoc.class);
@@ -71,40 +71,40 @@ public class InputEditorFactory {
 	                //InputEditor editor = (InputEditor) _class.newInstance();
 	                Class<?>[] types = editor.types();
 	                for (Class<?> type : types) {
-	                    inputEditorMap.put(type, sInputEditor);
+	                    inputEditorMap.put(type, inputEditor);
 	                    if (editor instanceof ListInputEditor) {
 	                        Class<?> baseType = ((ListInputEditor) editor).baseType();
-	                        listInputEditorMap.put(baseType, sInputEditor);
+	                        listInputEditorMap.put(baseType, inputEditor);
 	                    }
 	                }
 	            } catch (java.lang.InstantiationException e) {
 	                // ingore input editors that are inner classes
 	            } catch (Exception e) {
 	                // print message
-	                System.err.println(e.getClass().getName() + ": " + e.getMessage());
+	                Log.err.println(e.getClass().getName() + ": " + e.getMessage());
 	            }
         	}
         }
     }
 
     /**
-     * add all inputs of a plugin to a box *
+     * add all inputs of a beastObject to a box *
      */
-    public List<InputEditor> addInputs(Box box, BEASTInterface plugin, InputEditor editor, InputEditor validateListener, BeautiDoc doc) {
+    public List<InputEditor> addInputs(Box box, BEASTInterface beastObject, InputEditor editor, InputEditor validateListener, BeautiDoc doc) {
         /* add individual inputs **/
         List<Input<?>> inputs = null;
-        List<InputEditor> editors = new ArrayList<InputEditor>();
+        List<InputEditor> editors = new ArrayList<>();
     	
         try {
-            inputs = plugin.listInputs();
+            inputs = beastObject.listInputs();
         } catch (Exception e) {
             // TODO: handle exception
         }
         for (Input<?> input : inputs) {
             try {
-                String sFullInputName = plugin.getClass().getName() + "." + input.getName();
-                if (!doc.beautiConfig.suppressPlugins.contains(sFullInputName)) {
-                    InputEditor inputEditor = createInputEditor(input, plugin, true, ExpandOption.FALSE, ButtonStatus.ALL, editor, doc);
+                String fullInputName = beastObject.getClass().getName() + "." + input.getName();
+                if (!doc.beautiConfig.suppressBEASTObjects.contains(fullInputName)) {
+                    InputEditor inputEditor = createInputEditor(input, beastObject, true, ExpandOption.FALSE, ButtonStatus.ALL, editor, doc);
                     box.add(inputEditor.getComponent());
                     box.add(Box.createVerticalStrut(5));
                     //box.add(Box.createVerticalGlue());
@@ -115,7 +115,7 @@ public class InputEditorFactory {
                 }
             } catch (Exception e) {
                 // ignore
-                System.err.println(e.getClass().getName() + ": " + e.getMessage() + "\n" +
+                Log.err.println(e.getClass().getName() + ": " + e.getMessage() + "\n" +
                         "input " + input.getName() + " could not be added.");
                 e.printStackTrace();
                 JOptionPane.showMessageDialog(null, "Could not add entry for " + input.getName());
@@ -126,21 +126,21 @@ public class InputEditorFactory {
     } // addInputs
 
 
-    public InputEditor createInputEditor(Input<?> input, BEASTInterface plugin, BeautiDoc doc) throws Exception {
-        return createInputEditor(input, plugin, true, InputEditor.ExpandOption.FALSE, ButtonStatus.ALL, null, doc);
+    public InputEditor createInputEditor(Input<?> input, BEASTInterface beastObject, BeautiDoc doc) throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+        return createInputEditor(input, beastObject, true, InputEditor.ExpandOption.FALSE, ButtonStatus.ALL, null, doc);
     }
 
-    public InputEditor createInputEditor(Input<?> input, BEASTInterface plugin, boolean bAddButtons,
-                                                ExpandOption bForceExpansion, ButtonStatus buttonStatus,
-                                                InputEditor editor, BeautiDoc doc) throws Exception {
-    	return createInputEditor(input, -1, plugin, bAddButtons, bForceExpansion, buttonStatus, editor, doc);
+    public InputEditor createInputEditor(Input<?> input, BEASTInterface beastObject, boolean addButtons,
+                                                ExpandOption forceExpansion, ButtonStatus buttonStatus,
+                                                InputEditor editor, BeautiDoc doc) throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+    	return createInputEditor(input, -1, beastObject, addButtons, forceExpansion, buttonStatus, editor, doc);
     }
     
-    public InputEditor createInputEditor(Input<?> input, int listItemNr, BEASTInterface plugin, boolean bAddButtons,
-                ExpandOption bForceExpansion, ButtonStatus buttonStatus,
-                InputEditor editor, BeautiDoc doc) throws Exception {
+    public InputEditor createInputEditor(Input<?> input, int listItemNr, BEASTInterface beastObject, boolean addButtons,
+                ExpandOption forceExpansion, ButtonStatus buttonStatus,
+                InputEditor editor, BeautiDoc doc) throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         if (input.getType() == null) {
-            input.determineClass(plugin);
+            input.determineClass(beastObject);
         }
         //Class<?> inputClass = input.get() != null ? input.get().getClass(): input.getType();
         Class<?> inputClass = input.getType();
@@ -152,7 +152,7 @@ public class InputEditorFactory {
         } else {
         	if (input.get() != null && !input.get().getClass().equals(inputClass)
         			&& !(input.get() instanceof ArrayList)) {
-        		System.err.println(input.get().getClass() + " != " + inputClass);
+        		Log.err.println(input.get().getClass() + " != " + inputClass);
         		inputClass = input.get().getClass();
         	}
         }
@@ -163,11 +163,11 @@ public class InputEditorFactory {
         // check whether the super.editor has a custom method for creating an Editor
         if (editor != null) {        	
             try {
-                String sName = input.getName();
-                sName = new String(sName.charAt(0) + "").toUpperCase() + sName.substring(1);
-                sName = "create" + sName + "Editor";
+                String name = input.getName();
+                name = new String(name.charAt(0) + "").toUpperCase() + name.substring(1);
+                name = "create" + name + "Editor";
                 Class<?> _class = editor.getClass();
-                Method method = _class.getMethod(sName);
+                Method method = _class.getMethod(name);
                 inputEditor = (InputEditor) method.invoke(editor);
                 //Log.trace.println(inputEditor.getClass().getName() + " (CUSTOM EDITOR)");
                 return inputEditor;
@@ -180,11 +180,11 @@ public class InputEditorFactory {
             // handle list inputs
             if (listInputEditorMap.containsKey(inputClass)) {
                 // use custom list input editor
-                String sInputEditor = listInputEditorMap.get(inputClass);
-                Constructor<?> con = Class.forName(sInputEditor).getConstructor(BeautiDoc.class);
+                String inputEditorName = listInputEditorMap.get(inputClass);
+                Constructor<?> con = Class.forName(inputEditorName).getConstructor(BeautiDoc.class);
                 inputEditor = (InputEditor) con.newInstance(doc);
 
-                //inputEditor = (InputEditor) Class.forName(sInputEditor).newInstance();
+                //inputEditor = (InputEditor) Class.forName(inputEditor).newInstance();
             } else {
                 // otherwise, use generic list editor
                 inputEditor = new ListInputEditor(doc);
@@ -201,50 +201,50 @@ public class InputEditorFactory {
         	if (inputClass2 == null) {
         		inputEditor = new BEASTObjectInputEditor(doc);
         	} else {
-	            // handle Plugin-input with custom input editors
-	            String sInputEditor = inputEditorMap.get(inputClass2);
+	            // handle BEASTObject-input with custom input editors
+	            String inputEditorName = inputEditorMap.get(inputClass2);
 	            
-	            Constructor<?> con = Class.forName(sInputEditor).getConstructor(BeautiDoc.class);
+	            Constructor<?> con = Class.forName(inputEditorName).getConstructor(BeautiDoc.class);
 	            inputEditor = (InputEditor) con.newInstance(doc);
         	}
         }        	
 //    	} else if (inputEditorMap.containsKey(inputClass)) {
-//            // handle Plugin-input with custom input editors
-//            String sInputEditor = inputEditorMap.get(inputClass);
+//            // handle BEASTObject-input with custom input editors
+//            String inputEditor = inputEditorMap.get(inputClass);
 //            
-//            Constructor<?> con = Class.forName(sInputEditor).getConstructor(BeautiDoc.class);
+//            Constructor<?> con = Class.forName(inputEditor).getConstructor(BeautiDoc.class);
 //            inputEditor = (InputEditor) con.newInstance(doc);
-//            //inputEditor = (InputEditor) Class.forName(sInputEditor).newInstance(doc);
+//            //inputEditor = (InputEditor) Class.forName(inputEditor).newInstance(doc);
 //            //} else if (inputClass.isEnum()) {
 //            //    inputEditor = new EnumInputEditor();
 //        } else {
-//            // assume it is a general Plugin, so create a default Plugin input editor
+//            // assume it is a general BEASTObject, so create a default BEASTObject input editor
 //            inputEditor = new PluginInputEditor(doc);
 //        }
-        String sFullInputName = plugin.getClass().getName() + "." + input.getName();
-        //System.err.println(sFullInputName);
-        ExpandOption expandOption = bForceExpansion;
-        if (doc.beautiConfig.inlinePlugins.contains(sFullInputName) || bForceExpansion == ExpandOption.TRUE_START_COLLAPSED) {
+        String fullInputName = beastObject.getClass().getName() + "." + input.getName();
+        //System.err.println(fullInputName);
+        ExpandOption expandOption = forceExpansion;
+        if (doc.beautiConfig.inlineBEASTObject.contains(fullInputName) || forceExpansion == ExpandOption.TRUE_START_COLLAPSED) {
             expandOption = ExpandOption.TRUE;
-            // deal with initially collapsed plugins
-            if (doc.beautiConfig.collapsedPlugins.contains(sFullInputName) || bForceExpansion == ExpandOption.TRUE_START_COLLAPSED) {
+            // deal with initially collapsed beastObjects
+            if (doc.beautiConfig.collapsedBEASTObjects.contains(fullInputName) || forceExpansion == ExpandOption.TRUE_START_COLLAPSED) {
                 if (input.get() != null) {
                     Object o = input.get();
                     if (o instanceof ArrayList) {
                         for (Object o2 : (ArrayList<?>) o) {
                             if (o2 instanceof BEASTInterface) {
-                                String sID = ((BEASTInterface) o2).getID();
-                                if (!ListInputEditor.g_initiallyCollapsedIDs.contains(sID)) {
-                                    ListInputEditor.g_initiallyCollapsedIDs.add(sID);
-                                    ListInputEditor.g_collapsedIDs.add(sID);
+                                String id = ((BEASTInterface) o2).getID();
+                                if (!ListInputEditor.g_initiallyCollapsedIDs.contains(id)) {
+                                    ListInputEditor.g_initiallyCollapsedIDs.add(id);
+                                    ListInputEditor.g_collapsedIDs.add(id);
                                 }
                             }
                         }
                     } else if (o instanceof BEASTInterface) {
-                        String sID = ((BEASTInterface) o).getID();
-                        if (!ListInputEditor.g_initiallyCollapsedIDs.contains(sID)) {
-                            ListInputEditor.g_initiallyCollapsedIDs.add(sID);
-                            ListInputEditor.g_collapsedIDs.add(sID);
+                        String id = ((BEASTInterface) o).getID();
+                        if (!ListInputEditor.g_initiallyCollapsedIDs.contains(id)) {
+                            ListInputEditor.g_initiallyCollapsedIDs.add(id);
+                            ListInputEditor.g_collapsedIDs.add(id);
                         }
                     }
                 }
@@ -252,58 +252,58 @@ public class InputEditorFactory {
             }
         }
         inputEditor.setDoc(doc);
-        inputEditor.init(input, plugin, listItemNr, expandOption, bAddButtons);
-        inputEditor.setBorder(BorderFactory.createEmptyBorder());
+        inputEditor.init(input, beastObject, listItemNr, expandOption, addButtons);
+        ((JComponent) inputEditor).setBorder(BorderFactory.createEmptyBorder());
         inputEditor.getComponent().setVisible(true);
         //Log.trace.println(inputEditor.getClass().getName());
         return inputEditor;
     } // createInputEditor
 
     /**
-     * find plugins that could fit the input
+     * find beastObjects that could fit the input
      * @param input
-     * @param parent plugin containing the input
-     * @param sTabuList list of ids that are not allowed
+     * @param parent beastObject containing the input
+     * @param tabuList list of ids that are not allowed
      * @param doc
      * @return
      */
     
-    public List<String> getAvailablePlugins(Input<?> input, BEASTInterface parent, List<String> sTabuList, BeautiDoc doc) {
+    public List<String> getAvailablePlugins(Input<?> input, BEASTInterface parent, List<String> tabuList, BeautiDoc doc) {
 
-        //List<String> sPlugins = BeautiConfig.getInputCandidates(parent, input);
-        List<String> sPlugins = new ArrayList<String>();
-        if (sPlugins != null) {
-            return sPlugins;
+        //List<String> beastObjectNames = BeautiConfig.getInputCandidates(parent, input);
+        List<String> beastObjectNames = new ArrayList<>();
+        if (beastObjectNames != null) {
+            return beastObjectNames;
         }
 
 
         /* add ascendants to tabu list */
-        if (sTabuList == null) {
-            sTabuList = new ArrayList<String>();
+        if (tabuList == null) {
+            tabuList = new ArrayList<>();
         }
         if (!doc.isExpertMode()) {
-            for (BEASTInterface plugin : BEASTObjectPanel.listAscendants(parent, doc.pluginmap.values())) {
-                sTabuList.add(plugin.getID());
+            for (BEASTInterface beastObject : BEASTObjectPanel.listAscendants(parent, doc.pluginmap.values())) {
+                tabuList.add(beastObject.getID());
             }
         }
-        //System.err.println(sTabuList);
+        //System.err.println(tabuList);
 
-        /* collect all plugins in the system, that are not in the tabu list*/
-        sPlugins = new ArrayList<String>();
-        for (BEASTInterface plugin : doc.pluginmap.values()) {
-            if (input.getType().isAssignableFrom(plugin.getClass())) {
-                boolean bIsTabu = false;
-                if (sTabuList != null) {
-                    for (String sTabu : sTabuList) {
-                        if (sTabu.equals(plugin.getID())) {
-                            bIsTabu = true;
+        /* collect all beastObjects in the system, that are not in the tabu list*/
+        beastObjectNames = new ArrayList<>();
+        for (BEASTInterface beastObject : doc.pluginmap.values()) {
+            if (input.getType().isAssignableFrom(beastObject.getClass())) {
+                boolean isTabu = false;
+                if (tabuList != null) {
+                    for (String tabu : tabuList) {
+                        if (tabu.equals(beastObject.getID())) {
+                            isTabu = true;
                         }
                     }
                 }
-                if (!bIsTabu) {
+                if (!isTabu) {
                     try {
-                        if (input.canSetValue(plugin, parent)) {
-                            sPlugins.add(plugin.getID());
+                        if (input.canSetValue(beastObject, parent)) {
+                            beastObjectNames.add(beastObject.getID());
                         }
                     } catch (Exception e) {
                         // ignore
@@ -311,33 +311,33 @@ public class InputEditorFactory {
                 }
             }
         }
-        /* add all plugin-classes of type assignable to the input */
+        /* add all beastObject-classes of type assignable to the input */
         if (doc.isExpertMode()) {
-            List<String> sClasses = AddOnManager.find(input.getType(), "beast");
-            for (String sClass : sClasses) {
+            List<String> classes = AddOnManager.find(input.getType(), "beast");
+            for (String className : classes) {
                 try {
-                    Object o = Class.forName(sClass).newInstance();
+                    Object o = Class.forName(className).newInstance();
                     if (input.canSetValue(o, parent)) {
-                        sPlugins.add("new " + sClass);
+                        beastObjectNames.add("new " + className);
                     }
                 } catch (Exception e) {
                     // ignore
                 }
             }
         }
-        return sPlugins;
+        return beastObjectNames;
     } // getAvailablePlugins
 
     /**
      * finds beauti templates that can create subnets that fit an input
      * @param input
      * @param parent
-     * @param sTabuList
+     * @param tabuList
      * @param doc
      * @return
      */
 
-    public List<BeautiSubTemplate> getAvailableTemplates(Input<?> input, BEASTInterface parent, List<String> sTabuList, BeautiDoc doc) {
+    public List<BeautiSubTemplate> getAvailableTemplates(Input<?> input, BEASTInterface parent, List<String> tabuList, BeautiDoc doc) {
         Class<?> type = input.getType();
         List<BeautiSubTemplate> candidates = doc.beautiConfig.getInputCandidates(parent, input, type);
         if (input.getRule().equals(Validate.OPTIONAL)) {
diff --git a/src/beast/app/draw/InputShape.java b/src/beast/app/draw/InputShape.java
index 05271a2..8a0c339 100644
--- a/src/beast/app/draw/InputShape.java
+++ b/src/beast/app/draw/InputShape.java
@@ -35,9 +35,8 @@ import javax.swing.JPanel;
 
 import org.w3c.dom.Node;
 
-import beast.core.Input;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
+import beast.core.BEASTInterface;
+import beast.core.Input;
 
 
 
@@ -50,37 +49,37 @@ public class InputShape extends Shape {
         m_input = input;
     }
 
-    public InputShape(Node node, Document doc, boolean bReconstructPlugins) {
-        parse(node, doc, bReconstructPlugins);
+    public InputShape(Node node, Document doc, boolean reconstructBEASTObjects) {
+        parse(node, doc, reconstructBEASTObjects);
         //TODO: set inputName
     }
 
-    public BEASTObjectShape m_pluginShape = null;
+    public BEASTObjectShape m_beastObjectShape = null;
 
     BEASTObjectShape getPluginShape() {
-        return m_pluginShape;
+        return m_beastObjectShape;
     }
 
     void setPluginShape(BEASTObjectShape function) {
-        m_pluginShape = function;
+        m_beastObjectShape = function;
     }
 
-    BEASTInterface getPlugin() {
-        return m_pluginShape.m_plugin;
+    BEASTInterface getBEASTObject() {
+        return m_beastObjectShape.m_beastObject;
     }
 
-    String getInputName() throws Exception {
-        String sName = getLabel();
-        if (sName.indexOf('=') >= 0) {
-            sName = sName.substring(0, sName.indexOf('='));
+    String getInputName() {
+        String name = getLabel();
+        if (name.indexOf('=') >= 0) {
+            name = name.substring(0, name.indexOf('='));
         }
-        return sName;
+        return name;
     }
 
 
     @Override
     public void draw(Graphics2D g, JPanel panel) {
-        if (m_pluginShape == null || m_pluginShape.m_bNeedsDrawing) {
+        if (m_beastObjectShape == null || m_beastObjectShape.m_bNeedsDrawing) {
             if (m_bFilled) {
                 g.setColor(m_fillcolor);
                 g.fillOval(m_x, m_y, m_w, m_h);
@@ -91,16 +90,16 @@ public class InputShape extends Shape {
             g.setFont(g_InputFont);
             if (getLabel() != null) {
                 FontMetrics fm = g.getFontMetrics(g.getFont());
-                String sLabel = getLabel();
+                String label = getLabel();
                 int i = 0;
-                g.drawString(sLabel, m_x + m_w / 2 - fm.stringWidth(sLabel), m_y + m_h / 2 + i * fm.getHeight());
+                g.drawString(label, m_x + m_w / 2 - fm.stringWidth(label), m_y + m_h / 2 + i * fm.getHeight());
             }
         }
     }
 
     @Override
-    void parse(Node node, Document doc, boolean bReconstructPlugins) {
-        super.parse(node, doc, bReconstructPlugins);
+    void parse(Node node, Document doc, boolean reconstructBEASTObjects) {
+        super.parse(node, doc, reconstructBEASTObjects);
     }
 
     @Override
@@ -109,8 +108,8 @@ public class InputShape extends Shape {
     }
 
     @Override
-    boolean intersects(int nX, int nY) {
-        return (m_x + m_w / 2 - nX) * (m_x + m_w / 2 - nX) + (m_y + m_h / 2 - nY) * (m_y + m_h / 2 - nY) < m_w * m_w / 4 + m_h * m_h / 4;
+    boolean intersects(int x, int y) {
+        return (m_x + m_w / 2 - x) * (m_x + m_w / 2 - x) + (m_y + m_h / 2 - y) * (m_y + m_h / 2 - y) < m_w * m_w / 4 + m_h * m_h / 4;
     }
 
     @Override
@@ -118,17 +117,17 @@ public class InputShape extends Shape {
         if (m_input == null) {
             return "XXX";
         }
-        String sLabel = m_input.getName();
+        String label = m_input.getName();
         if (m_input.get() != null) {
             Object o = m_input.get();
             if (o instanceof String ||
                     o instanceof Integer ||
                     o instanceof Double ||
                     o instanceof Boolean) {
-                sLabel += "=" + o.toString();
+                label += "=" + o.toString();
             }
         }
-        return sLabel;
+        return label;
     }
 
     String toString(Object o) {
@@ -144,36 +143,36 @@ public class InputShape extends Shape {
     }
 
     String getLongLabel() {
-        String sLabel = m_input.getName();
+        String label = m_input.getName();
         if (m_input.get() != null) {
             Object o = m_input.get();
             if (o instanceof String ||
                     o instanceof Integer ||
                     o instanceof Double ||
                     o instanceof Boolean) {
-                sLabel += "=" + o.toString();
+                label += "=" + o.toString();
             } else if (o instanceof BEASTInterface) {
-                sLabel += "=" + ((BEASTInterface) o).getID();
+                label += "=" + ((BEASTInterface) o).getID();
             } else if (o instanceof List<?>) {
-                sLabel += "=[";
-                boolean bNeedsComma = false;
+                label += "=[";
+                boolean needsComma = false;
                 for (Object o2 : (List<?>) o) {
-                    if (bNeedsComma) {
-                        sLabel += ",";
+                    if (needsComma) {
+                        label += ",";
                     }
-                    sLabel += toString(o2);
-                    bNeedsComma = true;
+                    label += toString(o2);
+                    needsComma = true;
                 }
-                sLabel += "]";
+                label += "]";
             }
         }
-        return sLabel;
+        return label;
     }
 
     @Override
     String getID() {
-        if (m_pluginShape != null) {
-            return m_pluginShape.m_plugin.getID() + "." + m_input.getName();
+        if (m_beastObjectShape != null) {
+            return m_beastObjectShape.m_beastObject.getID() + "." + m_input.getName();
         } else {
             return m_sID;
         }
diff --git a/src/beast/app/draw/IntegerListInputEditor.java b/src/beast/app/draw/IntegerListInputEditor.java
index 894bb9e..2db8057 100644
--- a/src/beast/app/draw/IntegerListInputEditor.java
+++ b/src/beast/app/draw/IntegerListInputEditor.java
@@ -17,17 +17,6 @@
 
 package beast.app.draw;
 
-import beast.app.beauti.BeautiDoc;
-import beast.app.beauti.BeautiPanel;
-import beast.app.beauti.BeautiPanelConfig;
-import beast.core.BEASTInterface;
-import beast.core.Input;
-
-import javax.swing.*;
-import javax.swing.border.Border;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.event.ListSelectionListener;
 import java.awt.Color;
 import java.awt.Component;
 import java.awt.Dimension;
@@ -36,6 +25,23 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.JLabel;
+import javax.swing.JTextField;
+import javax.swing.SwingConstants;
+import javax.swing.border.Border;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.ListSelectionListener;
+
+import beast.app.beauti.BeautiDoc;
+import beast.app.beauti.BeautiPanel;
+import beast.app.beauti.BeautiPanelConfig;
+import beast.core.BEASTInterface;
+import beast.core.Input;
+import beast.core.util.Log;
+
 
 public class IntegerListInputEditor extends ListInputEditor {
 	private static final long serialVersionUID = 1L;
@@ -52,7 +58,8 @@ public class IntegerListInputEditor extends ListInputEditor {
     /**
      * return type of the list *
      */
-    public Class<?> baseType() {
+    @Override
+	public Class<?> baseType() {
         return Integer.class;
     }
     
@@ -77,9 +84,9 @@ public class IntegerListInputEditor extends ListInputEditor {
         protected Input<?> m_input;
 
         /**
-         * parent plugin *
+         * parent beastObject *
          */
-        protected BEASTInterface m_plugin;
+        protected BEASTInterface m_beastObject;
 
         /**
          * text field used for primitive input editors *
@@ -88,13 +95,14 @@ public class IntegerListInputEditor extends ListInputEditor {
         
         protected int itemNr;
 
-        public JTextField getEntry() {
+        @Override
+		public JTextField getEntry() {
             return m_entry;
         }
 
         JLabel m_inputLabel;
-        protected static Dimension PREFERRED_SIZE = new Dimension(200, 25);
-        protected static Dimension MAX_SIZE = new Dimension(1024, 25);
+        //protected static Dimension PREFERRED_SIZE = new Dimension(200, 25);
+        //protected static Dimension MAX_SIZE = new Dimension(1024, 25);
 
         /**
          * flag to indicate label, edit and validate buttons/labels should be added *
@@ -116,14 +124,16 @@ public class IntegerListInputEditor extends ListInputEditor {
          */
         List<InputEditor> m_validateListeners;
 
-        public void addValidationListener(InputEditor validateListener) {
+        @Override
+		public void addValidationListener(InputEditor validateListener) {
             if (m_validateListeners == null) {
-                m_validateListeners = new ArrayList<InputEditor>();
+                m_validateListeners = new ArrayList<>();
             }
             m_validateListeners.add(validateListener);
         }
 
-        public void notifyValidationListeners(ValidationStatus state) {
+        @Override
+		public void notifyValidationListeners(ValidationStatus state) {
             if (m_validateListeners != null) {
                 for (InputEditor listener : m_validateListeners) {
                     listener.startValidating(state);
@@ -131,7 +141,8 @@ public class IntegerListInputEditor extends ListInputEditor {
             }
         }
 
-    	protected BeautiDoc getDoc() {
+    	@Override
+		protected BeautiDoc getDoc() {
             if (doc == null) {
                 Component c = this;
                 while (c.getParent() != null) {
@@ -145,7 +156,8 @@ public class IntegerListInputEditor extends ListInputEditor {
         }
 
 
-        public Class<?>[] types() {
+        @Override
+		public Class<?>[] types() {
             Class<?>[] types = new Class<?>[1];
             types[0] = type();
             return types;
@@ -154,10 +166,11 @@ public class IntegerListInputEditor extends ListInputEditor {
         /**
          * construct an editor consisting of a label and input entry *
          */
-        public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-            m_bAddButtons = bAddButtons;
+        @Override
+		public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+            m_bAddButtons = addButtons;
             m_input = input;
-            m_plugin = plugin;
+            m_beastObject = beastObject;
             this.itemNr= itemNr;
             
             addInputLabel();
@@ -169,7 +182,8 @@ public class IntegerListInputEditor extends ListInputEditor {
             addValidationLabel();
         } // init
 
-        void setUpEntry() {
+        @Override
+		void setUpEntry() {
             m_entry = new JTextField();
             m_entry.setName(m_input.getName());
             m_entry.setMinimumSize(PREFERRED_SIZE);
@@ -197,27 +211,29 @@ public class IntegerListInputEditor extends ListInputEditor {
             });
         }
 
-        @SuppressWarnings({ "unchecked", "rawtypes" })
-    	protected void setValue(Object o) throws Exception {
+        @Override
+		@SuppressWarnings({ "unchecked", "rawtypes" })
+    	protected void setValue(Object o)  {
         	if (itemNr < 0) {
-        		m_input.setValue(o, m_plugin);
+        		m_input.setValue(o, m_beastObject);
         	} else {
         		// set value of an item in a list
         		List list = (List) m_input.get();
         		Object other = list.get(itemNr);
         		if (other != o) {
         			if (other instanceof BEASTInterface) {
-        				BEASTInterface.getOutputs(other).remove(m_plugin);
+        				BEASTInterface.getOutputs(other).remove(m_beastObject);
         			}
         			list.set(itemNr, o);
         			if (o instanceof BEASTInterface) {
-        				BEASTInterface.getOutputs(o).add(m_plugin);
+        				BEASTInterface.getOutputs(o).add(m_beastObject);
         			}
         		}
         	}
         }
         
-        protected void processEntry() {
+        @Override
+		protected void processEntry() {
             try {
             	setValue(m_entry.getText());
                 validateInput();
@@ -235,28 +251,31 @@ public class IntegerListInputEditor extends ListInputEditor {
             }
         }
 
-        protected void addInputLabel() {
+        @Override
+		protected void addInputLabel() {
             if (m_bAddButtons) {
-                String sName = formatName(m_input.getName());
-                addInputLabel(sName, m_input.getHTMLTipText());
+                String name = formatName(m_input.getName());
+                addInputLabel(name, m_input.getHTMLTipText());
             }
         }
 
-        protected String formatName(String sName) {
-    	    if (doc.beautiConfig.inputLabelMap.containsKey(m_plugin.getClass().getName() + "." + sName)) {
-    	        sName = doc.beautiConfig.inputLabelMap.get(m_plugin.getClass().getName() + "." + sName);
+        @Override
+		protected String formatName(String name) {
+    	    if (doc.beautiConfig.inputLabelMap.containsKey(m_beastObject.getClass().getName() + "." + name)) {
+    	        name = doc.beautiConfig.inputLabelMap.get(m_beastObject.getClass().getName() + "." + name);
     	    } else {
-    	        sName = sName.replaceAll("([a-z])([A-Z])", "$1 $2");
-    	        sName = sName.substring(0, 1).toUpperCase() + sName.substring(1);
+    	        name = name.replaceAll("([a-z])([A-Z])", "$1 $2");
+    	        name = name.substring(0, 1).toUpperCase() + name.substring(1);
     	    }
-    	    return sName;
+    	    return name;
         }
 
-        protected void addInputLabel(String sLabel, String sTipText) {
+        @Override
+		protected void addInputLabel(String label, String tipText) {
             if (m_bAddButtons) {
-                m_inputLabel = new JLabel(sLabel);
-                m_inputLabel.setToolTipText(sTipText);
-                m_inputLabel.setHorizontalTextPosition(JLabel.RIGHT);
+                m_inputLabel = new JLabel(label);
+                m_inputLabel.setToolTipText(tipText);
+                m_inputLabel.setHorizontalTextPosition(SwingConstants.RIGHT);
                 //Dimension size = new Dimension(g_nLabelWidth, 20);
                 Dimension size = new Dimension(200, 20);
                 m_inputLabel.setMaximumSize(size);
@@ -272,7 +291,8 @@ public class IntegerListInputEditor extends ListInputEditor {
             }
         }
 
-        protected void addValidationLabel() {
+        @Override
+		protected void addValidationLabel() {
             if (m_bAddButtons) {
                 m_validateLabel = new SmallLabel("x", new Color(200, 0, 0));
                 add(m_validateLabel);
@@ -282,7 +302,8 @@ public class IntegerListInputEditor extends ListInputEditor {
         }
 
         /* check the input is valid, continue checking recursively */
-        protected void validateAllEditors() {
+        @Override
+		protected void validateAllEditors() {
             for (InputEditor editor : doc.currentInputEditors) {
                 editor.validateInput();
             }
@@ -292,12 +313,12 @@ public class IntegerListInputEditor extends ListInputEditor {
         public void validateInput() {
             try {
                 m_input.validate();
-                if (m_entry != null && !m_input.canSetValue(m_entry.getText(), m_plugin)) {
-                    throw new Exception("invalid value");
+                if (m_entry != null && !m_input.canSetValue(m_entry.getText(), m_beastObject)) {
+                    throw new IllegalArgumentException("invalid value");
                 }
                 // recurse
                 try {
-                    validateRecursively(m_input, new HashSet<Input<?>>());
+                    validateRecursively(m_input, new HashSet<>());
                 } catch (Exception e) {
                     notifyValidationListeners(ValidationStatus.HAS_INVALIDMEMBERS);
                     if (m_validateLabel != null) {
@@ -313,7 +334,7 @@ public class IntegerListInputEditor extends ListInputEditor {
                 }
                 notifyValidationListeners(ValidationStatus.IS_VALID);
             } catch (Exception e) {
-                System.err.println("Validation message: " + e.getMessage());
+                Log.err.println("Validation message: " + e.getMessage());
                 if (m_validateLabel != null) {
                     m_validateLabel.setToolTipText(e.getMessage());
                     m_validateLabel.m_circleColor = Color.red;
@@ -324,9 +345,10 @@ public class IntegerListInputEditor extends ListInputEditor {
             repaint();
         }
 
-        /* Recurse in any of the input plugins
+        /* Recurse in any of the input beastObjects
           * and validate its inputs */
-        void validateRecursively(Input<?> input, Set<Input<?>> done) throws Exception {
+        @Override
+		void validateRecursively(Input<?> input, Set<Input<?>> done)  {
             if (done.contains(input)) {
                 // this prevent cycles to lock up validation
                 return;
@@ -335,12 +357,12 @@ public class IntegerListInputEditor extends ListInputEditor {
             }
             if (input.get() != null) {
                 if (input.get() instanceof BEASTInterface) {
-                    BEASTInterface plugin = ((BEASTInterface) input.get());
-                    for (Input<?> input2 : plugin.listInputs()) {
+                    BEASTInterface beastObject = ((BEASTInterface) input.get());
+                    for (Input<?> input2 : beastObject.listInputs()) {
                         try {
                             input2.validate();
                         } catch (Exception e) {
-                            throw new Exception(((BEASTInterface) input.get()).getID() + "</p><p> " + e.getMessage());
+                            throw new IllegalArgumentException(((BEASTInterface) input.get()).getID() + "</p><p> " + e.getMessage());
                         }
                         validateRecursively(input2, done);
                     }
@@ -348,12 +370,12 @@ public class IntegerListInputEditor extends ListInputEditor {
                 if (input.get() instanceof List<?>) {
                     for (Object o : (List<?>) input.get()) {
                         if (o != null && o instanceof BEASTInterface) {
-                            BEASTInterface plugin = (BEASTInterface) o;
-                            for (Input<?> input2 : plugin.listInputs()) {
+                            BEASTInterface beastObject = (BEASTInterface) o;
+                            for (Input<?> input2 : beastObject.listInputs()) {
                                 try {
                                     input2.validate();
                                 } catch (Exception e) {
-                                    throw new Exception(((BEASTInterface) o).getID() + " " + e.getMessage());
+                                    throw new IllegalArgumentException(((BEASTInterface) o).getID() + " " + e.getMessage());
                                 }
                                 validateRecursively(input2, done);
                             }
@@ -369,7 +391,8 @@ public class IntegerListInputEditor extends ListInputEditor {
         }
 
 
-        public void refreshPanel() {
+        @Override
+		public void refreshPanel() {
             Component c = this;
             while (c.getParent() != null) {
                 c = c.getParent();
@@ -382,20 +405,22 @@ public class IntegerListInputEditor extends ListInputEditor {
         /**
          * synchronise values in panel with current network *
          */
-        protected void sync() {
+        @Override
+		protected void sync() {
             Component c = this;
             while (c.getParent() != null) {
                 c = c.getParent();
                 if (c instanceof BeautiPanel) {
                     BeautiPanel panel = (BeautiPanel) c;
                     BeautiPanelConfig cfgPanel = panel.config;
-                    cfgPanel.sync(panel.iPartition);
+                    cfgPanel.sync(panel.partitionIndex);
                 }
             }
         }
 
         // we should leave it to the component to set its own border
-        @Deprecated
+        @Override
+		@Deprecated
         public void setBorder(Border border) {
     		super.setBorder(border);
         }
@@ -406,13 +431,15 @@ public class IntegerListInputEditor extends ListInputEditor {
         }
 
         // what is this method for? We should leave repainting to the standard mechanism
-        @Deprecated
+        @Override
+		@Deprecated
     	public void repaint() {
     	this.repaint(0);
     		super.repaint();
     	}
 
-    	public Component getComponent() {
+    	@Override
+		public Component getComponent() {
     		return this;
     	}
 
diff --git a/src/beast/app/draw/ListInputEditor.java b/src/beast/app/draw/ListInputEditor.java
index e49d3be..0e1b93a 100644
--- a/src/beast/app/draw/ListInputEditor.java
+++ b/src/beast/app/draw/ListInputEditor.java
@@ -1,15 +1,10 @@
 package beast.app.draw;
 
-import javax.imageio.ImageIO;
-import javax.swing.*;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-
-import beast.app.beauti.BeautiDoc;
-import beast.core.Input;
-import beast.core.BEASTInterface;
-
-import java.awt.*;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Image;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.util.ArrayList;
@@ -17,6 +12,22 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import javax.imageio.ImageIO;
+import javax.swing.BorderFactory;
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JTextField;
+import javax.swing.SwingConstants;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+import beast.app.beauti.BeautiDoc;
+import beast.core.BEASTInterface;
+import beast.core.Input;
+import beast.core.util.Log;
+
 public class ListInputEditor extends InputEditor.Base {
 
     private static final long serialVersionUID = 1L;
@@ -50,8 +61,8 @@ public class ListInputEditor extends InputEditor.Base {
     // the box containing any buttons
     protected Box buttonBox;
 
-    static protected Set<String> g_collapsedIDs = new HashSet<String>();
-    static Set<String> g_initiallyCollapsedIDs = new HashSet<String>();
+    static protected Set<String> g_collapsedIDs = new HashSet<>();
+    static Set<String> g_initiallyCollapsedIDs = new HashSet<>();
 
     public abstract class ActionListenerObject implements ActionListener {
         public Object m_o;
@@ -64,22 +75,22 @@ public class ListInputEditor extends InputEditor.Base {
 
     public abstract class ExpandActionListener implements ActionListener {
         Box m_box;
-        BEASTInterface m_plugin;
+        BEASTInterface m_beastObject;
 
-        public ExpandActionListener(Box box, BEASTInterface plugin) {
+        public ExpandActionListener(Box box, BEASTInterface beastObject) {
             super();
             m_box = box;
-            m_plugin = plugin;
+            m_beastObject = beastObject;
         }
     }
 
     //public ListInputEditor() {}
     public ListInputEditor(BeautiDoc doc) {
         super(doc);
-        m_entries = new ArrayList<JTextField>();
-        delButtonList = new ArrayList<SmallButton>();
-        m_editButton = new ArrayList<SmallButton>();
-        m_validateLabels = new ArrayList<SmallLabel>();
+        m_entries = new ArrayList<>();
+        delButtonList = new ArrayList<>();
+        m_editButton = new ArrayList<>();
+        m_validateLabels = new ArrayList<>();
         m_bExpandOption = ExpandOption.FALSE;
         setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
     }
@@ -103,17 +114,17 @@ public class ListInputEditor extends InputEditor.Base {
      * o a set of buttons for adding, deleting, editing items in the list
      */
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-        m_bAddButtons = bAddButtons;
-        m_bExpandOption = bExpandOption;
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+        m_bAddButtons = addButtons;
+        m_bExpandOption = isExpandOption;
         m_input = input;
-        m_plugin = plugin;
+        m_beastObject = beastObject;
         this.itemNr = -1;
         addInputLabel();
         if (m_inputLabel != null) {
             m_inputLabel.setMaximumSize(new Dimension(m_inputLabel.getSize().width, 1000));
             m_inputLabel.setAlignmentY(1.0f);
-            m_inputLabel.setVerticalAlignment(JLabel.TOP);
+            m_inputLabel.setVerticalAlignment(SwingConstants.TOP);
             m_inputLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
         }
 
@@ -121,8 +132,8 @@ public class ListInputEditor extends InputEditor.Base {
         // list of inputs 
         for (Object o : (List<?>) input.get()) {
             if (o instanceof BEASTInterface) {
-                BEASTInterface plugin2 = (BEASTInterface) o;
-                addSingleItem(plugin2);
+                BEASTInterface beastObject2 = (BEASTInterface) o;
+                addSingleItem(beastObject2);
             }
         }
 
@@ -138,12 +149,12 @@ public class ListInputEditor extends InputEditor.Base {
             buttonBox.add(addButton);
             if (!doc.isExpertMode()) {
                 // if nothing can be added, make add button invisible
-                List<String> sTabuList = new ArrayList<String>();
+                List<String> tabuList = new ArrayList<>();
                 for (int i = 0; i < m_entries.size(); i++) {
-                    sTabuList.add(m_entries.get(i).getText());
+                    tabuList.add(m_entries.get(i).getText());
                 }
-                List<String> sPlugins = doc.getInputEditorFactory().getAvailablePlugins(m_input, m_plugin, sTabuList, doc);
-                if (sPlugins.size() == 0) {
+                List<String> beastObjectNames = doc.getInputEditorFactory().getAvailablePlugins(m_input, m_beastObject, tabuList, doc);
+                if (beastObjectNames.size() == 0) {
                     addButton.setVisible(false);
                 }
             }
@@ -169,17 +180,18 @@ public class ListInputEditor extends InputEditor.Base {
 
     } // init
 
-    protected void addSingleItem(BEASTInterface plugin) {
+    protected void addSingleItem(BEASTInterface beastObject) {
         Box itemBox = Box.createHorizontalBox();
 
-        InputEditor editor = addPluginItem(itemBox, plugin);
+        InputEditor editor = addPluginItem(itemBox, beastObject);
         
         SmallButton editButton = new SmallButton("e", true, SmallButton.ButtonType.square);
-        editButton.setName(plugin.getID() + ".editButton");
+        editButton.setName(beastObject.getID() + ".editButton");
         if (m_bExpandOption == ExpandOption.FALSE || m_bExpandOption == ExpandOption.IF_ONE_ITEM && ((List<?>) m_input.get()).size() > 1) {
             editButton.setToolTipText("Edit item in the list");
-            editButton.addActionListener(new ActionListenerObject(plugin) {
-                public void actionPerformed(ActionEvent e) {
+            editButton.addActionListener(new ActionListenerObject(beastObject) {
+                @Override
+				public void actionPerformed(ActionEvent e) {
                     m_o = editItem(m_o);
                 }
             });
@@ -204,7 +216,7 @@ public class ListInputEditor extends InputEditor.Base {
                 (m_bExpandOption == ExpandOption.IF_ONE_ITEM && ((List<?>) m_input.get()).size() == 1)) {
             Box expandBox = Box.createVerticalBox();
             //box.add(itemBox);
-            doc.getInputEditorFactory().addInputs(expandBox, plugin, editor, null, doc);
+            doc.getInputEditorFactory().addInputs(expandBox, beastObject, editor, null, doc);
             //System.err.print(expandBox.getComponentCount());
             if (expandBox.getComponentCount() > 1) {
                 // only go here if it is worth showing expanded box
@@ -222,8 +234,9 @@ public class ListInputEditor extends InputEditor.Base {
             } else {
                 editButton.setVisible(false);
             }
-            editButton.addActionListener(new ExpandActionListener(expandBox, plugin) {
-                public void actionPerformed(ActionEvent e) {
+            editButton.addActionListener(new ExpandActionListener(expandBox, beastObject) {
+                @Override
+				public void actionPerformed(ActionEvent e) {
                     SmallButton editButton = (SmallButton) e.getSource();
                     m_box.setVisible(!m_box.isVisible());
                     if (m_box.isVisible()) {
@@ -232,19 +245,19 @@ public class ListInputEditor extends InputEditor.Base {
                         }catch (Exception e2) {
 							// TODO: handle exception
 						}
-                        g_collapsedIDs.remove(m_plugin.getID());
+                        g_collapsedIDs.remove(m_beastObject.getID());
                     } else {
                     	try {
                         editButton.setImg(RIGHT_ICON);
 	                    }catch (Exception e2) {
 							// TODO: handle exception
 						}
-                        g_collapsedIDs.add(m_plugin.getID());
+                        g_collapsedIDs.add(m_beastObject.getID());
                     }
                 }
             });
-            String sID = plugin.getID();
-            expandBox.setVisible(!g_collapsedIDs.contains(sID));
+            String id = beastObject.getID();
+            expandBox.setVisible(!g_collapsedIDs.contains(id));
             try {
             if (expandBox.isVisible()) {
                 editButton.setImg(DOWN_ICON);
@@ -257,7 +270,7 @@ public class ListInputEditor extends InputEditor.Base {
 
 
         } else {
-            if (BEASTObjectPanel.countInputs(plugin, doc) == 0) {
+            if (BEASTObjectPanel.countInputs(beastObject, doc) == 0) {
                 editButton.setVisible(false);
             }
         }
@@ -273,19 +286,19 @@ public class ListInputEditor extends InputEditor.Base {
     } // addSingleItem
 
     /**
-     * add components to box that are specific for the plugin.
-     * By default, this just inserts a label with the plugin ID
+     * add components to box that are specific for the beastObject.
+     * By default, this just inserts a label with the beastObject ID
      *
      * @param itemBox box to add components to
-     * @param plugin  plugin to add
+     * @param beastObject  beastObject to add
      */
-    protected InputEditor addPluginItem(Box itemBox, BEASTInterface plugin) {
-        String sName = plugin.getID();
-        if (sName == null || sName.length() == 0) {
-            sName = plugin.getClass().getName();
-            sName = sName.substring(sName.lastIndexOf('.') + 1);
+    protected InputEditor addPluginItem(Box itemBox, BEASTInterface beastObject) {
+        String name = beastObject.getID();
+        if (name == null || name.length() == 0) {
+            name = beastObject.getClass().getName();
+            name = name.substring(name.lastIndexOf('.') + 1);
         }
-        JLabel label = new JLabel(sName);
+        JLabel label = new JLabel(name);
 
         itemBox.add(Box.createRigidArea(new Dimension(5, 1)));
         itemBox.add(label);
@@ -294,11 +307,11 @@ public class ListInputEditor extends InputEditor.Base {
     }
 
     class IDDocumentListener implements DocumentListener {
-        BEASTInterface m_plugin;
+        BEASTInterface m_beastObject;
         JTextField m_entry;
 
-        IDDocumentListener(BEASTInterface plugin, JTextField entry) {
-            m_plugin = plugin;
+        IDDocumentListener(BEASTInterface beastObject, JTextField entry) {
+            m_beastObject = beastObject;
             m_entry = entry;
         }
 
@@ -318,30 +331,30 @@ public class ListInputEditor extends InputEditor.Base {
         }
 
         void processEntry() {
-            String sOldID = m_plugin.getID();
-            m_plugin.setID(m_entry.getText());
-            BEASTObjectPanel.renamePluginID(m_plugin, sOldID, m_plugin.getID(), doc);
+            String oldID = m_beastObject.getID();
+            m_beastObject.setID(m_entry.getText());
+            BEASTObjectPanel.renamePluginID(m_beastObject, oldID, m_beastObject.getID(), doc);
             validateAllEditors();
             m_entry.requestFocusInWindow();
         }
     }
 
     protected void addItem() {
-        List<String> sTabuList = new ArrayList<String>();
+        List<String> tabuList = new ArrayList<>();
         for (int i = 0; i < m_entries.size(); i++) {
-            sTabuList.add(m_entries.get(i).getText());
+            tabuList.add(m_entries.get(i).getText());
         }
-        List<BEASTInterface> plugins = pluginSelector(m_input, m_plugin, sTabuList);
-        if (plugins != null) {
-            for (BEASTInterface plugin : plugins) {
+        List<BEASTInterface> beastObjects = pluginSelector(m_input, m_beastObject, tabuList);
+        if (beastObjects != null) {
+            for (BEASTInterface beastObject : beastObjects) {
                 try {
-                	setValue(plugin);
-                    //m_input.setValue(plugin, m_plugin);
+                	setValue(beastObject);
+                    //m_input.setValue(beastObject, m_beastObject);
                 } catch (Exception ex) {
-                    System.err.println(ex.getClass().getName() + " " + ex.getMessage());
+                    Log.err.println(ex.getClass().getName() + " " + ex.getMessage());
                 }
-                addSingleItem(plugin);
-                getDoc().addPlugin(plugin);
+                addSingleItem(beastObject);
+                getDoc().addPlugin(beastObject);
             }
             validateInput();
             updateState();
@@ -351,12 +364,14 @@ public class ListInputEditor extends InputEditor.Base {
 
     protected Object editItem(Object o) {
         int i = ((List<?>) m_input.get()).indexOf(o);
-        BEASTInterface plugin = (BEASTInterface) ((List<?>) m_input.get()).get(i);
-        BEASTObjectDialog dlg = new BEASTObjectDialog(plugin, m_input.getType(), doc);
+        BEASTInterface beastObject = (BEASTInterface) ((List<?>) m_input.get()).get(i);
+        BEASTObjectDialog dlg = new BEASTObjectDialog(beastObject, m_input.getType(), doc);
         if (dlg.showDialog()) {
-            //m_labels.get(i).setText(dlg.m_panel.m_plugin.getID());
-            m_entries.get(i).setText(dlg.m_panel.m_plugin.getID());
-            //o = dlg.m_panel.m_plugin;
+            //m_labels.get(i).setText(dlg.m_panel.m_beastObject.getID());
+        	if (m_entries.size() > i) {
+        		m_entries.get(i).setText(dlg.m_panel.m_beastObject.getID());
+        	}
+            //o = dlg.m_panel.m_beastObject;
             dlg.accept((BEASTInterface) o, doc);
             refreshPanel();
         }
@@ -396,44 +411,44 @@ public class ListInputEditor extends InputEditor.Base {
      * Return null if nothing is selected.
      */
     protected List<BEASTInterface> pluginSelector(Input<?> input, BEASTInterface parent, List<String> tabooList) {
-        List<BEASTInterface> selectedPlugins = new ArrayList<BEASTInterface>();
-        List<String> sPlugins = doc.getInputEditorFactory().getAvailablePlugins(input, parent, tabooList, doc);
-        /* select a plugin **/
-        String sClassName = null;
-        if (sPlugins.size() == 1) {
+        List<BEASTInterface> selectedPlugins = new ArrayList<>();
+        List<String> beastObjectNames = doc.getInputEditorFactory().getAvailablePlugins(input, parent, tabooList, doc);
+        /* select a beastObject **/
+        String className = null;
+        if (beastObjectNames.size() == 1) {
             // if there is only one candidate, select that one
-            sClassName = sPlugins.get(0);
-        } else if (sPlugins.size() == 0) {
+            className = beastObjectNames.get(0);
+        } else if (beastObjectNames.size() == 0) {
             // no candidate => we cannot be in expert mode
-            // create a new Plugin
+            // create a new BEASTObject
             doc.setExpertMode(true);
-            sPlugins = doc.getInputEditorFactory().getAvailablePlugins(input, parent, tabooList, doc);
+            beastObjectNames = doc.getInputEditorFactory().getAvailablePlugins(input, parent, tabooList, doc);
             doc.setExpertMode(false);
-            sClassName = sPlugins.get(0);
+            className = beastObjectNames.get(0);
         } else {
             // otherwise, pop up a list box
-            sClassName = (String) JOptionPane.showInputDialog(null,
+            className = (String) JOptionPane.showInputDialog(null,
                     "Select a constant", "select",
                     JOptionPane.PLAIN_MESSAGE, null,
-                    sPlugins.toArray(new String[0]),
+                    beastObjectNames.toArray(new String[0]),
                     null);
-            if (sClassName == null) {
+            if (className == null) {
                 return null;
             }
         }
-        if (!sClassName.startsWith("new ")) {
-            /* return existing plugin */
-            selectedPlugins.add(doc.pluginmap.get(sClassName));
+        if (!className.startsWith("new ")) {
+            /* return existing beastObject */
+            selectedPlugins.add(doc.pluginmap.get(className));
             return selectedPlugins;
         }
-        /* create new plugin */
+        /* create new beastObject */
         try {
-            BEASTInterface plugin = (BEASTInterface) Class.forName(sClassName.substring(4)).newInstance();
-            BEASTObjectPanel.addPluginToMap(plugin, doc);
-            selectedPlugins.add(plugin);
+            BEASTInterface beastObject = (BEASTInterface) Class.forName(className.substring(4)).newInstance();
+            BEASTObjectPanel.addPluginToMap(beastObject, doc);
+            selectedPlugins.add(beastObject);
             return selectedPlugins;
         } catch (Exception ex) {
-            JOptionPane.showMessageDialog(null, "Could not select plugin: " +
+            JOptionPane.showMessageDialog(null, "Could not select beastObject: " +
                     ex.getClass().getName() + " " +
                     ex.getMessage()
             );
@@ -444,10 +459,10 @@ public class ListInputEditor extends InputEditor.Base {
     protected void updateState() {
         for (int i = 0; i < ((List<?>) m_input.get()).size(); i++) {
             try {
-                BEASTInterface plugin = (BEASTInterface) ((List<?>) m_input.get()).get(i);
-                plugin.validateInputs();
+                BEASTInterface beastObject = (BEASTInterface) ((List<?>) m_input.get()).get(i);
+                beastObject.validateInputs();
                 m_validateLabels.get(i).setVisible(false);
-            } catch (Exception e) {
+            } catch (IllegalArgumentException e) {
                 if (m_validateLabels.size() > i) {
                     m_validateLabels.get(i).setToolTipText(e.getMessage());
                     m_validateLabels.get(i).setVisible(true);
diff --git a/src/beast/app/draw/ModelBuilder.java b/src/beast/app/draw/ModelBuilder.java
index d243c1a..116b805 100644
--- a/src/beast/app/draw/ModelBuilder.java
+++ b/src/beast/app/draw/ModelBuilder.java
@@ -26,38 +26,63 @@ package beast.app.draw;
 
 
 
-import javax.imageio.ImageIO;
-import javax.swing.*;
-import javax.swing.filechooser.FileFilter;
-
-import beast.app.util.Utils;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
-import beast.evolution.alignment.Sequence;
-import beast.util.AddOnManager;
-import beast.util.Randomizer;
-import beast.util.XMLProducer;
-
-
 //import com.itextpdf.awt.PdfGraphics2D;
 //import com.itextpdf.text.pdf.PdfContentByte;
 //import com.itextpdf.text.pdf.PdfWriter;
-
-import java.awt.*;
-import java.awt.event.*;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionAdapter;
 import java.awt.image.BufferedImage;
 import java.awt.print.PageFormat;
 import java.awt.print.Printable;
 import java.awt.print.PrinterException;
 import java.awt.print.PrinterJob;
 import java.io.File;
-import java.io.FileOutputStream;
+import java.io.FileNotFoundException;
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.imageio.ImageIO;
+import javax.swing.Action;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JColorChooser;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JToolBar;
+import javax.swing.KeyStroke;
+import javax.swing.filechooser.FileFilter;
+
+import beast.app.util.Utils;
+import beast.core.BEASTInterface;
+import beast.evolution.alignment.Sequence;
+import beast.util.AddOnManager;
+import beast.util.Randomizer;
+import beast.util.XMLProducer;
+
 /**
  * program for drawing BEAST 2.0 models *
  */
@@ -107,8 +132,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
     boolean m_bIsEditable = true;
     
 
-    public void setEditable(boolean bIsEditable) {
-        m_bIsEditable = bIsEditable;
+    public void setEditable(boolean isEditable) {
+        m_bIsEditable = isEditable;
     }
 
     /**
@@ -202,8 +227,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             return m_sText;
         }
 
-        public void setText(String sText) {
-            m_sText = sText;
+        public void setText(String text) {
+            m_sText = text;
             a_pastenode.setEnabled(true);
         }
     } // class ClipBoard
@@ -218,27 +243,27 @@ public class ModelBuilder extends JPanel implements ComponentListener {
     ExtensionFileFilter ef5 = new ExtensionFileFilter(".png", "PNG images");
 
     boolean validateModel() {
-        int nStatus = m_doc.isValidModel();
-        if (nStatus == Document.STATUS_OK) {
+        int status = m_doc.isValidModel();
+        if (status == Document.STATUS_OK) {
             return true;
         }
-        String sMsg = "<html>Document is not valid: ";
-        switch (nStatus) {
+        String msg = "<html>Document is not valid: ";
+        switch (status) {
             case Document.STATUS_CYCLE:
-                sMsg += "there is a cycle in the model.";
+                msg += "there is a cycle in the model.";
                 break;
             case Document.STATUS_EMPTY_MODEL:
-                sMsg += "The model is empty, there is nothing to save.";
+                msg += "The model is empty, there is nothing to save.";
                 break;
             case Document.STATUS_NOT_RUNNABLE:
-                sMsg += "there is no top level runnable item in the model (e.g. an MCMC node).";
+                msg += "there is no top level runnable item in the model (e.g. an MCMC node).";
                 break;
             case Document.STATUS_ORPHANS_IN_MODEL:
-                sMsg += "there are orphaned items in the model (i.e. plugins that have no parents).";
+                msg += "there are orphaned items in the model (i.e. beastObjects that have no parents).";
                 break;
         }
-        sMsg += "<br>Do you still want to try to save the model?</html>";
-        if (JOptionPane.showConfirmDialog(this, sMsg, "Model not valid",
+        msg += "<br>Do you still want to try to save the model?</html>";
+        if (JOptionPane.showConfirmDialog(this, msg, "Model not valid",
                 JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
             return true;
         }
@@ -255,12 +280,13 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Save", "Save Graph", "save", KeyEvent.VK_S);
         } // c'tor
 
-        public ActionSave(String sName, String sToolTipText, String sIcon,
+        public ActionSave(String name, String toolTipText, String icon,
                           int acceleratorKey) {
-            super(sName, sToolTipText, sIcon, acceleratorKey);
+            super(name, toolTipText, icon, acceleratorKey);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             if (!m_sFileName.equals("")) {
                 if (!validateModel()) {
                     return;
@@ -290,24 +316,24 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             if (rval == JFileChooser.APPROVE_OPTION) {
                 // System.out.println("Saving to file \""+
                 // f.getAbsoluteFile().toString()+"\"");
-                String sFileName = fc.getSelectedFile().toString();
-                if (sFileName.lastIndexOf('/') > 0) {
-                    m_sDir = sFileName.substring(0, sFileName.lastIndexOf('/'));
+                String fileName = fc.getSelectedFile().toString();
+                if (fileName.lastIndexOf('/') > 0) {
+                    m_sDir = fileName.substring(0, fileName.lastIndexOf('/'));
                 }
-                if (!sFileName.endsWith(FILE_EXT))
-                    sFileName = sFileName.concat(FILE_EXT);
-                saveFile(sFileName);
+                if (!fileName.endsWith(FILE_EXT))
+                    fileName = fileName.concat(FILE_EXT);
+                saveFile(fileName);
                 return true;
             }
             return false;
         } // saveAs
 
-        protected void saveFile(String sFileName) {
+        protected void saveFile(String fileName) {
             try {
-                FileWriter outfile = new FileWriter(sFileName);
+                FileWriter outfile = new FileWriter(fileName);
                 outfile.write(m_doc.toXML());
                 outfile.close();
-                m_sFileName = sFileName;
+                m_sFileName = fileName;
             } catch (IOException e) {
                 e.printStackTrace();
             }
@@ -325,7 +351,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Print", "Print Graph", "print", KeyEvent.VK_P);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             PrinterJob printJob = PrinterJob.getPrinterJob();
             printJob.setPrintable(g_panel);
             if (printJob.printDialog())
@@ -354,13 +381,15 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Save As", "Save Graph As", "saveas", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             saveAs();
         } // actionPerformed
     } // class ActionSaveAs
 
     abstract class MyFileFilter extends FileFilter {
-        public boolean accept(File f) {
+        @Override
+		public boolean accept(File f) {
             return f.isDirectory()
                     || f.getName().toLowerCase().endsWith(getExtention());
         }
@@ -379,7 +408,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Export", "Export to graphics file", "export", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_bIsExporting = true;
 
 //            JFileChooser fc = new JFileChooser(m_sDir);
@@ -413,29 +443,29 @@ public class ModelBuilder extends JPanel implements ComponentListener {
 //            fc.setDialogTitle("Export Image As");
 //            int rval = fc.showSaveDialog(g_panel);
 //            if (rval == JFileChooser.APPROVE_OPTION) {
-//	            String sFileName = fc.getSelectedFile().toString();
+//	            String fileName = fc.getSelectedFile().toString();
             try {
 
                 File file = Utils.getSaveFile("Export image (type determined by extention)", new File(m_sDir), "Image files", "png", "bmp", "jpg", "svg", "pdf");
 
                 if (file != null) {
-                    String sFileName = file.getAbsolutePath();
-                    if (sFileName.lastIndexOf('/') > 0) {
-                        m_sDir = sFileName.substring(0, sFileName.lastIndexOf('/'));
+                    String fileName = file.getAbsolutePath();
+                    if (fileName.lastIndexOf('/') > 0) {
+                        m_sDir = fileName.substring(0, fileName.lastIndexOf('/'));
                     }
-                    if (sFileName != null && !sFileName.equals("")) {
-//                    if (!sFileName.toLowerCase().endsWith(".png")
-//                            && sFileName.toLowerCase().endsWith(".jpg")
-//                            && sFileName.toLowerCase().endsWith(".bmp")
-//                            && sFileName.toLowerCase().endsWith(".svg")) {
-//                        sFileName += ((MyFileFilter) fc.getFileFilter())
+                    if (fileName != null && !fileName.equals("")) {
+//                    if (!fileName.toLowerCase().endsWith(".png")
+//                            && fileName.toLowerCase().endsWith(".jpg")
+//                            && fileName.toLowerCase().endsWith(".bmp")
+//                            && fileName.toLowerCase().endsWith(".svg")) {
+//                        fileName += ((MyFileFilter) fc.getFileFilter())
 //                                .getExtention();
 //                    }
 
-                        if (sFileName.toLowerCase().endsWith(".pdf")) {
+                        if (fileName.toLowerCase().endsWith(".pdf")) {
                         	JOptionPane.showMessageDialog(null, "Not implemented yet");
 //                        	com.itextpdf.text.Document doc = new com.itextpdf.text.Document();
-//                        	PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(sFileName));
+//                        	PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(fileName));
 //                        	doc.setPageSize(new com.itextpdf.text.Rectangle(g_panel.getWidth(), g_panel.getHeight()));
 //                        	doc.open();
 //                        	PdfContentByte cb = writer.getDirectContent();
@@ -448,9 +478,9 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                             m_bIsExporting = false;
                             repaint();
                         	return;
-                        } else if (sFileName.toLowerCase().endsWith(".png")
-                                || sFileName.toLowerCase().endsWith(".jpg")
-                                || sFileName.toLowerCase().endsWith(".bmp")) {
+                        } else if (fileName.toLowerCase().endsWith(".png")
+                                || fileName.toLowerCase().endsWith(".jpg")
+                                || fileName.toLowerCase().endsWith(".bmp")) {
                             BufferedImage bi;
                             Graphics g;
                             bi = new BufferedImage(g_panel.getWidth(), g_panel
@@ -462,15 +492,15 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                                     .getHeight());
                             g_panel.printAll(g);
                             try {
-                                if (sFileName.toLowerCase().endsWith(".png")) {
-                                    ImageIO.write(bi, "png", new File(sFileName));
-                                } else if (sFileName.toLowerCase().endsWith(".jpg")) {
-                                    ImageIO.write(bi, "jpg", new File(sFileName));
-                                } else if (sFileName.toLowerCase().endsWith(".bmp")) {
-                                    ImageIO.write(bi, "bmp", new File(sFileName));
+                                if (fileName.toLowerCase().endsWith(".png")) {
+                                    ImageIO.write(bi, "png", new File(fileName));
+                                } else if (fileName.toLowerCase().endsWith(".jpg")) {
+                                    ImageIO.write(bi, "jpg", new File(fileName));
+                                } else if (fileName.toLowerCase().endsWith(".bmp")) {
+                                    ImageIO.write(bi, "bmp", new File(fileName));
                                 }
                             } catch (Exception e) {
-                                JOptionPane.showMessageDialog(null, sFileName
+                                JOptionPane.showMessageDialog(null, fileName
                                         + " was not written properly: "
                                         + e.getMessage());
                                 e.printStackTrace();
@@ -478,14 +508,14 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                             m_bIsExporting = false;
                             repaint();
                             return;
-                        } else if (sFileName.toLowerCase().endsWith(".svg")) {
-                            writeSVG(sFileName);
+                        } else if (fileName.toLowerCase().endsWith(".svg")) {
+                            writeSVG(fileName);
                             m_bIsExporting = false;
                             repaint();
                             return;
                         }
                         JOptionPane.showMessageDialog(null, "Extention of file "
-                                + sFileName
+                                + fileName
                                 + " not recognized as png,bmp,jpg or svg file");
                     }
                 }
@@ -497,8 +527,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             repaint();
         }
 
-        private void writeSVG(String sFileName) throws Exception {
-            PrintStream out = new PrintStream(sFileName);
+        private void writeSVG(String fileName) throws FileNotFoundException {
+            PrintStream out = new PrintStream(fileName);
             out.println("<?xml version='1.0'?>\n" + "<!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN'\n"
                     + "  'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'>\n"
                     + "<svg xmlns='http://www.w3.org/2000/svg' version='1.1'\n" + "      width='" + getWidth()
@@ -525,7 +555,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Exit", "Exit Program", "exit", KeyEvent.VK_F4);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             if (!m_doc.m_bIsSaved) {
                 int result = JOptionPane.showConfirmDialog(null,
                         "Drawing changed. Do you want to save it?",
@@ -554,7 +585,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("New", "New Network", "new", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_sFileName = "";
             m_doc = new Document();
             m_Selection.setDocument(m_doc);
@@ -575,20 +607,21 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Load", "Load Graph", "open", KeyEvent.VK_O);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             JFileChooser fc = new JFileChooser(m_sDir);
             fc.addChoosableFileFilter(ef1);
             fc.setDialogTitle("Load Graph");
             int rval = fc.showOpenDialog(g_panel);
 
             if (rval == JFileChooser.APPROVE_OPTION) {
-                String sFileName = fc.getSelectedFile().toString();
-                if (sFileName.lastIndexOf('/') > 0) {
-                    m_sDir = sFileName.substring(0, sFileName.lastIndexOf('/'));
+                String fileName = fc.getSelectedFile().toString();
+                if (fileName.lastIndexOf('/') > 0) {
+                    m_sDir = fileName.substring(0, fileName.lastIndexOf('/'));
                 }
                 g_panel.setCursor(new Cursor(Cursor.WAIT_CURSOR));
-                m_doc.loadFile(sFileName);
-                m_sFileName = sFileName;
+                m_doc.loadFile(fileName);
+                m_sFileName = fileName;
                 g_panel.repaint();
                 try {
                     Thread.sleep(1000);
@@ -612,11 +645,13 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             setEnabled(false);
         } // c'tor
 
-        public boolean isEnabled() {
+        @Override
+		public boolean isEnabled() {
             return m_doc.canUndo();
         }
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.undo();
             m_Selection.clear();
             setDrawingFlag();
@@ -635,11 +670,13 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             setEnabled(false);
         } // c'tor
 
-        public boolean isEnabled() {
+        @Override
+		public boolean isEnabled() {
             return m_doc.canRedo();
         }
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.redo();
             m_Selection.clear();
             setDrawingFlag();
@@ -657,7 +694,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Select All", "Select All", "selectall", KeyEvent.VK_A);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_Selection.clear();
             for (int i = 0; i < m_doc.m_objects.size(); i++) {
                 if (m_doc.m_objects.get(i).m_bNeedsDrawing) {
@@ -680,7 +718,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             setEnabled(false);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.deleteShapes(m_Selection.m_Selection);
             m_Selection.clear();
             updateStatus();
@@ -698,23 +737,24 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             setEnabled(false);
         } // c'tor
 
-        public ActionCopyNode(String sName, String sToolTipText, String sIcon,
+        public ActionCopyNode(String name, String toolTipText, String icon,
                               int acceleratorKey) {
-            super(sName, sToolTipText, sIcon, acceleratorKey);
+            super(name, toolTipText, icon, acceleratorKey);
         } // c'rot
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             copy();
         }
 
         public void copy() {
             if (m_Selection.hasSelection()) {
-                String sXML = "<doc>\n";
+                String xml = "<doc>\n";
                 for (int i : m_Selection.m_Selection) {
-                    sXML += m_doc.m_objects.get(i).getXML() + "\n";
+                    xml += m_doc.m_objects.get(i).getXML() + "\n";
                 }
-                sXML += "</doc>\n";
-                m_clipboard.setText(sXML);
+                xml += "</doc>\n";
+                m_clipboard.setText(xml);
             }
         } // copy
     } // class ActionCopyNode
@@ -730,7 +770,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             setEnabled(false);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             copy();
             m_doc.deleteShapes(m_Selection.m_Selection);
             m_Selection.clear();
@@ -749,7 +790,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             setEnabled(false);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             try {
                 m_doc.pasteShape(m_clipboard.getText());
                 updateStatus();
@@ -758,7 +800,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             }
         }
 
-        public boolean isEnabled() {
+        @Override
+		public boolean isEnabled() {
             return m_clipboard.hasText();
         }
     } // class ActionPasteNode
@@ -773,7 +816,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             setEnabled(false);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.collapse(m_Selection);
             m_Selection.refreshTracker();
             updateStatus();
@@ -799,7 +843,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Select", "Select", "select", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_nMode = MODE_SELECT;
         }
     } // class ActionSelect
@@ -811,7 +856,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Arrow", "Arrow", "arrow", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_nMode = MODE_ARROW;
         }
     } // class ActionArrow
@@ -823,7 +869,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Function", "Function", "function", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_nMode = MODE_FUNCTION;
         }
     } // class ActionFunction
@@ -836,8 +883,9 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             setEnabled(false);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
-            Shape shape = (Shape) m_doc.m_objects.get(m_Selection
+        @Override
+		public void actionPerformed(ActionEvent ae) {
+            Shape shape = m_doc.m_objects.get(m_Selection
                     .getSingleSelection());
             Color color = JColorChooser.showDialog(g_panel,
                     "Select Fill color", shape.getFillColor());
@@ -856,8 +904,9 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             setEnabled(false);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
-            Shape shape = (Shape) m_doc.m_objects.get(m_Selection
+        @Override
+		public void actionPerformed(ActionEvent ae) {
+            Shape shape = m_doc.m_objects.get(m_Selection
                     .getSingleSelection());
             Color color = JColorChooser.showDialog(g_panel,
                     "Select Fill color", shape.getFillColor());
@@ -879,7 +928,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Bring to front", "To front", "tofront", KeyEvent.VK_PLUS);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.toFront(m_Selection);
             g_panel.repaint();
         }
@@ -897,7 +947,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             putValue(Action.ACCELERATOR_KEY, keyStroke);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.forward(m_Selection);
             g_panel.repaint();
         }
@@ -913,7 +964,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Bring to back", "To back", "toback", KeyEvent.VK_MINUS);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.toBack(m_Selection);
             g_panel.repaint();
         }
@@ -931,7 +983,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             putValue(Action.ACCELERATOR_KEY, keyStroke);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.backward(m_Selection);
             g_panel.repaint();
         }
@@ -947,7 +1000,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Align Left", "Align Left", "alignleft", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.alignLeft(m_Selection);
             m_Selection.refreshTracker();
             updateStatus();
@@ -964,7 +1018,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Align Right", "Align Right", "alignright", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.alignRight(m_Selection);
             m_Selection.refreshTracker();
             updateStatus();
@@ -981,7 +1036,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Align Top", "Align Top", "aligntop", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.alignTop(m_Selection);
             m_Selection.refreshTracker();
             updateStatus();
@@ -998,7 +1054,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Align Bottom", "Align Bottom", "alignbottom", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.alignBottom(m_Selection);
             m_Selection.refreshTracker();
             updateStatus();
@@ -1016,7 +1073,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                     -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.centreHorizontal(m_Selection);
             m_Selection.refreshTracker();
             updateStatus();
@@ -1033,7 +1091,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Center Vertical", "Center Vertical", "centervertical", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.centreVertical(m_Selection);
             m_Selection.refreshTracker();
             updateStatus();
@@ -1050,7 +1109,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Space Horizontal", "Space Horizontal", "spacehorizontal", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.spaceHorizontal(m_Selection);
             m_Selection.refreshTracker();
             updateStatus();
@@ -1067,7 +1127,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Space Vertical", "Space Vertical", "spacevertical", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_doc.spaceVertical(m_Selection);
             m_Selection.refreshTracker();
             updateStatus();
@@ -1084,7 +1145,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("About", "Help about", "about", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             JOptionPane
                     .showMessageDialog(
                             null,
@@ -1101,7 +1163,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Relax", "Relax positions", "about", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_bRelax = !m_bRelax;
             m_viewRelax.setState(m_bRelax);
             g_panel.repaint();
@@ -1115,7 +1178,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("View loggers", "View loggers", "about", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_bViewLoggers = !m_bViewLoggers;
             setDrawingFlag();
             g_panel.repaint();
@@ -1129,7 +1193,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("View Operators", "View Operators", "viewoperators", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_bViewOperators = !m_bViewOperators;
             setDrawingFlag();
             g_panel.repaint();
@@ -1143,7 +1208,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("View Sequences", "View Sequences", "viewsequences", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             m_bViewSequences = !m_bViewSequences;
             setDrawingFlag();
             g_panel.repaint();
@@ -1157,7 +1223,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             super("Layout", "Layout graph", "layout", -1);
         } // c'tor
 
-        public void actionPerformed(ActionEvent e) {
+        @Override
+		public void actionPerformed(ActionEvent e) {
             g_panel.setCursor(new Cursor(Cursor.WAIT_CURSOR));
             m_doc.layout();
             m_doc.adjustArrows();
@@ -1171,9 +1238,9 @@ public class ModelBuilder extends JPanel implements ComponentListener {
     void updateStatus() {
         a_undo.setEnabled(m_doc.canUndo());
         a_redo.setEnabled(m_doc.canRedo());
-        int nSelectionSize = m_Selection.m_Selection.size();
-        boolean hasSelection = (nSelectionSize > 0);
-        boolean hasGroupSelection = (nSelectionSize > 1);
+        int selectionSize = m_Selection.m_Selection.size();
+        boolean hasSelection = (selectionSize > 0);
+        boolean hasGroupSelection = (selectionSize > 1);
 
         a_delnode.setEnabled(hasSelection);
         a_copynode.setEnabled(hasSelection);
@@ -1266,20 +1333,20 @@ public class ModelBuilder extends JPanel implements ComponentListener {
 
     } // init
 
-    boolean needsDrawing(BEASTInterface plugin) {
-        if (plugin == null) {
+    boolean needsDrawing(BEASTInterface beastObject) {
+        if (beastObject == null) {
             return true;
         }
-        if (!m_bViewOperators && plugin instanceof beast.core.Operator) {
+        if (!m_bViewOperators && beastObject instanceof beast.core.Operator) {
             return false;
         }
-        if (!m_bViewLoggers && plugin instanceof beast.core.Logger) {
+        if (!m_bViewLoggers && beastObject instanceof beast.core.Logger) {
             return false;
         }
-        if (!m_bViewSequences && plugin instanceof Sequence) {
+        if (!m_bViewSequences && beastObject instanceof Sequence) {
             return false;
         }
-        if (!m_bViewState && plugin instanceof beast.core.State) {
+        if (!m_bViewState && beastObject instanceof beast.core.State) {
             return false;
         }
         return true;
@@ -1287,20 +1354,20 @@ public class ModelBuilder extends JPanel implements ComponentListener {
 
     public void setDrawingFlag() {
         for (int i = 0; i < m_doc.m_objects.size(); i++) {
-            Shape shape = (Shape) m_doc.m_objects.get(i);
+            Shape shape = m_doc.m_objects.get(i);
             shape.m_bNeedsDrawing = false;
             if (shape.m_bNeedsDrawing) {
                 shape.m_bNeedsDrawing = true;
             }
             if (shape instanceof BEASTObjectShape) {
-                BEASTInterface plugin = ((BEASTObjectShape) shape).m_plugin;
-                if (needsDrawing(plugin)) {
+                BEASTInterface beastObject = ((BEASTObjectShape) shape).m_beastObject;
+                if (needsDrawing(beastObject)) {
                     shape.m_bNeedsDrawing = true;
                 }
             } else if (shape instanceof InputShape) {
-                BEASTObjectShape pluginShape = ((InputShape) shape).m_pluginShape;
-                if (pluginShape != null) {
-                    if (needsDrawing(pluginShape.m_plugin)) {
+                BEASTObjectShape beastObjectShape = ((InputShape) shape).m_beastObjectShape;
+                if (beastObjectShape != null) {
+                    if (needsDrawing(beastObjectShape.m_beastObject)) {
                         shape.m_bNeedsDrawing = true;
                     }
                 } else {
@@ -1308,19 +1375,19 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                 }
             } else if (shape instanceof Arrow) {
                 Shape tail = ((Arrow) shape).m_tailShape;
-                boolean bNeedsDrawing = true;
+                boolean needsDrawing = true;
                 if (tail instanceof BEASTObjectShape) {
-                    bNeedsDrawing = needsDrawing(((BEASTObjectShape) tail).m_plugin);
+                    needsDrawing = needsDrawing(((BEASTObjectShape) tail).m_beastObject);
                 }
-                if (bNeedsDrawing) {
+                if (needsDrawing) {
                     Shape head = ((Arrow) shape).m_headShape;
                     if (head instanceof InputShape) {
-                        BEASTObjectShape pluginShape = ((InputShape) head).m_pluginShape;
-                        if (pluginShape != null) {
-                            bNeedsDrawing = needsDrawing(pluginShape.m_plugin);
+                        BEASTObjectShape beastObjectShape = ((InputShape) head).m_beastObjectShape;
+                        if (beastObjectShape != null) {
+                            needsDrawing = needsDrawing(beastObjectShape.m_beastObject);
                         }
                     }
-                    if (bNeedsDrawing) {
+                    if (needsDrawing) {
                         shape.m_bNeedsDrawing = true;
                     }
                 }
@@ -1342,7 +1409,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             addMouseListener(new GBDrawMouseEventListener());
         }
 
-        public void paintComponent(Graphics gr) {
+        @Override
+		public void paintComponent(Graphics gr) {
             Graphics2D g = (Graphics2D) gr;
             RenderingHints rh = new RenderingHints(
                     RenderingHints.KEY_ANTIALIASING,
@@ -1350,13 +1418,13 @@ public class ModelBuilder extends JPanel implements ComponentListener {
             rh.put(RenderingHints.KEY_RENDERING,
                     RenderingHints.VALUE_RENDER_SPEED);
             g.setRenderingHints(rh);
-            ((Graphics2D) g).setBackground(Color.WHITE);
+            g.setBackground(Color.WHITE);
             Rectangle r = g.getClipBounds();
             g.clearRect(r.x, r.y, r.width, r.height);
 
             m_doc.adjustInputs();
             for (int i = 0; i < m_doc.m_objects.size(); i++) {
-                Shape shape = (Shape) m_doc.m_objects.get(i);
+                Shape shape = m_doc.m_objects.get(i);
                 if (shape.m_bNeedsDrawing) {
                     shape.draw(g, this);
                 }
@@ -1368,7 +1436,7 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                 if (m_Selection.m_tracker != null) {
                     g.setColor(Color.BLACK);
                     for (int i = 0; i < m_Selection.m_tracker.size(); i++) {
-                        TrackPoint p = (TrackPoint) m_Selection.m_tracker
+                        TrackPoint p = m_Selection.m_tracker
                                 .get(i);
                         g.fillRect(p.m_nX - 4, p.m_nY - 4, 8, 8);
                     }
@@ -1391,7 +1459,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
          *
          * @see Printable
          */
-        public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
+        @Override
+		public int print(Graphics g, PageFormat pageFormat, int pageIndex) {
             if (pageIndex > 0) {
                 return (NO_SUCH_PAGE);
             } else {
@@ -1413,13 +1482,14 @@ public class ModelBuilder extends JPanel implements ComponentListener {
 
         class GBDrawMouseMotionListener extends MouseMotionAdapter {
 
-            public void mouseDragged(MouseEvent me) {
+            @Override
+			public void mouseDragged(MouseEvent me) {
                 switch (m_nMode) {
                     case MODE_SELECT:
                         if (m_bIsMoving || m_Selection.isSingleSelection()
                                 && m_Selection.intersects(me.getX(), me.getY())) {
                             m_bIsMoving = true;
-                            Shape shape = (Shape) m_doc.m_objects.get(m_Selection
+                            Shape shape = m_doc.m_objects.get(m_Selection
                                     .getSingleSelection());
                             if (getCursor().getType() == Cursor.DEFAULT_CURSOR) {
                                 // simple move operation
@@ -1485,26 +1555,26 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                     case MODE_ARROW:
                         Arrow arrow = (Arrow) m_drawShape;
                         if (m_drawShape == null) {
-                            int iSelection = -1;
-                            for (int i = 0; iSelection < 0
+                            int selectionIndex = -1;
+                            for (int i = 0; selectionIndex < 0
                                     && i < m_doc.m_objects.size(); i++) {
-                                Shape shape = (Shape) m_doc.m_objects.get(i);
+                                Shape shape = m_doc.m_objects.get(i);
                                 if (shape.m_bNeedsDrawing
                                         && shape.intersects(me.getX(), me.getY())) {
                                     m_nPosX = shape.offsetX(me.getX());
                                     m_nPosY = shape.offsetY(me.getY());
-                                    iSelection = i;
+                                    selectionIndex = i;
                                 }
                             }
-                            if (iSelection < 0) {
+                            if (selectionIndex < 0) {
                                 return;
                             }
-                            Shape shape = (Shape) m_doc.m_objects.get(iSelection);
+                            Shape shape = m_doc.m_objects.get(selectionIndex);
                             if (shape instanceof Arrow) {
                                 return;
                             }
                             if (shape instanceof InputShape) {
-                                shape = ((InputShape) shape).m_pluginShape;
+                                shape = ((InputShape) shape).m_beastObjectShape;
                             }
                             arrow = new Arrow((BEASTObjectShape) shape, me.getX(), me
                                     .getY());
@@ -1521,14 +1591,15 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                 }
             } // mouseDragged
 
-            public void mouseMoved(MouseEvent me) {
+            @Override
+			public void mouseMoved(MouseEvent me) {
                 if (m_Selection.m_tracker != null
                         && m_Selection.isSingleSelection()) {
                     if (getCursor().getType() != Cursor.DEFAULT_CURSOR) {
                         setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
                     }
                     for (int i = 0; i < m_Selection.m_tracker.size(); i++) {
-                        TrackPoint p = (TrackPoint) m_Selection.m_tracker
+                        TrackPoint p = m_Selection.m_tracker
                                 .get(i);
                         if (me.getX() > p.m_nX - 4 && me.getX() < p.m_nX + 4
                                 && me.getY() > p.m_nY - 4
@@ -1540,7 +1611,7 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                             return;
                         }
                     }
-                    Shape shape = (Shape) m_doc.m_objects.get(m_Selection
+                    Shape shape = m_doc.m_objects.get(m_Selection
                             .getSingleSelection());
                     m_nPosX = me.getX() - shape.m_x;
                     m_nPosY = me.getY() - shape.m_y;
@@ -1552,18 +1623,18 @@ public class ModelBuilder extends JPanel implements ComponentListener {
 
                 // set up tool tip text
                 for (int i = m_doc.m_objects.size() - 1; i >= 0; i--) {
-                    Shape shape = (Shape) m_doc.m_objects.get(i);
+                    Shape shape = m_doc.m_objects.get(i);
                     if (shape.m_bNeedsDrawing
                             && shape.intersects(me.getX(), me.getY())) {
                         if (shape instanceof BEASTObjectShape) {
-                            BEASTObjectShape plugin = (BEASTObjectShape) shape;
+                            BEASTObjectShape beastObject = (BEASTObjectShape) shape;
                             try {
-                                String sToolTip = "<html>";
-                                for (InputShape input : plugin.m_inputs) {
-                                    sToolTip += input.getLongLabel() + "<br>";
+                                String toolTip = "<html>";
+                                for (InputShape input : beastObject.m_inputs) {
+                                    toolTip += input.getLongLabel() + "<br>";
                                 }
-                                sToolTip += "</html>";
-                                setToolTipText(sToolTip);
+                                toolTip += "</html>";
+                                setToolTipText(toolTip);
                             } catch (IllegalArgumentException e) {
                                 // TODO Auto-generated catch block
                                 e.printStackTrace();
@@ -1578,7 +1649,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
         } // class GBDrawMouseMotionListener
 
         class GBDrawMouseEventListener extends MouseAdapter {
-            public void mouseClicked(MouseEvent me) {
+            @Override
+			public void mouseClicked(MouseEvent me) {
                 if (me.getClickCount() == 2) {
                     handleDoubleClick(me);
                     return;
@@ -1591,35 +1663,35 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                 // otherwise, assume left click
                 switch (m_nMode) {
                     case MODE_SELECT:
-                        int iSelection = -1;
-                        for (int i = m_doc.m_objects.size() - 1; iSelection < 0 && i >= 0; i--) {
-                            Shape shape = (Shape) m_doc.m_objects.get(i);
+                        int selectionIndex = -1;
+                        for (int i = m_doc.m_objects.size() - 1; selectionIndex < 0 && i >= 0; i--) {
+                            Shape shape = m_doc.m_objects.get(i);
                             if (shape.m_bNeedsDrawing && !(shape instanceof Arrow) && shape.intersects(me.getX(), me.getY())) {
                                 m_nPosX = shape.offsetX(me.getX());
                                 m_nPosY = shape.offsetY(me.getY());
-                                iSelection = i;
+                                selectionIndex = i;
                             }
                         }
-                        if (iSelection < 0) {
-                            for (int i = m_doc.m_objects.size() - 1; iSelection < 0 && i >= 0; i--) {
-                                Shape shape = (Shape) m_doc.m_objects.get(i);
+                        if (selectionIndex < 0) {
+                            for (int i = m_doc.m_objects.size() - 1; selectionIndex < 0 && i >= 0; i--) {
+                                Shape shape = m_doc.m_objects.get(i);
                                 if (shape.m_bNeedsDrawing && shape.intersects(me.getX(), me.getY())) {
                                     m_nPosX = shape.offsetX(me.getX());
                                     m_nPosY = shape.offsetY(me.getY());
-                                    iSelection = i;
+                                    selectionIndex = i;
                                 }
                             }
-                            if (iSelection < 0) {
+                            if (selectionIndex < 0) {
                                 return;
                             }
                         }
-                        if ((me.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0) {
-                            m_Selection.toggleSelection(iSelection);
-                        } else if ((me.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) != 0) {
-                            m_Selection.addToSelection(iSelection);
+                        if ((me.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0) {
+                            m_Selection.toggleSelection(selectionIndex);
+                        } else if ((me.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK) != 0) {
+                            m_Selection.addToSelection(selectionIndex);
                         } else {
                             m_Selection.clear();
-                            m_Selection.setSingleSelection(iSelection);
+                            m_Selection.setSingleSelection(selectionIndex);
                         }
                         updateStatus();
                         break;
@@ -1636,20 +1708,20 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                             if (shape instanceof InputShape) {
                                 // resolve the associated input
                                 InputShape ellipse = (InputShape) shape;
-                                String sInput = ellipse.getInputName();
-                                BEASTInterface plugin = ellipse.getPlugin();
-                                if (plugin.isPrimitive(sInput)) {
-                                    String sValue = "";
-                                    if (plugin.getInputValue(sInput) != null) {
-                                        sValue = plugin.getInputValue(sInput)
+                                String input = ellipse.getInputName();
+                                BEASTInterface beastObject = ellipse.getBEASTObject();
+                                if (beastObject.isPrimitive(input)) {
+                                    String valueString = "";
+                                    if (beastObject.getInputValue(input) != null) {
+                                        valueString = beastObject.getInputValue(input)
                                                 .toString();
                                     }
-                                    sValue = JOptionPane.showInputDialog(sInput
-                                            + ":", sValue);
-                                    if (sValue != null) {
-                                        m_doc.setInputValue(ellipse.getPluginShape(), sInput, sValue);
-                                        // ellipse.setLabel(sInput + "=" +
-                                        // plugin.getInputValue(sInput).toString());
+                                    valueString = JOptionPane.showInputDialog(input
+                                            + ":", valueString);
+                                    if (valueString != null) {
+                                        m_doc.setInputValue(ellipse.getPluginShape(), input, valueString);
+                                        // ellipse.setLabel(input + "=" +
+                                        // beastObject.getInputValue(input).toString());
                                         g_panel.repaint();
                                     }
                                 }
@@ -1669,10 +1741,10 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                 JPopupMenu popupMenu = new JPopupMenu("Choose a value");
 
                 if (!m_Selection.hasSelection()) {
-                    int iSelection = -1;
-                    for (int i = 0; iSelection < 0
+                    int selectionIndex = -1;
+                    for (int i = 0; selectionIndex < 0
                             && i < m_doc.m_objects.size(); i++) {
-                        Shape shape = (Shape) m_doc.m_objects.get(i);
+                        Shape shape = m_doc.m_objects.get(i);
                         if (shape.m_bNeedsDrawing
                                 && shape.intersects(me.getX(), me.getY())) {
                             m_nPosX = shape.offsetX(me.getX());
@@ -1685,21 +1757,22 @@ public class ModelBuilder extends JPanel implements ComponentListener {
 
                 JMenuItem addNodeItem = new JMenuItem("Change label");
                 ActionListener label = new ActionListener() {
-                    public void actionPerformed(ActionEvent ae) {
+                    @Override
+					public void actionPerformed(ActionEvent ae) {
                         Shape shape = m_Selection.getSingleSelectionShape();
-                        String sName = (String) JOptionPane.showInputDialog(
+                        String name = (String) JOptionPane.showInputDialog(
                                 null, shape.getID(), "New label",
                                 JOptionPane.OK_CANCEL_OPTION, null, null, shape
                                 .getID());
-                        if (sName == null || sName.equals("")) {
+                        if (name == null || name.equals("")) {
                             return;
                         }
-                        while (sName.contains("\\n")) {
-                            int i = sName.indexOf("\\n");
-                            sName = sName.substring(0, i - 1) + '\n'
-                                    + sName.substring(i + 2);
+                        while (name.contains("\\n")) {
+                            int i = name.indexOf("\\n");
+                            name = name.substring(0, i - 1) + '\n'
+                                    + name.substring(i + 2);
                         }
-                        m_doc.setID(sName, m_Selection.getSingleSelection());
+                        m_doc.setID(name, m_Selection.getSingleSelection());
                         repaint();
                     }
                 };
@@ -1714,40 +1787,37 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                         isFilledMenu = new JMenuItem("Don't fill object");
                     }
                 }
-                isFilledMenu.addActionListener(new ActionListener() {
-                    public void actionPerformed(ActionEvent ae) {
+                isFilledMenu.addActionListener(ae -> {
                         m_doc.toggleFilled(m_Selection.getSingleSelection());
                         g_panel.repaint();
-                    }
-                });
+                    });
                 isFilledMenu.setEnabled(m_Selection.isSingleSelection());
                 popupMenu.add(isFilledMenu);
 
                 JMenuItem propertiesItem = new JMenuItem("Properties");
-                propertiesItem.addActionListener(new ActionListener() {
-                    public void actionPerformed(ActionEvent ae) {
+                propertiesItem.addActionListener(ae -> {
                         Shape shape = m_Selection.getSingleSelectionShape();
                         if (shape instanceof BEASTObjectShape) {
-                            BEASTInterface plugin = ((BEASTObjectShape) shape).m_plugin;
+                            BEASTInterface beastObject = ((BEASTObjectShape) shape).m_beastObject;
 
-                            List<BEASTInterface> plugins = new ArrayList<BEASTInterface>();
+                            List<BEASTInterface> beastObjects = new ArrayList<>();
                             for (Shape shape2 : m_doc.m_objects) {
                                 if (shape2 instanceof BEASTObjectShape) {
-                                    plugins.add(((BEASTObjectShape) shape2).m_plugin);
+                                    beastObjects.add(((BEASTObjectShape) shape2).m_beastObject);
                                 }
                             }
-                            BEASTObjectDialog dlg = new BEASTObjectDialog(plugin, plugin.getClass(), plugins, null);
+                            BEASTObjectDialog dlg = new BEASTObjectDialog(beastObject, beastObject.getClass(), beastObjects, null);
                             if (dlg.showDialog()) {
                                 // add newly created Plug-ins
-                                int nNewShapes = 0;
-                                if (plugins.size() < BEASTObjectPanel.g_plugins.size()) {
-                                    for (BEASTInterface plugin2 : BEASTObjectPanel.g_plugins.values()) {
-                                        if (!plugins.contains(plugin2)) {
+                                int newShapes = 0;
+                                if (beastObjects.size() < BEASTObjectPanel.g_plugins.size()) {
+                                    for (BEASTInterface beastObject2 : BEASTObjectPanel.g_plugins.values()) {
+                                        if (!beastObjects.contains(beastObject2)) {
                                             try {
-                                                nNewShapes++;
-                                                Shape shape2 = new BEASTObjectShape(plugin2, m_doc);
+                                                newShapes++;
+                                                Shape shape2 = new BEASTObjectShape(beastObject2, m_doc);
                                                 shape2.m_x = 10;
-                                                shape2.m_y = nNewShapes * 50;
+                                                shape2.m_y = newShapes * 50;
                                                 shape2.m_w = 80;
                                                 m_doc.addNewShape(shape2);
                                                 updateStatus();
@@ -1764,19 +1834,17 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                             }
                             repaint();
                         }
-                    }
-                });
+                    });
                 propertiesItem.setEnabled(m_Selection.isSingleSelection());
                 popupMenu.add(propertiesItem);
 
                 JMenuItem saveAsItem = new JMenuItem("Save as");
-                saveAsItem.addActionListener(new ActionListener() {
-                    public void actionPerformed(ActionEvent ae) {
+                saveAsItem.addActionListener(ae -> {
                         Shape shape = m_Selection.getSingleSelectionShape();
-                        BEASTInterface plugin = ((BEASTObjectShape) shape).m_plugin;
+                        BEASTInterface beastObject = ((BEASTObjectShape) shape).m_beastObject;
                         JFileChooser fc = new JFileChooser(m_sDir);
                         fc.addChoosableFileFilter(ef1);
-                        fc.setDialogTitle("Save Plugin As");
+                        fc.setDialogTitle("Save BEASTObject As");
                         if (!m_sFileName.equals("")) {
                             // can happen on actionQuit
                             fc.setSelectedFile(new File(m_sFileName));
@@ -1786,16 +1854,16 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                         if (rval == JFileChooser.APPROVE_OPTION) {
                             // System.out.println("Saving to file \""+
                             // f.getAbsoluteFile().toString()+"\"");
-                            String sFileName = fc.getSelectedFile().toString();
-                            if (sFileName.lastIndexOf('/') > 0) {
-                                m_sDir = sFileName.substring(0, sFileName
+                            String fileName = fc.getSelectedFile().toString();
+                            if (fileName.lastIndexOf('/') > 0) {
+                                m_sDir = fileName.substring(0, fileName
                                         .lastIndexOf('/'));
                             }
-                            if (!sFileName.endsWith(FILE_EXT))
-                                sFileName = sFileName.concat(FILE_EXT);
+                            if (!fileName.endsWith(FILE_EXT))
+                                fileName = fileName.concat(FILE_EXT);
                             try {
-                                FileWriter outfile = new FileWriter(sFileName);
-                                outfile.write(new XMLProducer().modelToXML(plugin));
+                                FileWriter outfile = new FileWriter(fileName);
+                                outfile.write(new XMLProducer().modelToXML(beastObject));
                                 outfile.close();
                             } catch (Exception e) {
                                 JOptionPane.showMessageDialog(null,
@@ -1803,11 +1871,10 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                                                 + e.getClass().getName() + " "
                                                 + e.getMessage());
                             }
-                            m_sFileName = sFileName;
+                            m_sFileName = fileName;
                         }
                         repaint();
-                    }
-                });
+                    });
                 saveAsItem.setEnabled(m_Selection.isSingleSelection());
                 popupMenu.add(saveAsItem);
 
@@ -1815,27 +1882,28 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                 popupMenu.show(g_panel, me.getX(), me.getY());
             } // handleRightClick
 
-            public void mouseReleased(MouseEvent me) {
+            @Override
+			public void mouseReleased(MouseEvent me) {
                 if (m_drawShape != null) {
                     m_drawShape.normalize();
                 }
                 m_bIsMoving = false;
-                boolean bAdded = true;
+                boolean added = true;
                 switch (m_nMode) {
                     case MODE_SELECT:
                         if (m_selectRect != null) {
 
-                            if ((me.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) == 0
-                                    && (me.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) == 0) {
+                            if ((me.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) == 0
+                                    && (me.getModifiersEx() & InputEvent.SHIFT_DOWN_MASK) == 0) {
                                 // fresh selection
                                 m_Selection.clear();
                             }
 
                             for (int i = 0; i < m_doc.m_objects.size(); i++) {
-                                if (((Shape) m_doc.m_objects.get(i))
+                                if (m_doc.m_objects.get(i)
                                         .intersects(m_selectRect)
-                                        && ((Shape) m_doc.m_objects.get(i)).m_bNeedsDrawing) {
-                                    if ((me.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0) {
+                                        && m_doc.m_objects.get(i).m_bNeedsDrawing) {
+                                    if ((me.getModifiersEx() & InputEvent.CTRL_DOWN_MASK) != 0) {
                                         m_Selection.toggleSelection(i);
                                     } else {
                                         m_Selection.addToSelection(i);
@@ -1856,13 +1924,13 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                             return;
                         }
                         if (function.m_w > 0 && function.m_h > 0) {
-                            String sFunctionClassName = (String) JOptionPane
+                            String functionClassName = (String) JOptionPane
                                     .showInputDialog(g_panel, "Select a constant",
                                             "select", JOptionPane.PLAIN_MESSAGE,
                                             null, m_doc.m_sPlugInNames, null);
-                            if (sFunctionClassName != null) {
+                            if (functionClassName != null) {
                                 try {
-                                    function.init(sFunctionClassName, m_doc);
+                                    function.init(functionClassName, m_doc);
                                     m_doc.addNewShape(function);
                                     updateStatus();
                                 } catch (Exception e) {
@@ -1870,32 +1938,32 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                                     e.printStackTrace();
                                 }
                             } else {
-                                bAdded = false;
+                                added = false;
                             }
                         } else {
-                            bAdded = false;
+                            added = false;
                         }
                         break;
                     case MODE_ARROW:
                         Arrow arrow = (Arrow) m_drawShape;
                         if (m_drawShape != null) {
-                            int iSelection = -1;
-                            for (int i = 0; iSelection < 0
+                            int selectionIndex = -1;
+                            for (int i = 0; selectionIndex < 0
                                     && i < m_doc.m_objects.size(); i++) {
-                                Shape shape = (Shape) m_doc.m_objects.get(i);
+                                Shape shape = m_doc.m_objects.get(i);
                                 if (shape.m_bNeedsDrawing
                                         && shape.intersects(me.getX(), me.getY())) {
                                     m_nPosX = shape.offsetX(me.getX());
                                     m_nPosY = shape.offsetY(me.getY());
-                                    iSelection = i;
+                                    selectionIndex = i;
                                 }
                             }
-                            if (iSelection < 0) {
+                            if (selectionIndex < 0) {
                                 m_drawShape = null;
                                 repaint();
                                 return;
                             }
-                            Shape target = m_doc.m_objects.get(iSelection);
+                            Shape target = m_doc.m_objects.get(selectionIndex);
                             if (!(target instanceof InputShape)) {
                                 // only connect to inputs of functions
                                 m_drawShape = null;
@@ -1905,8 +1973,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
 
                             // check no cycle is introduced
                             InputShape target2 = (InputShape) target;
-                            if (m_doc.isAscendant(arrow.m_tailShape.m_plugin,
-                                    target2.getPlugin())) {
+                            if (m_doc.isAscendant(arrow.m_tailShape.m_beastObject,
+                                    target2.getBEASTObject())) {
                                 JOptionPane
                                         .showMessageDialog(null,
                                                 "Cannot make this connection since this creates a cycle in the model");
@@ -1915,8 +1983,8 @@ public class ModelBuilder extends JPanel implements ComponentListener {
 
                             try {
                                 // try to add connection
-                                // this links the input of the target plugin
-                                // to the source plugin. If types mismatch,
+                                // this links the input of the target beastObject
+                                // to the source beastObject. If types mismatch,
                                 // an exception is thrown and no arrow added.
                                 arrow.setHead(target2, m_doc.m_objects, m_doc);
                                 m_doc.addNewShape(arrow);
@@ -1929,7 +1997,7 @@ public class ModelBuilder extends JPanel implements ComponentListener {
                 }
                 m_drawShape = null;
                 m_nMode = MODE_SELECT;
-                if (bAdded) {
+                if (added) {
                     m_Selection.setSingleSelection(m_doc.m_objects.size() - 1);
                     g_panel.repaint();
                 } else {
@@ -2003,89 +2071,72 @@ public class ModelBuilder extends JPanel implements ComponentListener {
         menuBar.add(viewMenu);
         final JCheckBoxMenuItem viewOperators = new JCheckBoxMenuItem(
                 "Show Operators", m_bViewOperators);
-        viewOperators.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
+        viewOperators.addActionListener(ae -> {
                 m_bViewOperators = viewOperators.getState();
                 setDrawingFlag();
                 g_panel.repaint();
-            }
-        });
+            });
         viewMenu.add(viewOperators);
         final JCheckBoxMenuItem viewLoggers = new JCheckBoxMenuItem(
                 "Show Loggers", m_bViewLoggers);
-        viewLoggers.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
+        viewLoggers.addActionListener(ae -> {
                 m_bViewLoggers = viewLoggers.getState();
                 setDrawingFlag();
                 g_panel.repaint();
-            }
-        });
+            });
         viewMenu.add(viewLoggers);
         final JCheckBoxMenuItem viewSequences = new JCheckBoxMenuItem(
                 "Show Sequences", m_bViewSequences);
-        viewSequences.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
+        viewSequences.addActionListener(ae -> {
                 m_bViewSequences = viewSequences.getState();
                 setDrawingFlag();
                 g_panel.repaint();
-            }
-        });
+            });
         viewMenu.add(viewSequences);
         final JCheckBoxMenuItem viewState = new JCheckBoxMenuItem("Show State",
                 m_bViewState);
-        viewState.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
+        viewState.addActionListener(ae -> {
                 m_bViewState = viewState.getState();
                 setDrawingFlag();
                 g_panel.repaint();
-            }
-        });
+            });
         viewMenu.add(viewState);
         m_viewRelax = new JCheckBoxMenuItem("Relax", m_bRelax);
-        m_viewRelax.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
+        m_viewRelax.addActionListener(ae -> {
                 m_bRelax = m_viewRelax.getState();
                 g_panel.repaint();
-            }
-        });
+            });
         viewMenu.add(m_viewRelax);
 
         JMenuItem layoutMenu = new JMenuItem("Layout Visible Items");
         layoutMenu.setMnemonic('L');
-        layoutMenu.addActionListener(new ActionListener() {
-            // implement ActionListener
-            public void actionPerformed(ActionEvent e) {
+        layoutMenu.addActionListener(e -> {
                 g_panel.setCursor(new Cursor(Cursor.WAIT_CURSOR));
                 m_doc.layout();
                 m_doc.adjustArrows();
                 repaint();
                 g_panel.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
-            }
-        });
+            });
         viewMenu.add(layoutMenu);
         viewMenu.addSeparator();
 
         final JCheckBoxMenuItem viewAllInputs = new JCheckBoxMenuItem("Show All Inputs",
                 m_doc.m_bShowALlInputs);
-        viewAllInputs.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
+        viewAllInputs.addActionListener(ae -> {
             	m_doc.m_bShowALlInputs = viewAllInputs.getState();
             	m_doc.reinit();
                 setDrawingFlag();
                 g_panel.repaint();
-            }
-        });
+            });
         viewMenu.add(viewAllInputs);
 
         final JCheckBoxMenuItem sanitseIDs = new JCheckBoxMenuItem("Sanitise IDs",
                 m_doc.m_bSanitiseIDs);
-        sanitseIDs.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
+        sanitseIDs.addActionListener(ae -> {
             	m_doc.m_bSanitiseIDs = sanitseIDs.getState();
                 setDrawingFlag();
                 g_panel.repaint();
-            }
-        });
+            });
         viewMenu.add(sanitseIDs);
         
         
@@ -2132,25 +2183,29 @@ public class ModelBuilder extends JPanel implements ComponentListener {
 
     // implements ComponentListener
 
-    public void componentHidden(ComponentEvent e) {
+    @Override
+	public void componentHidden(ComponentEvent e) {
         m_jScrollPane.revalidate();
     }
 
     // implements ComponentListener
 
-    public void componentMoved(ComponentEvent e) {
+    @Override
+	public void componentMoved(ComponentEvent e) {
         m_jScrollPane.revalidate();
     }
 
     // implements ComponentListener
 
-    public void componentResized(ComponentEvent e) {
+    @Override
+	public void componentResized(ComponentEvent e) {
         m_jScrollPane.revalidate();
     }
 
     // implements ComponentListener
 
-    public void componentShown(ComponentEvent e) {
+    @Override
+	public void componentShown(ComponentEvent e) {
         m_jScrollPane.revalidate();
     }
 
diff --git a/src/beast/app/draw/MyAction.java b/src/beast/app/draw/MyAction.java
index f41bcc1..d3dcf02 100644
--- a/src/beast/app/draw/MyAction.java
+++ b/src/beast/app/draw/MyAction.java
@@ -27,24 +27,24 @@ public abstract class MyAction extends AbstractAction {
      * path for icons
      */
 
-    public MyAction(String sName, String sToolTipText, String sIcon, int acceleratorKey) {
-        this(sName, sToolTipText, sIcon, KeyStroke.getKeyStroke(acceleratorKey, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
+    public MyAction(String name, String toolTipText, String icon, int acceleratorKey) {
+        this(name, toolTipText, icon, KeyStroke.getKeyStroke(acceleratorKey, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
     } // c'tor
 
-    public MyAction(String sName, String sToolTipText, String sIcon, String sAcceleratorKey) {
-        this(sName, sToolTipText, sIcon, KeyStroke.getKeyStroke(sAcceleratorKey));
+    public MyAction(String name, String toolTipText, String icon, String acceleratorKey) {
+        this(name, toolTipText, icon, KeyStroke.getKeyStroke(acceleratorKey));
     } // c'tor
 
-    public MyAction(String sName, String sToolTipText, String sIcon, KeyStroke acceleratorKeystroke) {
-        super(sName);
-        // setToolTipText(sToolTipText);
-        putValue(Action.SHORT_DESCRIPTION, sToolTipText);
-        putValue(Action.LONG_DESCRIPTION, sToolTipText);
+    public MyAction(String name, String toolTipText, String icon, KeyStroke acceleratorKeystroke) {
+        super(name);
+        // setToolTipText(toolTipText);
+        putValue(Action.SHORT_DESCRIPTION, toolTipText);
+        putValue(Action.LONG_DESCRIPTION, toolTipText);
         if (acceleratorKeystroke != null && acceleratorKeystroke.getKeyCode() >= 0) {
             putValue(Action.ACCELERATOR_KEY, acceleratorKeystroke);
         }
-        putValue(Action.MNEMONIC_KEY, new Integer(sName.charAt(0)));
-        java.net.URL tempURL = ClassLoader.getSystemResource(ModelBuilder.ICONPATH + sIcon + ".png");
+        putValue(Action.MNEMONIC_KEY, new Integer(name.charAt(0)));
+        java.net.URL tempURL = ClassLoader.getSystemResource(ModelBuilder.ICONPATH + icon + ".png");
         if (!Utils.isMac()) {
 	        if (tempURL != null) {
 	            putValue(Action.SMALL_ICON, new ImageIcon(tempURL));
@@ -62,6 +62,7 @@ public abstract class MyAction extends AbstractAction {
       * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent
       * )
       */
-    abstract public void actionPerformed(ActionEvent ae);
+    @Override
+	abstract public void actionPerformed(ActionEvent ae);
 
 } // class MyAction
diff --git a/src/beast/app/draw/ParameterInputEditor.java b/src/beast/app/draw/ParameterInputEditor.java
index 122455d..ea45dff 100644
--- a/src/beast/app/draw/ParameterInputEditor.java
+++ b/src/beast/app/draw/ParameterInputEditor.java
@@ -2,8 +2,6 @@ package beast.app.draw;
 
 
 import java.awt.Color;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.util.List;
 
 import javax.swing.BorderFactory;
@@ -18,13 +16,12 @@ import beast.app.beauti.BeautiDoc;
 import beast.app.beauti.BeautiPanel;
 import beast.app.beauti.PartitionContext;
 import beast.app.util.Utils;
+import beast.core.BEASTInterface;
 import beast.core.Distribution;
 import beast.core.Input;
 import beast.core.Operator;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 import beast.core.parameter.Parameter;
-import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
 import beast.evolution.branchratemodel.BranchRateModel;
 import beast.math.distributions.ParametricDistribution;
 
@@ -50,9 +47,9 @@ public class ParameterInputEditor extends BEASTObjectInputEditor {
     
     
     @Override
-    public void init(Input<?> input, BEASTInterface plugin, int itemNr, ExpandOption bExpandOption, boolean bAddButtons) {
-    	super.init(input, plugin, itemNr, bExpandOption, bAddButtons);
-    	m_plugin = plugin;
+    public void init(Input<?> input, BEASTInterface beastObject, int itemNr, ExpandOption isExpandOption, boolean addButtons) {
+    	super.init(input, beastObject, itemNr, isExpandOption, addButtons);
+    	m_beastObject = beastObject;
     }
 
     @Override
@@ -66,7 +63,7 @@ public class ParameterInputEditor extends BEASTObjectInputEditor {
         		}
         		m_entry.setText(s);
         	} else {
-        		Parameter.Base<?> parameter = (Parameter.Base<?>) ((List)m_input.get()).get(itemNr);
+        		Parameter.Base<?> parameter = (Parameter.Base<?>) ((List<?>)m_input.get()).get(itemNr);
         		String s = "";
         		for (Object d : parameter.valuesInput.get()) {
         			s += d + " ";
@@ -79,21 +76,21 @@ public class ParameterInputEditor extends BEASTObjectInputEditor {
     @Override
     protected void processEntry() {
         try {
-            String sValue = m_entry.getText();
+            String valueString = m_entry.getText();
             Parameter.Base<?> parameter = (Parameter.Base<?>) m_input.get();
         	String oldValue = "";
     		for (Object d : parameter.valuesInput.get()) {
     			oldValue += d + " ";
     		}
             int oldDim = parameter.getDimension();
-            parameter.valuesInput.setValue(sValue, parameter);
+            parameter.valuesInput.setValue(valueString, parameter);
             parameter.initAndValidate();
             int newDim = parameter.getDimension();
             if (oldDim != newDim) {
             	parameter.setDimension(oldDim);
                 parameter.valuesInput.setValue(oldValue, parameter);
                 parameter.initAndValidate();
-                throw new Exception("Entry caused change in dimension");
+                throw new IllegalArgumentException("Entry caused change in dimension");
             }
             validateInput();
         } catch (Exception ex) {
@@ -106,49 +103,48 @@ public class ParameterInputEditor extends BEASTObjectInputEditor {
 
 
     @Override
-    protected void addComboBox(JComponent box, Input<?> input, BEASTInterface plugin) {
+    protected void addComboBox(JComponent box, Input<?> input, BEASTInterface beastObject) {
         Box paramBox = Box.createHorizontalBox();
         Parameter.Base<?> parameter = null;
         if (itemNr >= 0) {
-        	parameter = (Parameter.Base<?>) ((List) input.get()).get(itemNr);
+        	parameter = (Parameter.Base<?>) ((List<?>) input.get()).get(itemNr);
         } else {
         	parameter = (Parameter.Base<?>) input.get();
         }
 
         if (parameter == null) {
-            super.addComboBox(box, input, plugin);
+            super.addComboBox(box, input, beastObject);
         } else {
             setUpEntry();
             paramBox.add(m_entry);
-            if (doc.bAllowLinking) {
+            if (doc.allowLinking) {
 	            boolean isLinked = doc.isLinked(m_input);
 				if (isLinked || doc.suggestedLinks((BEASTInterface) m_input.get()).size() > 0) {
 		            JButton linkbutton = new JButton(Utils.getIcon(BeautiPanel.ICONPATH + 
 		            		(isLinked ? "link.png" : "unlink.png")));
 		            linkbutton.setBorder(BorderFactory.createEmptyBorder());
 		            linkbutton.setToolTipText("link/unlink this parameter with another compatible parameter");
-		            linkbutton.addActionListener(new ActionListener() {
-						@Override
-						public void actionPerformed(ActionEvent e) {
+		            linkbutton.addActionListener(e -> {
 							if (doc.isLinked(m_input)) {
 								// unlink
 								try {
-									BEASTInterface candidate = doc.getUnlinkCandidate(m_input, m_plugin);
-									m_input.setValue(candidate, m_plugin);
+									BEASTInterface candidate = doc.getUnlinkCandidate(m_input, m_beastObject);
+									m_input.setValue(candidate, m_beastObject);
 									doc.deLink(m_input);
-								} catch (Exception e2) {
+								} catch (RuntimeException e2) {
 									e2.printStackTrace();
+									JOptionPane.showMessageDialog(this, "Could not unlink: " + e2.getMessage());
 								}
 								
 							} else {
 								// create a link
 								List<BEASTInterface> candidates = doc.suggestedLinks((BEASTInterface) m_input.get());
-								JComboBox jcb = new JComboBox(candidates.toArray());
+								JComboBox<BEASTInterface> jcb = new JComboBox<>(candidates.toArray(new BEASTInterface[]{}));
 								JOptionPane.showMessageDialog( null, jcb, "select parameter to link with", JOptionPane.QUESTION_MESSAGE);
 								BEASTInterface candidate = (BEASTInterface) jcb.getSelectedItem();
 								if (candidate != null) {
 									try {
-										m_input.setValue(candidate, m_plugin);
+										m_input.setValue(candidate, m_beastObject);
 										doc.addLink(m_input);
 									} catch (Exception e2) {
 										e2.printStackTrace();
@@ -156,8 +152,7 @@ public class ParameterInputEditor extends BEASTObjectInputEditor {
 								}
 							}
 							refreshPanel();
-						}
-					});
+						});
 		            paramBox.add(linkbutton);
 				}
             }            
@@ -171,58 +166,55 @@ public class ParameterInputEditor extends BEASTObjectInputEditor {
             }
             m_isEstimatedBox.setToolTipText(parameter.isEstimatedInput.getHTMLTipText());
 
-            boolean bIsClockRate = false;
+            boolean isClockRate = false;
             for (Object output : parameter.getOutputs()) {
                 if (output instanceof BranchRateModel.Base) {
-                    bIsClockRate |= ((BranchRateModel.Base) output).meanRateInput.get() == parameter;
+                    isClockRate |= ((BranchRateModel.Base) output).meanRateInput.get() == parameter;
                 }
             }
-            m_isEstimatedBox.setEnabled(!bIsClockRate || !getDoc().bAutoSetClockRate);
+            m_isEstimatedBox.setEnabled(!isClockRate || !getDoc().autoSetClockRate);
 
 
-            m_isEstimatedBox.addActionListener(new ActionListener() {
-                @Override
-                public void actionPerformed(ActionEvent e) {
+            m_isEstimatedBox.addActionListener(e -> {
                     try {
-                        Parameter.Base<?> parameter = (Parameter.Base<?>) m_input.get();
-                        parameter.isEstimatedInput.setValue(m_isEstimatedBox.isSelected(), parameter);
+                        Parameter.Base<?> parameter2 = (Parameter.Base<?>) m_input.get();
+                        parameter2.isEstimatedInput.setValue(m_isEstimatedBox.isSelected(), parameter2);
                         if (isParametricDistributionParameter) {
-                        	String sID = parameter.getID();
+                        	String id = parameter2.getID();
                         	
 
-                        	if (sID.startsWith("RealParameter")) {
+                        	if (id.startsWith("RealParameter")) {
                             	ParametricDistribution parent = null; 
-                	            for (Object plugin2 : parameter.getOutputs()) {
-                	                if (plugin2 instanceof ParametricDistribution) {
-                                		parent = (ParametricDistribution) plugin2; 
+                	            for (Object beastObject2 : parameter2.getOutputs()) {
+                	                if (beastObject2 instanceof ParametricDistribution) {
+                                		parent = (ParametricDistribution) beastObject2; 
                 	                    break;
                 	                }
                 	            }
                 	            Distribution grandparent = null; 
-                	            for (Object plugin2 : parent.getOutputs()) {
-                	                if (plugin2 instanceof Distribution) {
-                                		grandparent = (Distribution) plugin2; 
+                	            for (Object beastObject2 : parent.getOutputs()) {
+                	                if (beastObject2 instanceof Distribution) {
+                                		grandparent = (Distribution) beastObject2; 
                 	                    break;
                 	                }
                 	            }
-                        		sID = "parameter.hyper" + parent.getClass().getSimpleName() + "-" + 
+                        		id = "parameter.hyper" + parent.getClass().getSimpleName() + "-" + 
                         				m_input.getName() + "-" + grandparent.getID();
-                        		doc.pluginmap.remove(parameter.getID());
-                        		parameter.setID(sID);
-                        		doc.addPlugin(parameter);
+                        		doc.pluginmap.remove(parameter2.getID());
+                        		parameter2.setID(id);
+                        		doc.addPlugin(parameter2);
                         	}
                         	
                         	
-                        	PartitionContext context = new PartitionContext(sID.substring("parameter.".length()));
-                        	System.err.println(context + " " + sID);
+                        	PartitionContext context = new PartitionContext(id.substring("parameter.".length()));
+                        	Log.warning.println(context + " " + id);
                         	doc.beautiConfig.hyperPriorTemplate.createSubNet(context, true);
                         }
                         refreshPanel();
                     } catch (Exception ex) {
-                        System.err.println("ParameterInputEditor " + ex.getMessage());
+                        Log.err.println("ParameterInputEditor " + ex.getMessage());
                     }
-                }
-            });
+                });
             paramBox.add(m_isEstimatedBox);
 
             // only show the estimate flag if there is an operator that works on this parameter
@@ -231,23 +223,23 @@ public class ParameterInputEditor extends BEASTObjectInputEditor {
             //m_editPluginButton.setVisible(false);
             //m_bAddButtons = false;
             if (itemNr < 0) {
-	            for (Object plugin2 : ((BEASTInterface) m_input.get()).getOutputs()) {
-	                if (plugin2 instanceof ParametricDistribution) {
+	            for (Object beastObject2 : ((BEASTInterface) m_input.get()).getOutputs()) {
+	                if (beastObject2 instanceof ParametricDistribution) {
 	                    m_isEstimatedBox.setVisible(true);
 	                	isParametricDistributionParameter = true;
 	                    break;
 	                }
 	            }
-	            for (Object plugin2 : ((BEASTInterface) m_input.get()).getOutputs()) {
-	                if (plugin2 instanceof Operator) {
+	            for (Object beastObject2 : ((BEASTInterface) m_input.get()).getOutputs()) {
+	                if (beastObject2 instanceof Operator) {
 	                    m_isEstimatedBox.setVisible(true);
 	                    //m_editPluginButton.setVisible(true);
 	                    break;
 	                }
 	            }
             } else {
-	            for (Object plugin2 : ((BEASTInterface) ((List)m_input.get()).get(itemNr)).getOutputs()) {
-	                if (plugin2 instanceof Operator) {
+	            for (Object beastObject2 : ((BEASTInterface) ((List<?>)m_input.get()).get(itemNr)).getOutputs()) {
+	                if (beastObject2 instanceof Operator) {
 	                    m_isEstimatedBox.setVisible(true);
 	                    //m_editPluginButton.setVisible(true);
 	                    break;
@@ -263,8 +255,8 @@ public class ParameterInputEditor extends BEASTObjectInputEditor {
     protected void addValidationLabel() {
         super.addValidationLabel();
         // make edit button invisible (if it exists) when this parameter is not estimateable
-        if (m_editPluginButton != null)
-            m_editPluginButton.setVisible(m_isEstimatedBox.isVisible());
+        if (m_editBEASTObjectButton != null)
+            m_editBEASTObjectButton.setVisible(m_isEstimatedBox.isVisible());
     }
 
     @Override
diff --git a/src/beast/app/draw/Selection.java b/src/beast/app/draw/Selection.java
index 10b460c..fdfbc32 100644
--- a/src/beast/app/draw/Selection.java
+++ b/src/beast/app/draw/Selection.java
@@ -24,8 +24,10 @@
 */
 package beast.app.draw;
 
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
+
+import beast.core.util.Log;
 
 public class Selection {
     public List<TrackPoint> m_tracker = null;
@@ -33,7 +35,7 @@ public class Selection {
     Document m_doc = null;
 
     public Selection() {
-        m_Selection = new ArrayList<Integer>(1);
+        m_Selection = new ArrayList<>(1);
     } // c'tor
 
     public void setDocument(Document doc) {
@@ -49,66 +51,66 @@ public class Selection {
     }
 
     public int getSingleSelection() {
-        return ((Integer) m_Selection.get(0)).intValue();
+        return m_Selection.get(0).intValue();
     }
 
     Shape getSingleSelectionShape() {
-        return (Shape) m_doc.m_objects.get(getSingleSelection());
+        return m_doc.m_objects.get(getSingleSelection());
     }
 
-    void setSingleSelection(int nSelection) {
+    void setSingleSelection(int selection) {
         m_Selection.removeAll(m_Selection);
-        m_Selection.add(new Integer(nSelection));
-        if (nSelection >= 0) {
-            m_tracker = ((Shape) m_doc.m_objects.get(nSelection)).getTracker();
+        m_Selection.add(new Integer(selection));
+        if (selection >= 0) {
+            m_tracker = m_doc.m_objects.get(selection).getTracker();
         }
     }
 
-    //    void setSingleSelection(int nSelection, Document doc) {
+    //    void setSingleSelection(int selection, Document doc) {
 //    	m_Selection.removeAllElements();
-//    	m_Selection.add(nSelection);
-//    	m_tracker = ((Shape) doc.m_objects.get(nSelection)).getTracker();
+//    	m_Selection.add(selection);
+//    	m_tracker = ((Shape) doc.m_objects.get(selection)).getTracker();
 //    }
-    boolean contains(int iSelection) {
+    boolean contains(int selectionIndex) {
         for (int i = 0; i < m_Selection.size(); i++) {
-            if (iSelection == ((Integer) m_Selection.get(i)).intValue()) {
+            if (selectionIndex == m_Selection.get(i).intValue()) {
                 return true;
             }
         }
         return false;
     } // contains
 
-    void addToSelection(int iSelection) {
-        if (contains(iSelection)) {
+    void addToSelection(int selectionIndex) {
+        if (contains(selectionIndex)) {
             return;
         }
-        m_Selection.add(new Integer(iSelection));
-        List<TrackPoint> tracker = ((Shape) m_doc.m_objects.get(iSelection)).getTracker();
+        m_Selection.add(new Integer(selectionIndex));
+        List<TrackPoint> tracker = m_doc.m_objects.get(selectionIndex).getTracker();
         if (m_tracker == null) {
-            m_tracker = new ArrayList<TrackPoint>();
+            m_tracker = new ArrayList<>();
         }
         m_tracker.addAll(tracker);
     } // addToSelection
 
-    void toggleSelection(int iSelection) {
-        if (!contains(iSelection)) {
-            addToSelection(iSelection);
+    void toggleSelection(int selectionIndex) {
+        if (!contains(selectionIndex)) {
+            addToSelection(selectionIndex);
         } else {
             m_tracker.removeAll(m_tracker);
             for (int i = 0; i < m_Selection.size(); i++) {
-                if (iSelection == ((Integer) m_Selection.get(i)).intValue()) {
+                if (selectionIndex == m_Selection.get(i).intValue()) {
                     m_Selection.remove(i);
                     i--;
                 } else {
-                    List<TrackPoint> tracker = ((Shape) m_doc.m_objects.get(((Integer) m_Selection.get(i)).intValue())).getTracker();
+                    List<TrackPoint> tracker = m_doc.m_objects.get(m_Selection.get(i).intValue()).getTracker();
                     m_tracker.addAll(tracker);
                 }
             }
         }
         for (int i = 0; i < m_Selection.size(); i++) {
-            System.err.print((Integer) m_Selection.get(i) + " ");
+        	Log.warning.print(m_Selection.get(i) + " ");
         }
-        System.err.println();
+        Log.warning.println();
     } // toggleSelection
 
     public void clear() {
@@ -116,17 +118,17 @@ public class Selection {
         m_tracker = null;
     } // clear
 
-    boolean intersects(int nX, int nY) {
+    boolean intersects(int x, int y) {
         for (int i = 0; i < m_Selection.size(); i++) {
-            int iShape = ((Integer) m_Selection.get(i)).intValue();
-            if (((Shape) m_doc.m_objects.get(iShape)).intersects(nX, nY)) {
+            int shapeIndex = m_Selection.get(i).intValue();
+            if (m_doc.m_objects.get(shapeIndex).intersects(x, y)) {
                 return true;
             }
         }
         if (m_tracker != null) {
             for (int i = 0; i < m_tracker.size(); i++) {
-                TrackPoint p = (TrackPoint) m_tracker.get(i);
-                if (nX > p.m_nX - 5 && nX < p.m_nX + 5 && nY > p.m_nY - 5 && nY < p.m_nY + 5) {
+                TrackPoint p = m_tracker.get(i);
+                if (x > p.m_nX - 5 && x < p.m_nX + 5 && y > p.m_nY - 5 && y < p.m_nY + 5) {
                     return true;
                 }
             }
@@ -136,25 +138,25 @@ public class Selection {
 
     void offset(int dX, int dY) {
         for (int i = 0; i < m_tracker.size(); i++) {
-            TrackPoint p = (TrackPoint) m_tracker.get(i);
+            TrackPoint p = m_tracker.get(i);
             p.m_nX += dX;
             p.m_nY += dY;
         }
         for (int i = 0; i < m_Selection.size(); i++) {
-            int iShape = ((Integer) m_Selection.get(i)).intValue();
-            Shape shape = (Shape) m_doc.m_objects.get(iShape);
+            int shapeIndex = m_Selection.get(i).intValue();
+            Shape shape = m_doc.m_objects.get(shapeIndex);
             shape.offset(dX, dY);
         }
     }
 
     public void refreshTracker() {
         if (m_tracker == null) {
-            m_tracker = new ArrayList<TrackPoint>();
+            m_tracker = new ArrayList<>();
         }
         m_tracker.removeAll(m_tracker);
         for (int i = 0; i < m_Selection.size(); i++) {
-            int iSelection = ((Integer) m_Selection.get(i)).intValue();
-            List<TrackPoint> tracker = ((Shape) m_doc.m_objects.get(iSelection)).getTracker();
+            int selectionIndex = m_Selection.get(i).intValue();
+            List<TrackPoint> tracker = m_doc.m_objects.get(selectionIndex).getTracker();
             m_tracker.addAll(tracker);
         }
     }
diff --git a/src/beast/app/draw/Shape.java b/src/beast/app/draw/Shape.java
index f9e62b2..05e7583 100644
--- a/src/beast/app/draw/Shape.java
+++ b/src/beast/app/draw/Shape.java
@@ -29,11 +29,10 @@ import java.awt.Cursor;
 import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.Graphics2D;
-
 import java.awt.Rectangle;
 import java.io.PrintStream;
-import java.util.List;
 import java.util.ArrayList;
+import java.util.List;
 
 import javax.swing.JPanel;
 
@@ -75,25 +74,25 @@ abstract public class Shape {
     void drawLabel(Graphics2D g) {
         if (getLabel() != null) {
             FontMetrics fm = g.getFontMetrics(g.getFont());
-            String sLabel = getLabel();
+            String label = getLabel();
             if (m_doc != null && m_doc.sanitiseIDs()) {
-            	if (sLabel.contains(".")) {
-            		sLabel = sLabel.substring(0, sLabel.indexOf('.'));
+            	if (label.contains(".")) {
+            		label = label.substring(0, label.indexOf('.'));
             	}
             }
             int i = 0;
-            while (sLabel.indexOf('\n') >= 0) {
-                String sStr = sLabel.substring(0, sLabel.indexOf('\n'));
-                g.drawString(sStr, m_x + m_w / 2 - fm.stringWidth(sStr) / 2, m_y + m_h / 2 + i * fm.getHeight());
-                sLabel = sLabel.substring(sStr.length() + 1);
+            while (label.indexOf('\n') >= 0) {
+                String str = label.substring(0, label.indexOf('\n'));
+                g.drawString(str, m_x + m_w / 2 - fm.stringWidth(str) / 2, m_y + m_h / 2 + i * fm.getHeight());
+                label = label.substring(str.length() + 1);
                 i++;
             }
-            g.drawString(sLabel, m_x + m_w / 2 - fm.stringWidth(sLabel) / 2, m_y + m_h / 2 + i * fm.getHeight());
+            g.drawString(label, m_x + m_w / 2 - fm.stringWidth(label) / 2, m_y + m_h / 2 + i * fm.getHeight());
         }
     } // drawLabel
 
     List<TrackPoint> getTracker() {
-        List<TrackPoint> tracker = new ArrayList<TrackPoint>(8);
+        List<TrackPoint> tracker = new ArrayList<>(8);
         tracker.add(new TrackPoint(m_x, m_y, Cursor.NW_RESIZE_CURSOR));
         tracker.add(new TrackPoint(m_x + m_w, m_y, Cursor.NE_RESIZE_CURSOR));
         tracker.add(new TrackPoint(m_x, m_y + m_h, Cursor.SW_RESIZE_CURSOR));
@@ -106,7 +105,7 @@ abstract public class Shape {
         return tracker;
     }
 
-    void parse(Node node, Document doc, boolean bReconstructPlugins) {
+    void parse(Node node, Document doc, boolean reconstructBEASTObjects) {
         if (node.getAttributes().getNamedItem("id") != null) {
             m_sID = node.getAttributes().getNamedItem("id").getNodeValue();
         }
@@ -138,35 +137,35 @@ abstract public class Shape {
         }
     }
 
-    String XMLnormalizeAtt(String sStr) {
-        StringBuffer sStr2 = new StringBuffer();
-        for (int iStr = 0; iStr < sStr.length(); iStr++) {
-            switch (sStr.charAt(iStr)) {
+    String XMLnormalizeAtt(String str) {
+        StringBuffer str2 = new StringBuffer();
+        for (int strIndex = 0; strIndex < str.length(); strIndex++) {
+            switch (str.charAt(strIndex)) {
                 case '<':
-                    sStr2.append("<");
+                    str2.append("<");
                     break;
                 case '>':
-                    sStr2.append(">");
+                    str2.append(">");
                     break;
                 case '\"':
-                    sStr2.append(""");
+                    str2.append(""");
                     break;
                 case '\'':
-                    sStr2.append("'");
+                    str2.append("'");
                     break;
                 case '&':
-                    sStr2.append("&");
+                    str2.append("&");
                     break;
                 case 13:
                     break;
                 case '\n':
-                    sStr2.append("&#xD;&#xA;");
+                    str2.append("&#xD;&#xA;");
                     break;
                 default:
-                    sStr2.append(sStr.charAt(iStr));
+                    str2.append(str.charAt(strIndex));
             }
         }
-        return sStr2.toString();
+        return str2.toString();
     } // XMLnormalizeAtt
 
     String getAtts() {
@@ -193,28 +192,28 @@ abstract public class Shape {
         m_pencolor = other.m_pencolor;
     }
 
-    Color string2Color(String sColor) {
-        int iSpace = sColor.indexOf(' ');
-        if (iSpace < 0) {
+    Color string2Color(String color) {
+        int space = color.indexOf(' ');
+        if (space < 0) {
             return new Color(128, 128, 128);
         }
-        int iStart = 0;
-        String sR = sColor.substring(iStart, iSpace);
-        int r = (new Integer(sR)).intValue();
-        iStart = iSpace + 1;
-        iSpace = sColor.indexOf(' ', iStart);
-        if (iSpace < 0) {
+        int start = 0;
+        String rStr = color.substring(start, space);
+        int r = (new Integer(rStr)).intValue();
+        start = space + 1;
+        space = color.indexOf(' ', start);
+        if (space < 0) {
             return new Color(128, 128, 128);
         }
-        String sG = sColor.substring(iStart, iSpace);
-        int g = (new Integer(sG)).intValue();
-        iStart = iSpace + 1;
-        iSpace = sColor.indexOf(' ', iStart);
-        if (iSpace < 0) {
-            iSpace = sColor.length();
+        String gStr = color.substring(start, space);
+        int g = (new Integer(gStr)).intValue();
+        start = space + 1;
+        space = color.indexOf(' ', start);
+        if (space < 0) {
+            space = color.length();
         }
-        String sB = sColor.substring(iStart, iSpace);
-        int b = (new Integer(sB)).intValue();
+        String isStr = color.substring(start, space);
+        int b = (new Integer(isStr)).intValue();
         return new Color(r, g, b);
     } // string2Color
 
@@ -222,26 +221,26 @@ abstract public class Shape {
         return "<shape" + getAtts() + "/>";
     }
 
-    boolean intersects(int nX, int nY) {
-        return (nX >= m_x - 1 && nX <= m_x + m_w + 1 && nY >= m_y - 1 && nY <= m_y + m_h + 1);
+    boolean intersects(int x, int y) {
+        return (x >= m_x - 1 && x <= m_x + m_w + 1 && y >= m_y - 1 && y <= m_y + m_h + 1);
     }
 
     boolean intersects(Rectangle rect) {
         return rect.intersects(m_x - 1, m_y - 1, m_w + 2, m_h + 2);
     }
-//	boolean intersects(int nX, int nY) {
+//	boolean intersects(int x, int y) {
 //		return false;
 //	}
 //	boolean intersects(Rectangle rect) {
 //		return false;
 //	}
 
-    int offsetX(int nX) {
-        return nX - m_x;
+    int offsetX(int x) {
+        return x - m_x;
     }
 
-    int offsetY(int nY) {
-        return nY - m_y;
+    int offsetY(int y) {
+        return y - m_y;
     }
 
     void offset(int dX, int dY) {
@@ -249,59 +248,59 @@ abstract public class Shape {
         m_y += dY;
     }
 
-    void movePosition(int nOffsetX, int nOffsetY, int nToX, int nToY) {
-        m_x = nToX - nOffsetX;
-        m_y = nToY - nOffsetY;
+    void movePosition(int offsetX, int offsetY, int toX, int toY) {
+        m_x = toX - offsetX;
+        m_y = toY - offsetY;
     } // movePosition
 
-    void movePoint(int nPoint, int nOffsetX, int nOffsetY, int nToX, int nToY) {
-        switch (nPoint) {
+    void movePoint(int point, int offsetX, int offsetY, int toX, int toY) {
+        switch (point) {
             case 0:
-                m_w = m_w + m_x - nToX + nOffsetX;
-                m_x = nToX - nOffsetX;
-                m_h = m_h + m_y - nToY + nOffsetY;
-                m_y = nToY - nOffsetY;
+                m_w = m_w + m_x - toX + offsetX;
+                m_x = toX - offsetX;
+                m_h = m_h + m_y - toY + offsetY;
+                m_y = toY - offsetY;
                 break;
             case 1:
-                m_w = nToX - nOffsetX - m_x;
-                m_h = m_h + m_y - nToY + nOffsetY;
-                m_y = nToY - nOffsetY;
+                m_w = toX - offsetX - m_x;
+                m_h = m_h + m_y - toY + offsetY;
+                m_y = toY - offsetY;
                 break;
             case 2:
-                m_w = m_w + m_x - nToX + nOffsetX;
-                m_x = nToX - nOffsetX;
-                m_h = nToY - nOffsetY - m_y;
+                m_w = m_w + m_x - toX + offsetX;
+                m_x = toX - offsetX;
+                m_h = toY - offsetY - m_y;
                 break;
             case 3:
-                m_w = nToX - nOffsetX - m_x;
-                m_h = nToY - nOffsetY - m_y;
+                m_w = toX - offsetX - m_x;
+                m_h = toY - offsetY - m_y;
                 break;
             case 5:
-                m_w = nToX - nOffsetX - m_x;
+                m_w = toX - offsetX - m_x;
                 break;
             case 4:
-                m_w = m_w + m_x - nToX + nOffsetX;
-                m_x = nToX - nOffsetX;
+                m_w = m_w + m_x - toX + offsetX;
+                m_x = toX - offsetX;
                 break;
             case 7:
-                m_h = nToY - nOffsetY - m_y;
+                m_h = toY - offsetY - m_y;
                 break;
             case 6:
-                m_h = m_h + m_y - nToY + nOffsetY;
-                m_y = nToY - nOffsetY;
+                m_h = m_h + m_y - toY + offsetY;
+                m_y = toY - offsetY;
                 break;
         }
     } // movePoint
 
     void normalize() {
-        int nX1 = m_x;
-        int nX2 = m_x + m_w;
-        int nY1 = m_y;
-        int nY2 = m_y + m_h;
-        m_x = Math.min(nX1, nX2);
-        m_w = Math.max(nX1, nX2) - m_x;
-        m_y = Math.min(nY1, nY2);
-        m_h = Math.max(nY1, nY2) - m_y;
+        int x1 = m_x;
+        int x2 = m_x + m_w;
+        int y1 = m_y;
+        int y2 = m_y + m_h;
+        m_x = Math.min(x1, x2);
+        m_w = Math.max(x1, x2) - m_x;
+        m_y = Math.min(y1, y2);
+        m_h = Math.max(y1, y2) - m_y;
     }
 
     public Color getFillColor() {
@@ -336,23 +335,23 @@ abstract public class Shape {
         return m_y + m_h;
     }
 
-    void setX(int nX) {
-        m_x = nX;
+    void setX(int x) {
+        m_x = x;
     }
 
-    void setY(int nY) {
-        m_y = nY;
+    void setY(int y) {
+        m_y = y;
     }
 
-    void setX2(int nX2) {
-        m_w = nX2 - m_x;
+    void setX2(int x2) {
+        m_w = x2 - m_x;
     }
 
-    void setY2(int nY2) {
-        m_h = nY2 - m_y;
+    void setY2(int y2) {
+        m_h = y2 - m_y;
     }
 
-    //void setLabel(String sLabel) {}
+    //void setLabel(String label) {}
     String getLabel() {
         return "";
     }
@@ -369,19 +368,19 @@ abstract public class Shape {
         return m_nPenWidth;
     }
 
-    void setPenWidth(int nPenWidth) {
-        m_nPenWidth = nPenWidth;
+    void setPenWidth(int penWidth) {
+        m_nPenWidth = penWidth;
     }
 
     abstract void toSVG(PrintStream out);
 
-    void drawSVGString(PrintStream out, Font font, Color color, String sTextAnchor) {
+    void drawSVGString(PrintStream out, Font font, Color color, String textAnchor) {
         if (getLabel() != null) {
 
-            String sLabel = getLabel();
-            int i = 0;
-            while (sLabel.indexOf('\n') >= 0) {
-                String sStr = sLabel.substring(0, sLabel.indexOf('\n'));
+            String label = getLabel();
+            //int i = 0;
+            while (label.indexOf('\n') >= 0) {
+                String str = label.substring(0, label.indexOf('\n'));
                 out.println("<text x='"
                         + (m_x + m_w / 2)
                         + "' y='"
@@ -391,9 +390,9 @@ abstract public class Shape {
                         + (font.isBold() ? "oblique" : "") + (font.isItalic() ? "italic" : "") + "' "
                         +
                         "stroke='rgb(" + color.getRed() + "," + color.getGreen()
-                        + "," + color.getBlue() + ")' text-anchor='" + sTextAnchor + "'>" + sStr + "</text>\n");
-                sLabel = sLabel.substring(sStr.length() + 1);
-                i++;
+                        + "," + color.getBlue() + ")' text-anchor='" + textAnchor + "'>" + str + "</text>\n");
+                label = label.substring(str.length() + 1);
+                //i++;
             }
             out.println("<text x='"
                     + (m_x + m_w / 2)
@@ -404,7 +403,7 @@ abstract public class Shape {
                     + (font.isBold() ? "oblique" : "") + (font.isItalic() ? "italic" : "") + "' "
                     +
                     "stroke='rgb(" + color.getRed() + "," + color.getGreen() + "," + color.getBlue() + ")' " +
-                    "text-anchor='" + sTextAnchor + "'>" + sLabel + "</text>\n");
+                    "text-anchor='" + textAnchor + "'>" + label + "</text>\n");
         }
     }
 }
diff --git a/src/beast/app/draw/SmallButton.java b/src/beast/app/draw/SmallButton.java
index 3fc0f81..9df6471 100644
--- a/src/beast/app/draw/SmallButton.java
+++ b/src/beast/app/draw/SmallButton.java
@@ -1,16 +1,21 @@
 package beast.app.draw;
 
-import javax.swing.*;
-
-import java.awt.*;
+import java.awt.Image;
 import java.net.URL;
 
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+
 /**
  * @author Alexei Drummond
  */
 public class SmallButton extends JButton {
 
-    public enum ButtonType {roundRect, square, toolbar}
+	private static final long serialVersionUID = 1L;
+
+	public enum ButtonType {roundRect, square, toolbar}
     
     public SmallButton(String label, boolean isEnabled) {
         this(label, isEnabled, ButtonType.square);
@@ -26,7 +31,7 @@ public class SmallButton extends JButton {
 
 	private void setIcon(String label) {
         if (label.equals("e")) {
-        	setLabel("");
+        	setText("");
             URL url = ClassLoader.getSystemResource(ModelBuilder.ICONPATH + "edit.png");
             Icon icon = new ImageIcon(url);
         	setIcon(icon);
diff --git a/src/beast/app/draw/SmallButtonOld.java b/src/beast/app/draw/SmallButtonOld.java
index 5dc6043..dde8423 100644
--- a/src/beast/app/draw/SmallButtonOld.java
+++ b/src/beast/app/draw/SmallButtonOld.java
@@ -31,7 +31,7 @@ public class SmallButtonOld extends JButton {
         this.image = image;
     }
 
-    public SmallButtonOld(String label, boolean bIsEnabled) {
+    public SmallButtonOld(String label, boolean isEnabled) {
         super(label);
         //this.label = label;
         enableEvents(AWTEvent.MOUSE_EVENT_MASK);
@@ -40,13 +40,14 @@ public class SmallButtonOld extends JButton {
         setSize(15, 15);
         setMinimumSize(new Dimension(15, 15));
         setMaximumSize(new Dimension(15, 15));
-        setEnabled(bIsEnabled);
+        setEnabled(isEnabled);
     } // c'tor
 
     /**
      * paints the SmallButton
      */
-    public void paint(Graphics g) {
+    @Override
+	public void paint(Graphics g) {
         if (image != null) {
             g.drawImage(image, 0, 0, null);
             return;
diff --git a/src/beast/app/draw/SmallLabel.java b/src/beast/app/draw/SmallLabel.java
index 9e9ba9a..42dc9aa 100644
--- a/src/beast/app/draw/SmallLabel.java
+++ b/src/beast/app/draw/SmallLabel.java
@@ -36,7 +36,8 @@ public class SmallLabel extends JLabel {
     /**
      * paints the SmallButton
      */
-    public void paint(Graphics g) {
+    @Override
+	public void paint(Graphics g) {
         if (m_bIsEnabled) {
             int s = 14;
             GradientPaint m_gradientPaint = new GradientPaint(new Point(0, 0), Color.WHITE, new Point(getWidth(), getHeight()), m_circleColor);
@@ -59,8 +60,8 @@ public class SmallLabel extends JLabel {
     boolean m_bIsEnabled = true;
 
     @Override
-    public void setVisible(boolean bIsEnabled) {
-        m_bIsEnabled = bIsEnabled;
+    public void setVisible(boolean isEnabled) {
+        m_bIsEnabled = isEnabled;
     }
 
 } // class SmallButton
diff --git a/src/beast/app/draw/TrackPoint.java b/src/beast/app/draw/TrackPoint.java
index 4de76e7..78b4232 100644
--- a/src/beast/app/draw/TrackPoint.java
+++ b/src/beast/app/draw/TrackPoint.java
@@ -28,9 +28,9 @@ public class TrackPoint {
     public int m_nX;
     public int m_nY, m_nCursor;
 
-    public TrackPoint(int nX, int nY, int nCursor) {
-        m_nX = nX;
-        m_nY = nY;
-        m_nCursor = nCursor;
+    public TrackPoint(int x, int y, int cursor) {
+        m_nX = x;
+        m_nY = y;
+        m_nCursor = cursor;
     }
 }
diff --git a/src/beast/app/seqgen/MergeDataWith.java b/src/beast/app/seqgen/MergeDataWith.java
index 46a70e8..e799b73 100644
--- a/src/beast/app/seqgen/MergeDataWith.java
+++ b/src/beast/app/seqgen/MergeDataWith.java
@@ -1,31 +1,39 @@
 package beast.app.seqgen;
 
-import java.io.*;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
 import beast.app.beauti.BeautiDoc;
-import beast.core.*;
-import beast.core.Input.*;
-import beast.evolution.alignment.*;
-import beast.util.*;
+import beast.core.BEASTInterface;
+import beast.core.BEASTObject;
+import beast.core.Description;
+import beast.core.Input;
+import beast.core.Input.Validate;
+import beast.evolution.alignment.Alignment;
+import beast.evolution.alignment.Sequence;
+import beast.util.XMLParser;
+import beast.util.XMLParserException;
+import beast.util.XMLProducer;
 
 @Description("Helper for Sequence Simulator, allows specifying template input file and destination output file")
 public class MergeDataWith extends BEASTObject {
-	public Input<String> templateFileInput = new Input<String>("template","name of template file. " +
+	final public Input<String> templateFileInput = new Input<>("template","name of template file. " +
 			"The template file should be a valid beast2 XML file with a single (possibly empty) alignment. " +
 			"This alignment will be replaced by the alignment generated by the SequenceSimulator. " +
 			"Any occurrance of $(n) will be replaced by the iteration number of the SequenceSimulator. " +
 			"For example, calling a log filename \"output$(n).log\" will be replaced by " +
 			"\"output1.log\" at first iteration, \"output2.log\" at seccond iteration, etc..", Validate.REQUIRED);
-	public Input<String> outputFileInput = new Input<String>("output","name of the output file. " +
+	final public Input<String> outputFileInput = new Input<>("output","name of the output file. " +
 			"Instances of $(n) are replaced by iteration number.", Validate.REQUIRED);
 
 	File templateFile;
 	
 	@Override
-	public void initAndValidate() throws Exception {
+	public void initAndValidate() {
 		templateFile = new File(templateFileInput.get());
 		if (!(templateFile.exists())) {
 			throw new RuntimeException("Template file " + templateFileInput.get() + " does not exist"); 
@@ -33,7 +41,7 @@ public class MergeDataWith extends BEASTObject {
 	} // initAndValidate
 	
 	
-	void process(Alignment data, int iteration) throws Exception {
+	void process(Alignment data, int iteration) throws IOException, XMLParserException, IllegalArgumentException, IllegalAccessException {
 		// read template
 		String templateXML = BeautiDoc.load(templateFile);
 		templateXML = templateXML.replaceAll("\\$\\(n\\)", iteration+"");
@@ -51,16 +59,16 @@ public class MergeDataWith extends BEASTObject {
 		outputFile = outputFile.replaceAll("\\$\\(n\\)", iteration+"");
 		FileWriter outfile = new FileWriter(outputFile);
 		
-		Set<BEASTInterface> plugins = new HashSet<BEASTInterface>();
-		String sXML = new XMLProducer().toXML(b, plugins);
-        outfile.write(sXML);
+		Set<BEASTInterface> beastObjects = new HashSet<>();
+		String xml = new XMLProducer().toXML(b, beastObjects);
+        outfile.write(xml);
         outfile.close();
 	} // process
 
 
 	private Alignment getAlignment(BEASTInterface b) throws IllegalArgumentException, IllegalAccessException {
 		Alignment a = null;
-		for (BEASTInterface i : b.listActivePlugins()) {
+		for (BEASTInterface i : b.listActiveBEASTObjects()) {
 			if (i.getClass().equals(Alignment.class)){
 				return (Alignment) i;
 			} else {
diff --git a/src/beast/app/seqgen/SequenceSimulator.java b/src/beast/app/seqgen/SequenceSimulator.java
index d26317d..d63beda 100644
--- a/src/beast/app/seqgen/SequenceSimulator.java
+++ b/src/beast/app/seqgen/SequenceSimulator.java
@@ -3,14 +3,16 @@ package beast.app.seqgen;
 
 import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileNotFoundException;
 import java.io.FileReader;
+import java.io.IOException;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.List;
 
+import beast.core.BEASTInterface;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.BEASTInterface;
 import beast.core.Input.Validate;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.alignment.Sequence;
@@ -22,6 +24,7 @@ import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
 import beast.util.Randomizer;
 import beast.util.XMLParser;
+import beast.util.XMLParserException;
 import beast.util.XMLProducer;
 
 
@@ -32,19 +35,19 @@ import beast.util.XMLProducer;
 @Description("Performs random sequence generation for a given site model. " +
         "Sequences for the leave nodes in the tree are returned as an alignment.")
 public class SequenceSimulator extends beast.core.Runnable {
-    public Input<Alignment> m_data = new Input<Alignment>("data", "alignment data which specifies datatype and taxa of the beast.tree", Validate.REQUIRED);
-    public Input<Tree> m_treeInput = new Input<Tree>("tree", "phylogenetic beast.tree with sequence data in the leafs", Validate.REQUIRED);
-    public Input<SiteModel.Base> m_pSiteModelInput = new Input<SiteModel.Base>("siteModel", "site model for leafs in the beast.tree", Validate.REQUIRED);
-    public Input<BranchRateModel.Base> m_pBranchRateModelInput = new Input<BranchRateModel.Base>("branchRateModel",
+    final public Input<Alignment> m_data = new Input<>("data", "alignment data which specifies datatype and taxa of the beast.tree", Validate.REQUIRED);
+    final public Input<Tree> m_treeInput = new Input<>("tree", "phylogenetic beast.tree with sequence data in the leafs", Validate.REQUIRED);
+    final public Input<SiteModel.Base> m_pSiteModelInput = new Input<>("siteModel", "site model for leafs in the beast.tree", Validate.REQUIRED);
+    final public Input<BranchRateModel.Base> m_pBranchRateModelInput = new Input<>("branchRateModel",
             "A model describing the rates on the branches of the beast.tree.");
-    public Input<Integer> m_sequenceLengthInput = new Input<Integer>("sequencelength", "nr of samples to generate (default 1000).", 1000);
-    public Input<String> m_outputFileNameInput = new Input<String>(
+    final public Input<Integer> m_sequenceLengthInput = new Input<>("sequencelength", "nr of samples to generate (default 1000).", 1000);
+    final public Input<String> m_outputFileNameInput = new Input<>(
             "outputFileName",
             "If provided, simulated alignment is written to this file rather "
             + "than to standard out.");
 
-    public Input<List<MergeDataWith>> mergeListInput = new Input<List<MergeDataWith>>("merge", "specifies template used to merge the generated alignment with", new ArrayList<MergeDataWith>());
-    public Input<Integer> iterationsInput = new Input<Integer>("iterations","number of times the data is generated", 1);
+    final public Input<List<MergeDataWith>> mergeListInput = new Input<>("merge", "specifies template used to merge the generated alignment with", new ArrayList<>());
+    final public Input<Integer> iterationsInput = new Input<>("iterations","number of times the data is generated", 1);
     
     /**
      * nr of samples to generate *
@@ -94,7 +97,7 @@ public class SequenceSimulator extends beast.core.Runnable {
     }
 
     @Override
-    public void run() throws Exception {
+    public void run() throws IllegalArgumentException, IllegalAccessException, IOException, XMLParserException {
     	for (int i = 0; i < iterationsInput.get(); i++) {
 	        Alignment alignment = simulate();
 	        
@@ -117,26 +120,26 @@ public class SequenceSimulator extends beast.core.Runnable {
      * @param seq  integer representation of the sequence
      * @param node used to determine taxon for sequence
      * @return Sequence
-     * @throws Exception
+     * @
      */
-    Sequence intArray2Sequence(int[] seq, Node node) throws Exception {
+    Sequence intArray2Sequence(int[] seq, Node node)  {
         DataType dataType = m_data.get().getDataType();
-        String sSeq = dataType.state2string(seq);
-//    	StringBuilder sSeq = new StringBuilder();
-//    	String sMap = m_data.get().getMap();
-//    	if (sMap != null) {
+        String seqString = dataType.state2string(seq);
+//    	StringBuilder seq = new StringBuilder();
+//    	String map = m_data.get().getMap();
+//    	if (map != null) {
 //    		for (int i  = 0; i < m_sequenceLength; i++) {
-//    			sSeq.append(sMap.charAt(seq[i]));
+//    			seq.append(map.charAt(seq[i]));
 //    		}
 //    	} else {
 //    		for (int i  = 0; i < m_sequenceLength-1; i++) {
-//    			sSeq.append(seq[i] + ",");
+//    			seq.append(seq[i] + ",");
 //    		}
-//			sSeq.append(seq[m_sequenceLength-1] + "");
+//			seq.append(seq[m_sequenceLength-1] + "");
 //    	}
         List<Sequence> taxa = m_data.get().sequenceInput.get();
-        String sTaxon = taxa.get(node.getNr()).taxonInput.get();
-        return new Sequence(sTaxon, sSeq.toString());
+        String taxon = taxa.get(node.getNr()).taxonInput.get();
+        return new Sequence(taxon, seqString);
     } // intArray2Sequence
 
     /**
@@ -144,9 +147,9 @@ public class SequenceSimulator extends beast.core.Runnable {
      *
      * @return alignment containing randomly generated sequences for the nodes in the
      *         leaves of the tree
-     * @throws Exception
+     * @
      */
-    public Alignment simulate() throws Exception {
+    public Alignment simulate()  {
         Node root = m_tree.getRoot();
 
 
@@ -181,11 +184,11 @@ public class SequenceSimulator extends beast.core.Runnable {
      * @param parentSequence randomly generated sequence of the parent node
      * @param category       array of categories for each of the sites
      * @param alignment
-     * @throws Exception
+     * @
      */
-    void traverse(Node node, int[] parentSequence, int[] category, Alignment alignment) throws Exception {
-        for (int iChild = 0; iChild < 2; iChild++) {
-            Node child = (iChild == 0 ? node.getLeft() : node.getRight());
+    void traverse(Node node, int[] parentSequence, int[] category, Alignment alignment)  {
+        for (int childIndex = 0; childIndex < 2; childIndex++) {
+            Node child = (childIndex == 0 ? node.getLeft() : node.getRight());
             for (int i = 0; i < m_categoryCount; i++) {
                 getTransitionProbabilities(m_tree, child, i, m_probabilities[i]);
             }
@@ -238,12 +241,12 @@ public class SequenceSimulator extends beast.core.Runnable {
     /**
      * find a treelikelihood object among the plug-ins by recursively inspecting plug-ins *
      */
-    static TreeLikelihood getTreeLikelihood(BEASTInterface plugin) throws Exception {
-        for (BEASTInterface plugin2 : plugin.listActivePlugins()) {
-            if (plugin2 instanceof TreeLikelihood) {
-                return (TreeLikelihood) plugin2;
+    static TreeLikelihood getTreeLikelihood(BEASTInterface beastObject)  {
+        for (BEASTInterface beastObject2 : beastObject.listActiveBEASTObjects()) {
+            if (beastObject2 instanceof TreeLikelihood) {
+                return (TreeLikelihood) beastObject2;
             } else {
-                TreeLikelihood likelihood = getTreeLikelihood(plugin2);
+                TreeLikelihood likelihood = getTreeLikelihood(beastObject2);
                 if (likelihood != null) {
                     return likelihood;
                 }
@@ -272,8 +275,8 @@ public class SequenceSimulator extends beast.core.Runnable {
             if (args.length < 2) {
                 printUsageAndExit();
             }
-            String sFile = args[0];
-            int nReplications = Integer.parseInt(args[1]);
+            String fileName = args[0];
+            int replications = Integer.parseInt(args[1]);
             PrintStream out = System.out;
             if (args.length == 3) {
                 File file = new File(args[2]);
@@ -281,21 +284,21 @@ public class SequenceSimulator extends beast.core.Runnable {
             }
 
             // grab the file
-            String sXML = "";
-            BufferedReader fin = new BufferedReader(new FileReader(sFile));
+            String xml = "";
+            BufferedReader fin = new BufferedReader(new FileReader(fileName));
             while (fin.ready()) {
-                sXML += fin.readLine();
+                xml += fin.readLine();
             }
             fin.close();
 
             // parse the xml
             XMLParser parser = new XMLParser();
-            BEASTInterface plugin = parser.parseFragment(sXML, true);
+            BEASTInterface beastObject = parser.parseFragment(xml, true);
 
             // find relevant objects from the model
-            TreeLikelihood treeLikelihood = getTreeLikelihood(plugin);
+            TreeLikelihood treeLikelihood = getTreeLikelihood(beastObject);
             if (treeLikelihood == null) {
-                throw new Exception("No treelikelihood found in file. Giving up now.");
+                throw new IllegalArgumentException("No treelikelihood found in file. Giving up now.");
             }
             Alignment data = ((Input<Alignment>) treeLikelihood.getInput("data")).get();
             Tree tree = ((Input<Tree>) treeLikelihood.getInput("tree")).get();
@@ -305,12 +308,12 @@ public class SequenceSimulator extends beast.core.Runnable {
 
             // feed to sequence simulator and generate leaves
             SequenceSimulator treeSimulator = new SequenceSimulator();
-            treeSimulator.init(data, tree, pSiteModel, pBranchRateModel, nReplications);
+            treeSimulator.init(data, tree, pSiteModel, pBranchRateModel, replications);
             XMLProducer producer = new XMLProducer();
             Alignment alignment = treeSimulator.simulate();
-            sXML = producer.toRawXML(alignment);
+            xml = producer.toRawXML(alignment);
             out.println("<beast version='2.0'>");
-            out.println(sXML);
+            out.println(xml);
             out.println("</beast>");
         } catch (Exception e) {
             e.printStackTrace();
diff --git a/src/beast/app/seqgen/SimulatedAlignment.java b/src/beast/app/seqgen/SimulatedAlignment.java
index 39d9fa0..5fb8795 100644
--- a/src/beast/app/seqgen/SimulatedAlignment.java
+++ b/src/beast/app/seqgen/SimulatedAlignment.java
@@ -1,7 +1,7 @@
 package beast.app.seqgen;
 
+import java.io.FileNotFoundException;
 import java.io.PrintStream;
-import java.util.List;
 
 import beast.core.Description;
 import beast.core.Input;
@@ -23,13 +23,13 @@ import beast.util.XMLProducer;
 @Description("An alignment containing sequences randomly generated using a"
         + "given site model down a given tree.")
 public class SimulatedAlignment extends Alignment {
-    public Input<Alignment> m_data = new Input<Alignment>("data", "alignment data which specifies datatype and taxa of the beast.tree", Validate.REQUIRED);
-    public Input<Tree> m_treeInput = new Input<Tree>("tree", "phylogenetic beast.tree with sequence data in the leafs", Validate.REQUIRED);
-    public Input<SiteModel.Base> m_pSiteModelInput = new Input<SiteModel.Base>("siteModel", "site model for leafs in the beast.tree", Validate.REQUIRED);
-    public Input<BranchRateModel.Base> m_pBranchRateModelInput = new Input<BranchRateModel.Base>("branchRateModel",
+    final public Input<Alignment> m_data = new Input<>("data", "alignment data which specifies datatype and taxa of the beast.tree", Validate.REQUIRED);
+    final public Input<Tree> m_treeInput = new Input<>("tree", "phylogenetic beast.tree with sequence data in the leafs", Validate.REQUIRED);
+    final public Input<SiteModel.Base> m_pSiteModelInput = new Input<>("siteModel", "site model for leafs in the beast.tree", Validate.REQUIRED);
+    final public Input<BranchRateModel.Base> m_pBranchRateModelInput = new Input<>("branchRateModel",
             "A model describing the rates on the branches of the beast.tree.");
-    public Input<Integer> m_sequenceLengthInput = new Input<Integer>("sequencelength", "nr of samples to generate (default 1000).", 1000);
-    public Input<String> m_outputFileNameInput = new Input<String>(
+    final public Input<Integer> m_sequenceLengthInput = new Input<>("sequencelength", "nr of samples to generate (default 1000).", 1000);
+    final public Input<String> m_outputFileNameInput = new Input<>(
             "outputFileName",
             "If provided, simulated alignment is additionally written to this file.");    
 
@@ -75,7 +75,7 @@ public class SimulatedAlignment extends Alignment {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         m_tree = m_treeInput.get();
         m_siteModel = m_pSiteModelInput.get();
         m_branchRateModel = m_pBranchRateModelInput.get();
@@ -91,8 +91,14 @@ public class SimulatedAlignment extends Alignment {
         
         // Write simulated alignment to disk if requested:
         if (m_outputFileName != null) {
-            PrintStream pstream = new PrintStream(m_outputFileName);
-            pstream.println(new XMLProducer().toRawXML(this));
+            PrintStream pstream;
+			try {
+				pstream = new PrintStream(m_outputFileName);
+	            pstream.println(new XMLProducer().toRawXML(this));
+	            pstream.close();
+			} catch (FileNotFoundException e) {
+				throw new IllegalArgumentException(e.getMessage());
+			}
         }
         
         super.initAndValidate();
@@ -104,25 +110,24 @@ public class SimulatedAlignment extends Alignment {
      * @param seq  integer representation of the sequence
      * @param node used to determine taxon for sequence
      * @return Sequence
-     * @throws Exception
      */
-    Sequence intArray2Sequence(int[] seq, Node node) throws Exception {
+    Sequence intArray2Sequence(int[] seq, Node node) {
         DataType dataType = m_data.get().getDataType();
-        String sSeq = dataType.state2string(seq);
-//    	StringBuilder sSeq = new StringBuilder();
-//    	String sMap = m_data.get().getMap();
-//    	if (sMap != null) {
+        String seqString = dataType.state2string(seq);
+//    	StringBuilder seq = new StringBuilder();
+//    	String map = m_data.get().getMap();
+//    	if (map != null) {
 //    		for (int i  = 0; i < m_sequenceLength; i++) {
-//    			sSeq.append(sMap.charAt(seq[i]));
+//    			seq.append(map.charAt(seq[i]));
 //    		}
 //    	} else {
 //    		for (int i  = 0; i < m_sequenceLength-1; i++) {
-//    			sSeq.append(seq[i] + ",");
+//    			seq.append(seq[i] + ",");
 //    		}
-//			sSeq.append(seq[m_sequenceLength-1] + "");
+//			seq.append(seq[m_sequenceLength-1] + "");
 //    	}
-        String sTaxon = m_data.get().getTaxaNames().get(node.getNr());
-        return new Sequence(sTaxon, sSeq.toString());
+        String taxon = m_data.get().getTaxaNames().get(node.getNr());
+        return new Sequence(taxon, seqString);
     } // intArray2Sequence
 
     /**
@@ -130,9 +135,8 @@ public class SimulatedAlignment extends Alignment {
      *
      * @return alignment containing randomly generated sequences for the nodes in the
      *         leaves of the tree
-     * @throws Exception
      */
-    public void simulate() throws Exception {
+    public void simulate() {
         Node root = m_tree.getRoot();
 
 
@@ -163,11 +167,10 @@ public class SimulatedAlignment extends Alignment {
      * @param parentSequence randomly generated sequence of the parent node
      * @param category       array of categories for each of the sites
      * @param alignment
-     * @throws Exception
      */
-    void traverse(Node node, int[] parentSequence, int[] category) throws Exception {
-        for (int iChild = 0; iChild < 2; iChild++) {
-            Node child = (iChild == 0 ? node.getLeft() : node.getRight());
+    void traverse(Node node, int[] parentSequence, int[] category) {
+        for (int childIndex = 0; childIndex < 2; childIndex++) {
+            Node child = (childIndex == 0 ? node.getLeft() : node.getRight());
             for (int i = 0; i < m_categoryCount; i++) {
                 getTransitionProbabilities(m_tree, child, i, m_probabilities[i]);
             }
diff --git a/src/beast/app/tools/AppStore.java b/src/beast/app/tools/AppStore.java
index 2bfe220..e33b650 100644
--- a/src/beast/app/tools/AppStore.java
+++ b/src/beast/app/tools/AppStore.java
@@ -1,28 +1,46 @@
 package beast.app.tools;
 
 
-import beast.app.util.Utils;
-import beast.util.AddOnManager;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
-
-import javax.swing.*;
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.InputStreamReader;
 import java.io.PrintStream;
-import java.lang.reflect.Method;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.swing.Box;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.DefaultListModel;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+
+import beast.app.util.Utils;
+import beast.core.util.Log;
+import beast.util.AddOnManager;
 
 
 /**
@@ -33,7 +51,6 @@ import java.util.List;
  * @author  Walter Xie
  */
 public class AppStore {
-    private static final long serialVersionUID = 1L;
     public static final String DEFAULT_ICON = "beast/app/tools/images/utility.png";
 
     private final String ALL = "-all-";
@@ -55,22 +72,19 @@ public class AppStore {
         JLabel label = new JLabel("Filter: ");
         packageComboBox = new JComboBox<>(new String[]{ALL});
         packageComboBox.setToolTipText("Show application of the installed package(s)");
-        packageComboBox.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                JComboBox cb = (JComboBox)e.getSource();
+        packageComboBox.addActionListener(e -> {
+                JComboBox<?> cb = (JComboBox<?>) e.getSource();
                 if (cb.getSelectedItem() != null) {
                     resetAppList(cb.getSelectedItem().toString());
                 }
-            }
-        });
+            });
         label.setLabelFor(packageComboBox);
         top.add(label);
         top.add(packageComboBox);
         mainDialog.getContentPane().add(BorderLayout.NORTH, top);
 
-        Component pluginListBox = createList();
-        mainDialog.getContentPane().add(BorderLayout.CENTER, pluginListBox);
+        Component beastObjectListBox = createList();
+        mainDialog.getContentPane().add(BorderLayout.CENTER, beastObjectListBox);
 
         Box buttonBox = createButtonBox();
         mainDialog.getContentPane().add(buttonBox, BorderLayout.SOUTH);
@@ -89,12 +103,15 @@ public class AppStore {
         box.add(Box.createGlue());
 
         listApps = new JList<PackageApp>(model) {
-            //Subclass JList to workaround bug 4832765, which can cause the
+ 			private static final long serialVersionUID = 1L;
+
+			//Subclass JList to workaround bug 4832765, which can cause the
             //scroll pane to not let the user easily scroll up to the beginning
             //of the list.  An alternative would be to set the unitIncrement
             //of the JScrollBar to a fixed value. You wouldn't get the nice
             //aligned scrolling, but it should work.
-            public int getScrollableUnitIncrement(Rectangle visibleRect,
+            @Override
+			public int getScrollableUnitIncrement(Rectangle visibleRect,
                                                   int orientation,
                                                   int direction) {
                 int row;
@@ -119,21 +136,24 @@ public class AppStore {
         };
         listApps.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
         listApps.setCellRenderer(new DefaultListCellRenderer() {
-            @Override
-            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,
+			private static final long serialVersionUID = 1L;
+
+			@Override
+            public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected,
                                                           boolean cellHasFocus) {
                 JLabel label = (JLabel) super
                         .getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
                 label.setIcon(((PackageApp) value).icon);
-                label.setHorizontalTextPosition(JLabel.CENTER);
-                label.setVerticalTextPosition(JLabel.BOTTOM);
+                label.setHorizontalTextPosition(SwingConstants.CENTER);
+                label.setVerticalTextPosition(SwingConstants.BOTTOM);
                 return label;
             }
         });
         listApps.setLayoutOrientation(JList.HORIZONTAL_WRAP);
         listApps.setVisibleRowCount(-1);
         listApps.addMouseListener(new MouseAdapter() {
-            public void mouseClicked(MouseEvent e) {
+            @Override
+			public void mouseClicked(MouseEvent e) {
                 if (e.getClickCount() == 2) {
                     launchButton.doClick();
                 }
@@ -148,7 +168,7 @@ public class AppStore {
 
         JScrollPane listScroller = new JScrollPane(listApps);
         listScroller.setPreferredSize(new Dimension(660, 400));
-        listScroller.setAlignmentX(JDialog.LEFT_ALIGNMENT);
+        listScroller.setAlignmentX(Component.LEFT_ALIGNMENT);
 
         JLabel label = new JLabel("List of available package applications");
         label.setLabelFor(listApps);
@@ -200,9 +220,7 @@ public class AppStore {
         Box box = Box.createHorizontalBox();
         box.add(Box.createGlue());
 
-        launchButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        launchButton.addActionListener(e -> {
                 PackageApp packageApp = listApps.getSelectedValue();
                 if (packageApp != null) {
                     try {
@@ -212,18 +230,14 @@ public class AppStore {
                         JOptionPane.showMessageDialog(null, "Launch failed because: " + ex.getMessage());
                     }
                 }
-            }
-        });
+            });
         box.add(launchButton);
 
         JButton closeButton = new JButton("Close");
-        closeButton.addActionListener(new ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
+        closeButton.addActionListener(e -> {
 //				setVisible(false);
                 mainDialog.dispose();
-            }
-        });
+            });
         box.add(Box.createGlue());
         box.add(closeButton);
         box.add(Box.createGlue());
@@ -233,8 +247,8 @@ public class AppStore {
     List<PackageApp> getPackageApps() {
         List<PackageApp> packageApps = new ArrayList<>();
         List<String> dirs = AddOnManager.getBeastDirectories();
-        for (String sJarDir : dirs) {
-            File versionFile = new File(sJarDir + "/version.xml");
+        for (String jarDirName : dirs) {
+            File versionFile = new File(jarDirName + "/version.xml");
             if (versionFile.exists() && versionFile.isFile()) {
                 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                 Document doc;
@@ -248,7 +262,7 @@ public class AppStore {
                         Element addOnAppElement = (Element) nodes.item(j);
                         PackageApp packageApp = new PackageApp();
                         packageApp.packageName = addon.getAttribute("name");
-                        packageApp.jarDir = sJarDir;
+                        packageApp.jarDir = jarDirName;
                         packageApp.className = addOnAppElement.getAttribute("class");
                         packageApp.description = addOnAppElement.getAttribute("description");
                         packageApp.argumentsString = addOnAppElement.getAttribute("args");
@@ -347,7 +361,7 @@ public class AppStore {
 
             System.err.println(pb.command());
 
-            File log = new File("log");
+            //File log = new File("log");
             pb.redirectErrorStream(true);
             
             // Start the process and wait for it to finish.
@@ -355,13 +369,13 @@ public class AppStore {
             int c;
             BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream()));
             while ((c = input.read()) != -1) {
-                System.out.print((char)c);
+                Log.info.print((char)c);
             }
             input.close();
             final int exitStatus = process.waitFor();
 
             if (exitStatus != 0) {
-                System.err.println(Utils.toString(process.getErrorStream()));
+                Log.err.println(Utils.toString(process.getErrorStream()));
             } else {
 //                System.out.println(Utils.toString(process.getInputStream()));
             }
diff --git a/src/beast/app/tools/AppStoreLauncher.java b/src/beast/app/tools/AppStoreLauncher.java
index 70806f3..d908f57 100644
--- a/src/beast/app/tools/AppStoreLauncher.java
+++ b/src/beast/app/tools/AppStoreLauncher.java
@@ -1,5 +1,8 @@
 package beast.app.tools;
 
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
 import beast.app.beastapp.BeastLauncher;
 
 public class AppStoreLauncher extends BeastLauncher {
@@ -8,8 +11,15 @@ public class AppStoreLauncher extends BeastLauncher {
 	 * 
 	 * This class should be compiled against 1.6 and packaged by itself. The
 	 * remained of BEAST can be compiled against Java 1.7 or higher
+	 * @throws IOException 
+	 * @throws InvocationTargetException 
+	 * @throws IllegalArgumentException 
+	 * @throws IllegalAccessException 
+	 * @throws ClassNotFoundException 
+	 * @throws SecurityException 
+	 * @throws NoSuchMethodException 
 	 * **/
-	public static void main(String[] args) throws Exception {
+	public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
 		if (javaVersionCheck("AppStore")) {
 			loadBEASTJars();
 			AppStore.main(args);
diff --git a/src/beast/app/tools/EBSPAnalyser.java b/src/beast/app/tools/EBSPAnalyser.java
index 96f387b..a67c412 100644
--- a/src/beast/app/tools/EBSPAnalyser.java
+++ b/src/beast/app/tools/EBSPAnalyser.java
@@ -1,15 +1,11 @@
 package beast.app.tools;
 
-import jam.console.ConsoleApplication;
-import jam.panels.OptionsPanel;
-
 import java.awt.BorderLayout;
 import java.awt.Font;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
+import java.io.IOException;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -29,9 +25,13 @@ import javax.swing.border.EmptyBorder;
 import beast.app.BEASTVersion;
 import beast.app.util.Utils;
 import beast.app.util.WholeNumberField;
+import beast.core.util.Log;
 import beast.evolution.tree.coalescent.CompoundPopulationFunction;
 import beast.evolution.tree.coalescent.CompoundPopulationFunction.Type;
 import beast.math.statistic.DiscreteStatistics;
+import beast.util.HeapSort;
+import jam.console.ConsoleApplication;
+import jam.panels.OptionsPanel;
 
 
 
@@ -42,59 +42,60 @@ public class EBSPAnalyser {
     String m_sInputFile;
     int m_nBurninPercentage = 10;
 
-    private void run() throws Exception {
+    private void run() throws IOException {
         parse(m_sInputFile, m_nBurninPercentage, m_type, m_out);
     }
 
-    void parse(String sFile, int nBurnInPercentage, CompoundPopulationFunction.Type type, PrintStream out) throws Exception {
-        logln("Processing " + sFile);
-        BufferedReader fin = new BufferedReader(new FileReader(sFile));
-        String sStr;
-        int nData = 0;
+    void parse(String fileName, int burnInPercentage, CompoundPopulationFunction.Type type, PrintStream out) throws IOException {
+        logln("Processing " + fileName);
+        BufferedReader fin = new BufferedReader(new FileReader(fileName));
+        String str;
+        int data = 0;
         // first, sweep through the log file to determine size of the log
         while (fin.ready()) {
-            sStr = fin.readLine();
+            str = fin.readLine();
             // terrible hackish code, must improve later
-            if( sStr.charAt(0) == '#' ) {
-                int i = sStr.indexOf("spec=");
+            if( str.charAt(0) == '#' ) {
+                int i = str.indexOf("spec=");
                 if( i > 0 ) {
-                   if( sStr.indexOf("type=\"stepwise\"") > 0 ) {
+                   if( str.indexOf("type=\"stepwise\"") > 0 ) {
                       m_type = Type.STEPWISE;
-                   }  else if( sStr.indexOf("type=\"linear\"") > 0 ) {
+                   }  else if( str.indexOf("type=\"linear\"") > 0 ) {
                       m_type = Type.LINEAR;
                    }
                 }
             }
-            if (sStr.indexOf('#') < 0 && sStr.matches(".*[0-9a-zA-Z].*")) {
-                nData++;
+            if (str.indexOf('#') < 0 && str.matches(".*[0-9a-zA-Z].*")) {
+                data++;
             }
         }
-        final int nBurnIn = nData * nBurnInPercentage / 100;
-        logln(" skipping " + nBurnIn + " line\n\n");
-        nData = -nBurnIn - 1;
-        fin = new BufferedReader(new FileReader(sFile));
+        final int burnIn = data * burnInPercentage / 100;
+        logln(" skipping " + burnIn + " line\n\n");
+        data = -burnIn - 1;
+        fin.close();
+        fin = new BufferedReader(new FileReader(fileName));
 
         // process log
-        final List<List<Double>> times = new ArrayList<List<Double>>();
-        final List<List<Double>> popSizes = new ArrayList<List<Double>>();
+        final List<List<Double>> times = new ArrayList<>();
+        final List<List<Double>> popSizes = new ArrayList<>();
         double[] alltimes = null;
         while (fin.ready()) {
-            sStr = fin.readLine();
-            if (sStr.indexOf('#') < 0 && sStr.matches(".*[0-9a-zA-Z].*")) {
-                if (++nData > 0) {
-                    final String[] sStrs = sStr.split("\t");
-                    final List<Double> times2 = new ArrayList<Double>();
-                    final List<Double> popSizes2 = new ArrayList<Double>();
+            str = fin.readLine();
+            if (str.indexOf('#') < 0 && str.matches(".*[0-9a-zA-Z].*")) {
+                if (++data > 0) {
+                    final String[] strs = str.split("\t");
+                    final List<Double> times2 = new ArrayList<>();
+                    final List<Double> popSizes2 = new ArrayList<>();
                     if (alltimes == null) {
-                        alltimes = new double[sStrs.length - 1];
+                        alltimes = new double[strs.length - 1];
                     }
-                    for (int i = 1; i < sStrs.length; i++) {
-                        final String[] sStrs2 = sStrs[i].split(":");
-                        final Double time = Double.parseDouble(sStrs2[0]);
+                    for (int i = 1; i < strs.length; i++) {
+                        final String[] strs2 = strs[i].split(":");
+                        final Double time = Double.parseDouble(strs2[0]);
                         alltimes[i - 1] += time;
-                        if (sStrs2.length > 1) {
+                        if (strs2.length > 1) {
                             times2.add(time);
-                            popSizes2.add(Double.parseDouble(sStrs2[1]));
+                            popSizes2.add(Double.parseDouble(strs2[1]));
                         }
                     }
                     times.add(times2);
@@ -117,24 +118,29 @@ public class EBSPAnalyser {
         // generate output
         out.println("time\tmean\tmedian\t95HPD lower\t95HPD upper");
         final double[] popSizeAtTimeT = new double[times.size()];
+        int[] indices = new int[times.size()];
+
         for (final double time : alltimes) {
             for (int j = 0; j < popSizeAtTimeT.length; j++) {
                 popSizeAtTimeT[j] = calcPopSize(type, times.get(j), popSizes.get(j), time);
             }
-            Arrays.sort(popSizeAtTimeT);
+
+            HeapSort.sort(popSizeAtTimeT, indices);
+
             out.print(time + "\t");
+
             out.print(DiscreteStatistics.mean(popSizeAtTimeT) + "\t");
             out.print(DiscreteStatistics.median(popSizeAtTimeT) + "\t");
-            out.print(DiscreteStatistics.quantile(0.025, popSizeAtTimeT) + "\t");
-            out.print(DiscreteStatistics.quantile(0.975, popSizeAtTimeT) + "\t");
-            out.println();
+
+            double[] hpdInterval = DiscreteStatistics.HPDInterval(0.95, popSizeAtTimeT, indices);
+            out.println(hpdInterval[0] + "\t" + hpdInterval[1]);
         }
     }
 
     private double calcPopSize(CompoundPopulationFunction.Type type, List<Double> xs, List<Double> ys, double d) {
         // TODO completely untested
         // assume linear
-        //assert sType.equals("Linear");
+        //assert typeName.equals("Linear");
 
         final int n = xs.size();
         final double xn = xs.get(n - 1);
@@ -166,11 +172,11 @@ public class EBSPAnalyser {
         return 0;
     }
 
-    private void parseArgs(String[] args) throws Exception {
+    private void parseArgs(String[] args) {
         int i = 0;
         try {
             while (i < args.length) {
-                int iOld = i;
+                int old = i;
                 if (i < args.length) {
                     if (args[i].equals("")) {
                         i += 1;
@@ -190,24 +196,26 @@ public class EBSPAnalyser {
                         } else if (args[i + 1].equals("stepwise")) {
                             m_type = Type.STEPWISE;
                         } else {
-                            throw new Exception("Expected linear of stepwise, not " + args[i + 1]);
+                            throw new IllegalArgumentException("Expected linear or stepwise, not " + args[i + 1]);
                         }
                         i += 2;
                     } else if (args[i].equals("-burnin")) {
                         m_nBurninPercentage = Integer.parseInt(args[i + 1]);
                         i += 2;
                     }
-                    if (i == iOld) {
-                        throw new Exception("Unrecognised argument (argument " + i + ": " + args[i] + ")");
+                    if (i == old) {
+                        throw new IllegalArgumentException("Unrecognised argument (argument " + i + ": " + args[i] + ")");
                     }
                 }
             }
+        } catch (IllegalArgumentException e) {
+        	throw e;
         } catch (Exception e) {
             e.printStackTrace();
-            throw new Exception("Error parsing command line arguments: " + Arrays.toString(args) + "\nArguments ignored\n\n" + getUsage());
+            throw new IllegalArgumentException("Error parsing command line arguments: " + Arrays.toString(args) + "\nArguments ignored\n\n" + getUsage());
         }
         if (m_sFileOut == null) {
-            System.err.println("No output file specified");
+        	Log.warning.println("No output file specified");
         }
 
     }
@@ -224,25 +232,25 @@ public class EBSPAnalyser {
     }
 
     protected void log(String s) {
-        System.err.print(s);
+    	Log.warning.print(s);
     }
 
     protected void logln(String s) {
-        System.err.println(s);
+    	Log.warning.println(s);
     }
 
     private void printTitle(String aboutString) {
         aboutString = "LogCombiner" + aboutString.replaceAll("</p>", "\n\n");
         aboutString = aboutString.replaceAll("<br>", "\n");
         aboutString = aboutString.replaceAll("<[^>]*>", " ");
-        String[] sStrs = aboutString.split("\n");
-        for (String sStr : sStrs) {
-            int n = 80 - sStr.length();
+        String[] strs = aboutString.split("\n");
+        for (String str : strs) {
+            int n = 80 - str.length();
             int n1 = n / 2;
             for (int i = 0; i < n1; i++) {
                 log(" ");
             }
-            logln(sStr);
+            logln(str);
         }
     }
 
@@ -252,9 +260,9 @@ public class EBSPAnalyser {
         private final OptionsPanel optionPanel;
 
         private final JTextField inputFileNameText = new JTextField("not selected", 16);
-        private final JComboBox typeCombo = new JComboBox(new String[]{"linear", "stepwise"});
+        private final JComboBox<String> typeCombo = new JComboBox<>(new String[]{"linear", "stepwise"});
 
-        final WholeNumberField burninText = new WholeNumberField((long) 0, Long.MAX_VALUE);
+        final WholeNumberField burninText = new WholeNumberField(0, Long.MAX_VALUE);
         private final JTextField outputFileNameText = new JTextField("not selected", 16);
 
         private File outputFile = null;
@@ -274,8 +282,7 @@ public class EBSPAnalyser {
             panel.setOpaque(false);
 
             JButton button = new JButton("Choose Input File...");
-            button.addActionListener(new ActionListener() {
-                public void actionPerformed(ActionEvent ae) {
+            button.addActionListener(ae -> {
                     File file = Utils.getLoadFile("Select input file...");
                     if (file == null) {
                         // the dialog was cancelled...
@@ -285,13 +292,11 @@ public class EBSPAnalyser {
                     inputFile = file;
                     inputFileNameText.setText(inputFile.getName());
 
-                }
-            });
+                });
             inputFileNameText.setEditable(false);
 
             JButton button2 = new JButton("Choose Output File...");
-            button2.addActionListener(new ActionListener() {
-                public void actionPerformed(ActionEvent ae) {
+            button2.addActionListener(ae -> {
                     File file = Utils.getSaveFile("Select output file...");
                     if (file == null) {
                         // the dialog was cancelled...
@@ -301,8 +306,7 @@ public class EBSPAnalyser {
                     outputFile = file;
                     outputFileNameText.setText(outputFile.getName());
 
-                }
-            });
+                });
             outputFileNameText.setEditable(false);
 
             JPanel panel1 = new JPanel(new BorderLayout(0, 0));
@@ -349,7 +353,7 @@ public class EBSPAnalyser {
         }
 
         public String[] getArgs() {
-            java.util.List<String> args = new ArrayList<String>();
+            java.util.List<String> args = new ArrayList<>();
             if (inputFile != null) {
                 args.add("-i");
                 args.add(inputFile.getPath());
@@ -422,7 +426,7 @@ public class EBSPAnalyser {
                     analyser.run();
 
                 } catch (Exception ex) {
-                    System.err.println("Exception: " + ex.getMessage());
+                    Log.err.println("Exception: " + ex.getMessage());
                     ex.printStackTrace();
                 }
                 System.out.println("Finished - Quit program to exit.");
diff --git a/src/beast/app/tools/LogCombiner.java b/src/beast/app/tools/LogCombiner.java
index 1ecea3c..88b0d96 100644
--- a/src/beast/app/tools/LogCombiner.java
+++ b/src/beast/app/tools/LogCombiner.java
@@ -1,14 +1,12 @@
 package beast.app.tools;
 
 
-import beast.app.BEASTVersion;
-import beast.util.LogAnalyser;
-import jam.console.ConsoleApplication;
-
-import javax.swing.*;
-import javax.swing.table.TableCellEditor;
-
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
 import java.text.DecimalFormat;
 import java.text.DecimalFormatSymbols;
 import java.util.ArrayList;
@@ -16,6 +14,14 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Locale;
 
+import javax.swing.JFrame;
+import javax.swing.table.TableCellEditor;
+
+import beast.app.BEASTVersion;
+import beast.core.util.Log;
+import beast.util.LogAnalyser;
+import jam.console.ConsoleApplication;
+
 
 /**
  * combines log files produced by a ParticleFilter for
@@ -23,7 +29,7 @@ import java.util.Locale;
  */
 public class LogCombiner extends LogAnalyser {
 
-    List<String> m_sLogFileName = new ArrayList<String>();
+    List<String> m_sLogFileName = new ArrayList<>();
     String m_sParticleDir;
     int m_nParticles = -1;
     String m_sFileOut;
@@ -42,18 +48,18 @@ public class LogCombiner extends LogAnalyser {
     // resample the log files to this frequency (the original sampling frequency must be a factor of this value)
     int m_nResample = 1;
 
-    private void parseArgs(String[] args) throws Exception {
+    private void parseArgs(String[] args) {
         int i = 0;
         format = new DecimalFormat("#.############E0", new DecimalFormatSymbols(Locale.US));
-        m_sLogFileName = new ArrayList<String>();
+        m_sLogFileName = new ArrayList<>();
         try {
             while (i < args.length) {
-                int iOld = i;
+                int old = i;
                 if (i < args.length) {
                     if (args[i].equals("")) {
                         i += 1;
                     } else if (args[i].equals("-help") || args[i].equals("-h") || args[i].equals("--help")) {
-                        System.out.println(getUsage());
+                        Log.info.println(getUsage());
                         System.exit(0);
                     } else if (args[i].equals("-o")) {
                         m_sFileOut = args[i + 1];
@@ -62,7 +68,7 @@ public class LogCombiner extends LogAnalyser {
                     } else if (args[i].equals("-b") || args[i].equals("-burnin") || args[i].equals("--burnin")) {
                         m_nBurninPercentage = Integer.parseInt(args[i + 1]);
                         if (m_nBurninPercentage < 0 || m_nBurninPercentage > 100) {
-                            System.err.println("Error: Burn-in percentage must be between 0 and 100.");
+                        	Log.err.println("Error: Burn-in percentage must be between 0 and 100.");
                             System.exit(1);
                         }
                         i += 2;
@@ -89,14 +95,16 @@ public class LogCombiner extends LogAnalyser {
                         m_nSampleInterval = -1;
                         i++;
                     }
-                    if (i == iOld) {
-                        throw new Exception("Unrecognised argument");
+                    if (i == old) {
+                        throw new IllegalArgumentException("Unrecognised argument");
                     }
                 }
             }
+        } catch (IllegalArgumentException e) {
+        	throw e;
         } catch (Exception e) {
             e.printStackTrace();
-            throw new Exception("Error parsing command line arguments: " + Arrays.toString(args) + "\nArguments ignored\n\n" + getUsage());
+            throw new IllegalArgumentException("Error parsing command line arguments: " + Arrays.toString(args) + "\nArguments ignored\n\n" + getUsage());
         }
     }
 
@@ -106,44 +114,50 @@ public class LogCombiner extends LogAnalyser {
      */
     Double[][] m_fCombinedTraces;
 
-    private void combineParticleLogs() throws Exception {
-        List<String> sLogs = new ArrayList<String>();
+    private void combineParticleLogs() {
+        List<String> logs = new ArrayList<>();
         for (int i = 0; i < m_nParticles; i++) {
-            String sDir = m_sParticleDir + "/particle" + i;
-            File dir = new File(sDir);
+            String dirName = m_sParticleDir + "/particle" + i;
+            File dir = new File(dirName);
             if (!dir.exists() || !dir.isDirectory()) {
-                throw new Exception("Could not process particle " + i + ". Expected " + sDir + " to be a directory, but it is not.");
+                throw new IllegalArgumentException("Could not process particle " + i + ". Expected " + dirName + " to be a directory, but it is not.");
             }
-            sLogs.add(sDir + "/" + m_sLogFileName.get(0));
+            logs.add(dirName + "/" + m_sLogFileName.get(0));
         }
-        int[] nBurnIns = new int[sLogs.size()];
-        Arrays.fill(nBurnIns, m_nBurninPercentage);
-        combineLogs(sLogs.toArray(new String[0]), nBurnIns);
+        int[] burnIns = new int[logs.size()];
+        Arrays.fill(burnIns, m_nBurninPercentage);
+        try {
+			combineLogs(logs.toArray(new String[0]), burnIns);
+		} catch (IOException e) {
+			e.printStackTrace();
+			throw new IllegalArgumentException(e.getMessage());
+		}
     }
 
-    private void combineLogs(String[] sLogs, int[] nBurbIns) throws Exception {
+    private void combineLogs(String[] logs, int[] burbIns) throws IOException {
         m_fCombinedTraces = null;
         // read logs
-        int nColumns = 0;
+        int columns = 0;
         int k = 0;
-        for (String sFile : sLogs) {
-            BufferedReader fin = new BufferedReader(new FileReader(sFile));
-            String sStr = fin.readLine();
-            if (sStr.toUpperCase().startsWith("#NEXUS")) {
+        for (String fileName : logs) {
+            BufferedReader fin = new BufferedReader(new FileReader(fileName));
+            String str = fin.readLine();
+            if (str.toUpperCase().startsWith("#NEXUS")) {
                 m_bIsTreeLog = true;
-                readTreeLogFile(sFile, nBurbIns[k]);
+                readTreeLogFile(fileName, burbIns[k]);
             } else {
-                readLogFile(sFile, nBurbIns[k]);
+                readLogFile(fileName, burbIns[k]);
             }
 
             if (m_fCombinedTraces == null) {
                 m_fCombinedTraces = m_fTraces;
                 if (!m_bIsTreeLog) {
-                    nColumns = m_sLabels.length;
+                    columns = m_sLabels.length;
                 }
             } else {
-                if (nColumns != m_sLabels.length) {
-                    throw new Exception("ERROR: The number of columns in file " + sFile + " does not match that of the first file");
+                if (columns != m_sLabels.length) {
+                    fin.close();
+                    throw new IllegalArgumentException("ERROR: The number of columns in file " + fileName + " does not match that of the first file");
                 }
                 for (int i = 0; i < m_fTraces.length; i++) {
                     Double[] logLine = m_fTraces[i];
@@ -155,6 +169,7 @@ public class LogCombiner extends LogAnalyser {
                 }
             }
             k++;
+            fin.close();
         }
         if (!m_bIsTreeLog) {
             // reset sample column
@@ -170,54 +185,55 @@ public class LogCombiner extends LogAnalyser {
         }
     }
 
-    protected void readTreeLogFile(String sFile, int nBurnInPercentage) throws Exception {
-        log("\nLoading " + sFile);
-        BufferedReader fin = new BufferedReader(new FileReader(sFile));
-        String sStr = null;
+    protected void readTreeLogFile(String fileName, int burnInPercentage) throws IOException {
+        log("\nLoading " + fileName);
+        BufferedReader fin = new BufferedReader(new FileReader(fileName));
+        String str = null;
         m_sPreAmble = "";
-        int nData = 0;
+        int data = 0;
         // first, sweep through the log file to determine size of the log
         while (fin.ready()) {
-            sStr = fin.readLine();
-            if (sStr.matches("^tree STATE.*")) {
-                nData++;
+            str = fin.readLine();
+            if (str.matches("^tree STATE.*")) {
+                data++;
             } else {
-                if (nData == 0) {
-                    m_sPreAmble += sStr + "\n";
+                if (data == 0) {
+                    m_sPreAmble += str + "\n";
                 }
             }
         }
-        int nLines = nData / 80;
+        int lines = data / 80;
         // reserve memory
-        int nBurnIn = nData * nBurnInPercentage / 100;
-        logln(" skipping " + nBurnIn + " trees\n\n" + BAR);
+        int burnIn = data * burnInPercentage / 100;
+        logln(" skipping " + burnIn + " trees\n\n" + BAR);
         if (m_sTrees == null) {
-            m_sTrees = new ArrayList<String>();
+            m_sTrees = new ArrayList<>();
         }
-        fin = new BufferedReader(new FileReader(sFile));
-        nData = -nBurnIn - 1;
+        fin.close();
+        fin = new BufferedReader(new FileReader(fileName));
+        data = -burnIn - 1;
         // grab data from the log, ignoring burn in samples
-        int nSample0 = -1;
+        int sample0 = -1;
 
         while (fin.ready()) {
-            sStr = fin.readLine();
-            if (sStr.matches("^tree STATE_.*")) {
-                if (++nData >= 0) {
+            str = fin.readLine();
+            if (str.matches("^tree STATE_.*")) {
+                if (++data >= 0) {
                     if (m_nSampleInterval < 0) {
-                        String sStr2 = sStr.substring(11, sStr.indexOf("=")).trim();
-                        sStr2 = sStr2.split("\\s")[0];
-                        if (nSample0 < 0) {
-                            nSample0 = Integer.parseInt(sStr2);
+                        String str2 = str.substring(11, str.indexOf("=")).trim();
+                        str2 = str2.split("\\s")[0];
+                        if (sample0 < 0) {
+                            sample0 = Integer.parseInt(str2);
                         } else {
-                            m_nSampleInterval = Integer.parseInt(sStr2) - nSample0;
+                            m_nSampleInterval = Integer.parseInt(str2) - sample0;
                         }
 
                     }
-                    sStr = sStr.replaceAll("^tree STATE_[^\\s=]*", "");
-                    m_sTrees.add(sStr);
+                    str = str.replaceAll("^tree STATE_[^\\s=]*", "");
+                    m_sTrees.add(str);
                 }
             }
-            if (nData % nLines == 0) {
+            if (data % lines == 0) {
                 log("*");
             }
         }
@@ -225,8 +241,8 @@ public class LogCombiner extends LogAnalyser {
     } // readTreeLogFile
 
     private void printCombinedLogs() {
-        int nData = (m_bIsTreeLog ? m_sTrees.size() : m_fCombinedTraces[0].length);
-        logln("Collected " + nData + " lines in combined log");
+        int data = (m_bIsTreeLog ? m_sTrees.size() : m_fCombinedTraces[0].length);
+        logln("Collected " + data + " lines in combined log");
         if (m_sFileOut != null) {
             log("Writing to file " + m_sFileOut);
             try {
@@ -240,16 +256,16 @@ public class LogCombiner extends LogAnalyser {
         // preamble
         m_out.println(m_sPreAmble);
 
-        int nLines = 0;
+        int lines = 0;
         if (m_bIsTreeLog) {
             for (int i = 0; i < m_sTrees.size(); i++) {
                 if ((m_nSampleInterval * i) % m_nResample == 0) {
-                    String sTree = m_sTrees.get(i);
-                    sTree = format(sTree);
-                    m_out.println("tree STATE_" + (m_nSampleInterval * i) + (Character.isSpaceChar(sTree.charAt(0)) ? "" : " ") + sTree);
-                    nLines++;
+                    String tree = m_sTrees.get(i);
+                    tree = format(tree);
+                    m_out.println("tree STATE_" + (m_nSampleInterval * i) + (Character.isSpaceChar(tree.charAt(0)) ? "" : " ") + tree);
+                    lines++;
                 }
-                if (i % (nData / 80) == 0) {
+                if (i % (data / 80) == 0) {
                     log("*");
                 }
             }
@@ -277,44 +293,44 @@ public class LogCombiner extends LogAnalyser {
                         }
                     }
                     m_out.print("\n");
-                    nLines++;
+                    lines++;
                 }
-                if ((nData / 80 > 0) && i % (nData / 80) == 0) {
+                if ((data / 80 > 0) && i % (data / 80) == 0) {
                     log("*");
                 }
             }
         }
-        logln("\n" + nLines + " lines in combined log");
+        logln("\n" + lines + " lines in combined log");
     }
 
-    protected String format(String sTree) {
+    protected String format(String tree) {
         if (m_bUseDecimalFormat) {
             // convert scientific to decimal format
-            if (sTree.matches(".*[0-9]+\\.[0-9]+[0-9-]+E[0-9-]+.*")) {
+            if (tree.matches(".*[0-9]+\\.[0-9]+[0-9-]+E[0-9-]+.*")) {
                 int k = 0;
-                while (k < sTree.length()) {
-                    char c = sTree.charAt(k);
+                while (k < tree.length()) {
+                    char c = tree.charAt(k);
                     if (Character.isDigit(c)) {
-                        int iStart = k;
-                        while (++k < sTree.length() && Character.isDigit(sTree.charAt(k))) {
+                        int start = k;
+                        while (++k < tree.length() && Character.isDigit(tree.charAt(k))) {
                         }
-                        if (k < sTree.length() && sTree.charAt(k) == '.') {
-                            while (++k < sTree.length() && Character.isDigit(sTree.charAt(k))) {
+                        if (k < tree.length() && tree.charAt(k) == '.') {
+                            while (++k < tree.length() && Character.isDigit(tree.charAt(k))) {
                             }
-                            if (k < sTree.length() && (sTree.charAt(k) == 'E' || sTree.charAt(k) == 'e')) {
+                            if (k < tree.length() && (tree.charAt(k) == 'E' || tree.charAt(k) == 'e')) {
                                 k++;
-                                if (k < sTree.length() && sTree.charAt(k) == '-') {
+                                if (k < tree.length() && tree.charAt(k) == '-') {
                                     k++;
                                 }
-                                if (k < sTree.length() && Character.isDigit(sTree.charAt(k))) {
-                                    while (++k < sTree.length() && Character.isDigit(sTree.charAt(k))) {
+                                if (k < tree.length() && Character.isDigit(tree.charAt(k))) {
+                                    while (++k < tree.length() && Character.isDigit(tree.charAt(k))) {
                                     }
-                                    int iEnd = k;
-                                    String sNumber = sTree.substring(iStart, iEnd);
-                                    double d = Double.parseDouble(sNumber);
-                                    sNumber = format.format(d);
-                                    sTree = sTree.substring(0, iStart) + sNumber + sTree.substring(iEnd);
-                                    k = iStart + sNumber.length();
+                                    int end = k;
+                                    String number = tree.substring(start, end);
+                                    double d = Double.parseDouble(number);
+                                    number = format.format(d);
+                                    tree = tree.substring(0, start) + number + tree.substring(end);
+                                    k = start + number.length();
                                 }
                             }
                         }
@@ -325,24 +341,24 @@ public class LogCombiner extends LogAnalyser {
             }
         } else {
             // convert decimal to scientific format
-            if (sTree.matches(".*[0-9]+\\.[0-9]+[^E-].*")) {
+            if (tree.matches(".*[0-9]+\\.[0-9]+[^E-].*")) {
                 int k = 0;
-                while (k < sTree.length()) {
-                    char c = sTree.charAt(k);
+                while (k < tree.length()) {
+                    char c = tree.charAt(k);
                     if (Character.isDigit(c)) {
-                        int iStart = k;
-                        while (++k < sTree.length() && Character.isDigit(sTree.charAt(k))) {
+                        int start = k;
+                        while (++k < tree.length() && Character.isDigit(tree.charAt(k))) {
                         }
-                        if (k < sTree.length() && sTree.charAt(k) == '.') {
-                            while (++k < sTree.length() && Character.isDigit(sTree.charAt(k))) {
+                        if (k < tree.length() && tree.charAt(k) == '.') {
+                            while (++k < tree.length() && Character.isDigit(tree.charAt(k))) {
                             }
-                            if (k < sTree.length() && sTree.charAt(k) != '-' && sTree.charAt(k) != 'E' && sTree.charAt(k) != 'e') {
-                                int iEnd = k;
-                                String sNumber = sTree.substring(iStart, iEnd);
-                                double d = Double.parseDouble(sNumber);
-                                sNumber = format.format(d);
-                                sTree = sTree.substring(0, iStart) + sNumber + sTree.substring(iEnd);
-                                k = iStart + sNumber.length();
+                            if (k < tree.length() && tree.charAt(k) != '-' && tree.charAt(k) != 'E' && tree.charAt(k) != 'e') {
+                                int end = k;
+                                String number = tree.substring(start, end);
+                                double d = Double.parseDouble(number);
+                                number = format.format(d);
+                                tree = tree.substring(0, start) + number + tree.substring(end);
+                                k = start + number.length();
                             }
                         }
                     } else {
@@ -351,7 +367,7 @@ public class LogCombiner extends LogAnalyser {
                 }
             }
         }
-        return sTree;
+        return tree;
     }
 
     private static String getUsage() {
@@ -373,14 +389,14 @@ public class LogCombiner extends LogAnalyser {
         aboutString = "LogCombiner" + aboutString.replaceAll("</p>", "\n\n");
         aboutString = aboutString.replaceAll("<br>", "\n");
         aboutString = aboutString.replaceAll("<[^>]*>", " ");
-        String[] sStrs = aboutString.split("\n");
-        for (String sStr : sStrs) {
-            int n = 80 - sStr.length();
+        String[] strs = aboutString.split("\n");
+        for (String str : strs) {
+            int n = 80 - str.length();
             int n1 = n / 2;
             for (int i = 0; i < n1; i++) {
                 log(" ");
             }
-            logln(sStr);
+            logln(str);
         }
     }
 
@@ -459,7 +475,7 @@ public class LogCombiner extends LogAnalyser {
                 combiner.m_sFileOut = dialog.getOutputFileName();
 
                 if (combiner.m_sFileOut == null) {
-                    System.err.println("No output file specified");
+                	Log.warning.println("No output file specified");
                 }
 
                 try {
@@ -467,7 +483,7 @@ public class LogCombiner extends LogAnalyser {
                     combiner.printCombinedLogs();
 
                 } catch (Exception ex) {
-                    System.err.println("Exception: " + ex.getMessage());
+                	Log.warning.println("Exception: " + ex.getMessage());
                     ex.printStackTrace();
                 }
                 System.out.println("Finished - Quit program to exit.");
@@ -484,10 +500,10 @@ public class LogCombiner extends LogAnalyser {
                 combiner.parseArgs(args);
                 if (combiner.m_sParticleDir == null) {
                     // classical log combiner
-                    String[] sLogFiles = combiner.m_sLogFileName.toArray(new String[0]);
-                    int[] nBurnIns = new int[sLogFiles.length];
-                    Arrays.fill(nBurnIns, combiner.m_nBurninPercentage);
-                    combiner.combineLogs(sLogFiles, nBurnIns);
+                    String[] logFiles = combiner.m_sLogFileName.toArray(new String[0]);
+                    int[] burnIns = new int[logFiles.length];
+                    Arrays.fill(burnIns, combiner.m_nBurninPercentage);
+                    combiner.combineLogs(logFiles, burnIns);
 
                 } else {
                     // particle log combiner
diff --git a/src/beast/app/tools/LogCombinerDialog.java b/src/beast/app/tools/LogCombinerDialog.java
index 8f3ddc2..0b47859 100644
--- a/src/beast/app/tools/LogCombinerDialog.java
+++ b/src/beast/app/tools/LogCombinerDialog.java
@@ -26,15 +26,36 @@
 package beast.app.tools;
 
 
-//import dr.app.gui.FileDrop;
-
-//import dr.app.gui.table.TableEditorStopper;
-//import dr.app.gui.components.WholeNumberField;
-import jam.panels.ActionPanel;
-import jam.panels.OptionsPanel;
-import jam.table.TableRenderer;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
 
-import javax.swing.*;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.ScrollPaneConstants;
+import javax.swing.SwingConstants;
+import javax.swing.UIManager;
 import javax.swing.border.Border;
 import javax.swing.border.EmptyBorder;
 import javax.swing.event.ListSelectionEvent;
@@ -46,13 +67,13 @@ import beast.app.util.FileDrop;
 import beast.app.util.Utils;
 import beast.app.util.WholeNumberField;
 
+//import dr.app.gui.FileDrop;
 
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
+//import dr.app.gui.table.TableEditorStopper;
+//import dr.app.gui.components.WholeNumberField;
+import jam.panels.ActionPanel;
+import jam.panels.OptionsPanel;
+import jam.table.TableRenderer;
 
 public class LogCombinerDialog {
     private final JFrame frame;
@@ -62,13 +83,13 @@ public class LogCombinerDialog {
     JTable filesTable = null;
     private FilesTableModel filesTableModel = null;
 
-    private final JComboBox fileTypeCombo = new JComboBox(new String[]{"Log Files", "Tree Files"});
+    private final JComboBox<String> fileTypeCombo = new JComboBox<>(new String[]{"Log Files", "Tree Files"});
     private final JCheckBox decimalCheck = new JCheckBox("Convert numbers from scientific to decimal notation");
     private final JCheckBox renumberOutput = new JCheckBox("Renumber ouput states");
     private final JCheckBox resampleCheck = new JCheckBox("Resample states at lower frequency: ");
     private final WholeNumberField resampleText = new WholeNumberField(0, Integer.MAX_VALUE);
 
-    private final List<FileInfo> files = new ArrayList<FileInfo>();
+    private final List<FileInfo> files = new ArrayList<>();
 
     private final JTextField fileNameText = new JTextField("not selected", 16);
     private File outputFile = null;
@@ -100,14 +121,15 @@ public class LogCombinerDialog {
         //TableEditorStopper.ensureEditingStopWhenTableLosesFocus(filesTable);
 
         filesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
-            public void valueChanged(ListSelectionEvent evt) {
+            @Override
+			public void valueChanged(ListSelectionEvent evt) {
                 filesTableSelectionChanged();
             }
         });
 
         JScrollPane scrollPane1 = new JScrollPane(filesTable,
-                JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
-                JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+                ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
+                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
         //scrollPane1.setMaximumSize(new Dimension(10000, 10));
         scrollPane1.setPreferredSize(new Dimension(500, 285));
 
@@ -127,34 +149,34 @@ public class LogCombinerDialog {
         Color focusColor = UIManager.getColor("Focus.color");
         Border focusBorder = BorderFactory.createMatteBorder(2, 2, 2, 2, focusColor);
         new FileDrop(null, scrollPane1, focusBorder, new FileDrop.Listener() {
-            public void filesDropped(java.io.File[] files) {
+            @Override
+			public void filesDropped(java.io.File[] files) {
                 addFiles(files);
             }   // end filesDropped
         }); // end FileDrop.Listener
 
         resampleText.setEnabled(false);
         resampleText.setColumns(12);
-        resampleCheck.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
+        resampleCheck.addActionListener(e -> {
                 resampleText.setEnabled(resampleCheck.isSelected());
-            }
-        });
+            });
 
         ActionListener buttonListener = new ActionListener() {
-            public void actionPerformed(ActionEvent ae) {
+            @Override
+			public void actionPerformed(ActionEvent ae) {
                 File file = Utils.getSaveFile("Select output file...", new File(Beauti.g_sDir), "Beast log and tree files", "log", "trees");
                 if (file == null) {
                     // the dialog was cancelled...
                     return;
                 }
                 outputFile = file;
-                String sFileName = file.getAbsolutePath();
+                String fileName = file.getAbsolutePath();
                 String fileSep = System.getProperty("file.separator");
                 if (fileSep.equals("\\")) {
                 	fileSep = "\\\\";
                 }
-                if (sFileName.lastIndexOf(fileSep) > 0) {
-                    Beauti.g_sDir = sFileName.substring(0, sFileName.lastIndexOf(fileSep));
+                if (fileName.lastIndexOf(fileSep) > 0) {
+                    Beauti.g_sDir = fileName.substring(0, fileName.lastIndexOf(fileSep));
                 }
                 fileNameText.setText(outputFile.getName());
 
@@ -266,14 +288,14 @@ public class LogCombinerDialog {
 
             files.add(fileInfo);
 
-            String sFileName = file.getAbsolutePath();
+            String fileName = file.getAbsolutePath();
             String fileSep = System.getProperty("file.separator");
             if (fileSep.equals("\\")) {
             	fileSep = "\\\\";
             }
 
-            if (sFileName.lastIndexOf(fileSep) > 0) {
-                Beauti.g_sDir = sFileName.substring(0, sFileName.lastIndexOf(fileSep));
+            if (fileName.lastIndexOf(fileSep) > 0) {
+                Beauti.g_sDir = fileName.substring(0, fileName.lastIndexOf(fileSep));
             }
         }
 
@@ -291,7 +313,8 @@ public class LogCombinerDialog {
          */
         private static final long serialVersionUID = 7602227478402204088L;
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             File[] files = Utils.getLoadFiles("Select log file", new File(Beauti.g_sDir), "Trace or tree log files", "log", "trees");
             if (files != null) {
                 addFiles(files);
@@ -306,7 +329,8 @@ public class LogCombinerDialog {
          */
         private static final long serialVersionUID = 5934278375005327047L;
 
-        public void actionPerformed(ActionEvent ae) {
+        @Override
+		public void actionPerformed(ActionEvent ae) {
             int row = filesTable.getSelectedRow();
             if (row != -1) {
                 files.remove(row);
@@ -332,15 +356,18 @@ public class LogCombinerDialog {
         public FilesTableModel() {
         }
 
-        public int getColumnCount() {
+        @Override
+		public int getColumnCount() {
             return columns.length;
         }
 
-        public int getRowCount() {
+        @Override
+		public int getRowCount() {
             return files.size();
         }
 
-        public Object getValueAt(int rowIndex, int columnIndex) {
+        @Override
+		public Object getValueAt(int rowIndex, int columnIndex) {
             FileInfo fileInfo = files.get(rowIndex);
             if (columnIndex == 0) {
                 return fileInfo.file.getName();
@@ -349,7 +376,8 @@ public class LogCombinerDialog {
             }
         }
 
-        public boolean isCellEditable(int rowIndex, int columnIndex) {
+        @Override
+		public boolean isCellEditable(int rowIndex, int columnIndex) {
             return (columnIndex == 1);
         }
 
@@ -361,7 +389,8 @@ public class LogCombinerDialog {
          * @param rowIndex    row of cell
          * @param columnIndex column of cell
          */
-        public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+        @Override
+		public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
             FileInfo fileInfo = files.get(rowIndex);
             if (columnIndex == 1) {
                 int newBurnin = (int)aValue;
@@ -374,11 +403,13 @@ public class LogCombinerDialog {
             }
         }
 
-        public String getColumnName(int columnIndex) {
+        @Override
+		public String getColumnName(int columnIndex) {
             return columns[columnIndex];
         }
 
-        public Class<?> getColumnClass(int columnIndex) {
+        @Override
+		public Class<?> getColumnClass(int columnIndex) {
             return getValueAt(0, columnIndex).getClass();
         }
     }
diff --git a/src/beast/app/tools/LogCombinerLauncher.java b/src/beast/app/tools/LogCombinerLauncher.java
index a2f45b7..6fe3e16 100644
--- a/src/beast/app/tools/LogCombinerLauncher.java
+++ b/src/beast/app/tools/LogCombinerLauncher.java
@@ -1,14 +1,16 @@
 package beast.app.tools;
 
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
 import beast.app.beastapp.BeastLauncher;
-import beast.app.beastapp.BeastMain;
 
 /** Launches log-combiner 
  * @see BeastLauncher 
  * **/
 public class LogCombinerLauncher extends BeastLauncher {
 
-	public static void main(String[] args) throws Exception {
+	public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
 		if (javaVersionCheck("LogCombiner")) {
 			loadBEASTJars();
 			LogCombiner.main(args);
diff --git a/src/beast/app/tools/TableEditorStopper.java b/src/beast/app/tools/TableEditorStopper.java
index b9cccb6..28a9c25 100644
--- a/src/beast/app/tools/TableEditorStopper.java
+++ b/src/beast/app/tools/TableEditorStopper.java
@@ -5,6 +5,7 @@ import java.awt.event.FocusAdapter;
 import java.awt.event.FocusEvent;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
+
 import javax.swing.JTable;
 import javax.swing.table.TableCellEditor;
 
@@ -49,7 +50,8 @@ public class TableEditorStopper extends FocusAdapter implements PropertyChangeLi
         table.addPropertyChangeListener("tableCellEditor", this);
     }
 
-    public void propertyChange(PropertyChangeEvent evt) {
+    @Override
+	public void propertyChange(PropertyChangeEvent evt) {
         if (focused != null) {
             focused.removeFocusListener(this);
         }
@@ -59,7 +61,8 @@ public class TableEditorStopper extends FocusAdapter implements PropertyChangeLi
         }
     }
 
-    public void focusLost(FocusEvent e) {
+    @Override
+	public void focusLost(FocusEvent e) {
         if (focused != null) {
             focused.removeFocusListener(this);
             focused = e.getOppositeComponent();
diff --git a/src/beast/app/treeannotator/CladeSystem.java b/src/beast/app/treeannotator/CladeSystem.java
index d99f1f1..82198ca 100644
--- a/src/beast/app/treeannotator/CladeSystem.java
+++ b/src/beast/app/treeannotator/CladeSystem.java
@@ -1,10 +1,15 @@
 package beast.app.treeannotator;
 
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
 import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
 
-import java.util.*;
-
 /**
  * extracted from TreeAnnotator
  */
diff --git a/src/beast/app/treeannotator/ContourAttrib.java b/src/beast/app/treeannotator/ContourAttrib.java
index 92c294e..78a39b9 100644
--- a/src/beast/app/treeannotator/ContourAttrib.java
+++ b/src/beast/app/treeannotator/ContourAttrib.java
@@ -57,6 +57,7 @@ public class ContourAttrib implements Cloneable, java.io.Serializable {
 	*
 	*  @return  Returns a clone of this object.
 	**/
+	@Override
 	public Object clone() {
 		ContourAttrib newObject = null;
 
diff --git a/src/beast/app/treeannotator/ContourGenerator.java b/src/beast/app/treeannotator/ContourGenerator.java
index 64e77b1..f449a65 100644
--- a/src/beast/app/treeannotator/ContourGenerator.java
+++ b/src/beast/app/treeannotator/ContourGenerator.java
@@ -1,6 +1,9 @@
 package beast.app.treeannotator;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.List;
+
+import beast.core.util.Log;
 
 
 /**
@@ -44,7 +47,7 @@ public class ContourGenerator {
 	private static final int kMinNumPoints = 3;
 
 	//	A list of contour paths.
-	private List<ContourPath> pathList = new ArrayList<ContourPath>();
+	private List<ContourPath> pathList = new ArrayList<>();
 
 	//	A flag to indicate that the contours have been computed or not.
 	private boolean cCalculated = false;
@@ -93,15 +96,15 @@ public class ContourGenerator {
 	*
 	*  @param  xArr   2D array containing the grid x coordinate data.
 	*  @param  yArr   2D array containing the grid y coordinate data.
-	*  @param  fArr   2D array containing the grid function (z) data.
+	*  @param  zArr   2D array containing the grid function (z) data.
 	*  @param  cAttr  Array containing attributes of the contour levels.
 	**/
-	public ContourGenerator(double[][] xArr, double[][] yArr, double[][] fArr, ContourAttrib[] cAttr) {
+	public ContourGenerator(double[][] xArr, double[][] yArr, double[][] zArr, ContourAttrib[] cAttr) {
 
 		//	Make sure input data is reasonable.
-		if (yArr.length != xArr.length || yArr.length != fArr.length)
+		if (yArr.length != xArr.length || yArr.length != zArr.length)
 			throw new IllegalArgumentException(kInconsistantArrMsg);
-		if (yArr[0].length != xArr[0].length || yArr[0].length != fArr[0].length)
+		if (yArr[0].length != xArr[0].length || yArr[0].length != zArr[0].length)
 			throw new IllegalArgumentException(kInconsistantArrMsg);
 		if (xArr.length <= 1 || xArr[0].length <= 1)
 			throw new IllegalArgumentException(kArrSizeMsg);
@@ -109,7 +112,7 @@ public class ContourGenerator {
 		this.cAttr = cAttr;
 		xArray = xArr;
 		yArray = yArr;
-		funcArray = fArr;
+		funcArray = zArr;
 
 	}
 
@@ -122,13 +125,13 @@ public class ContourGenerator {
 	*
 	*  @param  xArr   1D array containing the grid x coordinate data.
 	*  @param  yArr   1D array containing the grid y coordinate data.
-	*  @param  fArr   2D array containing the grid function (z) data.
+	*  @param  zArr   2D array containing the grid function (z) data.
 	*  @param  cAttr  Array containing attributes of the contour levels.
 	**/
-	public ContourGenerator(double[] xArr, double[] yArr, double[][] fArr, ContourAttrib[] cAttr) {
+	public ContourGenerator(double[] xArr, double[] yArr, double[][] zArr, ContourAttrib[] cAttr) {
 
 		//	Make sure input data is reasonable.
-		if (yArr.length != fArr.length || xArr.length != fArr[0].length)
+		if (yArr.length != zArr.length || xArr.length != zArr[0].length)
 			throw new IllegalArgumentException(kInconsistantArrMsg);
 		if (xArr.length <= 1)
 			throw new IllegalArgumentException(kArrSizeMsg);
@@ -136,7 +139,7 @@ public class ContourGenerator {
 		this.cAttr = cAttr;
 		xArr1D = xArr;
 		yArr1D = yArr;
-		funcArray = fArr;
+		funcArray = zArr;
 	}
 
 	/**
@@ -147,25 +150,25 @@ public class ContourGenerator {
 	*
 	*  @param  xArr   2D array containing the grid x coordinate data.
 	*  @param  yArr   2D array containing the grid y coordinate data.
-	*  @param  fArr   2D array containing the grid function (z) data.
+	*  @param  zArr   2D array containing the grid function (z) data.
 	*  @param  nc     The number of contour levels to generate.
 	*  @param  logInterval  Uses a logarithmic contour interval if true, and
 	*                       uses a linear interval if false.
 	**/
-	public ContourGenerator(double[][] xArr, double[][] yArr, double[][] fArr,
+	public ContourGenerator(double[][] xArr, double[][] yArr, double[][] zArr,
 								int nc, boolean logInterval) {
 
 		//	Make sure input data is reasonable.
-		if (yArr.length != xArr.length || yArr.length != fArr.length)
+		if (yArr.length != xArr.length || yArr.length != zArr.length)
 			throw new IllegalArgumentException(kInconsistantArrMsg);
-		if (yArr[0].length != xArr[0].length || yArr[0].length != fArr[0].length)
+		if (yArr[0].length != xArr[0].length || yArr[0].length != zArr[0].length)
 			throw new IllegalArgumentException(kInconsistantArrMsg);
 		if (xArr.length <= 1 || xArr[0].length <= 1)
 			throw new IllegalArgumentException(kArrSizeMsg);
 
 		xArray = xArr;
 		yArray = yArr;
-		funcArray = fArr;
+		funcArray = zArr;
 
 		if (logInterval)
 			findLogIntervals(nc);
@@ -183,23 +186,23 @@ public class ContourGenerator {
 	*
 	*  @param  xArr   1D array containing the grid x coordinate data.
 	*  @param  yArr   1D array containing the grid y coordinate data.
-	*  @param  fArr   2D array containing the grid function (z) data.
+	*  @param  zArr   2D array containing the grid function (z) data.
 	*  @param  nc     The number of contour levels to generate.
 	*  @param  logInterval  Uses a logarithmic contour interval if true, and
 	*                       uses a linear interval if false.
 	**/
-	public ContourGenerator(double[] xArr, double[] yArr, double[][] fArr,
+	public ContourGenerator(double[] xArr, double[] yArr, double[][] zArr,
 								int nc, boolean logInterval) {
 
 		//	Make sure input data is reasonable.
-		if (yArr.length != fArr.length || xArr.length != fArr[0].length)
+		if (yArr.length != zArr.length || xArr.length != zArr[0].length)
 			throw new IllegalArgumentException(kInconsistantArrMsg);
 		if (xArr.length <= 1)
 			throw new IllegalArgumentException(kArrSizeMsg);
 
 		xArr1D = xArr;
 		yArr1D = yArr;
-		funcArray = fArr;
+		funcArray = zArr;
 
 		if (logInterval)
 			findLogIntervals(nc);
@@ -295,7 +298,7 @@ public class ContourGenerator {
 		for (int i=0; i < nc; i++) {
 			cAttr[i] = new ContourAttrib( zMin + (i+1)*delta );
 			if (DEBUG)
-				System.out.println("level[" + i + "] = " + (zMin + (i+1)*delta));
+				Log.info.println("level[" + i + "] = " + (zMin + (i+1)*delta));
 		}
 
 	}
@@ -776,11 +779,11 @@ public class ContourGenerator {
 		}
 
 		if (DEBUG) {
-			System.out.println("i, j = " + gi + "," + gj);
-			System.out.println("cont = " + (float)cont + ",  fij = " + (float)fij +
+			Log.info.println("i, j = " + gi + "," + gj);
+			Log.info.println("cont = " + (float)cont + ",  fij = " + (float)fij +
 									",  func = " + (float)func + ",  xyf = " + (float)xyf);
-			System.out.println("xVal = " + (float)xVal + ",  yVal = " + (float)yVal);
-			System.out.println("wxx = " + (float)wxx + ",  wyy = " + (float)wyy);
+			Log.info.println("xVal = " + (float)xVal + ",  yVal = " + (float)yVal);
+			Log.info.println("wxx = " + (float)wxx + ",  wyy = " + (float)wyy);
 		}
 
 		//	Figure out what to do with this point.
diff --git a/src/beast/app/treeannotator/ContourPath.java b/src/beast/app/treeannotator/ContourPath.java
index 5633287..1770cff 100644
--- a/src/beast/app/treeannotator/ContourPath.java
+++ b/src/beast/app/treeannotator/ContourPath.java
@@ -107,6 +107,7 @@ public class ContourPath implements Cloneable, java.io.Serializable {
 	*
 	*  @return  Returns a clone of this object.
 	**/
+	@Override
 	public Object clone() {
 		ContourPath newObject = null;
 
diff --git a/src/beast/app/treeannotator/ContourWithSynder.java b/src/beast/app/treeannotator/ContourWithSynder.java
index 059aa99..0d4c17a 100644
--- a/src/beast/app/treeannotator/ContourWithSynder.java
+++ b/src/beast/app/treeannotator/ContourWithSynder.java
@@ -1,7 +1,9 @@
 package beast.app.treeannotator;
 
-import java.util.*;
 import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
 
 
 /**
@@ -25,7 +27,8 @@ public class ContourWithSynder extends KernelDensityEstimator2D  {
         super(x, y, n);
     }
 
-    public ContourPath[] getContourPaths(double hpdValue) {
+    @Override
+	public ContourPath[] getContourPaths(double hpdValue) {
 
         if (contourPaths == null) {
 
@@ -35,7 +38,7 @@ public class ContourWithSynder extends KernelDensityEstimator2D  {
             contourPlot.setDeltas(getXGrid()[1]-getXGrid()[0],getYGrid()[1]-getYGrid()[0] );
             contourPlot.setOffsets(getXGrid()[0],getYGrid()[0]);
 
-            List<LinkedList<Point2D>> allPaths = new ArrayList<LinkedList<Point2D>>();
+            List<LinkedList<Point2D>> allPaths = new ArrayList<>();
             contourPlot.ContourKernel(getKDE(),allPaths,thresholdDensity);
 
             contourPaths = new ContourPath[allPaths.size()];
diff --git a/src/beast/app/treeannotator/FileDrop.java b/src/beast/app/treeannotator/FileDrop.java
index df48e17..aca9b3a 100644
--- a/src/beast/app/treeannotator/FileDrop.java
+++ b/src/beast/app/treeannotator/FileDrop.java
@@ -253,7 +253,8 @@ public class FileDrop {
 
         if (supportsDnD()) {   // Make a drop listener
             dropListener = new java.awt.dnd.DropTargetListener() {
-                public void dragEnter(java.awt.dnd.DropTargetDragEvent evt) {
+                @Override
+				public void dragEnter(java.awt.dnd.DropTargetDragEvent evt) {
                     log(out, "FileDrop: dragEnter event.");
 
                     // Is this an acceptable drag event?
@@ -278,11 +279,13 @@ public class FileDrop {
                     }   // end else: drag not ok
                 }   // end dragEnter
 
-                public void dragOver(java.awt.dnd.DropTargetDragEvent evt) {   // This is called continually as long as the mouse is
+                @Override
+				public void dragOver(java.awt.dnd.DropTargetDragEvent evt) {   // This is called continually as long as the mouse is
                     // over the drag target.
                 }   // end dragOver
 
-                public void drop(java.awt.dnd.DropTargetDropEvent evt) {
+                @Override
+				public void drop(java.awt.dnd.DropTargetDropEvent evt) {
                     log(out, "FileDrop: drop event.");
                     try {   // Get whatever was dropped
                         java.awt.datatransfer.Transferable tr = evt.getTransferable();
@@ -366,7 +369,8 @@ public class FileDrop {
                     }   // end finally
                 }   // end drop
 
-                public void dragExit(java.awt.dnd.DropTargetEvent evt) {
+                @Override
+				public void dragExit(java.awt.dnd.DropTargetEvent evt) {
                     log(out, "FileDrop: dragExit event.");
                     // If it's a Swing component, reset its border
                     if (c instanceof javax.swing.JComponent) {
@@ -376,7 +380,8 @@ public class FileDrop {
                     }   // end if: JComponent
                 }   // end dragExit
 
-                public void dropActionChanged(java.awt.dnd.DropTargetDragEvent evt) {
+                @Override
+				public void dropActionChanged(java.awt.dnd.DropTargetDragEvent evt) {
                     log(out, "FileDrop: dropActionChanged event.");
                     // Is this an acceptable drag event?
                     if (isDragOk(out, evt)) {   //evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE );
@@ -419,11 +424,11 @@ public class FileDrop {
     // BEGIN 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added.
     private static String ZERO_CHAR_STRING = "" + (char) 0;
 
-    private static File[] createFileArray(BufferedReader bReader, PrintStream out) {
+    private static File[] createFileArray(BufferedReader reader, PrintStream out) {
         try {
-            java.util.List<File> list = new java.util.ArrayList<File>();
+            java.util.List<File> list = new java.util.ArrayList<>();
             java.lang.String line = null;
-            while ((line = bReader.readLine()) != null) {
+            while ((line = reader.readLine()) != null) {
                 try {
                     // kde seems to append a 0 char to the end of the reader
                     if (ZERO_CHAR_STRING.equals(line)) continue;
@@ -435,7 +440,7 @@ public class FileDrop {
                 }
             }
 
-            return (java.io.File[]) list.toArray(new File[list.size()]);
+            return list.toArray(new File[list.size()]);
         } catch (IOException ex) {
             log(out, "FileDrop: IOException");
         }
@@ -457,7 +462,8 @@ public class FileDrop {
 
         // Listen for hierarchy changes and remove the drop target when the parent gets cleared out.
         c.addHierarchyListener(new java.awt.event.HierarchyListener() {
-            public void hierarchyChanged(java.awt.event.HierarchyEvent evt) {
+            @Override
+			public void hierarchyChanged(java.awt.event.HierarchyEvent evt) {
                 log(out, "FileDrop: Hierarchy changed.");
                 java.awt.Component parent = c.getParent();
                 if (parent == null) {
@@ -804,7 +810,8 @@ public class FileDrop {
          * @return An array of supported data flavors
          * @since 1.1
          */
-        public java.awt.datatransfer.DataFlavor[] getTransferDataFlavors() {
+        @Override
+		public java.awt.datatransfer.DataFlavor[] getTransferDataFlavors() {
             if (customFlavor != null)
                 return new java.awt.datatransfer.DataFlavor[]
                         {customFlavor,
@@ -830,7 +837,8 @@ public class FileDrop {
          * @return The dropped data
          * @since 1.1
          */
-        public Object getTransferData(java.awt.datatransfer.DataFlavor flavor)
+        @Override
+		public Object getTransferData(java.awt.datatransfer.DataFlavor flavor)
                 throws java.awt.datatransfer.UnsupportedFlavorException, java.io.IOException {
             // Native object
             if (flavor.equals(DATA_FLAVOR))
@@ -853,7 +861,8 @@ public class FileDrop {
          * @return Whether or not the flavor is supported
          * @since 1.1
          */
-        public boolean isDataFlavorSupported(java.awt.datatransfer.DataFlavor flavor) {
+        @Override
+		public boolean isDataFlavorSupported(java.awt.datatransfer.DataFlavor flavor) {
             // Native object
             if (flavor.equals(DATA_FLAVOR))
                 return true;
diff --git a/src/beast/app/treeannotator/KernelDensityEstimator2D.java b/src/beast/app/treeannotator/KernelDensityEstimator2D.java
index 03cf8cb..76a680c 100644
--- a/src/beast/app/treeannotator/KernelDensityEstimator2D.java
+++ b/src/beast/app/treeannotator/KernelDensityEstimator2D.java
@@ -1,11 +1,11 @@
 package beast.app.treeannotator;
 
+import java.util.Arrays;
+
 import beast.math.statistic.DiscreteStatistics;
 import cern.colt.list.DoubleArrayList;
 import cern.jet.stat.Descriptive;
 
-import java.util.Arrays;
-
 
 /**
  * KernelDensityEstimator2D creates a bi-variate kernel density smoother for data
@@ -133,7 +133,8 @@ public class KernelDensityEstimator2D implements ContourMaker {
         return level;
     }
 
-    public ContourPath[] getContourPaths(double hpdValue) {
+    @Override
+	public ContourPath[] getContourPaths(double hpdValue) {
 
         double thresholdDensity = findLevelCorrespondingToMass(hpdValue);
         ContourGenerator contour = new ContourGenerator(getXGrid(), getYGrid(), getKDE(),
@@ -256,7 +257,7 @@ public class KernelDensityEstimator2D implements ContourMaker {
 
         KernelDensityEstimator2D kde = new KernelDensityEstimator2D(x, y, 4);
 
-//        System.out.println(new Vector(kde.getXGrid()));
+        System.out.println(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 ec7238e..72c65c9 100644
--- a/src/beast/app/treeannotator/RealNumberField.java
+++ b/src/beast/app/treeannotator/RealNumberField.java
@@ -9,15 +9,21 @@
 
 package beast.app.treeannotator;
 
-import javax.swing.*;
-import javax.swing.event.*;
+import java.awt.Toolkit;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+
+import javax.swing.JOptionPane;
+import javax.swing.JTextField;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.EventListenerList;
 import javax.swing.text.AttributeSet;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.Document;
 import javax.swing.text.PlainDocument;
-import java.awt.*;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
 
 public class RealNumberField extends JTextField implements FocusListener, DocumentListener {
 	private static final long serialVersionUID = 1L;
@@ -73,10 +79,12 @@ public class RealNumberField extends JTextField implements FocusListener, Docume
         this.allowEmpty = allowEmpty;
     }
 
-    public void focusGained(FocusEvent evt) {
+    @Override
+	public void focusGained(FocusEvent evt) {
     }
 
-    public void focusLost(FocusEvent evt) {
+    @Override
+	public void focusLost(FocusEvent evt) {
         validateField();
     }
 
@@ -222,21 +230,25 @@ public class RealNumberField extends JTextField implements FocusListener, Docume
         }
     }
 
-    protected Document createDefaultModel() {
+    @Override
+	protected Document createDefaultModel() {
         Document doc = new RealNumberField.RealNumberFieldDocument();
         doc.addDocumentListener(this);
         return doc;
     }
 
-    public void insertUpdate(DocumentEvent e) {
+    @Override
+	public void insertUpdate(DocumentEvent e) {
         fireChanged();
     }
 
-    public void removeUpdate(DocumentEvent e) {
+    @Override
+	public void removeUpdate(DocumentEvent e) {
         fireChanged();
     }
 
-    public void changedUpdate(DocumentEvent e) {
+    @Override
+	public void changedUpdate(DocumentEvent e) {
         fireChanged();
     }
 
@@ -247,6 +259,7 @@ public class RealNumberField extends JTextField implements FocusListener, Docume
     class RealNumberFieldDocument extends PlainDocument {
 		private static final long serialVersionUID = 1L;
 
+		@Override
 		public void insertString(int offs, String str, AttributeSet a)
                 throws BadLocationException {
 
diff --git a/src/beast/app/treeannotator/SnyderContour.java b/src/beast/app/treeannotator/SnyderContour.java
index 4cbd525..f1a3ae9 100644
--- a/src/beast/app/treeannotator/SnyderContour.java
+++ b/src/beast/app/treeannotator/SnyderContour.java
@@ -1,6 +1,6 @@
 package beast.app.treeannotator;
 
-import java.awt.*;
+import java.awt.Dimension;
 import java.awt.geom.Point2D;
 import java.util.LinkedList;
 import java.util.List;
@@ -20,9 +20,9 @@ public class SnyderContour {
     // Below, constant data members:
     final static boolean SHOW_NUMBERS = true;
     final static int BLANK = 32,
-            OPEN_SUITE = (int) '{',
-            CLOSE_SUITE = (int) '}',
-            BETWEEN_ARGS = (int) ',',
+            OPEN_SUITE = '{',
+            CLOSE_SUITE = '}',
+            BETWEEN_ARGS = ',',
             N_CONTOURS = 1,
             PLOT_MARGIN = 20,
             WEE_BIT = 3,
@@ -139,7 +139,7 @@ public class SnyderContour {
         if ((iflag == 2) || (iflag == 3)) { // start new path
             u = ((xy[0] - 1.0) * deltaX) + offsetX;
             v = ((xy[1] - 1.0) * deltaY) + offsetY;
-            LinkedList<Point2D> path = new LinkedList<Point2D>();
+            LinkedList<Point2D> path = new LinkedList<>();
             path.add(new Point2D.Double(u, v));
             allPaths.add(path);
         }
diff --git a/src/beast/app/treeannotator/TreeAnnotator.java b/src/beast/app/treeannotator/TreeAnnotator.java
index 9b2aaa0..68f708f 100644
--- a/src/beast/app/treeannotator/TreeAnnotator.java
+++ b/src/beast/app/treeannotator/TreeAnnotator.java
@@ -25,6 +25,26 @@
 
 package beast.app.treeannotator;
 
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+
+import javax.swing.JFrame;
+
 import beast.app.BEASTVersion;
 import beast.app.beauti.BeautiDoc;
 import beast.app.tools.LogCombiner;
@@ -41,17 +61,6 @@ import beast.util.NexusParser;
 import beast.util.TreeParser;
 import jam.console.ConsoleApplication;
 
-import javax.swing.*;
-
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.util.*;
-
 //import org.rosuda.JRI.REXP;
 //import org.rosuda.JRI.RVector;
 //import org.rosuda.JRI.Rengine;
@@ -75,15 +84,15 @@ public class TreeAnnotator {
     
     abstract class TreeSet {
     	abstract boolean hasNext();
-    	abstract Tree next() throws Exception;
-    	abstract void reset() throws Exception ;
+    	abstract Tree next() throws IOException;
+    	abstract void reset() throws IOException;
     }    
     
     class FastTreeSet extends TreeSet {
     	int current = 0;
     	Tree [] trees;
     	
-    	public FastTreeSet(String inputFileName, int burninPercentage) throws Exception {
+    	public FastTreeSet(String inputFileName, int burninPercentage) throws IOException  {
             progressStream.println("0              25             50             75            100");
             progressStream.println("|--------------|--------------|--------------|--------------|");
     		TreeSetParser parser = new TreeSetParser(burninPercentage, false);
@@ -101,12 +110,12 @@ public class TreeAnnotator {
 		}
 
 		@Override
-		Tree next() throws Exception {
+		Tree next()  {
 			return trees[current++];
 		}
 
 		@Override
-		void reset() throws Exception {
+		void reset()  {
 			current = 0;
 		}
     }
@@ -126,7 +135,7 @@ public class TreeAnnotator {
         // label count origin for NEXUS trees
         int origin = -1;
        
-        MemoryFriendlyTreeSet(String inputFileName, int burninPercentage) throws Exception {
+        MemoryFriendlyTreeSet(String inputFileName, int burninPercentage) throws IOException  {
     		this.inputFileName = inputFileName;
     		init(burninPercentage);
         	progressStream.println("Processing " + (totalTrees - burninCount) + " trees from file" +
@@ -137,11 +146,12 @@ public class TreeAnnotator {
 
     	/** determine number of trees in the file,
     	 * and number of trees to skip as burnin 
+    	 * @throws IOException 
     	 * @throws FileNotFoundException **/
-    	private void init(int burninPercentage) throws Exception {
+    	private void init(int burninPercentage) throws IOException  {
             fin = new BufferedReader(new FileReader(new File(inputFileName)));
             if (!fin.ready()) {
-            	throw new Exception("File appears empty");
+            	throw new IOException("File appears empty");
             }
         	String str = nextLine();
             if (!str.toUpperCase().trim().startsWith("#NEXUS")) {
@@ -166,52 +176,54 @@ public class TreeAnnotator {
             burninCount = Math.max(0, (burninPercentage * totalTrees)/100);
 		}
 
-    	void reset() throws Exception {
+    	@Override
+		void reset() throws FileNotFoundException  {
     		current = 0;
             fin = new BufferedReader(new FileReader(new File(inputFileName)));
             lineNr = 0;
             try {
                 while (fin.ready()) {
-                    final String sStr = nextLine();
-                    if (sStr == null) {
+                    final String str = nextLine();
+                    if (str == null) {
                         return;
                     }
-                    final String sLower = sStr.toLowerCase();
-                    if (sLower.matches("^\\s*begin\\s+trees;\\s*$")) {
+                    final String lower = str.toLowerCase();
+                    if (lower.matches("^\\s*begin\\s+trees;\\s*$")) {
                         parseTreesBlock();
                         return;
                     }
                 }
             } catch (Exception e) {
                 e.printStackTrace();
-                throw new Exception("Around line " + lineNr + "\n" + e.getMessage());
+                throw new RuntimeException("Around line " + lineNr + "\n" + e.getMessage());
             }
         } // parseFile
 
         /**
-         * read next line from Nexus file that is not a comment and not empty *
+         * read next line from Nexus file that is not a comment and not empty 
+         * @throws IOException *
          */
-        String nextLine() throws Exception {
-            String sStr = readLine();
-            if (sStr == null) {
+        String nextLine() throws IOException  {
+            String str = readLine();
+            if (str == null) {
                 return null;
             }
-            if (sStr.contains("[")) {
-                final int iStart = sStr.indexOf('[');
-                int iEnd = sStr.indexOf(']', iStart);
-                while (iEnd < 0) {
-                    sStr += readLine();
-                    iEnd = sStr.indexOf(']', iStart);
+            if (str.contains("[")) {
+                final int start = str.indexOf('[');
+                int end = str.indexOf(']', start);
+                while (end < 0) {
+                    str += readLine();
+                    end = str.indexOf(']', start);
                 }
-                sStr = sStr.substring(0, iStart) + sStr.substring(iEnd + 1);
-                if (sStr.matches("^\\s*$")) {
+                str = str.substring(0, start) + str.substring(end + 1);
+                if (str.matches("^\\s*$")) {
                     return nextLine();
                 }
             }
-            if (sStr.matches("^\\s*$")) {
+            if (str.matches("^\\s*$")) {
                 return nextLine();
             }
-            return sStr;
+            return str;
         }
 
         /**
@@ -225,15 +237,15 @@ public class TreeAnnotator {
             return fin.readLine();
         }
 
-        private void parseTreesBlock() throws Exception {
+        private void parseTreesBlock() throws IOException  {
             // read to first non-empty line within trees block
-            String sStr = fin.readLine().trim();
-            while (sStr.equals("")) {
-                sStr = fin.readLine().trim();
+            String str = fin.readLine().trim();
+            while (str.equals("")) {
+                str = fin.readLine().trim();
             }
 
             // if first non-empty line is "translate" then parse translate block
-            if (sStr.toLowerCase().contains("translate")) {
+            if (str.toLowerCase().contains("translate")) {
                 translationMap = parseTranslateBlock();
                 origin = getIndexedTranslationMapOrigin(translationMap);
                 if (origin != -1) {
@@ -244,8 +256,8 @@ public class TreeAnnotator {
             // read bunrinCount trees
             current = 0;
             while (current < burninCount && fin.ready()) {
-    			sStr = nextLine();
-                if (sStr.toLowerCase().startsWith("tree ")) {
+    			str = nextLine();
+                if (str.toLowerCase().startsWith("tree ")) {
                 	current++;
                 }
             }
@@ -290,7 +302,7 @@ public class TreeAnnotator {
          */
         private Map<String, String> parseTranslateBlock() throws IOException {
 
-            final Map<String, String> translationMap = new HashMap<String, String>();
+            final Map<String, String> translationMap = new HashMap<>();
 
             String line = readLine();
             final StringBuilder translateBlock = new StringBuilder();
@@ -313,43 +325,45 @@ public class TreeAnnotator {
 
     	
     	
-    	boolean hasNext() {
+    	@Override
+		boolean hasNext() {
     		return current < totalTrees;
     	}
     	
-    	Tree next() throws Exception {
-			String sStr = nextLine();
+    	@Override
+		Tree next() throws IOException {
+			String str = nextLine();
     		if (!isNexus) {
                 TreeParser treeParser;
 
                 if (origin != -1) {
-                    treeParser = new TreeParser(taxa, sStr, origin, false);
+                    treeParser = new TreeParser(taxa, str, origin, false);
                 } else {
                     try {
-                        treeParser = new TreeParser(taxa, sStr, 0, false);
+                        treeParser = new TreeParser(taxa, str, 0, false);
                     } catch (ArrayIndexOutOfBoundsException e) {
-                        treeParser = new TreeParser(taxa, sStr, 1, false);
+                        treeParser = new TreeParser(taxa, str, 1, false);
                     }
                 }
                 return treeParser;
     		}
     		
             // read trees from NEXUS file
-            if (sStr.toLowerCase().startsWith("tree ")) {
+            if (str.toLowerCase().startsWith("tree ")) {
             	current++;
-                final int i = sStr.indexOf('(');
+                final int i = str.indexOf('(');
                 if (i > 0) {
-                    sStr = sStr.substring(i);
+                    str = str.substring(i);
                 }
                 TreeParser treeParser;
 
                 if (origin != -1) {
-                    treeParser = new TreeParser(taxa, sStr, origin, false);
+                    treeParser = new TreeParser(taxa, str, origin, false);
                 } else {
                     try {
-                        treeParser = new TreeParser(taxa, sStr, 0, false);
+                        treeParser = new TreeParser(taxa, str, 0, false);
                     } catch (ArrayIndexOutOfBoundsException e) {
-                        treeParser = new TreeParser(taxa, sStr, 1, false);
+                        treeParser = new TreeParser(taxa, str, 1, false);
                     }
                 }
 
@@ -374,7 +388,8 @@ public class TreeAnnotator {
             desc = s;
         }
 
-        public String toString() {
+        @Override
+		public String toString() {
             return desc;
         }
     }
@@ -391,7 +406,8 @@ public class TreeAnnotator {
             desc = s;
         }
 
-        public String toString() {
+        @Override
+		public String toString() {
             return desc;
         }
     }
@@ -407,7 +423,7 @@ public class TreeAnnotator {
     public TreeAnnotator() { }
 
     public TreeAnnotator(final int burninPercentage,
-    					 boolean lowMemory, // bAllowSingleChild was defunct (always set to false), now replaced by flag to say how much 
+    					 boolean lowMemory, // allowSingleChild was defunct (always set to false), now replaced by flag to say how much 
                          HeightsSummary heightsOption,
                          double posteriorLimit,
                          double hpd2D,
@@ -415,7 +431,7 @@ public class TreeAnnotator {
                          String targetTreeFileName,
                          String inputFileName,
                          String outputFileName
-    ) throws Exception {
+    ) throws IOException  {
 
         this.posteriorLimit = posteriorLimit;
         this.hpd2D = hpd2D;
@@ -500,16 +516,16 @@ public class TreeAnnotator {
                 if (targetTreeFileName != null) {
                     progressStream.println("Reading user specified target tree, " + targetTreeFileName);
                     
-                    String sTree = BeautiDoc.load(targetTreeFileName);
+                    String tree = BeautiDoc.load(targetTreeFileName);
                     
-                    if (sTree.startsWith("#NEXUS")) {
+                    if (tree.startsWith("#NEXUS")) {
                     	NexusParser parser2 = new NexusParser();
                     	parser2.parseFile(new File(targetTreeFileName));
                     	targetTree = parser2.trees.get(0);
                     } else {
 	                    try {
 		                    TreeParser parser2 = new TreeParser();
-		                    parser2.initByName("IsLabelledNewick", true, "newick", sTree);
+		                    parser2.initByName("IsLabelledNewick", true, "newick", tree);
 		                    targetTree = parser2;
 	                    } catch (Exception e) {
 	                        Log.err.println("Error Parsing Target Tree: " + e.getMessage());
@@ -600,8 +616,8 @@ public class TreeAnnotator {
             
             stream.print("tree TREE1 = ");
             int[] dummy = new int[1];
-            String sNewick = targetTree.getRoot().toSortedNewick(dummy, true);
-            stream.print(sNewick);
+            String newick = targetTree.getRoot().toSortedNewick(dummy, true);
+            stream.print(newick);
             stream.println(";");
 //            stream.println(targetTree.getRoot().toShortNewick(false));
 //            stream.println();
@@ -655,13 +671,13 @@ public class TreeAnnotator {
             }
         }
 
-        for (TreeAnnotationPlugin plugin : plugins) {
-            Set<String> claimed = plugin.setAttributeNames(attributeNames);
+        for (TreeAnnotationPlugin beastObject : beastObjects) {
+            Set<String> claimed = beastObject.setAttributeNames(attributeNames);
             attributeNames.removeAll(claimed);
         }
     }
 
-    private Tree summarizeTrees(CladeSystem cladeSystem, boolean useSumCladeCredibility) throws Exception {
+    private Tree summarizeTrees(CladeSystem cladeSystem, boolean useSumCladeCredibility) throws IOException  {
 
         Tree bestTree = null;
         double bestScore = Double.NEGATIVE_INFINITY;
@@ -763,7 +779,7 @@ public class TreeAnnotator {
             if (clade.attributeValues != null && clade.attributeValues.size() > 0) {
                 double[] values = new double[clade.attributeValues.size()];
 
-                HashMap<Object, Integer> hashMap = new HashMap<Object, Integer>();
+                HashMap<Object, Integer> hashMap = new HashMap<>();
 
                 Object[] v = clade.attributeValues.get(0);
                 if (v[i] != null) {
@@ -867,8 +883,8 @@ public class TreeAnnotator {
 
                     if (!filter) {
                         boolean processed = false;
-                        for (TreeAnnotationPlugin plugin : plugins) {
-                            if (plugin.handleAttribute(node, attributeName, values)) {
+                        for (TreeAnnotationPlugin beastObject : beastObjects) {
+                            if (beastObject.handleAttribute(node, attributeName, values)) {
                                 processed = true;
                             }
                         }
@@ -1004,7 +1020,7 @@ public class TreeAnnotator {
         double minRange = Double.MAX_VALUE;
         int hpdIndex = 0;
 
-        int diff = (int) Math.round(hpd * (double) values.length);
+        int diff = (int) Math.round(hpd * values.length);
         for (int i = 0; i <= (values.length - diff); i++) {
             double minValue = values[indices[i]];
             double maxValue = values[indices[i + diff - 1]];
@@ -1169,9 +1185,9 @@ public class TreeAnnotator {
     double posteriorLimit = 0.0;
     double hpd2D = 0.80;
 
-    private final List<TreeAnnotationPlugin> plugins = new ArrayList<TreeAnnotationPlugin>();
+    private final List<TreeAnnotationPlugin> beastObjects = new ArrayList<>();
 
-    Set<String> attributeNames = new HashSet<String>();
+    Set<String> attributeNames = new HashSet<>();
     TaxonSet taxa = null;
 
     static boolean processBivariateAttributes = false;
@@ -1393,7 +1409,7 @@ public class TreeAnnotator {
         }
         if (burnin >= 100) {
         	Log.err.println("burnin is a percentage and should be less than 100.");
-        	System.exit(0);
+        	System.exit(1);
         }
 
         double posteriorLimit = 0.0;
@@ -1406,7 +1422,7 @@ public class TreeAnnotator {
             hpd2D = arguments.getRealOption("hpd2D");
             if (hpd2D <= 0 || hpd2D >=1) {
             	Log.err.println("hpd2D is a fraction and should be in between 0.0 and 1.0.");
-            	System.exit(0);            	
+            	System.exit(1);            	
             }
             processBivariateAttributes = true;
         }
@@ -1456,8 +1472,8 @@ public class TreeAnnotator {
         boolean handleAttribute(Node node, String attributeName, double[] values);
     }
 
-    boolean setTreeHeightsByCA(Tree targetTree)
-            throws Exception {
+    boolean setTreeHeightsByCA(Tree targetTree) throws IOException
+             {
         progressStream.println("Setting node heights...");
         progressStream.println("0              25             50             75            100");
         progressStream.println("|--------------|--------------|--------------|--------------|");
@@ -1470,14 +1486,14 @@ public class TreeAnnotator {
         // this call increments the clade counts and it shouldn't
         // this is remedied with removeClades call after while loop below
         CladeSystem cladeSystem = new CladeSystem(targetTree);
-        final int nClades = cladeSystem.getCladeMap().size();
+        final int clades = cladeSystem.getCladeMap().size();
 
         // allocate posterior tree nodes order once
-        int[] postOrderList = new int[nClades];
-        BitSet[] ctarget = new BitSet[nClades];
-        BitSet[] ctree = new BitSet[nClades];
+        int[] postOrderList = new int[clades];
+        BitSet[] ctarget = new BitSet[clades];
+        BitSet[] ctree = new BitSet[clades];
 
-        for (int k = 0; k < nClades; ++k) {
+        for (int k = 0; k < clades; ++k) {
             ctarget[k] = new BitSet();
             ctree[k] = new BitSet();
         }
@@ -1485,10 +1501,10 @@ public class TreeAnnotator {
         cladeSystem.getTreeCladeCodes(targetTree, ctarget);
 
         // temp collecting heights inside loop allocated once
-        double[] hs = new double[nClades];
+        double[] hs = new double[clades];
 
         // heights total sum from posterior trees
-        double[] ths = new double[nClades];
+        double[] ths = new double[clades];
 
         totalTreesUsed = 0;
 
@@ -1498,15 +1514,15 @@ public class TreeAnnotator {
         	Tree tree = treeSet.next();
             TreeUtils.preOrderTraversalList(tree, postOrderList);
             cladeSystem.getTreeCladeCodes(tree, ctree);
-            for (int k = 0; k < nClades; ++k) {
+            for (int k = 0; k < clades; ++k) {
                 int j = postOrderList[k];
-                for (int i = 0; i < nClades; ++i) {
+                for (int i = 0; i < clades; ++i) {
                     if( CollectionUtils.isSubSet(ctarget[i], ctree[j]) ) {
                         hs[i] = tree.getNode(j).getHeight();
                     }
                 }
             }
-            for (int k = 0; k < nClades; ++k) {
+            for (int k = 0; k < clades; ++k) {
                 ths[k] += hs[k];
             }
             totalTreesUsed += 1;
@@ -1520,7 +1536,7 @@ public class TreeAnnotator {
         }
         targetTree.initAndValidate();
         cladeSystem.removeClades(targetTree.getRoot(), true);
-        for (int k = 0; k < nClades; ++k) {
+        for (int k = 0; k < clades; ++k) {
             ths[k] /= totalTreesUsed;
             final Node node = targetTree.getNode(k);
             node.setHeight(ths[k]);
diff --git a/src/beast/app/treeannotator/TreeAnnotatorDialog.java b/src/beast/app/treeannotator/TreeAnnotatorDialog.java
index 783c304..6c32583 100644
--- a/src/beast/app/treeannotator/TreeAnnotatorDialog.java
+++ b/src/beast/app/treeannotator/TreeAnnotatorDialog.java
@@ -25,19 +25,30 @@
 
 package beast.app.treeannotator;
 
-import beast.app.util.WholeNumberField;
-import jam.panels.OptionsPanel;
-
-import javax.swing.*;
-import javax.swing.border.Border;
-import javax.swing.border.EmptyBorder;
-import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.FileDialog;
 import java.awt.event.ItemEvent;
 import java.awt.event.ItemListener;
 import java.io.File;
 
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+
+import beast.app.util.WholeNumberField;
+import jam.panels.OptionsPanel;
+
 public class TreeAnnotatorDialog {
 	private JFrame frame;
 
@@ -46,9 +57,9 @@ public class TreeAnnotatorDialog {
     private WholeNumberField burninText = new WholeNumberField(0, Integer.MAX_VALUE);
 	private RealNumberField limitText = new RealNumberField(0.0, 1.0);
 
-    private JComboBox summaryTreeCombo = new JComboBox(TreeAnnotator.Target.values());
+    private JComboBox<TreeAnnotator.Target> summaryTreeCombo = new JComboBox<>(TreeAnnotator.Target.values());
 
-    private JComboBox nodeHeightsCombo = new JComboBox(TreeAnnotator.HeightsSummary.values());
+    private JComboBox<TreeAnnotator.HeightsSummary> nodeHeightsCombo = new JComboBox<>(TreeAnnotator.HeightsSummary.values());
 
     private JCheckBox lowMemCheckbox = new JCheckBox();
     
@@ -82,8 +93,7 @@ public class TreeAnnotatorDialog {
         final JButton targetFileButton = new JButton("Choose File...");
 		final JTextField targetFileNameText = new JTextField("not selected", 16);
 
-		targetFileButton.addActionListener( new ActionListener() {
-			public void actionPerformed(ActionEvent ae) {
+		targetFileButton.addActionListener(ae -> {
 				FileDialog dialog = new FileDialog(frame,
 						"Select target file...",
 						FileDialog.LOAD);
@@ -97,7 +107,7 @@ public class TreeAnnotatorDialog {
 				targetFile = new File(dialog.getDirectory(), dialog.getFile());
 				targetFileNameText.setText(targetFile.getName());
 
-			}});
+			});
 		targetFileNameText.setEditable(false);
 
 		JPanel panel1 = new JPanel(new BorderLayout(0,0));
@@ -108,8 +118,7 @@ public class TreeAnnotatorDialog {
 		JButton inputFileButton = new JButton("Choose File...");
 		final JTextField inputFileNameText = new JTextField("not selected", 16);
 
-		inputFileButton.addActionListener( new ActionListener() {
-			public void actionPerformed(ActionEvent ae) {
+		inputFileButton.addActionListener(ae -> {
 				FileDialog dialog = new FileDialog(frame,
 						"Select input tree file...",
 						FileDialog.LOAD);
@@ -123,7 +132,7 @@ public class TreeAnnotatorDialog {
 				inputFile = new File(dialog.getDirectory(), dialog.getFile());
 				inputFileNameText.setText(inputFile.getName());
 
-			}});
+			});
 		inputFileNameText.setEditable(false);
 
         label1.setEnabled(false);
@@ -131,7 +140,8 @@ public class TreeAnnotatorDialog {
         targetFileButton.setEnabled(false);
 
         summaryTreeCombo.addItemListener(new ItemListener() {
-            public void itemStateChanged(ItemEvent itemEvent) {
+            @Override
+			public void itemStateChanged(ItemEvent itemEvent) {
                 boolean selected = summaryTreeCombo.getSelectedItem().toString().equals("User target tree");
                 label1.setEnabled(selected);
                 targetFileNameText.setEnabled(selected);
@@ -146,7 +156,8 @@ public class TreeAnnotatorDialog {
         Color focusColor = UIManager.getColor("Focus.color");
         Border focusBorder = BorderFactory.createMatteBorder( 2, 2, 2, 2, focusColor );
         new FileDrop( null, inputFileNameText, focusBorder, new FileDrop.Listener()
-        {   public void filesDropped( java.io.File[] files )
+        {   @Override
+		public void filesDropped( java.io.File[] files )
             {
                 inputFile = files[0];
                 inputFileNameText.setText(inputFile.getName());
@@ -158,8 +169,7 @@ public class TreeAnnotatorDialog {
 		JButton outputFileButton = new JButton("Choose File...");
 		final JTextField outputFileNameText = new JTextField("not selected", 16);
 
-		outputFileButton.addActionListener( new ActionListener() {
-			public void actionPerformed(ActionEvent ae) {
+		outputFileButton.addActionListener(ae -> {
 				FileDialog dialog = new FileDialog(frame,
 						"Select output file...",
 						FileDialog.SAVE);
@@ -173,7 +183,7 @@ public class TreeAnnotatorDialog {
 				outputFile = new File(dialog.getDirectory(), dialog.getFile());
 				outputFileNameText.setText(outputFile.getName());
 
-			}});
+			});
 		outputFileNameText.setEditable(false);
 
 		JPanel panel3 = new JPanel(new BorderLayout(0,0));
diff --git a/src/beast/app/treeannotator/TreeAnnotatorLauncher.java b/src/beast/app/treeannotator/TreeAnnotatorLauncher.java
index 6c1ff92..a19eaba 100644
--- a/src/beast/app/treeannotator/TreeAnnotatorLauncher.java
+++ b/src/beast/app/treeannotator/TreeAnnotatorLauncher.java
@@ -1,6 +1,9 @@
 package beast.app.treeannotator;
 
 
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+
 import beast.app.beastapp.BeastLauncher;
 
 
@@ -12,7 +15,7 @@ import beast.app.beastapp.BeastLauncher;
  * **/
 public class TreeAnnotatorLauncher extends BeastLauncher  {
 
-	public static void main(String[] args) throws Exception {
+	public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {
 		if (javaVersionCheck("TreeAnnotator")) {
 			loadBEASTJars();
 			TreeAnnotator.main(args);
diff --git a/src/beast/app/treeannotator/TreeSetParser.java b/src/beast/app/treeannotator/TreeSetParser.java
index ed62833..af038c7 100644
--- a/src/beast/app/treeannotator/TreeSetParser.java
+++ b/src/beast/app/treeannotator/TreeSetParser.java
@@ -28,6 +28,7 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Vector;
 
+import beast.core.util.Log;
 import beast.evolution.tree.Node;
 
 public class TreeSetParser {
@@ -56,25 +57,25 @@ public class TreeSetParser {
 	/** flag to indicate that single child nodes are allowed **/
 	boolean m_bAllowSingleChild = false;
 	
-	public TreeSetParser(int nBurnInPercentage, boolean bAllowSingleChild) {
-		m_sLabels = new ArrayList<String>();
-		m_fLongitude = new ArrayList<Float>();
-		m_fLatitude = new ArrayList<Float>();
-		m_nBurnInPercentage = Math.max(nBurnInPercentage, 0);
+	public TreeSetParser(int burnInPercentage, boolean allowSingleChild) {
+		m_sLabels = new ArrayList<>();
+		m_fLongitude = new ArrayList<>();
+		m_fLatitude = new ArrayList<>();
+		m_nBurnInPercentage = Math.max(burnInPercentage, 0);
 		m_fMinLat = 90; m_fMinLong = 180;
 		m_fMaxLat = -90; m_fMaxLong = -180;
-		m_bAllowSingleChild = bAllowSingleChild;
+		m_bAllowSingleChild = allowSingleChild;
 	} // c'tor
 	
-	public TreeSetParser(List<String> sLabels, List<Float> fLongitude, List<Float> fLatitude, int nBurnInPercentage) {
-		m_sLabels = sLabels;
+	public TreeSetParser(List<String> labels, List<Float> longitude, List<Float> latitude, int burnInPercentage) {
+		m_sLabels = labels;
 		if (m_sLabels != null) {
 			m_bIsLabelledNewick = true;
 			m_nNrOfLabels = m_sLabels.size();
 		}
-		m_fLongitude = fLongitude;
-		m_fLatitude = fLatitude;
-		m_nBurnInPercentage = Math.max(nBurnInPercentage, 0);
+		m_fLongitude = longitude;
+		m_fLatitude = latitude;
+		m_nBurnInPercentage = Math.max(burnInPercentage, 0);
 		m_fMinLat = 90; m_fMinLong = 180;
 		m_fMaxLat = -90; m_fMaxLong = -180;
 	}
@@ -84,17 +85,17 @@ public class TreeSetParser {
 	long fileMarked = 0;
 
 	
-	public Node [] parseFile(String sFile) throws Exception {
-		//List<String> sNewickTrees = new List<String>();
-		List<Node> trees = new ArrayList<Node>();
+	public Node [] parseFile(String fileName) throws IOException {
+		//List<String> newickTrees = new List<>();
+		List<Node> trees = new ArrayList<>();
 		m_nOffset = 0;
 		// parse Newick tree file
-		File file = new File(sFile);
+		File file = new File(fileName);
 		fileStep = Math.max(file.length() / 61, 1);
 		fileRead = 0;
 		fileMarked = 0;
 		
-		BufferedReader fin = new BufferedReader(new FileReader(sFile));
+		BufferedReader fin = new BufferedReader(new FileReader(fileName));
 		
         int nrOfTrees = 0;
         // first, sweep through the log file to determine the number of trees
@@ -105,145 +106,145 @@ public class TreeSetParser {
         }
         fin.close();
         
-        fin = new BufferedReader(new FileReader(sFile));
-		String sStr = readLine(fin);
+        fin = new BufferedReader(new FileReader(fileName));
+		String str = readLine(fin);
 		// grab translate block
-		while (fin.ready() && sStr.toLowerCase().indexOf("translate") < 0) {
-			sStr = readLine(fin);
+		while (fin.ready() && str.toLowerCase().indexOf("translate") < 0) {
+			str = readLine(fin);
 		}
 		m_bIsLabelledNewick = false;
 		m_nNrOfLabels = m_sLabels.size();
-		boolean bAddLabels = (m_nNrOfLabels == 0);
-		if (sStr.toLowerCase().indexOf("translate") < 0) {
+		boolean addLabels = (m_nNrOfLabels == 0);
+		if (str.toLowerCase().indexOf("translate") < 0) {
 			m_bIsLabelledNewick = true;
 			// could not find translate block, assume it is a list of Newick trees instead of Nexus file
 			fin.close();
 			fileRead = 0;
 			fileMarked = 0;
-			fin = new BufferedReader(new FileReader(sFile));
+			fin = new BufferedReader(new FileReader(fileName));
 			while (fin.ready() && m_nNrOfLabels == 0) {
-				sStr = readLine(fin);
-				fileRead += sStr.length();
-				if (sStr.length() > 2 && sStr.indexOf("(") >= 0) {
-					String sStr2 = sStr;
-					sStr2 = sStr2.substring(sStr2.indexOf("("));
-					while (sStr2.indexOf('[') >= 0) {
-						int i0 = sStr2.indexOf('[');
-						int i1 = sStr2.indexOf(']');
-						sStr2 = sStr2.substring(0, i0) + sStr2.substring(i1 + 1);
+				str = readLine(fin);
+				fileRead += str.length();
+				if (str.length() > 2 && str.indexOf("(") >= 0) {
+					String str2 = str;
+					str2 = str2.substring(str2.indexOf("("));
+					while (str2.indexOf('[') >= 0) {
+						int i0 = str2.indexOf('[');
+						int i1 = str2.indexOf(']');
+						str2 = str2.substring(0, i0) + str2.substring(i1 + 1);
 					}
-					sStr2 = sStr2.replaceAll("[;\\(\\),]"," ");
-					sStr2 = sStr2.replaceAll(":[0-9\\.Ee-]+"," ");
-					String [] sLabels = sStr2.split("\\s+");
-					if (bAddLabels) {
+					str2 = str2.replaceAll("[;\\(\\),]"," ");
+					str2 = str2.replaceAll(":[0-9\\.Ee-]+"," ");
+					String [] labels = str2.split("\\s+");
+					if (addLabels) {
 						m_nNrOfLabels = 0;
-						for (int i = 0; i < sLabels.length; i++) {
-							if (sLabels[i].length() > 0) {
-									m_sLabels.add(sLabels[i]);
+						for (int i = 0; i < labels.length; i++) {
+							if (labels[i].length() > 0) {
+									m_sLabels.add(labels[i]);
 								m_nNrOfLabels++;
 							}
 						}
 					}
-					Node tree = parseNewick(sStr);
+					Node tree = parseNewick(str);
 					tree.sort();
 					tree.labelInternalNodes(m_nNrOfLabels);
 					trees.add(tree);
-//					sNewickTrees.add(sStr);
+//					newickTrees.add(str);
 				}
 			}
 
 			while (fin.ready()) {
-				sStr = readLine(fin);
-				if (sStr.length() > 2 && sStr.indexOf("(") >= 0) {
-					Node tree = parseNewick(sStr);
+				str = readLine(fin);
+				if (str.length() > 2 && str.indexOf("(") >= 0) {
+					Node tree = parseNewick(str);
 					tree.sort();
 					tree.labelInternalNodes(m_nNrOfLabels);
 					trees.add(tree);
-					if (trees.size() % 100 ==0) {if (m_nNrOfLabels>=100||trees.size() % 1000 ==0) {System.err.print(trees.size() + " ");}}
-//					sNewickTrees.add(sStr);
+					if (trees.size() % 100 ==0) {if (m_nNrOfLabels>=100||trees.size() % 1000 ==0) {Log.warning.print(trees.size() + " ");}}
+//					newickTrees.add(str);
 				}
 			}
 			
 		} else {
 			// read tree set from file, and store in individual strings
-			sStr = readLine(fin);
+			str = readLine(fin);
 			//m_nNrOfLabels = 0;
-			boolean bLastLabel = false;
-			while (fin.ready() && !bLastLabel) {
-				if (sStr.indexOf(";") >= 0) {
-					sStr = sStr.replace(';',' ');
-					sStr = sStr.trim();
-					if (sStr.isEmpty()) {
+			boolean isLastLabel = false;
+			while (fin.ready() && !isLastLabel) {
+				if (str.indexOf(";") >= 0) {
+					str = str.replace(';',' ');
+					str = str.trim();
+					if (str.isEmpty()) {
 						break;
 					}
-					bLastLabel = true;
+					isLastLabel = true;
 				}
-				sStr = sStr.replaceAll(",", "");
-				sStr = sStr.replaceAll("^\\s+", "");
-				String[] sStrs = sStr.split("\\s+");
-				int iLabel = new Integer(sStrs[0]).intValue();
-				String sLabel = sStrs[1];
-				if (m_sLabels.size() < iLabel) {
+				str = str.replaceAll(",", "");
+				str = str.replaceAll("^\\s+", "");
+				String[] strs = str.split("\\s+");
+				int labelIndex = new Integer(strs[0]).intValue();
+				String label = strs[1];
+				if (m_sLabels.size() < labelIndex) {
 					//m_sLabels.add("__dummy__");
 					m_nOffset = 1;
 				}
 				// check if there is geographic info in the name
-				if (sLabel.contains("(")) {
-					int iStr = sLabel.indexOf('(');
-					int iStr2 = sLabel.indexOf('x', iStr);
-					if (iStr2 >= 0) {
-						int iStr3 = sLabel.indexOf(')', iStr2);
-						if (iStr3 >= 0) {
-							float fLat = Float.parseFloat(sLabel.substring(iStr+1, iStr2));// + 180;
-							float fLong = Float.parseFloat(sLabel.substring(iStr2+1, iStr3));// + 360)%360;
-							if (fLat!=0 || fLong!=0) {
-								m_fMinLat = Math.min(m_fMinLat, fLat);
-								m_fMaxLat = Math.max(m_fMaxLat, fLat);
-								m_fMinLong = Math.min(m_fMinLong, fLong);
-								m_fMaxLong = Math.max(m_fMaxLong, fLong);
+				if (label.contains("(")) {
+					int strIndex = label.indexOf('(');
+					int str2 = label.indexOf('x', strIndex);
+					if (str2 >= 0) {
+						int str3 = label.indexOf(')', str2);
+						if (str3 >= 0) {
+							float lat = Float.parseFloat(label.substring(strIndex+1, str2));// + 180;
+							float _long = Float.parseFloat(label.substring(str2+1, str3));// + 360)%360;
+							if (lat!=0 || _long!=0) {
+								m_fMinLat = Math.min(m_fMinLat, lat);
+								m_fMaxLat = Math.max(m_fMaxLat, lat);
+								m_fMinLong = Math.min(m_fMinLong, _long);
+								m_fMaxLong = Math.max(m_fMaxLong, _long);
 							}
 							while (m_fLatitude.size() < m_sLabels.size()) {
 								m_fLatitude.add(0f);
 								m_fLongitude.add(0f);
 							}
-							m_fLatitude.add(fLat);
-							m_fLongitude.add(fLong);
+							m_fLatitude.add(lat);
+							m_fLongitude.add(_long);
 						}
 					}
-					sLabel = sLabel.substring(0, sLabel.indexOf("("));
+					label = label.substring(0, label.indexOf("("));
 				}
-				if (bAddLabels) {
-					m_sLabels.add(sLabel);
+				if (addLabels) {
+					m_sLabels.add(label);
 					m_nNrOfLabels++;
 				}
-				if (!bLastLabel) {
-					sStr = readLine(fin);
+				if (!isLastLabel) {
+					str = readLine(fin);
 				}
 			}
 			
 			// read trees
 			// read trees
-            int nBurnIn = m_nBurnInPercentage * nrOfTrees / 100;
+            int burnIn = m_nBurnInPercentage * nrOfTrees / 100;
             //int k = 0;                    
             while (fin.ready()) {
-                    sStr = readLine(fin);
-                    sStr = sStr.trim();
-                    if (sStr.length() > 5) {
-                            String sTree = sStr.substring(0,5);
-                            if (sTree.toLowerCase().startsWith("tree ")) {
+                    str = readLine(fin);
+                    str = str.trim();
+                    if (str.length() > 5) {
+                            String tree = str.substring(0,5);
+                            if (tree.toLowerCase().startsWith("tree ")) {
                                     //k++;
-                                    if (nBurnIn <= 0) {
-                                            int i = sStr.indexOf('(');
+                                    if (burnIn <= 0) {
+                                            int i = str.indexOf('(');
                                             if (i > 0) {
-                                                    sStr = sStr.substring(i);
+                                                    str = str.substring(i);
                                             }
-                                            Node tree = parseNewick(sStr);
-                                            tree.sort();
-                                            tree.labelInternalNodes(m_nNrOfLabels);
-                                            trees.add(tree);
-                                            //if (trees.size() % 100 ==0) {if (m_nNrOfLabels>=100||trees.size() % 1000 ==0) {System.err.print(trees.size() + " ");}}
+                                            Node treeRoot = parseNewick(str);
+                                            treeRoot.sort();
+                                            treeRoot.labelInternalNodes(m_nNrOfLabels);
+                                            trees.add(treeRoot);
+                                            //if (trees.size() % 100 ==0) {if (m_nNrOfLabels>=100||trees.size() % 1000 ==0) {Log.warning.print(trees.size() + " ");}}
                                     } else {
-                                            nBurnIn--;
+                                            burnIn--;
                                     }
                             }
                     }
@@ -259,17 +260,17 @@ public class TreeSetParser {
 		
 		
 		// convert lengths (stored as node heights) to heights
-		double fMaxHeight = 0;
+		double maxHeight = 0;
 		double [] heights = new double[trees.size()];
 		for (int i = 0; i < trees.size(); i++) {
 			heights[i] = lengthToHeight(trees.get(i), 0);
-			fMaxHeight = Math.max(fMaxHeight, heights[i]);
+			maxHeight = Math.max(maxHeight, heights[i]);
 		}
 		for (int i = 0; i < trees.size(); i++) {
 			offsetHeight(trees.get(i), heights[i]);
 		}
 
-		System.err.println();
+		Log.warning.println();
 		//System.err.println("Geo: " +m_fMinLong + "x" + m_fMinLat + " " + m_fMaxLong + "x" + m_fMaxLat);
 		return trees.toArray(new Node[1]);
 	} // parseFile
@@ -280,7 +281,7 @@ public class TreeSetParser {
 		String s = fin.readLine();
 		fileRead += s.length();
 		if (fileRead > fileMarked - 10) {
-			System.err.print("*");
+			Log.warning.print("*");
 			fileMarked += fileStep;
 			k++;
 		}
@@ -302,56 +303,56 @@ public class TreeSetParser {
 	/** convert length to height
 	 *  and set ID of leafs
 	 */
-	private double lengthToHeight(Node node, double fOffSet) {
+	private double lengthToHeight(Node node, double offSet) {
 		if (node.isLeaf()) {
-			node.setHeight(-fOffSet - node.getHeight());
+			node.setHeight(-offSet - node.getHeight());
 			node.setID(m_sLabels.get(node.getNr()));
 			return -node.getHeight();
 		} else {
-			double fPosY = fOffSet + node.getHeight();
-			double fYMax = 0;
-			fYMax = Math.max(fYMax, lengthToHeight(node.getLeft(), fPosY));
+			double posY = offSet + node.getHeight();
+			double yMax = 0;
+			yMax = Math.max(yMax, lengthToHeight(node.getLeft(), posY));
 			if (node.getRight() != null) {
-				fYMax = Math.max(fYMax, lengthToHeight(node.getRight(), fPosY));
+				yMax = Math.max(yMax, lengthToHeight(node.getRight(), posY));
 			}
-			node.setHeight(-fPosY);
-			return fYMax;
+			node.setHeight(-posY);
+			return yMax;
 		}
 	}
 
-	/** Try to map sStr into an index. First, assume it is a number.
+	/** Try to map str into an index. First, assume it is a number.
 	 * If that does not work, look in list of labels to see whether it is there.
 	 */
-	private int getLabelIndex(String sStr) throws Exception {
+	private int getLabelIndex(String str) {
 		if (!m_bIsLabelledNewick) {
 			try {
-				return Integer.parseInt(sStr) - m_nOffset;
+				return Integer.parseInt(str) - m_nOffset;
 			} catch (Exception e) {
 			}
 		}
 		for (int i = 0; i < m_nNrOfLabels; i++) {
-			if (sStr.equals(m_sLabels.get(i))) {
+			if (str.equals(m_sLabels.get(i))) {
 				return i;
 			}
 		}
-		// sStr may have (double) qoutes missing
+		// str may have (double) qoutes missing
 		for (int i = 0; i < m_nNrOfLabels; i++) {
-			String sLabel = m_sLabels.get(i);
-			if (sLabel.startsWith("'") && sLabel.endsWith("'") ||
-					sLabel.startsWith("\"") && sLabel.endsWith("\"")) {
-				sLabel = sLabel.substring(1, sLabel.length()-1);
-				if (sStr.equals(sLabel)) {
+			String label = m_sLabels.get(i);
+			if (label.startsWith("'") && label.endsWith("'") ||
+					label.startsWith("\"") && label.endsWith("\"")) {
+				label = label.substring(1, label.length()-1);
+				if (str.equals(label)) {
 					return i;
 				}
 			}
 		}
-		// sStr may have extra (double) qoutes
-		if (sStr.startsWith("'") && sStr.endsWith("'") ||
-				sStr.startsWith("\"") && sStr.endsWith("\"")) {
-			sStr = sStr.substring(1, sStr.length()-1);
-			return getLabelIndex(sStr);
+		// str may have extra (double) qoutes
+		if (str.startsWith("'") && str.endsWith("'") ||
+				str.startsWith("\"") && str.endsWith("\"")) {
+			str = str.substring(1, str.length()-1);
+			return getLabelIndex(str);
 		}
-		throw new Exception("Label '" + sStr + "' in Newick tree could not be identified");
+		throw new IllegalArgumentException("Label '" + str + "' in Newick tree could not be identified");
 	}
 	
 
@@ -420,26 +421,26 @@ public class TreeSetParser {
 		 return UNKNOWN;
 	 }
 
-	 public Node parseNewick(String sStr) throws Exception {
+	 public Node parseNewick(String str) {
 		 try {
-		if (sStr == null || sStr.length() == 0) {
+		if (str == null || str.length() == 0) {
 			return null;
 		}
 		
-		m_chars = sStr.toCharArray();
-		m_iTokenStart = sStr.indexOf('(');
+		m_chars = str.toCharArray();
+		m_iTokenStart = str.indexOf('(');
 		if (m_iTokenStart < 0) {
 			return null;
 		}
 		m_iTokenEnd = m_iTokenStart;
-		Vector<Node> stack = new Vector<Node>();
-		Vector<Boolean> isFirstChild =  new Vector<Boolean>();
-		Vector<String> sMetaData =  new Vector<String>();
+		Vector<Node> stack = new Vector<>();
+		Vector<Boolean> isFirstChild =  new Vector<>();
+		Vector<String> metaDataString =  new Vector<>();
 		stack.add(new Node());
 		isFirstChild.add(true);
 		stack.lastElement().setHeight(DEFAULT_LENGTH);
-		sMetaData.add(null);
-		boolean bIsLabel = true;
+		metaDataString.add(null);
+		boolean isLabel = true;
 		while (m_iTokenEnd < m_chars.length) {
 			switch (nextToken()) {
 			case BRACE_OPEN:
@@ -448,8 +449,8 @@ public class TreeSetParser {
 				node2.setHeight(DEFAULT_LENGTH);
 				stack.add(node2);
 				isFirstChild.add(true);
-				sMetaData.add(null);
-				bIsLabel = true;
+				metaDataString.add(null);
+				isLabel = true;
 			}
 				break;
 			case BRACE_CLOSE:
@@ -468,13 +469,13 @@ public class TreeSetParser {
 						Node parent = stack.lastElement();
 						parent.setLeft(left);
 						left.setParent(parent);
-						String metaData = sMetaData.remove(sMetaData.size() - 1);
+						String metaData = metaDataString.remove(metaDataString.size() - 1);
 						left.metaDataString = metaData;
 						parseMetaData(left, metaData);
 						break;
 					} else {
 						// don't know how to process single child nodes
-						throw new Exception("Node with single child found.");
+						throw new IllegalArgumentException("Node with single child found.");
 					}
 				}
 				// process multi(i.e. more than 2)-child nodes by pairwise merging.
@@ -493,20 +494,20 @@ public class TreeSetParser {
 					right.setParent(dummyparent);
 					stack.add(dummyparent);
 					isFirstChild.add(false);
-					String metaData = sMetaData.remove(sMetaData.size() - 1);
+					String metaData = metaDataString.remove(metaDataString.size() - 1);
 					parseMetaData(left, metaData);
 				}
 				// last two nodes on stack merged into single parent node 
 				Node right = stack.lastElement();
 				stack.remove(stack.size()-1);
 				isFirstChild.remove(isFirstChild.size()-1);
-				String metaData = sMetaData.remove(sMetaData.size() - 1);
+				String metaData = metaDataString.remove(metaDataString.size() - 1);
 				parseMetaData(right, metaData);
 
 				Node left = stack.lastElement();
 				stack.remove(stack.size()-1);
 				isFirstChild.remove(isFirstChild.size()-1);
-				metaData = sMetaData.remove(sMetaData.size() - 1);
+				metaData = metaDataString.remove(metaDataString.size() - 1);
 				parseMetaData(left, metaData);
 
 				Node parent = stack.lastElement();
@@ -514,7 +515,7 @@ public class TreeSetParser {
 				left.setParent(parent);
 				parent.setRight(right);
 				right.setParent(parent);
-				metaData = sMetaData.lastElement();
+				metaData = metaDataString.lastElement();
 				parseMetaData(parent, metaData);
 			}
 				break;
@@ -524,66 +525,66 @@ public class TreeSetParser {
 				node2.setHeight(DEFAULT_LENGTH);
 				stack.add(node2);
 				isFirstChild.add(false);
-				sMetaData.add(null);
-				bIsLabel = true;
+				metaDataString.add(null);
+				isLabel = true;
 			}
 				break;
 			case COLON:
-				bIsLabel = false;
+				isLabel = false;
 				break;
 			case TEXT:
-				if (bIsLabel) {
-					String sLabel = sStr.substring(m_iTokenStart, m_iTokenEnd);
-					stack.lastElement().setNr(getLabelIndex(sLabel)); 
+				if (isLabel) {
+					String label = str.substring(m_iTokenStart, m_iTokenEnd);
+					stack.lastElement().setNr(getLabelIndex(label)); 
 				} else {
-					String sLength = sStr.substring(m_iTokenStart, m_iTokenEnd);
-					stack.lastElement().setHeight(Float.parseFloat(sLength)); 
+					String length = str.substring(m_iTokenStart, m_iTokenEnd);
+					stack.lastElement().setHeight(Float.parseFloat(length)); 
 				}
 				break;
 			case META_DATA:
-				if (sMetaData.lastElement() == null) {
-					sMetaData.set(sMetaData.size()-1, sStr.substring(m_iTokenStart+1, m_iTokenEnd-1));
+				if (metaDataString.lastElement() == null) {
+					metaDataString.set(metaDataString.size()-1, str.substring(m_iTokenStart+1, m_iTokenEnd-1));
 				} else {
-					sMetaData.set(sMetaData.size()-1, sMetaData.lastElement() 
-					 + ("," +sStr.substring(m_iTokenStart+1, m_iTokenEnd-1)));
+					metaDataString.set(metaDataString.size()-1, metaDataString.lastElement() 
+					 + ("," +str.substring(m_iTokenStart+1, m_iTokenEnd-1)));
 				}
 				break;
 			case SEMI_COLON:
 				//System.err.println(stack.lastElement().toString());
-				parseMetaData(stack.lastElement(), sMetaData.lastElement());
+				parseMetaData(stack.lastElement(), metaDataString.lastElement());
 				return stack.lastElement();
 			default:
-				throw new Exception("parseNewick: unknown token");	
+				throw new IllegalArgumentException("parseNewick: unknown token");	
 			}
 		}
 		return stack.lastElement();
 		 } catch (Exception e) {
 			 e.printStackTrace();
-			 throw new Exception(e.getMessage() + ": " + sStr.substring(Math.max(0, m_iTokenStart-100), m_iTokenStart) + " >>>" + sStr.substring(m_iTokenStart, m_iTokenEnd) + " <<< ..."); 
+			 throw new IllegalArgumentException(e.getMessage() + ": " + str.substring(Math.max(0, m_iTokenStart-100), m_iTokenStart) + " >>>" + str.substring(m_iTokenStart, m_iTokenEnd) + " <<< ..."); 
 		 }
 		//return node;
 	 }
 	 
 	 
-		public void parseMetaData(Node node, String sMetaData) {
-			node.metaDataString = sMetaData;
-			if (sMetaData == null) {
+		public void parseMetaData(Node node, String metaDataString) {
+			node.metaDataString = metaDataString;
+			if (metaDataString == null) {
 				return;
 			}
 			// parse by key=value pairs
 			int i = 0;
 			int start = 1;
 			try {
-				while ((i = sMetaData.indexOf('=', i)) >= 0) {
-					String key = sMetaData.substring(start, i).trim();
+				while ((i = metaDataString.indexOf('=', i)) >= 0) {
+					String key = metaDataString.substring(start, i).trim();
 					String value = null;
 					int k = 0;
-					if ((k = sMetaData.indexOf('=', i+1)) >= 0) {
-						int j = sMetaData.lastIndexOf(',', k);
-						value = sMetaData.substring(i + 1, j);
+					if ((k = metaDataString.indexOf('=', i+1)) >= 0) {
+						int j = metaDataString.lastIndexOf(',', k);
+						value = metaDataString.substring(i + 1, j);
 						start = j + 1;
 					} else {
-						value = sMetaData.substring(i+1);
+						value = metaDataString.substring(i+1);
 					}
 					if (value.length() > 0 && value.charAt(0) != '{') {
 						try {
diff --git a/src/beast/app/util/Arguments.java b/src/beast/app/util/Arguments.java
index 095a3c2..c33590a 100644
--- a/src/beast/app/util/Arguments.java
+++ b/src/beast/app/util/Arguments.java
@@ -10,9 +10,8 @@ public class Arguments {
     public static final String ARGUMENT_CHARACTER = "-";
 
     public static class ArgumentException extends Exception {
-        /**
-         *
-         */
+ 		private static final long serialVersionUID = 1L;
+
         public ArgumentException() {
             super();
         }
diff --git a/src/beast/app/util/ErrorLogHandler.java b/src/beast/app/util/ErrorLogHandler.java
index 053432c..0e0cd33 100644
--- a/src/beast/app/util/ErrorLogHandler.java
+++ b/src/beast/app/util/ErrorLogHandler.java
@@ -15,7 +15,8 @@ public class ErrorLogHandler extends StreamHandler {
     }
 
 
-    public void publish(LogRecord record) {
+    @Override
+	public void publish(LogRecord record) {
         super.publish(record);
         flush();
 
@@ -32,7 +33,8 @@ public class ErrorLogHandler extends StreamHandler {
         }
     }
 
-    public void close() {
+    @Override
+	public void close() {
         flush();
     }
 
@@ -56,7 +58,8 @@ public class ErrorLogHandler extends StreamHandler {
          * @param record the log record to be formatted.
          * @return a formatted log record
          */
-        public synchronized String format(LogRecord record) {
+        @Override
+		public synchronized String format(LogRecord record) {
             StringBuffer sb = new StringBuffer();
             String message = formatMessage(record);
             sb.append(message);
diff --git a/src/beast/app/util/FileDrop.java b/src/beast/app/util/FileDrop.java
index 2641656..f805c0e 100644
--- a/src/beast/app/util/FileDrop.java
+++ b/src/beast/app/util/FileDrop.java
@@ -253,7 +253,8 @@ public class FileDrop {
 
         if (supportsDnD()) {   // Make a drop listener
             dropListener = new java.awt.dnd.DropTargetListener() {
-                public void dragEnter(java.awt.dnd.DropTargetDragEvent evt) {
+                @Override
+				public void dragEnter(java.awt.dnd.DropTargetDragEvent evt) {
                     log(out, "FileDrop: dragEnter event.");
 
                     // Is this an acceptable drag event?
@@ -278,11 +279,13 @@ public class FileDrop {
                     }   // end else: drag not ok
                 }   // end dragEnter
 
-                public void dragOver(java.awt.dnd.DropTargetDragEvent evt) {   // This is called continually as long as the mouse is
+                @Override
+				public void dragOver(java.awt.dnd.DropTargetDragEvent evt) {   // This is called continually as long as the mouse is
                     // over the drag target.
                 }   // end dragOver
 
-                public void drop(java.awt.dnd.DropTargetDropEvent evt) {
+                @Override
+				public void drop(java.awt.dnd.DropTargetDropEvent evt) {
                     log(out, "FileDrop: drop event.");
                     try {   // Get whatever was dropped
                         java.awt.datatransfer.Transferable tr = evt.getTransferable();
@@ -295,9 +298,10 @@ public class FileDrop {
                             log(out, "FileDrop: file list accepted.");
 
                             // Get a useful list
-                            java.util.List fileList = (java.util.List)
+                            @SuppressWarnings("unchecked")
+							java.util.List<File> fileList = (java.util.List<File>)
                                     tr.getTransferData(java.awt.datatransfer.DataFlavor.javaFileListFlavor);
-                            java.util.Iterator iterator = fileList.iterator();
+                            //java.util.Iterator<File> iterator = fileList.iterator();
 
                             // Convert list to array
                             java.io.File[] filesTemp = new java.io.File[fileList.size()];
@@ -366,7 +370,8 @@ public class FileDrop {
                     }   // end finally
                 }   // end drop
 
-                public void dragExit(java.awt.dnd.DropTargetEvent evt) {
+                @Override
+				public void dragExit(java.awt.dnd.DropTargetEvent evt) {
                     log(out, "FileDrop: dragExit event.");
                     // If it's a Swing component, reset its border
                     if (c instanceof javax.swing.JComponent) {
@@ -376,7 +381,8 @@ public class FileDrop {
                     }   // end if: JComponent
                 }   // end dragExit
 
-                public void dropActionChanged(java.awt.dnd.DropTargetDragEvent evt) {
+                @Override
+				public void dropActionChanged(java.awt.dnd.DropTargetDragEvent evt) {
                     log(out, "FileDrop: dropActionChanged event.");
                     // Is this an acceptable drag event?
                     if (isDragOk(out, evt)) {   //evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE );
@@ -403,7 +409,8 @@ public class FileDrop {
         if (supportsDnD == null) {
             boolean support = false;
             try {
-                Class arbitraryDndClass = Class.forName("java.awt.dnd.DnDConstants");
+                @SuppressWarnings("unused")
+				Class<?> arbitraryDndClass = Class.forName("java.awt.dnd.DnDConstants");
                 support = true;
             }   // end try
             catch (Exception e) {
@@ -418,11 +425,11 @@ public class FileDrop {
     // BEGIN 2007-09-12 Nathan Blomquist -- Linux (KDE/Gnome) support added.
     private static String ZERO_CHAR_STRING = "" + (char) 0;
 
-    private static File[] createFileArray(BufferedReader bReader, PrintStream out) {
+    private static File[] createFileArray(BufferedReader reader, PrintStream out) {
         try {
-            java.util.List list = new java.util.ArrayList();
+            java.util.List<File> list = new java.util.ArrayList<>();
             java.lang.String line = null;
-            while ((line = bReader.readLine()) != null) {
+            while ((line = reader.readLine()) != null) {
                 try {
                     // kde seems to append a 0 char to the end of the reader
                     if (ZERO_CHAR_STRING.equals(line)) continue;
@@ -434,7 +441,7 @@ public class FileDrop {
                 }
             }
 
-            return (java.io.File[]) list.toArray(new File[list.size()]);
+            return list.toArray(new File[list.size()]);
         } catch (IOException ex) {
             log(out, "FileDrop: IOException");
         }
@@ -456,7 +463,8 @@ public class FileDrop {
 
         // Listen for hierarchy changes and remove the drop target when the parent gets cleared out.
         c.addHierarchyListener(new java.awt.event.HierarchyListener() {
-            public void hierarchyChanged(java.awt.event.HierarchyEvent evt) {
+            @Override
+			public void hierarchyChanged(java.awt.event.HierarchyEvent evt) {
                 log(out, "FileDrop: Hierarchy changed.");
                 java.awt.Component parent = c.getParent();
                 if (parent == null) {
@@ -620,7 +628,8 @@ public class FileDrop {
      */
     public static class Event extends java.util.EventObject {
 
-        private java.io.File[] files;
+		private static final long serialVersionUID = 1L;
+		private java.io.File[] files;
 
         /**
          * Constructs an {@link Event} with the array
@@ -768,7 +777,7 @@ public class FileDrop {
          * @see Fetcher
          * @since 1.1
          */
-        public TransferableObject(Class dataClass, Fetcher fetcher) {
+        public TransferableObject(Class<?> dataClass, Fetcher fetcher) {
             this.fetcher = fetcher;
             this.customFlavor = new java.awt.datatransfer.DataFlavor(dataClass, MIME_TYPE);
         }   // end constructor
@@ -799,7 +808,8 @@ public class FileDrop {
          * @return An array of supported data flavors
          * @since 1.1
          */
-        public java.awt.datatransfer.DataFlavor[] getTransferDataFlavors() {
+        @Override
+		public java.awt.datatransfer.DataFlavor[] getTransferDataFlavors() {
             if (customFlavor != null)
                 return new java.awt.datatransfer.DataFlavor[]
                         {customFlavor,
@@ -825,7 +835,8 @@ public class FileDrop {
          * @return The dropped data
          * @since 1.1
          */
-        public Object getTransferData(java.awt.datatransfer.DataFlavor flavor)
+        @Override
+		public Object getTransferData(java.awt.datatransfer.DataFlavor flavor)
                 throws java.awt.datatransfer.UnsupportedFlavorException, java.io.IOException {
             // Native object
             if (flavor.equals(DATA_FLAVOR))
@@ -848,7 +859,8 @@ public class FileDrop {
          * @return Whether or not the flavor is supported
          * @since 1.1
          */
-        public boolean isDataFlavorSupported(java.awt.datatransfer.DataFlavor flavor) {
+        @Override
+		public boolean isDataFlavorSupported(java.awt.datatransfer.DataFlavor flavor) {
             // Native object
             if (flavor.equals(DATA_FLAVOR))
                 return true;
diff --git a/src/beast/app/util/MessageLogHandler.java b/src/beast/app/util/MessageLogHandler.java
index 9e909ff..87cd5a4 100644
--- a/src/beast/app/util/MessageLogHandler.java
+++ b/src/beast/app/util/MessageLogHandler.java
@@ -1,6 +1,8 @@
 package beast.app.util;
 
-import java.util.logging.*;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+import java.util.logging.StreamHandler;
 
 public class MessageLogHandler extends StreamHandler {
 
@@ -10,12 +12,14 @@ public class MessageLogHandler extends StreamHandler {
     }
 
 
-    public void publish(LogRecord record) {
+    @Override
+	public void publish(LogRecord record) {
         super.publish(record);
         flush();
     }
 
-    public void close() {
+    @Override
+	public void close() {
         flush();
     }
 
@@ -35,7 +39,8 @@ public class MessageLogHandler extends StreamHandler {
          * @param record the log record to be formatted.
          * @return a formatted log record
          */
-        public synchronized String format(LogRecord record) {
+        @Override
+		public synchronized String format(LogRecord record) {
             final StringBuffer sb = new StringBuffer();
             sb.append(formatMessage(record));
             sb.append(lineSeparator);
diff --git a/src/beast/app/util/Utils.java b/src/beast/app/util/Utils.java
index d7c7158..e63b6ee 100644
--- a/src/beast/app/util/Utils.java
+++ b/src/beast/app/util/Utils.java
@@ -1,19 +1,32 @@
 package beast.app.util;
 
-import javax.swing.*;
-import javax.swing.UIManager.LookAndFeelInfo;
-import javax.swing.filechooser.FileNameExtensionFilter;
-
-import beast.app.beauti.BeautiPanel;
-import beast.app.beauti.BeautiPanelConfig;
-
-import java.awt.*;
-import java.io.*;
+import java.awt.Component;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.Toolkit;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.lang.reflect.Method;
 import java.net.URL;
 import java.util.HashSet;
 import java.util.Set;
 
+import javax.swing.ImageIcon;
+import javax.swing.JFileChooser;
+import javax.swing.LookAndFeel;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+import beast.app.beauti.BeautiPanel;
+import beast.app.beauti.BeautiPanelConfig;
+import beast.core.util.Log;
+
 /**
  * @author Andrew Rambaut
  * @author Alexei Drummond
@@ -93,7 +106,7 @@ public class Utils {
                     Class<?> qm = Class.forName("ch.randelshofer.quaqua.QuaquaManager");
                     Method method = qm.getMethod("setExcludedUIs", Set.class);
 
-                    Set<String> excludes = new HashSet<String>();
+                    Set<String> excludes = new HashSet<>();
                     excludes.add("Button");
                     excludes.add("ToolBar");
                     method.invoke(null, excludes);
@@ -111,7 +124,7 @@ public class Utils {
 
 
             } catch (Exception e) {
-                System.err.println(e.getMessage());
+            	Log.warning.println(e.getMessage());
                 try {
                     UIManager.setLookAndFeel(laf);
                 } catch (UnsupportedLookAndFeelException e1) {
@@ -188,11 +201,11 @@ public class Utils {
         return getFile(message, false, defaultFileOrDir, true, description, extensions);
     }
 
-    public static File[] getFile(String message, boolean bLoadNotSave, File defaultFileOrDir, boolean bAllowMultipleSelection, String description, final String... extensions) {
+    public static File[] getFile(String message, boolean isLoadNotSave, File defaultFileOrDir, boolean allowMultipleSelection, String description, final String... extensions) {
         if (isMac()) {
             java.awt.Frame frame = new java.awt.Frame();
             java.awt.FileDialog chooser = new java.awt.FileDialog(frame, message,
-                    (bLoadNotSave ? java.awt.FileDialog.LOAD : java.awt.FileDialog.SAVE));
+                    (isLoadNotSave ? java.awt.FileDialog.LOAD : java.awt.FileDialog.SAVE));
             if (defaultFileOrDir != null) {
                 if (defaultFileOrDir.isDirectory()) {
                     chooser.setDirectory(defaultFileOrDir.getAbsolutePath());
@@ -216,10 +229,10 @@ public class Utils {
                 chooser.setFilenameFilter(filter);
             }
 
-            chooser.setMultipleMode(bAllowMultipleSelection);
+            chooser.setMultipleMode(allowMultipleSelection);
             chooser.setVisible(true);
             if (chooser.getFile() == null) return null;
-            if (bAllowMultipleSelection) {
+            if (allowMultipleSelection) {
             	return chooser.getFiles();
             }
             File file = new java.io.File(chooser.getDirectory(), chooser.getFile());
@@ -231,7 +244,7 @@ public class Utils {
             java.awt.Frame frame = new java.awt.Frame();
             frame.setTitle(message);
             final JFileChooser chooser = new JFileChooser(defaultFileOrDir);
-            chooser.setMultiSelectionEnabled(bAllowMultipleSelection);
+            chooser.setMultiSelectionEnabled(allowMultipleSelection);
             //chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
 
             if (description != null) {
@@ -239,10 +252,10 @@ public class Utils {
                 chooser.setFileFilter(filter);
             }
 
-            if (bLoadNotSave) {
+            if (isLoadNotSave) {
                 if (chooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
                     frame.dispose();
-                    if (bAllowMultipleSelection) {
+                    if (allowMultipleSelection) {
                         return chooser.getSelectedFiles();
                     } else {
                         if (chooser.getSelectedFile() == null) {
@@ -254,7 +267,7 @@ public class Utils {
             } else {
                 if (chooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
                     frame.dispose();
-                    if (bAllowMultipleSelection) {
+                    if (allowMultipleSelection) {
                         return chooser.getSelectedFiles();
                     } else {
                         if (chooser.getSelectedFile() == null) {
@@ -278,31 +291,31 @@ public class Utils {
         reader.close();
         return out.toString();
     }
-	public static ImageIcon getIcon(int iPanel, BeautiPanelConfig config) {
-	    String sIconLocation = BeautiPanel.ICONPATH + iPanel + ".png";
+	public static ImageIcon getIcon(int panelIndex, BeautiPanelConfig config) {
+	    String iconLocation = BeautiPanel.ICONPATH + panelIndex + ".png";
 	    if (config != null) {
-	        sIconLocation = BeautiPanel.ICONPATH + config.getIcon();
+	        iconLocation = BeautiPanel.ICONPATH + config.getIcon();
 	    }
-	    return Utils.getIcon(sIconLocation);
+	    return Utils.getIcon(iconLocation);
 	}
 
     /**
      * Retrieve icon.
      *
-     * @param sIconLocation location of icon
+     * @param iconLocation location of icon
      * @return icon or null if no icon found
      */
-	public static ImageIcon getIcon(String sIconLocation) {
+	public static ImageIcon getIcon(String iconLocation) {
 	    try {
-	        URL url = (URL) ClassLoader.getSystemResource(sIconLocation);
+	        URL url = ClassLoader.getSystemResource(iconLocation);
 	        if (url == null) {
-//	            System.err.println("Cannot find icon " + sIconLocation);
+//	            System.err.println("Cannot find icon " + iconLocation);
 	            return null;
 	        }
 	        ImageIcon icon = new ImageIcon(url);
 	        return icon;
 	    } catch (Exception e) {
-	        System.err.println("Cannot load icon " + sIconLocation + " " + e.getMessage());
+	    	Log.warning.println("Cannot load icon " + iconLocation + " " + e.getMessage());
 	        return null;
 	    }
 	
diff --git a/src/beast/app/util/Utils6.java b/src/beast/app/util/Utils6.java
index e962608..8cf4ba5 100644
--- a/src/beast/app/util/Utils6.java
+++ b/src/beast/app/util/Utils6.java
@@ -12,17 +12,19 @@ import java.net.URL;
 import javax.swing.ImageIcon;
 import javax.swing.JComponent;
 
-import beast.app.beauti.BeautiPanel;
-import beast.app.beauti.BeautiPanelConfig;
+import beast.core.util.Log;
 
 /** Utils that work with Java6 **/
 public class Utils6 {
 
     public static class Canvas extends JComponent {
-        Image imageBuffer;
+		private static final long serialVersionUID = 1L;
+		
+		Image imageBuffer;
         public Canvas() { }
 
-        public void paintComponent( Graphics g ) {
+        @Override
+		public void paintComponent( Graphics g ) {
             // copy buffered image
             if ( imageBuffer != null )
                 g.drawImage(imageBuffer, 0,0, this);
@@ -37,7 +39,8 @@ public class Utils6 {
             return imageBuffer.getGraphics();
         }
 
-        public void setBounds( int x, int y, int width, int height ) {
+        @Override
+		public void setBounds( int x, int y, int width, int height ) {
             setPreferredSize( new Dimension(width, height) );
             setMinimumSize( new Dimension(width, height) );
             super.setBounds( x, y, width, height );
@@ -81,17 +84,17 @@ public class Utils6 {
     }
 
 
-	public static ImageIcon getIcon(String sIconLocation) {
+	public static ImageIcon getIcon(String iconLocation) {
 	    try {
-	        URL url = (URL) ClassLoader.getSystemResource(sIconLocation);
+	        URL url = ClassLoader.getSystemResource(iconLocation);
 	        if (url == null) {
-	            System.err.println("Cannot find icon " + sIconLocation);
+	        	Log.warning.println("Cannot find icon " + iconLocation);
 	            return null;
 	        }
 	        ImageIcon icon = new ImageIcon(url);
 	        return icon;
 	    } catch (Exception e) {
-	        System.err.println("Cannot load icon " + sIconLocation + " " + e.getMessage());
+	    	Log.warning.println("Cannot load icon " + iconLocation + " " + e.getMessage());
 	        return null;
 	    }
 	}
diff --git a/src/beast/app/util/Version.java b/src/beast/app/util/Version.java
index e346ede..9738ee2 100644
--- a/src/beast/app/util/Version.java
+++ b/src/beast/app/util/Version.java
@@ -18,17 +18,17 @@ public abstract class Version {
     public abstract String[] getCredits();
 
     public String getHTMLCredits() {
-        String sStr = "";
+        String str = "";
         for (String s : getCredits()) {
             if (s.contains("@")) {
-                sStr += "<a href=\"mailto:" + s + "\">" + s + "</a><br>";
+                str += "<a href=\"mailto:" + s + "\">" + s + "</a><br>";
             }
             if (s.contains("http")) {
-                sStr += "<a href=\"" + s + "\">" + s + "</a><br>";
+                str += "<a href=\"" + s + "\">" + s + "</a><br>";
             } else {
-                sStr += "<p>" + s + "</p>";
+                str += "<p>" + s + "</p>";
             }
         }
-        return sStr;
+        return str;
     }
 }
diff --git a/src/beast/app/util/WholeNumberField.java b/src/beast/app/util/WholeNumberField.java
index 93a534c..f5dc190 100644
--- a/src/beast/app/util/WholeNumberField.java
+++ b/src/beast/app/util/WholeNumberField.java
@@ -1,20 +1,27 @@
 package beast.app.util;
 
-import javax.swing.*;
-import javax.swing.event.*;
+import java.awt.Toolkit;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+
+import javax.swing.JOptionPane;
+import javax.swing.JTextField;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.event.EventListenerList;
 import javax.swing.text.AttributeSet;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.Document;
 import javax.swing.text.PlainDocument;
-import java.awt.*;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
 
 
 public class WholeNumberField extends JTextField
         implements FocusListener, DocumentListener {
+	private static final long serialVersionUID = 1L;
 
-    protected static char MINUS_CHAR = '-';
+	protected static char MINUS_CHAR = '-';
     protected EventListenerList changeListeners = new EventListenerList();
     protected long min;
     protected long max;
@@ -41,10 +48,12 @@ public class WholeNumberField extends JTextField
         this.addFocusListener(this);
     }
 
-    public void focusGained(FocusEvent evt) {
+    @Override
+	public void focusGained(FocusEvent evt) {
     }
 
-    public void focusLost(FocusEvent evt) {
+    @Override
+	public void focusLost(FocusEvent evt) {
         if (range_check && !range_checked) {
             range_checked = true;
             try {
@@ -120,23 +129,27 @@ public class WholeNumberField extends JTextField
             return value;
     }
 
-    protected Document createDefaultModel() {
+    @Override
+	protected Document createDefaultModel() {
         Document doc = new WholeNumberFieldDocument();
         doc.addDocumentListener(this);
         return doc;
     }
 
-    public void insertUpdate(DocumentEvent e) {
+    @Override
+	public void insertUpdate(DocumentEvent e) {
         range_checked = false;
         fireChanged();
     }
 
-    public void removeUpdate(DocumentEvent e) {
+    @Override
+	public void removeUpdate(DocumentEvent e) {
         range_checked = false;
         fireChanged();
     }
 
-    public void changedUpdate(DocumentEvent e) {
+    @Override
+	public void changedUpdate(DocumentEvent e) {
         range_checked = false;
         fireChanged();
     }
@@ -146,7 +159,10 @@ public class WholeNumberField extends JTextField
     };
 
     class WholeNumberFieldDocument extends PlainDocument {
-        public void insertString(int offs, String str, AttributeSet a)
+		private static final long serialVersionUID = 1L;
+
+		@Override
+		public void insertString(int offs, String str, AttributeSet a)
                 throws BadLocationException {
 
             if (str == null) return;
diff --git a/src/beast/core/BEASTInterface.java b/src/beast/core/BEASTInterface.java
index e9939e6..05b6312 100644
--- a/src/beast/core/BEASTInterface.java
+++ b/src/beast/core/BEASTInterface.java
@@ -25,22 +25,30 @@ package beast.core;
 
 
 import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 public interface BEASTInterface {
-    public void initAndValidate() throws Exception;
+    public void initAndValidate();
 
 	/** identifiable **/
 	public String getID();
 	public void setID(String ID);
+	
 	/** return set of Outputs, that is Objects for which this object is an Input **/
-	public Set getOutputs();
+	public Set<BEASTInterface> getOutputs();
 
+	/** return Map of Inputs containing both Inputs and InptForAnnotatedConstructors 
+	 * indexed by Input name **/
+	public Map<String, Input<?>> getInputs();
 	
 	
     /* Utility for testing purposes only.
@@ -51,7 +59,7 @@ public interface BEASTInterface {
      * inputs are declared in the class, then calls
      * initAndValidate().
      */
-   default public void init(final Object... objects) throws Exception {
+   default public void init(final Object... objects) {
        final List<Input<?>> inputs = listInputs();
        int i = 0;
        for (final Object object : objects) {
@@ -67,14 +75,14 @@ public interface BEASTInterface {
     * assigns 2 to input kappa and true to input lambda.
     * After assigning inputs, initAndValidate() is called.
     */
-  default public void initByName(final Object... objects) throws Exception {
+  default public void initByName(final Object... objects) {
       if (objects.length % 2 == 1) {
           throw new RuntimeException("Expected even number of arguments, name-value pairs");
       }
       for (int i = 0; i < objects.length; i += 2) {
           if (objects[i] instanceof String) {
-              final String sName = (String) objects[i];
-              setInputValue(sName, objects[i + 1]);
+              final String name = (String) objects[i];
+              setInputValue(name, objects[i + 1]);
           } else {
               throw new RuntimeException("Expected a String in " + i + "th argument ");
           }
@@ -88,14 +96,17 @@ public interface BEASTInterface {
   } // initByName
 
 	
-	//@SuppressWarnings("rawtypes") 
-	static Set getOutputs(Object object) {
+	@SuppressWarnings({"unchecked", "rawtypes" }) 
+	static Set<BEASTInterface> getOutputs(Object object) {
     	try {
             Method method = object.getClass().getMethod("getOutputs");
             Object outputs = method.invoke(object);
-            return (Set) outputs;
+            if (outputs instanceof Set<?>) {
+            	return (Set) outputs;
+            }
+    		throw new RuntimeException("call to getOutputs() on object did not return a java.util.Set");
     	} catch (Exception e) {
-    		throw new RuntimeException("could not call getID() on object: " + e.getMessage());
+    		throw new RuntimeException("could not call getOutputs() on object: " + e.getMessage());
     	}
 	}
 
@@ -130,7 +141,7 @@ public interface BEASTInterface {
      * @return references for this plug in and all its inputs *
      */
     default public String getCitations() {
-        return getCitations(new HashSet<String>(), new HashSet<String>());
+        return getCitations(new HashSet<>(), new HashSet<>());
     }
 
     default String getCitations(final HashSet<String> citations, final HashSet<String> IDs) {
@@ -153,8 +164,8 @@ public interface BEASTInterface {
             //return buf.toString();
         }
         try {
-            for (final BEASTInterface plugin : listActivePlugins()) {
-                buf.append(plugin.getCitations(citations, IDs));
+            for (final BEASTInterface beastObject : listActiveBEASTObjects()) {
+                buf.append(beastObject.getCitations(citations, IDs));
             }
         } catch (Exception e) {
             e.printStackTrace();
@@ -166,16 +177,77 @@ public interface BEASTInterface {
     /**
      * create list of inputs to this plug-in *
      */
-    default public List<Input<?>> listInputs() throws IllegalArgumentException, IllegalAccessException {
-        final List<Input<?>> inputs = new ArrayList<Input<?>>();
+    default public List<Input<?>> listInputs() { 
+        final List<Input<?>> inputs = new ArrayList<>();
+        
+        // First, collect all Inputs
         final Field[] fields = getClass().getFields();
         for (final Field field : fields) {
             if (field.getType().isAssignableFrom(Input.class)) {
-                final Input<?> input = (Input<?>) field.get(this);
-                inputs.add(input);
+            	try {
+            		final Input<?> input = (Input<?>) field.get(this);
+            		inputs.add(input);
+            	} catch (IllegalAccessException e) {
+            		// not a publicly accessible input, ignore
+            	}
             }
         }
-        return inputs;
+        
+        // Second, collect InputForAnnotatedConstructors of annotated constructor (if any)
+	    Constructor<?>[] allConstructors = this.getClass().getDeclaredConstructors();
+	    for (Constructor<?> ctor : allConstructors) {
+	    	Annotation[][] annotations = ctor.getParameterAnnotations();
+	    	List<Param> paramAnnotations = new ArrayList<>();
+	    	for (Annotation [] a0 : annotations) {
+		    	for (Annotation a : a0) {
+		    		if (a instanceof Param) {
+		    			paramAnnotations.add((Param) a);
+		    		}
+		    	}
+	    	}
+	    	Class<?>[] types  = ctor.getParameterTypes();	    	
+    		Type[] gtypes = ctor.getGenericParameterTypes();
+	    	if (types.length > 0 && paramAnnotations.size() > 0) {
+	    		int offset = 0;
+	    		if (types.length == paramAnnotations.size() + 1) {
+	    			offset = 1;
+	    		}
+	    		for (int i = 0; i < paramAnnotations.size(); i++) {
+	    			Param param = paramAnnotations.get(i);
+	    			Type type = types[i + offset];
+	    			Class<?> clazz = null;
+					try {
+						clazz = Class.forName(type.getTypeName());
+					} catch (ClassNotFoundException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+	    			if (clazz.isAssignableFrom(List.class)) {
+                        Type[] genericTypes2 = ((ParameterizedType) gtypes[i + offset]).getActualTypeArguments();
+                        Class<?> theClass = (Class<?>) genericTypes2[0];
+	    				InputForAnnotatedConstructor<?> t = null;
+						try {
+							t = new InputForAnnotatedConstructor<>(this, theClass, param);
+						} catch (NoSuchMethodException | SecurityException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+	    				inputs.add(t);
+	    			} else {
+	    				InputForAnnotatedConstructor<?> t = null;
+						try {
+							t = new InputForAnnotatedConstructor<>(this, types[i + offset], param);
+						} catch (NoSuchMethodException | SecurityException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
+	    				inputs.add(t);
+	    			}
+	    		}
+	    	}
+		}
+	    
+	    return inputs;
     } // listInputs
 
     /**
@@ -185,47 +257,48 @@ public interface BEASTInterface {
      *
      * @return list of all active plug-ins
      * @throws IllegalAccessException
-     * @throws IllegalArgumentException
      */
-    default public List<BEASTInterface> listActivePlugins() throws IllegalArgumentException, IllegalAccessException {
-        final List<BEASTInterface> plugins = new ArrayList<BEASTInterface>();
-        final Field[] fields = getClass().getFields();
-        for (final Field field : fields) {
-            if (field.getType().isAssignableFrom(Input.class)) {
-                final Input<?> input = (Input<?>) field.get(this);
-                if (input.get() != null) {
-                    if (input.get() instanceof List<?>) {
-                        final List<?> vector = (List<?>) input.get();
-                        for (final Object o : vector) {
-                            if (o instanceof BEASTInterface) {
-                                plugins.add((BEASTInterface) o);
-                            }
-                        }
-                    } else if (input.get() != null && input.get() instanceof BEASTInterface) {
-                        plugins.add((BEASTInterface) input.get());
-                    }
-                }
-            }
+    default public List<BEASTInterface> listActiveBEASTObjects() {
+        final List<BEASTInterface> beastObjects = new ArrayList<>();
+
+        for (Input<?> input : getInputs().values()) {
+        	if (input.get() != null) {
+        		if (input.get() instanceof List<?>) {
+        			final List<?> list = (List<?>) input.get();
+        			for (final Object o : list) {
+        				if (o instanceof BEASTInterface) {
+        					beastObjects.add((BEASTInterface) o);
+        				}
+        			}
+        		} else if (input.get() != null && input.get() instanceof BEASTInterface) {
+        			beastObjects.add((BEASTInterface) input.get());
+        		}
+        	}
         }
-        return plugins;
+        return beastObjects;
+    }
+
+    @Deprecated /** use listActiveBEASTObjects instead **/
+    default public List<BEASTInterface> listActivePlugins() throws IllegalArgumentException, IllegalAccessException {
+    	return listActiveBEASTObjects();
     } // listActivePlugins
 
     /**
      * get description of an input
      *
      * @param name of the input
-     * @return list of inputs
+     * @return description of input
      */
     default public String getTipText(final String name) throws IllegalArgumentException, IllegalAccessException {
-        final Field[] fields = getClass().getDeclaredFields();
-        for (final Field field : fields) {
-            if (field.getType().isAssignableFrom(Input.class)) {
-                final Input<?> input = (Input<?>) field.get(this);
-                if (input.getName().equals(name)) {
-                    return input.getTipText();
-                }
-            }
-        }
+		try {
+	    	Input<?> input = getInput(name);
+	    	if (input != null) {
+	    		return input.getTipText();
+	    	}
+		} catch (Exception e) {
+			// whatever happened, getting a tip text is no reason to interrupt anything,
+			// so ignore and return null
+		}
         return null;
     } // getTipText
 
@@ -233,7 +306,7 @@ public interface BEASTInterface {
     /**
      * check whether the input is an Integer, Double, Boolean or String *
      */
-    default public boolean isPrimitive(final String name) throws Exception {
+    default public boolean isPrimitive(final String name) {
         final Input<?> input = getInput(name);
         final Class<?> inputType = input.getType();
 
@@ -242,30 +315,18 @@ public interface BEASTInterface {
         }
 
         assert inputType != null;
-        for (final Class c : new Class[]{Integer.class, Double.class, Boolean.class, String.class}) {
+        for (final Class<?> c : new Class[]{Integer.class, Long.class, Double.class, Float.class, Boolean.class, String.class}) {
             if (inputType.isAssignableFrom(c)) {
                 return true;
             }
         }
-//        if (inputType.isAssignableFrom(Integer.class)) {
-//            return true;
-//        }
-//        if (inputType.isAssignableFrom(Double.class)) {
-//            return true;
-//        }
-//        if (inputType.isAssignableFrom(Boolean.class)) {
-//            return true;
-//        }
-//        if (inputType.isAssignableFrom(String.class)) {
-//            return true;
-//        }
         return false;
     } // isPrimitive
 
     /**
      * get value of an input by input name *
      */
-    default public Object getInputValue(final String name) throws Exception {
+    default public Object getInputValue(final String name) {
         final Input<?> input = getInput(name);
         return input.get();
     } // getInputValue
@@ -273,7 +334,7 @@ public interface BEASTInterface {
     /**
      * set value of an input by input name *
      */
-    default public void setInputValue(final String name, final Object value) throws Exception {
+    default public void setInputValue(final String name, final Object value) {
         final Input<?> input = getInput(name);
         if (!input.canSetValue(value, this)) {
             throw new RuntimeException("Cannot set input value of " + name);
@@ -284,33 +345,28 @@ public interface BEASTInterface {
     /**
      * get input by input name *
      */
-    default public Input<?> getInput(final String name) throws Exception {
-        final Field[] fields = getClass().getFields();
-        for (final Field field : fields) {
-            if (field.getType().isAssignableFrom(Input.class)) {
-                final Input<?> input = (Input<?>) field.get(this);
-                if (input.getName().equals(name)) {
-                    return input;
-                }
-            }
-        }
-
+    default public Input<?> getInput(final String name) {
+    	
+    	Map<String, Input<?>> inputs = getInputs();
+    	if (inputs.containsKey(name)) {
+    		return inputs.get(name);
+    	}
 
         String inputNames = " "; // <- space here to prevent error in .substring below
         for (final Input<?> input : listInputs()) {
             inputNames += input.getName() + ",";
         }
-        throw new Exception("This BEASTInterface (" + (this.getID() == null ? this.getClass().getName() : this.getID()) + ") has no input with name " + name + ". " +
+        throw new IllegalArgumentException("This BEASTInterface (" + (this.getID() == null ? this.getClass().getName() : this.getID()) + ") has no input with name " + name + ". " +
                 "Choose one of these inputs:" + inputNames.substring(0, inputNames.length() - 1));
     } // getInput
 
 
     /**
-     * check validation rules for all its inputs *
-     *
-     * @throws Exception when validation fails
+     * check validation rules for all its inputs
+     * 
+     * @throws IllegalArgumentException when validation fails
      */
-    default public void validateInputs() throws Exception {
+    default public void validateInputs() {
         for (final Input<?> input : listInputs()) {
             input.validate();
         }
@@ -327,51 +383,13 @@ public interface BEASTInterface {
 
     default public void getPredecessors(final List<BEASTInterface> predecessors) {
         predecessors.add(this);
-        try {
-            for (final BEASTInterface plugin2 : listActivePlugins()) {
-                if (!predecessors.contains(plugin2)) {
-                    plugin2.getPredecessors(predecessors);
-                }
+        for (final BEASTInterface beastObject2 : listActiveBEASTObjects()) {
+            if (!predecessors.contains(beastObject2)) {
+                beastObject2.getPredecessors(predecessors);
             }
-        } catch (IllegalArgumentException | IllegalAccessException e) {
-            e.printStackTrace();
         }
     }
 
-
-// // This class was formerly called 'Plugin'
-//    @Description(
-//            value = "Base class for all BEAST objects, which is pretty much every class " +
-//                    "you want to incorporate in a model.",
-//            isInheritable = false
-//    )
-//    abstract public class Core implements BEASTInterface {
-//        /**
-//         * set of Objects that have this Object in one of its Inputs *
-//         * @deprecate use getOuputs() or BEASTInterface.getOuputs(object) instead
-//         */
-//    	@Deprecated
-//        public Set<BEASTInterface> outputs = new HashSet<BEASTInterface>();
-//    	
-//        /**
-//         * @return set of Objects that have this Object in one of its Inputs
-//         */
-//    	@SuppressWarnings("rawtypes")
-//    	public Set getOutputs() {
-//    		return outputs;
-//    	};
-//
-//        // identifiable
-//        protected String ID;
-//
-//        public String getID() {
-//            return ID;
-//        }
-//
-//        public void setID(final String ID) {
-//            this.ID = ID;
-//        }
-//    }
 }
 
 
diff --git a/src/beast/core/BEASTObject.java b/src/beast/core/BEASTObject.java
index bde194f..846fea3 100644
--- a/src/beast/core/BEASTObject.java
+++ b/src/beast/core/BEASTObject.java
@@ -24,15 +24,11 @@
 package beast.core;
 
 
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
-// This class was formerly called 'Plugin'
 @Description(
         value = "Base class for all BEAST objects, which is pretty much every class " +
                 "you want to incorporate in a model.",
@@ -44,29 +40,54 @@ abstract public class BEASTObject implements BEASTInterface{
      * @deprecate use getOuputs() or BEASTObject.getOuputs(object) instead
      */
 	@Deprecated
-    public Set<BEASTObject> outputs = new HashSet<BEASTObject>();
+    public Set<BEASTInterface> outputs = new HashSet<>();
+	
+	/** 
+	 * cache collecting all Inputs and InputForAnnotatedConstrutors 
+	 * indexed through input name
+	 */
+    private Map<String,Input<?>> inputcache;
 	
     /**
      * @return set of Objects that have this Object in one of its Inputs
      */
-	@SuppressWarnings("rawtypes")
-	public Set getOutputs() {
+	@Override
+	public Set<BEASTInterface> getOutputs() {
 		return outputs;
 	};
 
-    // identifiable
+	@Override
+	public Map<String, Input<?>> getInputs() {
+		if (inputcache == null) {
+			inputcache = new HashMap<>();
+			try {
+				for (Input<?> input : listInputs()) {
+					inputcache.put(input.getName(), input);
+				}
+			} catch (IllegalArgumentException e) {
+				e.printStackTrace();
+				throw new RuntimeException("Problem getting inputs " + e.getClass().getName() + e.getMessage());
+			}
+		}
+		return inputcache;
+	};
+
+	// identifiable
     protected String ID;
 
+	@Override
     public String getID() {
         return ID;
     }
 
+	@Override
     public void setID(final String ID) {
         this.ID = ID;
     }
 
     // A default method in BEASTInterface cannot override
     // a method in Object, so it needs to be in BEASTObject
+	@Override
     public String toString() {
     	return getID();
     }
diff --git a/src/beast/core/BEASTObjectAnnotation.java b/src/beast/core/BEASTObjectAnnotation.java
deleted file mode 100644
index 9571377..0000000
--- a/src/beast/core/BEASTObjectAnnotation.java
+++ /dev/null
@@ -1,12 +0,0 @@
-package beast.core;
-
-import java.lang.annotation.*;
-
-/**
- * An annotation used for specifying a BEAST object without needing to extend BEASTObject directly.
- * Useful when one wants to extend a different object, since there is no multiple inheritance in Java.
- */
- at Target({ElementType.TYPE})
- at Retention(RetentionPolicy.RUNTIME)
- at Inherited
-public @interface BEASTObjectAnnotation {}
diff --git a/src/beast/core/CalculationNode.java b/src/beast/core/CalculationNode.java
index ceeb5c2..ce90ed1 100644
--- a/src/beast/core/CalculationNode.java
+++ b/src/beast/core/CalculationNode.java
@@ -10,7 +10,7 @@ package beast.core;
  *
  * @author Andrew Rambaut
  */
- at Description("Plugin that performs calculations based on the State.")
+ at Description("BEASTObject that performs calculations based on the State.")
 public abstract class CalculationNode extends BEASTObject {
 
     //=================================================================
@@ -45,11 +45,11 @@ public abstract class CalculationNode extends BEASTObject {
     }
 
     /**
-     * @return whether the API for the particular Plugin returns different
+     * @return whether the API for the particular BEASTObject returns different
      *         answers than before the operation was applied.
      *         <p/>
      *         This method is called before the CalculationNode do their calculations.
-     *         Called in order of the partial order defined by Input-Plugin relations.
+     *         Called in order of the partial order defined by Input-BEASTObject relations.
      *         Called only on those CalculationNodes potentially affected by a
      *         StateNode change.
      *         <p/>
@@ -61,22 +61,22 @@ public abstract class CalculationNode extends BEASTObject {
 
 
 //        *         <p/>
-//        *         Default implementation inspects all input plugins
+//        *         Default implementation inspects all input beastObjects
 //        *         and checks if there is any dirt anywhere.
 //        *         Derived classes can provide a more efficient implementation
-//        *         by checking which part of any input StateNode or Plugin has changed.
+//        *         by checking which part of any input StateNode or BEASTObject has changed.
 //        *         <p/>
 //        *         Note this default implementation is relative expensive since it uses
 //        *         introspection, so overrides should be preferred.
 //        *         After the operation has changed the state.state
         // this is a prototypical implementation of requiresRecalculation()
 //        try {
-//            for (Plugin plugin : listActivePlugins()) {
-//                if (plugin instanceof StateNode && ((StateNode)plugin).somethingIsDirty()) {
+//            for (BEASTObject beastObject : listActivePlugins()) {
+//                if (beastObject instanceof StateNode && ((StateNode)beastObject).somethingIsDirty()) {
 //                	return true;
 //                }
 //
-//                if (plugin instanceof CalculationNode && ((CalculationNode)plugin).isDirtyCalculation()) {
+//                if (beastObject instanceof CalculationNode && ((CalculationNode)beastObject).isDirtyCalculation()) {
 //                    return true;
 //                }
 //            }
diff --git a/src/beast/core/Citation.java b/src/beast/core/Citation.java
index c7f191b..45c9739 100644
--- a/src/beast/core/Citation.java
+++ b/src/beast/core/Citation.java
@@ -25,7 +25,11 @@
 
 package beast.core;
 
-import java.lang.annotation.*;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
 
 /**
  * This is an annotation that can be used to add a reference
diff --git a/src/beast/core/Distribution.java b/src/beast/core/Distribution.java
index 7c18d37..1a457e7 100644
--- a/src/beast/core/Distribution.java
+++ b/src/beast/core/Distribution.java
@@ -43,14 +43,13 @@ public abstract class Distribution extends CalculationNode implements Loggable,
      *         Note that some efficiency can be gained by testing whether the
      *         Distribution is dirty, and if not, call getCurrentLogP() instead
      *         of recalculating.
-     * @throws Exception an exception
      */
-    public double calculateLogP() throws Exception {
+    public double calculateLogP() {
         logP = 0;
         return logP;
     }
 
-    /** The plugin implements f( arguments | conditionals) **/
+    /** The beastObject implements f( arguments | conditionals) **/
 
     /**
      * @return a list of unique ids for the state nodes that form the argument
@@ -82,7 +81,7 @@ public abstract class Distribution extends CalculationNode implements Loggable,
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         // nothing to do
     }
 
@@ -105,12 +104,12 @@ public abstract class Distribution extends CalculationNode implements Loggable,
      * Loggable interface implementation follows *
      */
     @Override
-    public void init(final PrintStream out) throws Exception {
+    public void init(final PrintStream out) {
         out.print(getID() + "\t");
     }
 
     @Override
-    public void log(final int nSample, final PrintStream out) {
+    public void log(final int sample, final PrintStream out) {
         out.print(getCurrentLogP() + "\t");
     }
 
@@ -133,8 +132,8 @@ public abstract class Distribution extends CalculationNode implements Loggable,
     }
 
     @Override
-    public double getArrayValue(final int iDim) {
-        if (iDim == 0) return getArrayValue();
+    public double getArrayValue(final int dim) {
+        if (dim == 0) return getArrayValue();
         return 0;
     }
     
@@ -157,7 +156,7 @@ public abstract class Distribution extends CalculationNode implements Loggable,
      * 
      * @return logP if not stochastic, zero otherwise
      */
-	public double getNonStochasticLogP() throws Exception {
+	public double getNonStochasticLogP() {
 		if (isStochastic()) {
 			return 0;
 		} else {
diff --git a/src/beast/core/Function.java b/src/beast/core/Function.java
index 3964d30..276c028 100644
--- a/src/beast/core/Function.java
+++ b/src/beast/core/Function.java
@@ -1,8 +1,8 @@
 package beast.core;
 
 /**
- * Allows a YABBYObject, in particular a StateNode or CalculationNode to present itself as
- * an array of values. This is particular handy for generic calculations on a YABBYObject,
+ * Allows a BEASTObject, in particular a StateNode or CalculationNode to present itself as
+ * an array of values. This is particular handy for generic calculations on a BEASTObject,
  * like calculation of ESS, posterior of a distribution or in the SpreadSheet interface
  * where the possibilities of calculations are limitless.
  * *
@@ -17,13 +17,24 @@ public interface Function {
     /**
      * @return main value. For a 1 dimensional Function, this is the only
      *         value, but for a Tree this can be the root height, while the individual
-     *         values obtained from getValue(iDim) return the node heights.
+     *         values obtained from getValue(dim) return the node heights.
      */
     public double getArrayValue();
 
     /**
-     * @param iDim requested dimention
-     * @return iDim'th value (if any)
+     * @param dim requested dimension
+     * @return dim'th value (if any)
      */
-    public double getArrayValue(int iDim);
+    public double getArrayValue(int dim);
+
+    /**
+     * @return all values as a double[]
+     */
+    default double[] getDoubleValues() {
+        double[] values = new double[getDimension()];
+        for (int i = 0; i < values.length; i++) {
+            values[i] = getArrayValue(i);
+        }
+        return values;
+    }
 }
diff --git a/src/beast/core/Input.java b/src/beast/core/Input.java
index 4b12bd7..44b4715 100644
--- a/src/beast/core/Input.java
+++ b/src/beast/core/Input.java
@@ -25,14 +25,18 @@
 package beast.core;
 
 
-import beast.core.parameter.RealParameter;
-import beast.core.util.Log;
-
 import java.io.File;
-import java.lang.reflect.*;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.util.Arrays;
 import java.util.List;
 
+import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
+
 
 /**
  * Represents input of a BEASTObject class.
@@ -93,9 +97,9 @@ public class Input<T> {
     /**
      * simple constructor, requiring only the input name and tiptext
      */
-    public Input(String sName, String sTipText) {
-        name = sName;
-        tipText = sTipText;
+    public Input(String name, String tipText) {
+        this.name = name;
+        this.tipText = tipText;
         value = null;
         checkName();
     } // c'tor
@@ -105,16 +109,16 @@ public class Input<T> {
      * This allows inputs of types that cannot be determined through
      * introspection, such as template class inputs, e.g. Input<Parameter<?>>
      */
-    public Input(String sName, String sTipText, Class<?> theClass) {
-        this(sName, sTipText);
+    public Input(String name, String tipText, Class<?> theClass) {
+        this(name, tipText);
         this.theClass = theClass;
     } // c'tor
 
     /**
      * constructor for List<>
      */
-    public Input(String sName, String sTipText, T startValue) {
-        this(sName, sTipText);
+    public Input(String name, String tipText, T startValue) {
+        this(name, tipText);
         value = startValue;
         defaultValue = startValue;
     } // c'tor
@@ -122,18 +126,18 @@ public class Input<T> {
     /**
      * constructor for List<> with type specified
      */
-    public Input(String sName, String sTipText, T startValue, Class<?> theClass) {
-        this(sName, sTipText, startValue);
+    public Input(String name, String tipText, T startValue, Class<?> theClass) {
+        this(name, tipText, startValue);
         this.theClass = theClass;
     } // c'tor
 
     /**
      * constructor for List<> with XOR rules
      */
-    public Input(String sName, String sTipText, T startValue, Validate rule, Input<?> other) {
-        this(sName, sTipText, startValue);
+    public Input(String name, String tipText, T startValue, Validate rule, Input<?> other) {
+        this(name, tipText, startValue);
         if (rule != Validate.XOR) {
-            System.err.println("Programmer error: input rule should be XOR for this Input constructor");
+            Log.err.println("Programmer error: input rule should be XOR for this Input constructor");
         }
         this.rule = rule;
         this.other = other;
@@ -145,8 +149,8 @@ public class Input<T> {
     /**
      * constructor for List<> with XOR rules with type specified
      */
-    public Input(String sName, String sTipText, T startValue, Validate rule, Input<?> other, Class<?> theClass) {
-        this(sName, sTipText, startValue, rule, other);
+    public Input(String name, String tipText, T startValue, Validate rule, Input<?> other, Class<?> theClass) {
+        this(name, tipText, startValue, rule, other);
         this.theClass = theClass;
     } // c'tor
 
@@ -156,11 +160,11 @@ public class Input<T> {
      * at least one value to be specified.
      * If optional (i.e. no value need to be specified), leave the rule out
      */
-    public Input(String sName, String sTipText, T startValue, Validate rule) {
-        this(sName, sTipText, startValue);
+    public Input(String name, String tipText, T startValue, Validate rule) {
+        this(name, tipText, startValue);
         /*if (rule != Validate.REQUIRED) {
-            System.err.println("Programmer error: input rule should be REQUIRED for this Input constructor"
-                    + " (" + sName + ")");
+            Log.err.println("Programmer error: input rule should be REQUIRED for this Input constructor"
+                    + " (" + name + ")");
         }*/
         this.rule = rule;
     } // c'tor
@@ -168,19 +172,19 @@ public class Input<T> {
     /**
      * constructor for REQUIRED rules for List-inputs, with type pre-specified
      */
-    public Input(String sName, String sTipText, T startValue, Validate rule, Class<?> type) {
-        this(sName, sTipText, startValue, rule);
+    public Input(String name, String tipText, T startValue, Validate rule, Class<?> type) {
+        this(name, tipText, startValue, rule);
         theClass = type;
     } // c'tor
 
     /**
      * constructor for REQUIRED rules
      */
-    public Input(String sName, String sTipText, Validate rule) {
-        this(sName, sTipText);
+    public Input(String name, String tipText, Validate rule) {
+        this(name, tipText);
         if (rule != Validate.REQUIRED) {
-            System.err.println("Programmer error: input rule should be REQUIRED for this Input constructor"
-                    + " (" + sName + ")");
+            Log.err.println("Programmer error: input rule should be REQUIRED for this Input constructor"
+                    + " (" + name + ")");
         }
         this.rule = rule;
     } // c'tor
@@ -188,18 +192,18 @@ public class Input<T> {
     /**
      * constructor for REQUIRED rules, with type pre-specified
      */
-    public Input(String sName, String sTipText, Validate rule, Class<?> type) {
-        this(sName, sTipText, rule);
+    public Input(String name, String tipText, Validate rule, Class<?> type) {
+        this(name, tipText, rule);
         this.theClass = type;
     }
 
     /**
      * constructor for XOR rules *
      */
-    public Input(String sName, String sTipText, Validate rule, Input<?> other) {
-        this(sName, sTipText);
+    public Input(String name, String tipText, Validate rule, Input<?> other) {
+        this(name, tipText);
         if (rule != Validate.XOR) {
-            System.err.println("Programmer error: input rule should be XOR for this Input constructor");
+            Log.err.println("Programmer error: input rule should be XOR for this Input constructor");
         }
         this.rule = rule;
         this.other = other;
@@ -210,8 +214,8 @@ public class Input<T> {
     /**
      * constructor for XOR rules, with type pre-specified
      */
-    public Input(String sName, String sTipText, Validate rule, Input<?> other, Class<?> type) {
-        this(sName, sTipText, rule, other);
+    public Input(String name, String tipText, Validate rule, Input<?> other, Class<?> type) {
+        this(name, tipText, rule, other);
         this.theClass = type;
     }
 
@@ -222,12 +226,12 @@ public class Input<T> {
      * the value optional? When providing a 'no-input' entry in the list and setting that as the default,
      * that should cover that situation.)
      */
-    public Input(String sName, String sTipText, T startValue, T[] sPossibleValues) {
-        name = sName;
-        tipText = sTipText;
+    public Input(String name, String tipText, T startValue, T[] possibleValues) {
+        this.name = name;
+        this.tipText = tipText;
         value = startValue;
         defaultValue = startValue;
-        possibleValues = sPossibleValues;
+        this.possibleValues = possibleValues;
         checkName();
     } // c'tor
 
@@ -239,9 +243,9 @@ public class Input<T> {
                 name.toLowerCase().equals("idref") ||
                 name.toLowerCase().equals("spec") ||
                 name.toLowerCase().equals("name")) {
-            System.err.println("Found an input with invalid name: " + name);
-            System.err.println("'id', 'idref', 'spec' and 'name' are reserved and cannot be used");
-            System.exit(0);
+        	Log.err.println("Found an input with invalid name: " + name);
+        	Log.err.println("'id', 'idref', 'spec' and 'name' are reserved and cannot be used");
+            System.exit(1);
         }
     }
 
@@ -273,6 +277,9 @@ public class Input<T> {
         if (theClass == Double.class) {
             return ("<double>");
         }
+        if (theClass == Float.class) {
+            return ("<float>");
+        }
         if (theClass == String.class) {
             return "<string>";
         }
@@ -301,7 +308,7 @@ public class Input<T> {
         this.rule = rule;
     }
 
-    public Input<?> getOther() {
+    final public Input<?> getOther() {
         return other;
     }
 
@@ -379,15 +386,14 @@ public class Input<T> {
      * Otherwise, m_value is assigned to value.
      *
      * @param value
-     * @param plugin
-     * @throws Exception
+     * @param beastObject
      */
     @SuppressWarnings("unchecked")
-    public void setValue(final Object value, final BEASTInterface plugin) {
+    public void setValue(final Object value, final BEASTInterface beastObject) {
         if (value == null) {
             if (this.value != null) {
                 if (this.value instanceof BEASTInterface) {
-                    ((BEASTInterface) this.value).getOutputs().remove(plugin);
+                    ((BEASTInterface) this.value).getOutputs().remove(beastObject);
                 }
             }
             this.value = null;
@@ -395,19 +401,19 @@ public class Input<T> {
         }
         if (theClass == null) {
             try {
-                determineClass(plugin);
+                determineClass(beastObject);
             } catch (Exception e) {
                 e.printStackTrace();
-                throw new RuntimeException("Failed to determine class of beastobject id=" + plugin.getID());
+                throw new RuntimeException("Failed to determine class of beastobject id=" + beastObject.getID());
             }
         }
         if (value instanceof String) {
             try {
-                setStringValue((String) value, plugin);
+                setStringValue((String) value, beastObject);
             } catch (Exception e) {
                 e.printStackTrace();
-            	Log.warning.println("Failed to set the string value to '" + value + "' for beastobject id=" + plugin.getID());
-                throw new RuntimeException("Failed to set the string value to '" + value + "' for beastobject id=" + plugin.getID());
+            	Log.warning.println("Failed to set the string value to '" + value + "' for beastobject id=" + beastObject.getID());
+                throw new RuntimeException("Failed to set the string value to '" + value + "' for beastobject id=" + beastObject.getID());
             }
         } else if (this.value != null && this.value instanceof List<?>) {
             if (theClass.isAssignableFrom(value.getClass())) {
@@ -424,7 +430,7 @@ public class Input<T> {
 //                }
                 vector.add(value);
                 if (value instanceof BEASTInterface) {
-                    ((BEASTInterface) value).getOutputs().add(plugin);
+                    ((BEASTInterface) value).getOutputs().add(beastObject);
                 }
             } else if (value instanceof List<?> && theClass.isAssignableFrom(((List<?>) value).get(0).getClass())) {
                 // add all elements in given list to input list.
@@ -433,7 +439,7 @@ public class Input<T> {
                 for (Object v : ((List<?>) value)) {
                     vector.add(v);
                     if (v instanceof BEASTInterface) {
-                        ((BEASTInterface) v).getOutputs().add(plugin);
+                        ((BEASTInterface) v).getOutputs().add(beastObject);
                     }
                 }
             } else {
@@ -445,9 +451,9 @@ public class Input<T> {
             if (theClass.isAssignableFrom(value.getClass())) {
                 if (value instanceof BEASTInterface) {
                     if (this.value != null) {
-                        ((BEASTInterface) this.value).getOutputs().remove(plugin);
+                        ((BEASTInterface) this.value).getOutputs().remove(beastObject);
                     }
-                    ((BEASTInterface) value).getOutputs().add(plugin);
+                    ((BEASTInterface) value).getOutputs().add(beastObject);
                 }
                 this.value = (T) value;
             } else {
@@ -465,17 +471,17 @@ public class Input<T> {
      * It is best for Beauti to throw an Exception from canSetName() with some
      * diagnostic info when the value cannot be set.
      */
-    public boolean canSetValue(Object value, BEASTInterface plugin) {
+    public boolean canSetValue(Object value, BEASTInterface beastObject) {
         String inputName = new String(name.charAt(0) + "").toUpperCase() + name.substring(1);
         try {
-            Method method = plugin.getClass().getMethod("canSet" + inputName, Object.class);
-            //System.err.println("Calling method " + plugin.getClass().getName() +"."+ method.getName());
-            Object o = method.invoke(plugin, value);
+            Method method = beastObject.getClass().getMethod("canSet" + inputName, Object.class);
+            //System.err.println("Calling method " + beastObject.getClass().getName() +"."+ method.getName());
+            Object o = method.invoke(beastObject, value);
             return (Boolean) o;
         } catch (java.lang.NoSuchMethodException e) {
             return true;
         } catch (java.lang.reflect.InvocationTargetException e) {
-            System.err.println(plugin.getClass().getName() + "." + getName() + ": " + e.getCause());
+        	Log.warning.println(beastObject.getClass().getName() + "." + getName() + ": " + e.getCause());
 
             if (e.getCause() != null) {
                 throw new RuntimeException(e.getCause().getMessage());
@@ -483,7 +489,7 @@ public class Input<T> {
             return false;
         } catch (IllegalAccessException e) {
             e.printStackTrace();
-            throw new RuntimeException("Illegal method access attempted on beastobject id=" + plugin.getID());
+            throw new RuntimeException("Illegal method access attempted on beastobject id=" + beastObject.getID());
         }
     }
 
@@ -493,16 +499,15 @@ public class Input<T> {
      * If T is a vector, i.e. Input<List<S>>, the actual value of S
      * is assigned instead
      *
-     * @param plugin whose type is to be determined
-     * @throws Exception
+     * @param beastObject whose type is to be determined
      */
-    public void determineClass(final Object plugin) throws Exception {
+    public void determineClass(final Object beastObject) {
         try {
-            final Field[] fields = plugin.getClass().getFields();
-            // find this input in the plugin
+            final Field[] fields = beastObject.getClass().getFields();
+            // find this input in the beastObject
             for (int i = 0; i < fields.length; i++) {
                 if (fields[i].getType().isAssignableFrom(Input.class)) {
-                    Input<?> input = (Input<?>) fields[i].get(plugin);
+                    final Input<?> input = (Input<?>) fields[i].get(beastObject);
                     if (input == this) {
                         // found the input, now determine the type of the input
                         Type t = fields[i].getGenericType();
@@ -512,8 +517,13 @@ public class Input<T> {
                         // to determine the type (that I know of...)
                         if (value != null && value instanceof List<?>) {
                             Type[] genericTypes2 = ((ParameterizedType) genericTypes[0]).getActualTypeArguments();
-                            theClass = (Class<?>) genericTypes2[0];
-                            // gettting type of map is not possible?!?
+                            try {
+                            	theClass = (Class<?>) genericTypes2[0];
+                            } catch (ClassCastException e) {
+                            	// can get here with parameterised types, e.g Input<List<Parameter.Base<T>>>
+                            	theClass = (Class<?>) ((ParameterizedType)genericTypes2[0]).getRawType();
+                            }
+                            // getting type of map is not possible?!?
                             //} else if (value != null && value instanceof Map<?,?>) {
                             //    Type[] genericTypes2 = ((ParameterizedType) genericTypes[0]).getActualTypeArguments();
                             //    theClass = (Class<?>) genericTypes2[0];
@@ -523,27 +533,27 @@ public class Input<T> {
                             	Object o = genericTypes[0];
                             	if (o instanceof ParameterizedType) {
                                     Type rawType = ((ParameterizedType) genericTypes[0]).getRawType();
-                                    System.err.println(rawType.getTypeName());
+                                    // Log.warning.println(rawType.getTypeName());
                             		if (rawType.getTypeName().equals("java.util.List")) {
                             			// if we got here, value==null
-                            			throw new Exception("Programming error: Input<List> not initialised");
+                            			throw new RuntimeException("Programming error: Input<List> not initialised");
                             		}
                             	}
                                 theClass = (Class<?>) o;
                             } catch (Exception e) {
                                 // resolve ID
                                 String id = "";
-                                Method method = plugin.getClass().getMethod("getID");
+                                Method method = beastObject.getClass().getMethod("getID");
                                 if (method != null) {
-                                    id = (String) method.invoke(plugin);
+                                    id = (String) method.invoke(beastObject);
                                 }
                                 // assemble error message
-                                System.err.println(plugin.getClass().getName() + " " + id + " failed. " +
-                                        "Possibly template or abstract Plugin used " +
+                                Log.err.println(beastObject.getClass().getName() + " " + id + " failed. " +
+                                        "Possibly template or abstract BEASTObject used " +
                                         "or if it is a list, the list was not initilised???");
-                                System.err.println("class is " + plugin.getClass());
+                                Log.err.println("class is " + beastObject.getClass());
                                 e.printStackTrace(System.err);
-                                System.exit(0);
+                                System.exit(1);
                             }
                         }
                         break;
@@ -559,63 +569,74 @@ public class Input<T> {
      * Try to parse value of string into Integer, Double or Boolean,
      * or it this types differs, just assign as string.
      *
-     * @param sValue value representation
-     * @throws Exception when all conversions fail
+     * @param stringValue value representation
+     * @throws IllegalArgumentException when all conversions fail
      */
     @SuppressWarnings({"unchecked", "rawtypes"})
-    private void setStringValue(final String sValue, final BEASTInterface plugin) throws Exception {
+    private void setStringValue(final String stringValue, final BEASTInterface beastObject) {
         // figure out the type of T and create object based on T=Integer, T=Double, T=Boolean, T=Valuable
         if (value instanceof List<?>) {
             List list = (List) value;
             list.clear();
             // remove start and end spaces
-            String sValue2 = sValue.replaceAll("^\\s+", "");
-            sValue2 = sValue2.replaceAll("\\s+$", "");
+            String stringValue2 = stringValue.replaceAll("^\\s+", "");
+            stringValue2 = stringValue2.replaceAll("\\s+$", "");
             // split into space-separated bits
-            String[] sValues = sValue2.split("\\s+");
-            for (int i = 0; i < sValues.length; i++) {
+            String[] stringValues = stringValue2.split("\\s+");
+            for (int i = 0; i < stringValues.length; i++) {
                 if (theClass.equals(Integer.class)) {
-                    list.add(new Integer(sValues[i % sValues.length]));
+                    list.add(new Integer(stringValues[i % stringValues.length]));
                 } else if (theClass.equals(Double.class)) {
-                    list.add(new Double(sValues[i % sValues.length]));
+                    list.add(new Double(stringValues[i % stringValues.length]));
                 } else if (theClass.equals(Boolean.class)) {
-                    String str = sValues[i % sValues.length].toLowerCase();
+                    String str = stringValues[i % stringValues.length].toLowerCase();
                     list.add(str.equals("1") || str.equals("true") || str.equals("yes"));
                 } else if (theClass.equals(String.class)) {
-                    list.add(new String(sValues[i % sValues.length]));
+                    list.add(new String(stringValues[i % stringValues.length]));
                 }
             }
             return;
         }
 
         if (theClass.equals(Integer.class)) {
-            value = (T) new Integer(sValue);
+            value = (T) new Integer(stringValue);
+            return;
+        }
+        if (theClass.equals(Long.class)) {
+            value = (T) new Long(stringValue);
             return;
         }
         if (theClass.equals(Double.class)) {
-            value = (T) new Double(sValue);
+            value = (T) new Double(stringValue);
+            return;
+        }
+        if (theClass.equals(Float.class)) {
+            value = (T) new Float(stringValue);
             return;
         }
         if (theClass.equals(Boolean.class)) {
-            final String sValue2 = sValue.toLowerCase();
-            if (sValue2.equals("yes") || sValue2.equals("true")) {
-                value = (T) Boolean.TRUE;
-                return;
-            } else if (sValue2.equals("no") || sValue2.equals("false")) {
-                value = (T) Boolean.FALSE;
-                return;
-            }
+        	// RRB why the local parsing instead of using the Boolean c'tor?
+//            final String valueString2 = stringValue.toLowerCase();
+//            if (valueString2.equals("yes") || valueString2.equals("true")) {
+//                value = (T) Boolean.TRUE;
+//                return;
+//            } else if (valueString2.equals("no") || valueString2.equals("false")) {
+//                value = (T) Boolean.FALSE;
+//                return;
+//            }
+        	value = (T) new Boolean(stringValue);
+        	return;
         }
         if (theClass.equals(Function.class)) {
             final RealParameter param = new RealParameter();
-            param.initByName("value", sValue, "upper", 0.0, "lower", 0.0, "dimension", 1);
+            param.initByName("value", stringValue, "upper", 0.0, "lower", 0.0, "dimension", 1);
             param.initAndValidate();
             if (value != null && value instanceof List) {
                 ((List) value).add(param);
             } else {
                 value = (T) param;
             }
-            param.getOutputs().add(plugin);
+            param.getOutputs().add(beastObject);
             return;
         }
 
@@ -624,34 +645,34 @@ public class Input<T> {
         		possibleValues = (T[]) theClass.getDeclaringClass().getEnumConstants();
         	}
             for (final T t : possibleValues) {
-                if (sValue.equals(t.toString())) {
+                if (stringValue.equals(t.toString())) {
                     value = t;
                     return;
                 }
             }
-            throw new Exception("Input 104: value " + sValue + " not found. Select one of " + Arrays.toString(possibleValues));
+            throw new IllegalArgumentException("Input 104: value " + stringValue + " not found. Select one of " + Arrays.toString(possibleValues));
         }
 
         // call a string constructor of theClass
         try {
             Constructor ctor;
-            Object v = sValue;
+            Object v = stringValue;
             try {
             	ctor = theClass.getDeclaredConstructor(String.class);
             } catch (NoSuchMethodException e) {
             	// we get here if there is not String constructor
             	// try integer constructor instead
             	try {
-            		if (sValue.startsWith("0x")) {
-            			v = Integer.parseInt(sValue.substring(2), 16);
+            		if (stringValue.startsWith("0x")) {
+            			v = Integer.parseInt(stringValue.substring(2), 16);
             		} else {
-            			v = Integer.parseInt(sValue);
+            			v = Integer.parseInt(stringValue);
             		}
                 	ctor = theClass.getDeclaredConstructor(int.class);
                 	
             	} catch (NumberFormatException e2) {
                 	// could not parse as integer, try double instead
-            		v = Double.parseDouble(sValue);
+            		v = Double.parseDouble(stringValue);
                 	ctor = theClass.getDeclaredConstructor(double.class);
             	}
             }
@@ -663,11 +684,11 @@ public class Input<T> {
                 value = (T) o;
             }
             if (o instanceof BEASTInterface) {
-                ((BEASTInterface) o).getOutputs().add(plugin);
+                ((BEASTInterface) o).getOutputs().add(beastObject);
             }
         } catch (Exception e) {
-            throw new Exception("Input 103: type mismatch, cannot initialize input '" + getName() +
-                    "' with value '" + sValue + "'.\nExpected something of type " + getType().getName() +
+            throw new IllegalArgumentException("Input 103: type mismatch, cannot initialize input '" + getName() +
+                    "' with value '" + stringValue + "'.\nExpected something of type " + getType().getName() +
                     ". " + (e.getMessage() != null ? e.getMessage() : ""));
         }
     } // setStringValue
@@ -675,19 +696,18 @@ public class Input<T> {
     /**
      * validate input according to validation rule *
      *
-     * @throws Exception when validation fails. why not return a string?
      */
-    public void validate() throws Exception {
+    public void validate() {
         if (possibleValues != null) {
             // it is an enumeration, check the value is in the list
-            boolean bFound = false;
+            boolean found = false;
             for (final T value : possibleValues) {
                 if (value.equals(this.value)) {
-                    bFound = true;
+                    found = true;
                 }
             }
-            if (!bFound) {
-                throw new Exception("Expected one of " + Arrays.toString(possibleValues) + " but got " + this.value);
+            if (!found) {
+                throw new IllegalArgumentException("Expected one of " + Arrays.toString(possibleValues) + " but got " + this.value);
             }
         }
 
@@ -697,22 +717,22 @@ public class Input<T> {
                 break;
             case REQUIRED:
                 if (get() == null) {
-                    throw new Exception("Input '" + getName() + "' must be specified.");
+                    throw new IllegalArgumentException("Input '" + getName() + "' must be specified.");
                 }
                 if (get() instanceof List<?>) {
                     if (((List<?>) get()).size() == 0) {
-                        throw new Exception("At least one input of name '" + getName() + "' must be specified.");
+                        throw new IllegalArgumentException("At least one input of name '" + getName() + "' must be specified.");
                     }
                 }
                 break;
             case XOR:
                 if (get() == null) {
                     if (other.get() == null) {
-                        throw new Exception("Either input '" + getName() + "' or '" + other.getName() + "' needs to be specified");
+                        throw new IllegalArgumentException("Either input '" + getName() + "' or '" + other.getName() + "' needs to be specified");
                     }
                 } else {
                     if (other.get() != null) {
-                        throw new Exception("Only one of input '" + getName() + "' and '" + other.getName() + "' must be specified (not both)");
+                        throw new IllegalArgumentException("Only one of input '" + getName() + "' and '" + other.getName() + "' must be specified (not both)");
                     }
                 }
                 // noting to do
@@ -720,10 +740,10 @@ public class Input<T> {
             case FORBIDDEN:
                 if (get() instanceof List<?>) {
                     if (((List<?>) get()).size() > 0) {
-                        throw new Exception("No input of name '" + getName() + "' must be specified.");
+                        throw new IllegalArgumentException("No input of name '" + getName() + "' must be specified.");
                     }
                 } else if (get() != null) {
-                    throw new Exception("Input '" + getName() + "' must not be specified.");
+                    throw new IllegalArgumentException("Input '" + getName() + "' must not be specified.");
                 }
                 break;
         }
diff --git a/src/beast/core/InputForAnnotatedConstructor.java b/src/beast/core/InputForAnnotatedConstructor.java
new file mode 100644
index 0000000..3dfcd04
--- /dev/null
+++ b/src/beast/core/InputForAnnotatedConstructor.java
@@ -0,0 +1,277 @@
+package beast.core;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+
+import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
+
+ at Description("Emulates the behaviour of an Input for constructors annotated with Param annotations.")
+public class InputForAnnotatedConstructor<T> extends Input<T> {
+	
+	/** BEAST object for which to emulate this Input **/
+	BEASTInterface beastObject;
+	
+	/** get and set methods **/
+	Method getter, setter;
+	
+	
+	public InputForAnnotatedConstructor(BEASTInterface beastObject, Class<?> theClass, Param param) throws NoSuchMethodException, SecurityException,  IllegalArgumentException  {
+		if (beastObject == null) {
+			throw new NullPointerException();
+		}
+		this.beastObject = beastObject;
+		
+		if (theClass == null) {
+			throw new NullPointerException();
+		}
+		this.theClass = theClass;
+		
+		// TODO: handle defaultValue from Param annotations
+		// this.defaultValue = param.defaultValue();
+		if (param.description().trim().length() == 0) {
+			Log.warning.println("Param annotation found without proper description " + param.toString());
+		}
+		this.tipText = param.description();
+		
+		if (name == null) {
+			throw new NullPointerException();
+		}
+		this.name = param.name();
+
+		this.rule = param.optional() ? Validate.OPTIONAL : Validate.REQUIRED;
+		
+		String methodName = "get" + 
+		    	name.substring(0, 1).toUpperCase() +
+		    	name.substring(1);
+		try {
+			getter = beastObject.getClass().getMethod(methodName);
+		} catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) {
+			Log.err.println("Programmer error: when getting here an InputType was identified, but no getter for Param annotation found");
+			throw e;
+		}
+
+		methodName = "set" + 
+		    	name.substring(0, 1).toUpperCase() +
+		    	name.substring(1);
+		try {
+			setter = beastObject.getClass().getMethod(methodName, theClass);
+		} catch (NoSuchMethodException | SecurityException | IllegalArgumentException e) {
+			Log.err.println("Programmer error: when getting here an InputType was identified, but no setter for Param annotation found");
+			throw e;
+		}
+	}
+	
+	@Override
+	public void setValue(Object value, BEASTInterface beastObject) {
+        if (value == null) {
+            if (this.value != null) {
+                if (this.value instanceof BEASTInterface) {
+                    ((BEASTInterface) this.value).getOutputs().remove(beastObject);
+                }
+            }
+            setValue(null);
+            return;
+        }
+        if (value instanceof String) {
+            try {
+                setStringValue((String) value);
+            } catch (Exception e) {
+                e.printStackTrace();
+            	Log.warning.println("Failed to set the string value to '" + value + "' for beastobject id=" + beastObject.getID());
+                throw new RuntimeException("Failed to set the string value to '" + value + "' for beastobject id=" + beastObject.getID());
+            }
+        } else if (this.value != null && this.value instanceof List<?>) {
+            if (theClass.isAssignableFrom(value.getClass())) {
+//              // don't insert duplicates
+                // RRB: DO insert duplicates: this way CompoundValuable can be set up to 
+                // contain rate matrices with dependent variables/parameters.
+                // There does not seem to be an example where a duplicate insertion is a problem...
+//                for (Object o : vector) {
+//                    if (o.equals(value)) {
+//                        return;
+//                    }
+//                }
+                setValue(value);
+                if (value instanceof BEASTInterface) {
+                    ((BEASTInterface) value).getOutputs().add(beastObject);
+                }
+            } else if (value instanceof List<?> && theClass.isAssignableFrom(((List<?>) value).get(0).getClass())) {
+                // add all elements in given list to input list.
+                for (Object v : ((List<?>) value)) {
+                    setValue(v);
+                    if (v instanceof BEASTInterface) {
+                        ((BEASTInterface) v).getOutputs().add(beastObject);
+                    }
+                }
+            } else {
+                throw new RuntimeException("Input 101: type mismatch for input " + getName() +
+                        ". " + theClass.getName() + ".isAssignableFrom(" + value.getClass() + ")=false");
+            }
+
+        } else {
+            if (theClass.isAssignableFrom(value.getClass())) {
+                if (value instanceof BEASTInterface) {
+                    if (this.value != null) {
+                        ((BEASTInterface) this.value).getOutputs().remove(beastObject);
+                    }
+                    ((BEASTInterface) value).getOutputs().add(beastObject);
+                }
+                setValue(value);
+            } else {
+                throw new RuntimeException("Input 102: type mismatch for input " + getName());
+            }
+        }
+	}
+
+	
+	private void setValue(Object value) {
+		try {
+			setter.invoke(beastObject, value);
+			if (value instanceof BEASTInterface) {
+	              ((BEASTInterface) value).getOutputs().add(beastObject);
+			}
+		} catch (IllegalAccessException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IllegalArgumentException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (InvocationTargetException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+	}
+
+    /**
+     * Try to parse value of string into Integer, Double or Boolean,
+     * or it this types differs, just assign as string.
+     *
+     * @param valueString value representation
+     * @throws IllegalArgumentException when all conversions fail
+     */
+    @SuppressWarnings({"unchecked", "rawtypes"})
+    private void setStringValue(final String valueString) {
+        // figure out the type of T and create object based on T=Integer, T=Double, T=Boolean, T=Valuable
+        if (value instanceof List<?>) {
+            List list = (List) get();
+            list.clear();
+            // remove start and end spaces
+            String valueString2 = valueString.replaceAll("^\\s+", "");
+            valueString2 = valueString2.replaceAll("\\s+$", "");
+            // split into space-separated bits
+            String[] valuesString = valueString2.split("\\s+");
+            for (int i = 0; i < valuesString.length; i++) {
+                if (theClass.equals(Integer.class)) {
+                    list.add(new Integer(valuesString[i % valuesString.length]));
+                } else if (theClass.equals(Double.class)) {
+                    list.add(new Double(valuesString[i % valuesString.length]));
+                } else if (theClass.equals(Boolean.class)) {
+                    String str = valuesString[i % valuesString.length].toLowerCase();
+                    list.add(str.equals("1") || str.equals("true") || str.equals("yes"));
+                } else if (theClass.equals(String.class)) {
+                    list.add(new String(valuesString[i % valuesString.length]));
+                }
+            }
+            return;
+        }
+
+        if (theClass.equals(Integer.class)) {
+            setValue(new Integer(valueString));
+            return;
+        }
+        if (theClass.equals(Double.class)) {
+        	setValue(new Double(valueString));
+            return;
+        }
+        if (theClass.equals(Boolean.class)) {
+            final String valueString2 = valueString.toLowerCase();
+            if (valueString2.equals("yes") || valueString2.equals("true")) {
+            	setValue(Boolean.TRUE);
+                return;
+            } else if (valueString2.equals("no") || valueString2.equals("false")) {
+            	setValue(Boolean.FALSE);
+                return;
+            }
+        }
+        if (theClass.equals(Function.class)) {
+            final RealParameter param = new RealParameter();
+            param.initByName("value", valueString, "upper", 0.0, "lower", 0.0, "dimension", 1);
+            param.initAndValidate();
+        	setValue(param);
+            param.getOutputs().add(beastObject);
+            return;
+        }
+
+        if (theClass.isEnum()) {
+        	if (possibleValues == null) {
+        		possibleValues = (T[]) theClass.getDeclaringClass().getEnumConstants();
+        	}
+            for (final T t : possibleValues) {
+                if (valueString.equals(t.toString())) {
+                	setValue(t);
+                    return;
+                }
+            }
+            throw new IllegalArgumentException("Input 104: value " + valueString + " not found. Select one of " + Arrays.toString(possibleValues));
+        }
+
+        // call a string constructor of theClass
+        try {
+            Constructor ctor;
+            Object v = valueString;
+            try {
+            	ctor = theClass.getDeclaredConstructor(String.class);
+            } catch (NoSuchMethodException e) {
+            	// we get here if there is not String constructor
+            	// try integer constructor instead
+            	try {
+            		if (valueString.startsWith("0x")) {
+            			v = Integer.parseInt(valueString.substring(2), 16);
+            		} else {
+            			v = Integer.parseInt(valueString);
+            		}
+                	ctor = theClass.getDeclaredConstructor(int.class);
+                	
+            	} catch (NumberFormatException e2) {
+                	// could not parse as integer, try double instead
+            		v = Double.parseDouble(valueString);
+                	ctor = theClass.getDeclaredConstructor(double.class);
+            	}
+            }
+            ctor.setAccessible(true);
+            final Object o = ctor.newInstance(v);
+            setValue(o);
+            if (o instanceof BEASTInterface) {
+                ((BEASTInterface) o).getOutputs().add(beastObject);
+            }
+        } catch (Exception e) {
+            throw new IllegalArgumentException("Input 103: type mismatch, cannot initialize input '" + getName() +
+                    "' with value '" + valueString + "'.\nExpected something of type " + getType().getName() +
+                    ". " + (e.getMessage() != null ? e.getMessage() : ""));
+        }
+    } // setStringValue
+
+	
+	@SuppressWarnings("unchecked")
+	@Override
+	public T get() {
+		try {
+			return (T) getter.invoke(beastObject);
+		} catch (IllegalAccessException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IllegalArgumentException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (InvocationTargetException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+
+}
diff --git a/src/beast/core/Loggable.java b/src/beast/core/Loggable.java
index 67735fe..aa59e43 100644
--- a/src/beast/core/Loggable.java
+++ b/src/beast/core/Loggable.java
@@ -17,18 +17,17 @@ public interface Loggable {
      * or Nexus tree preamble
      *
      * @param out log stream
-     * @throws Exception
      */
-    void init(PrintStream out) throws Exception;
+    void init(PrintStream out);
 
     /**
      * log this sample for current state to PrintStream,
      * e.g. value of a parameter, list of parameters or Newick tree
      *
-     * @param nSample chain sample number
+     * @param sample chain sample number
      * @param out     log stream
      */
-    void log(int nSample, PrintStream out);
+    void log(int sample, PrintStream out);
 
     /**
      * close log. An end of log message can be left (as in End; for Nexus trees)
diff --git a/src/beast/core/Logger.java b/src/beast/core/Logger.java
index c312bdc..c652f67 100644
--- a/src/beast/core/Logger.java
+++ b/src/beast/core/Logger.java
@@ -26,19 +26,26 @@ package beast.core;
 
 
 
-import beast.core.Input.Validate;
-import beast.core.util.Log;
-import beast.evolution.tree.Tree;
-import beast.util.XMLProducer;
-
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.io.UnsupportedEncodingException;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.List;
 
+import beast.core.Input.Validate;
+import beast.core.util.Log;
+import beast.evolution.tree.Tree;
+import beast.util.XMLProducer;
+
 
 @Description("Logs results of a calculation processes on regular intervals.")
 public class Logger extends BEASTObject {
@@ -53,19 +60,19 @@ public class Logger extends BEASTObject {
         none, alphabetic, smart
     }
 
-    public Input<String> fileNameInput = new Input<String>("fileName", "Name of the file, or stdout if left blank");
+    final public Input<String> fileNameInput = new Input<>("fileName", "Name of the file, or stdout if left blank");
 
-    public Input<Integer> everyInput = new Input<Integer>("logEvery", "Number of the samples logged", 1);
-    public Input<BEASTObject> modelInput = new Input<BEASTObject>("model", "Model to log at the top of the log. " +
+    final public Input<Integer> everyInput = new Input<>("logEvery", "Number of the samples logged", 1);
+    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. ");
-    public Input<LOGMODE> modeInput = new Input<LOGMODE>("mode", "logging mode, one of " + LOGMODE.values(), LOGMODE.autodetect, LOGMODE.values());
-    public Input<SORTMODE> sortModeInput = new Input<SORTMODE>("sort", "sort items to be logged, one of " + SORTMODE.values(), SORTMODE.none, SORTMODE.values());
-    public Input<Boolean> sanitiseHeadersInput = new Input<Boolean>("sanitiseHeaders", "whether to remove any clutter introduced by Beauti" , false);
+    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<Boolean> sanitiseHeadersInput = new Input<>("sanitiseHeaders", "whether to remove any clutter introduced by Beauti" , false);
 
-    public Input<List<BEASTObject>> loggersInput = new Input<List<BEASTObject>>("log",
+    final public Input<List<BEASTObject>> loggersInput = new Input<>("log",
             "Element in a log. This can be any plug in that is Loggable.",
-            new ArrayList<BEASTObject>(), Validate.REQUIRED, Loggable.class);
+            new ArrayList<>(), Validate.REQUIRED, Loggable.class);
 
     // the file name to log to, or null, or "" if logging to stdout
     private String fileName;
@@ -107,63 +114,61 @@ public class Logger extends BEASTObject {
     int startSample;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
 
         fileName = fileNameInput.get();
 
         final List<BEASTObject> loggers = loggersInput.get();
-        final int nLoggers = loggers.size();
-        if (nLoggers == 0) {
-            throw new Exception("Logger with nothing to log specified");
+        final int loggerCount = loggers.size();
+        if (loggerCount == 0) {
+            throw new RuntimeException("Logger with nothing to log specified");
         }
 
-        loggerList = new ArrayList<Loggable>();
+        loggerList = new ArrayList<>();
         for (final BEASTObject logger : loggers) {
             loggerList.add((Loggable) logger);
         }
 
         // determine logging mode
-        final LOGMODE sMode = modeInput.get();
-        if (sMode.equals(LOGMODE.autodetect)) {
-            mode = LOGMODE.compound;
-            if (nLoggers == 1 && loggerList.get(0) instanceof Tree) {
-                mode = LOGMODE.tree;
+        final LOGMODE mode = modeInput.get();
+        if (mode.equals(LOGMODE.autodetect)) {
+            this.mode = LOGMODE.compound;
+            if (loggerCount == 1 && loggerList.get(0) instanceof Tree) {
+            	this.mode = LOGMODE.tree;
             }
-        } else if (sMode.equals(LOGMODE.tree)) {
-            mode = LOGMODE.tree;
-        } else if (sMode.equals(LOGMODE.compound)) {
-            mode = LOGMODE.compound;
+        } else if (mode.equals(LOGMODE.tree)) {
+        	this.mode = LOGMODE.tree;
+        } else if (mode.equals(LOGMODE.compound)) {
+        	this.mode = LOGMODE.compound;
         } else {
-            throw new Exception("Mode '" + sMode + "' is not supported. Choose one of " + LOGMODE.values());
+            throw new IllegalArgumentException("Mode '" + mode + "' is not supported. Choose one of " + LOGMODE.values());
         }
 
         if (everyInput.get() != null) {
             every = everyInput.get();
         }
         
-        if (mode == LOGMODE.compound) {
+        if (this.mode == LOGMODE.compound) {
         	switch (sortModeInput.get()) {
         	case none:
         		// nothing to do
        			break;
         	case alphabetic:
         		// sort loggers by id
-        		Collections.sort(loggerList, new Comparator<Loggable>() {
-					@Override
-					public int compare(final Loggable o1, final Loggable o2) {
+        		Collections.sort(loggerList, (Loggable o1, Loggable o2) -> {
 						final String id1 = ((BEASTObject)o1).getID();
 						final String id2 = ((BEASTObject)o2).getID();  //was o1, probably a bug, found by intelliJ
 						if (id1 == null || id2 == null) {return 0;}
 						return id1.compareTo(id2);
 					}
-				});
+				);
     			break;
         	case smart:
         		// Group loggers with same id-prefix, where the prefix of an id is
         		// defined as the part of an id before the first full stop.
         		// This way, multi-partition analysis generated by BEAUti get all  
         		// related log items together in Tracer
-        		final List<String> ids = new ArrayList<String>();
+        		final List<String> ids = new ArrayList<>();
                 for (final Loggable aLoggerList : loggerList) {
                     String id = ((BEASTObject) aLoggerList).getID();
                     if (id == null) {
@@ -202,15 +207,15 @@ public class Logger extends BEASTObject {
     /**
      * initialise log, open file (if necessary) and produce header of log
      */
-    public void init() throws Exception {
+    public void init() throws IOException {
         final boolean needsHeader = openLogFile();
         if (needsHeader) {
             if (modelInput.get() != null) {
                 // print model at top of log
-                String sXML = new XMLProducer().modelToXML(modelInput.get());
-                sXML = "#" + sXML.replaceAll("\\n", "\n#");
+                String xml = new XMLProducer().modelToXML(modelInput.get());
+                xml = "#" + xml.replaceAll("\\n", "\n#");
                 m_out.println("#\n#model:\n#");
-                m_out.println(sXML);
+                m_out.println(xml);
                 m_out.println("#");
             }
             ByteArrayOutputStream baos = null;
@@ -321,7 +326,7 @@ public class Logger extends BEASTObject {
 	}
 
 
-	boolean openLogFile() throws Exception {
+	boolean openLogFile() throws IOException {
         if (isLoggingToStdout()) {
             m_out = System.out;
             return true;
@@ -353,13 +358,13 @@ public class Logger extends BEASTObject {
                             //System.exit(0);
                         }
                         // Check with user what to do next
-                        System.out.println("Trying to write file " + fileName + " but the file already exists (perhaps use the -overwrite flag?).");
-                        System.out.println("Overwrite (Y/N)?:");
-                        System.out.flush();
+                        Log.info.println("Trying to write file " + fileName + " but the file already exists (perhaps use the -overwrite flag?).");
+                        Log.info.println("Overwrite (Y/N)?:");
+                        Log.info.flush();
                         final BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in));
-                        final String sMsg = stdin.readLine();
-                        if (!sMsg.toLowerCase().equals("y")) {
-                            System.out.println("Exiting now.");
+                        final String msg = stdin.readLine();
+                        if (!msg.toLowerCase().equals("y")) {
+                        	Log.info.println("Exiting now.");
                             System.exit(0);
                         }
                     }
@@ -369,12 +374,12 @@ public class Logger extends BEASTObject {
                 }
                 case overwrite:// (over)write log file
                 {
-                    String sMsg = "Writing";
+                    String msg = "Writing";
                     if (new File(fileName).exists()) {
-                        sMsg = "Warning: Overwriting";
+                        msg = "Warning: Overwriting";
                     }
                     m_out = new PrintStream(fileName);
-                    Log.warning.println(sMsg + " file " + fileName);
+                    Log.warning.println(msg + " file " + fileName);
                     return true;
                 }
                 case resume:// append log file, pick up SampleOffset by reading existing log
@@ -384,17 +389,17 @@ public class Logger extends BEASTObject {
                         if (mode == LOGMODE.compound) {
                             // first find the sample nr offset
                             final BufferedReader fin = new BufferedReader(new FileReader(fileName));
-                            String sStr = null;
+                            String str = null;
                             while (fin.ready()) {
-                                sStr = fin.readLine();
+                                str = fin.readLine();
                             }
                             fin.close();
-                            assert sStr != null;
-                            final int nSampleOffset = Integer.parseInt(sStr.split("\\s")[0]);
-                            if (sampleOffset > 0 && nSampleOffset != sampleOffset) {
-                                throw new Exception("Error 400: Cannot resume: log files do not end in same sample number");
+                            assert str != null;
+                            final int sampleOffset = Integer.parseInt(str.split("\\s")[0]);
+                            if (Logger.sampleOffset > 0 && sampleOffset != Logger.sampleOffset) {
+                                throw new RuntimeException("Error 400: Cannot resume: log files do not end in same sample number");
                             }
-                            sampleOffset = nSampleOffset;
+                            Logger.sampleOffset = sampleOffset;
                             // open the file for appending
                             final FileOutputStream out2 = new FileOutputStream(fileName, true);
                             m_out = new PrintStream(out2);
@@ -413,18 +418,18 @@ public class Logger extends BEASTObject {
                             m_out = new PrintStream(out2);
 
                             //final StringBuilder buf = new StringBuilder();
-                            String sStrLast = null;
-                            //String sStr = fin.readLine();
+                            String strLast = null;
+                            //String str = fin.readLine();
                             boolean endSeen = false;
                             while (fin.ready()) {
                                 if( endSeen ) {
                                     m_out.println("End;");
                                     endSeen = false;
                                 }
-                                final String sStr = fin.readLine();
-                                if (!sStr.equals("End;")) {
-                                	m_out.println(sStr);
-                                    sStrLast = sStr;
+                                final String str = fin.readLine();
+                                if (!str.equals("End;")) {
+                                	m_out.println(str);
+                                    strLast = str;
                                 } else {
                                     endSeen = true;
                                 }
@@ -432,18 +437,18 @@ public class Logger extends BEASTObject {
                             fin.close();
 
                             // determine number of the last sample
-                            if( sStrLast == null ) {
+                            if( strLast == null ) {
                                 // empty log file?
-                                 throw new Exception("Error 402: empty tree log file " + fileName + "? (check if there is a back up file " + fileName + ".bu)");
+                                 throw new RuntimeException("Error 402: empty tree log file " + fileName + "? (check if there is a back up file " + fileName + ".bu)");
                             }
-                            final String sStr = sStrLast.split("\\s+")[1];
-                            final int nSampleOffset = Integer.parseInt(sStr.substring(6));
-                            if (sampleOffset > 0 && nSampleOffset != sampleOffset) {
+                            final String str = strLast.split("\\s+")[1];
+                            final int sampleOffset = Integer.parseInt(str.substring(6));
+                            if (Logger.sampleOffset > 0 && sampleOffset != Logger.sampleOffset) {
                                 //final boolean ok1 = treeFileBackup.renameTo(new File(fileName));        assert ok1;
                                 Files.move(treeFileBackup.toPath(), new File(fileName).toPath(), StandardCopyOption.ATOMIC_MOVE);
-                                throw new Exception("Error 401: Cannot resume: log files do not end in same sample number");
+                                throw new RuntimeException("Error 401: Cannot resume: log files do not end in same sample number");
                             }
-                            sampleOffset = nSampleOffset;
+                            Logger.sampleOffset = sampleOffset;
                             // it is safe to remove the backup file now
                             new File(fileName + ".bu").delete();
                         }
@@ -451,12 +456,13 @@ public class Logger extends BEASTObject {
                         return false;
                     } else {
                         m_out = new PrintStream(fileName);
-                        Log.info.println("Writing file " + fileName);
+                        Log.warning.println("WARNING: Resuming, but file " + fileName + " does not exist yet (perhaps the seed number is not the same as before?).");
+                        Log.info.println("Writing new file " + fileName);
                         return true;
                     }
                 }
                 default:
-                    throw new Exception("DEVELOPER ERROR: unknown file mode for logger " + FILE_MODE);
+                    throw new RuntimeException("DEVELOPER ERROR: unknown file mode for logger " + FILE_MODE);
             }
         }
     } // openLogFile
@@ -464,18 +470,18 @@ public class Logger extends BEASTObject {
     /**
      * log the state for given sample nr
      * *
-     * * @param nSample
+     * * @param sample
      */
-    public void log(int nSample) {
-        if ((nSample < 0) || (nSample % every > 0)) {
+    public void log(int sampleNr) {
+        if ((sampleNr < 0) || (sampleNr % every > 0)) {
             return;
         }
         if (sampleOffset >= 0) {
-            if (nSample == 0) {
+            if (sampleNr == 0) {
                 // don't need to duplicate the last line in the log
                 return;
             }
-            nSample += sampleOffset;
+            sampleNr += sampleOffset;
         }
         ByteArrayOutputStream baos = null;
         PrintStream tmp = null;
@@ -485,10 +491,10 @@ public class Logger extends BEASTObject {
             m_out = new PrintStream(baos);
         }
         if (mode == LOGMODE.compound) {
-            m_out.print((nSample) + "\t");
+            m_out.print((sampleNr) + "\t");
         }
         for (final Loggable m_logger : loggerList) {
-            m_logger.log(nSample, m_out);
+            m_logger.log(sampleNr, m_out);
         }
         if ( baos != null ) {
             assert tmp == System.out ;
@@ -502,23 +508,23 @@ public class Logger extends BEASTObject {
                 e.printStackTrace();
             }
             if (startLogTime < 0) {
-                if (nSample - sampleOffset > 6000) {
+                if (sampleNr - sampleOffset > 6000) {
                     startLogTime++;
                     if (startLogTime == 0) {
                         startLogTime = System.currentTimeMillis();
-                        startSample = nSample;
+                        startSample = sampleNr;
                     }
                 }
                 m_out.print(" --");
             } else {
 
-                final long nLogTime = System.currentTimeMillis();
-                final int nSecondsPerMSamples = (int) ((nLogTime - startLogTime) * 1000.0 / (nSample - startSample + 1.0));
-                final String sTimePerMSamples =
-                        (nSecondsPerMSamples >= 3600 ? nSecondsPerMSamples / 3600 + "h" : "") +
-                                (nSecondsPerMSamples >= 60 ? (nSecondsPerMSamples % 3600) / 60 + "m" : "") +
-                                (nSecondsPerMSamples % 60 + "s");
-                m_out.print(" " + sTimePerMSamples + "/Msamples");
+                final long logTime = System.currentTimeMillis();
+                final int secondsPerMSamples = (int) ((logTime - startLogTime) * 1000.0 / (sampleNr - startSample + 1.0));
+                final String timePerMSamples =
+                        (secondsPerMSamples >= 3600 ? secondsPerMSamples / 3600 + "h" : "") +
+                                (secondsPerMSamples >= 60 ? (secondsPerMSamples % 3600) / 60 + "m" : "") +
+                                (secondsPerMSamples % 60 + "s");
+                m_out.print(" " + timePerMSamples + "/Msamples");
             }
         }
         m_out.println();
@@ -526,49 +532,49 @@ public class Logger extends BEASTObject {
 
 
     private String prettifyLogLine(String logContent) {
-        final String[] sStrs = logContent.split("\t");
+        final String[] strs = logContent.split("\t");
         logContent = "";
-        for (final String sStr : sStrs) {
-            logContent += prettifyLogEntry(sStr);
+        for (final String str : strs) {
+            logContent += prettifyLogEntry(str);
         }
         return logContent;
     }
 
-    private String prettifyLogEntry(String sStr) {
+    private String prettifyLogEntry(String str) {
         // TODO Q2R intelliJ says \\ can't be used in a range ...
-        if (sStr.matches("[\\d-E]+\\.[\\d-E]+")) {
+        if (str.matches("[\\d-E]+\\.[\\d-E]+")) {
             // format as double
-            if (sStr.contains("E")) {
-                if (sStr.length() > 15) {
-                    final String[] sStrs = sStr.split("E");
-                    return " " + sStrs[0].substring(0, 15 - sStrs[1].length() - 2) + "E" + sStrs[1];
+            if (str.contains("E")) {
+                if (str.length() > 15) {
+                    final String[] strs = str.split("E");
+                    return " " + strs[0].substring(0, 15 - strs[1].length() - 2) + "E" + strs[1];
                 } else {
-                    return "               ".substring(sStr.length()) + sStr;
+                    return "               ".substring(str.length()) + str;
                 }
             }
-            final String s1 = sStr.substring(0, sStr.indexOf("."));
-            String s2 = sStr.substring(sStr.indexOf(".") + 1);
+            final String s1 = str.substring(0, str.indexOf("."));
+            String s2 = str.substring(str.indexOf(".") + 1);
             while (s2.length() < 4) {
                 s2 = s2 + " ";
             }
             s2 = s2.substring(0, 4);
-            sStr = s1 + "." + s2;
-            sStr = "               ".substring(sStr.length()) + sStr;
-        } else if (sStr.length() < 15) {
+            str = s1 + "." + s2;
+            str = "               ".substring(str.length()) + str;
+        } else if (str.length() < 15) {
             // format integer, boolean
-            sStr = "               ".substring(sStr.length()) + sStr;
+            str = "               ".substring(str.length()) + str;
         } else {
-            sStr = " " + sStr;
+            str = " " + str;
         }
-        int nOverShoot = sStr.length() - 15;
-        while (nOverShoot > 0 && sStr.length() > 2 && sStr.charAt(1) == ' ') {
-            sStr = sStr.substring(1);
-            nOverShoot--;
+        int overShoot = str.length() - 15;
+        while (overShoot > 0 && str.length() > 2 && str.charAt(1) == ' ') {
+            str = str.substring(1);
+            overShoot--;
         }
-        if (nOverShoot > 0) {
-            sStr = sStr.substring(0, 8) + "_" + sStr.substring(sStr.length() - 6);
+        if (overShoot > 0) {
+            str = str.substring(0, 8) + "_" + str.substring(str.length() - 6);
         }
-        return sStr;
+        return str;
     }
 
 
diff --git a/src/beast/core/MCMC.java b/src/beast/core/MCMC.java
index 67564be..c57c33f 100644
--- a/src/beast/core/MCMC.java
+++ b/src/beast/core/MCMC.java
@@ -24,13 +24,21 @@
 */
 package beast.core;
 
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.xml.sax.SAXException;
+
 import beast.core.util.CompoundDistribution;
 import beast.core.util.Evaluator;
 import beast.core.util.Log;
 import beast.util.Randomizer;
 
-import java.util.*;
-
 @Description("MCMC chain. This is the main element that controls which posterior " +
         "to calculate, how long to run the chain and all other properties, " +
         "which operators to apply on the state space and where to log results.")
@@ -42,45 +50,45 @@ import java.util.*;
         DOI="10.1371/journal.pcbi.1003537")
 public class MCMC extends Runnable {
 
-    public Input<Integer> chainLengthInput =
-            new Input<Integer>("chainLength", "Length of the MCMC chain i.e. number of samples taken in main loop",
+    final public Input<Integer> chainLengthInput =
+            new Input<>("chainLength", "Length of the MCMC chain i.e. number of samples taken in main loop",
                     Input.Validate.REQUIRED);
 
-    public Input<State> startStateInput =
-            new Input<State>("state", "elements of the state space");
+    final public Input<State> startStateInput =
+            new Input<>("state", "elements of the state space");
 
-    public Input<List<StateNodeInitialiser>> initialisersInput =
-            new Input<List<StateNodeInitialiser>>("init", "one or more state node initilisers used for determining " +
+    final public Input<List<StateNodeInitialiser>> initialisersInput =
+            new Input<>("init", "one or more state node initilisers used for determining " +
                     "the start state of the chain",
-                    new ArrayList<StateNodeInitialiser>());
+                    new ArrayList<>());
 
-    public Input<Integer> storeEveryInput =
-            new Input<Integer>("storeEvery", "store the state to disk every X number of samples so that we can " +
+    final public Input<Integer> storeEveryInput =
+            new Input<>("storeEvery", "store the state to disk every X number of samples so that we can " +
                     "resume computation later on if the process failed half-way.", -1);
 
-    public Input<Integer> burnInInput =
-            new Input<Integer>("preBurnin", "Number of burn in samples taken before entering the main loop", 0);
+    final public Input<Integer> burnInInput =
+            new Input<>("preBurnin", "Number of burn in samples taken before entering the main loop", 0);
 
 
-    public Input<Integer> numInitializationAttempts =
-            new Input<Integer>("numInitializationAttempts", "Number of initialization attempts before failing (default=10)", 10);
+    final public Input<Integer> numInitializationAttempts =
+            new Input<>("numInitializationAttempts", "Number of initialization attempts before failing (default=10)", 10);
 
-    public Input<Distribution> posteriorInput =
-            new Input<Distribution>("distribution", "probability distribution to sample over (e.g. a posterior)",
+    final public Input<Distribution> posteriorInput =
+            new Input<>("distribution", "probability distribution to sample over (e.g. a posterior)",
                     Input.Validate.REQUIRED);
 
-    public Input<List<Operator>> operatorsInput =
-            new Input<List<Operator>>("operator", "operator for generating proposals in MCMC state space",
-                    new ArrayList<Operator>());//, Input.Validate.REQUIRED);
+    final public Input<List<Operator>> operatorsInput =
+            new Input<>("operator", "operator for generating proposals in MCMC state space",
+                    new ArrayList<>());//, Input.Validate.REQUIRED);
 
-    public Input<List<Logger>> loggersInput =
-            new Input<List<Logger>>("logger", "loggers for reporting progress of MCMC chain",
-                    new ArrayList<Logger>(), Input.Validate.REQUIRED);
+    final public Input<List<Logger>> loggersInput =
+            new Input<>("logger", "loggers for reporting progress of MCMC chain",
+                    new ArrayList<>(), Input.Validate.REQUIRED);
 
-    public Input<Boolean> sampleFromPriorInput = new Input<Boolean>("sampleFromPrior", "whether to ignore the likelihood when sampling (default false). " +
+    final public Input<Boolean> sampleFromPriorInput = new Input<>("sampleFromPrior", "whether to ignore the likelihood when sampling (default false). " +
             "The distribution with id 'likelihood' in the posterior input will be ignored when this flag is set.", false);
 
-    public Input<OperatorSchedule> operatorScheduleInput = new Input<OperatorSchedule>("operatorschedule", "specify operator selection and optimisation schedule", new OperatorSchedule());
+    final public Input<OperatorSchedule> operatorScheduleInput = new Input<>("operatorschedule", "specify operator selection and optimisation schedule", new OperatorSchedule());
 
     /**
      * Alternative representation of operatorsInput that allows random selection
@@ -91,7 +99,7 @@ public class MCMC extends Runnable {
     /**
      * The state that takes care of managing StateNodes,
      * operations on StateNodes and propagates store/restore/requireRecalculation
-     * calls to the appropriate Plugins.
+     * calls to the appropriate BEASTObjects.
      */
     protected State state;
 
@@ -114,51 +122,9 @@ public class MCMC extends Runnable {
     public MCMC() {
     }
 
-    /**
-     * Constructor for MCMC chain.
-     *
-     * @param chainLength
-     * @param state
-     * @param storeEvery
-     * @param preBurnin
-     * @param posterior
-     * @param operators
-     * @param loggers
-     * @throws Exception
-     */
-    public MCMC(
-            @Param(name = "chainLength", description = "Length of the MCMC chain i.e. number of samples taken in main loop") int chainLength,
-            @Param(name = "state", description = "elements of the state space") State state,
-            @Param(name = "initialisers", description = "one or more state node initilisers used for determining the start state of the chain") List<StateNodeInitialiser> initialisers,
-            @Param(name = "storeEvery", description = "store the state to disk every X number of samples so that we can resume computation later on if the process failed half-way.") int storeEvery,
-            @Param(name = "preBurnin", description = "Number of burn in samples taken before entering the main loop", defaultValue = "0") int preBurnin,
-            @Param(name = "posterior", description = "probability distribution to sample over (e.g. a posterior)") Distribution posterior,
-            @Param(name = "operators", description = "operator for generating proposals in MCMC state space") List<Operator> operators,
-            @Param(name = "loggers", description = "loggers for reporting progress of MCMC chain") List<Logger> loggers,
-            @Param(name = "sampleFromPrior", description = "whether to ignore the likelihood when sampling (default false). The distribution with id 'likelihood' in the posterior input will be ignored when this flag is set.", defaultValue = "false") boolean sampleFromPrior,
-            @Param(name = "operatorSchedule", description = "specify operator selection and optimisation schedule", optional = true) OperatorSchedule operatorSchedule) {
-
-        try {
-            initByName(
-                    "chainLength", chainLength,
-                    "state", state,
-                    "initialisers", initialisers,
-                    "storeEvery", storeEvery,
-                    "preBurnin", preBurnin,
-                    "distribution", posterior,
-                    "operator", operators,
-                    "logger", loggers,
-                    "sampleFromPrior", sampleFromPrior,
-                    "operatorSchedule", operatorSchedule
-            );
-        } catch (Exception e) {
-            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
-            throw new RuntimeException();
-        }
-    }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         Log.info.println("===============================================================================");
         Log.info.println("Citations for this model:");
         Log.info.println(getCitations());
@@ -170,25 +136,25 @@ public class MCMC extends Runnable {
         }
 
         if (sampleFromPriorInput.get()) {
-            // remove plugin with id likelihood from posterior, if it is a CompoundDistribution
+            // remove beastObject with id likelihood from posterior, if it is a CompoundDistribution
             if (posteriorInput.get() instanceof CompoundDistribution) {
                 final CompoundDistribution posterior = (CompoundDistribution) posteriorInput.get();
                 final List<Distribution> distrs = posterior.pDistributions.get();
-                final int nDistr = distrs.size();
-                for (int i = 0; i < nDistr; i++) {
+                final int distrCount = distrs.size();
+                for (int i = 0; i < distrCount; i++) {
                     final Distribution distr = distrs.get(i);
-                    final String sID = distr.getID();
-                    if (sID != null && sID.equals("likelihood")) {
+                    final String id = distr.getID();
+                    if (id != null && id.equals("likelihood")) {
                         distrs.remove(distr);
                         break;
                     }
                 }
-                if (distrs.size() == nDistr) {
-                    throw new Exception("Sample from prior flag is set, but distribution with id 'likelihood' is " +
+                if (distrs.size() == distrCount) {
+                    throw new RuntimeException("Sample from prior flag is set, but distribution with id 'likelihood' is " +
                             "not an input to posterior.");
                 }
             } else {
-                throw new Exception("Don't know how to sample from prior since posterior is not a compound distribution. " +
+                throw new RuntimeException("Don't know how to sample from prior since posterior is not a compound distribution. " +
                         "Suggestion: set sampleFromPrior flag to false.");
             }
         }
@@ -196,14 +162,14 @@ public class MCMC extends Runnable {
 
         // StateNode initialisation, only required when the state is not read from file
         if (restoreFromFile) {
-            final HashSet<StateNode> initialisedStateNodes = new HashSet<StateNode>();
+            final HashSet<StateNode> initialisedStateNodes = new HashSet<>();
             for (final StateNodeInitialiser initialiser : initialisersInput.get()) {
                 // make sure that the initialiser does not re-initialises a StateNode
-                final List<StateNode> list = new ArrayList<StateNode>(1);
+                final List<StateNode> list = new ArrayList<>(1);
                 initialiser.getInitialisedStateNodes(list);
                 for (final StateNode stateNode : list) {
                     if (initialisedStateNodes.contains(stateNode)) {
-                        throw new Exception("Trying to initialise stateNode (id=" + stateNode.getID() + ") more than once. " +
+                        throw new RuntimeException("Trying to initialise stateNode (id=" + stateNode.getID() + ") more than once. " +
                                 "Remove an initialiser from MCMC to fix this.");
                     }
                 }
@@ -214,7 +180,7 @@ public class MCMC extends Runnable {
         }
 
         // State initialisation
-        final HashSet<StateNode> operatorStateNodes = new HashSet<StateNode>();
+        final HashSet<StateNode> operatorStateNodes = new HashSet<>();
         for (final Operator op : operatorsInput.get()) {
             for (final StateNode stateNode : op.listStateNodes()) {
                 operatorStateNodes.add(stateNode);
@@ -247,16 +213,24 @@ public class MCMC extends Runnable {
         // sanity check: all operator state nodes should be in the state
         final List<StateNode> stateNodes = this.state.stateNodeInput.get();
         for (final Operator op : operatorsInput.get()) {
-            for (final StateNode stateNode : op.listStateNodes()) {
-                if (!stateNodes.contains(stateNode)) {
-                    throw new Exception("Operator " + op.getID() + " has a statenode " + stateNode.getID() + " in its inputs that is missing from the state.");
-                }
+            List<StateNode> nodes = op.listStateNodes();
+            if (nodes.size() == 0) {
+                    throw new RuntimeException("Operator " + op.getID() + "has no state nodes in the state. "
+                                    + "Each operator should operate on at least one estimated state node in the state. "
+                                    + "Remove the operator or add its statenode(s) to the state and/or set estimate='true'.");
+                    // otherwise the chain may hang without obvious reason
             }
-        }
+	        for (final StateNode stateNode : op.listStateNodes()) {
+	            if (!stateNodes.contains(stateNode)) {
+	                throw new RuntimeException("Operator " + op.getID() + " has a statenode " + stateNode.getID() + " in its inputs that is missing from the state.");
+	            }
+	        }
+	    }
+    
         // sanity check: all state nodes should be operated on
         for (final StateNode stateNode : stateNodes) {
             if (!operatorStateNodes.contains(stateNode)) {
-                System.out.println("Warning: state contains a node " + stateNode.getID() + " for which there is no operator.");
+                Log.warning.println("Warning: state contains a node " + stateNode.getID() + " for which there is no operator.");
             }
         }
     } // init
@@ -284,8 +258,8 @@ public class MCMC extends Runnable {
     protected List<Logger> loggers;
 
     @Override
-    public void run() throws Exception {
-        // set up state (again). Other plugins may have manipulated the
+    public void run() throws IOException, SAXException, ParserConfigurationException {
+        // set up state (again). Other beastObjects may have manipulated the
         // StateNodes, e.g. set up bounds or dimensions
         state.initAndValidate();
         // also, initialise state with the file name to store and set-up whether to resume from file
@@ -294,7 +268,7 @@ public class MCMC extends Runnable {
 
         burnIn = burnInInput.get();
         chainLength = chainLengthInput.get();
-        int nInitialisationAttempts = 0;
+        int initialisationAttempts = 0;
         state.setEverythingDirty(true);
         posterior = posteriorInput.get();
 
@@ -309,11 +283,14 @@ public class MCMC extends Runnable {
                     initialiser.initStateNodes();
                 }
                 oldLogLikelihood = state.robustlyCalcPosterior(posterior);
-                nInitialisationAttempts += 1;
-            } while (Double.isInfinite(oldLogLikelihood) && nInitialisationAttempts < numInitializationAttempts.get());
+                initialisationAttempts += 1;
+            } while (Double.isInfinite(oldLogLikelihood) && initialisationAttempts < numInitializationAttempts.get());
         }
         final long startTime = System.currentTimeMillis();
 
+        state.storeCalculationNodes();
+
+        
         // do the sampling
         logAlpha = 0;
         debugFlag = Boolean.valueOf(System.getProperty("beast.debug"));
@@ -322,10 +299,10 @@ public class MCMC extends Runnable {
 //        System.err.println("Start state:");
 //        System.err.println(state.toString());
 
-        System.err.println("Start likelihood: " + oldLogLikelihood + " " + (nInitialisationAttempts > 1 ? "after " + nInitialisationAttempts + " initialisation attempts" : ""));
+        Log.info.println("Start likelihood: " + oldLogLikelihood + " " + (initialisationAttempts > 1 ? "after " + initialisationAttempts + " initialisation attempts" : ""));
         if (Double.isInfinite(oldLogLikelihood) || Double.isNaN(oldLogLikelihood)) {
             reportLogLikelihoods(posterior, "");
-            throw new Exception("Could not find a proper state to initialise. Perhaps try another seed.");
+            throw new RuntimeException("Could not find a proper state to initialise. Perhaps try another seed.");
         }
 
         loggers = loggersInput.get();
@@ -365,15 +342,15 @@ public class MCMC extends Runnable {
 
         doLoop();
 
-        System.out.println();
+        Log.info.println();
         operatorSchedule.showOperatorRates(System.out);
 
-        System.out.println();
+        Log.info.println();
         final long endTime = System.currentTimeMillis();
-        System.out.println("Total calculation time: " + (endTime - startTime) / 1000.0 + " seconds");
+        Log.info.println("Total calculation time: " + (endTime - startTime) / 1000.0 + " seconds");
         close();
 
-        System.err.println("End likelihood: " + oldLogLikelihood);
+        Log.warning.println("End likelihood: " + oldLogLikelihood);
 //        System.err.println(state);
         state.storeToFile(chainLength);
         operatorSchedule.storeToFile();
@@ -382,10 +359,13 @@ public class MCMC extends Runnable {
 
 
     /**
-     * main MCMC loop *
+     * main MCMC loop 
+     * @throws IOException *
      */
-    protected void doLoop() throws Exception {
+    protected void doLoop() throws IOException {
         int corrections = 0;
+        final boolean isStochastic = posterior.isStochastic();
+        
         if (burnIn > 0) {
         	Log.warning.println("Please wait while BEAST takes " + burnIn + " pre-burnin samples");
         }
@@ -393,13 +373,13 @@ public class MCMC extends Runnable {
             final int currentState = sampleNr;
 
             state.store(currentState);
-//            if (m_nStoreEvery > 0 && iSample % m_nStoreEvery == 0 && iSample > 0) {
-//                state.storeToFile(iSample);
+//            if (m_nStoreEvery > 0 && sample % m_nStoreEvery == 0 && sample > 0) {
+//                state.storeToFile(sample);
 //            	operatorSchedule.storeToFile();
 //            }
 
             final Operator operator = operatorSchedule.selectOperator();
-            //System.out.print("\n" + sampleNr + " " + operator.getName()+ ":");
+            //System.err.print("\n" + sampleNr + " " + operator.getName()+ ":");
 
             final Distribution evaluatorDistribution = operator.getEvaluatorDistribution();
             Evaluator evaluator = null;
@@ -427,7 +407,6 @@ public class MCMC extends Runnable {
                     }
                 };
             }
-
             final double logHastingsRatio = operator.proposal(evaluator);
 
             if (logHastingsRatio != Double.NEGATIVE_INFINITY) {
@@ -440,7 +419,7 @@ public class MCMC extends Runnable {
                 newLogLikelihood = posterior.calculateLogP();
 
                 logAlpha = newLogLikelihood - oldLogLikelihood + logHastingsRatio; //CHECK HASTINGS
-                //System.out.println(logAlpha + " " + newLogLikelihood + " " + oldLogLikelihood);
+                // System.err.print(logAlpha + " " + newLogLikelihood + " " + oldLogLikelihood);
                 if (logAlpha >= 0 || Randomizer.nextDouble() < Math.exp(logAlpha)) {
                     // accept
                     oldLogLikelihood = newLogLikelihood;
@@ -449,7 +428,7 @@ public class MCMC extends Runnable {
                     if (sampleNr >= 0) {
                         operator.accept();
                     }
-                    //System.out.print(" accept");
+                    //System.err.print(" accept");
                 } else {
                     // reject
                     if (sampleNr >= 0) {
@@ -457,7 +436,7 @@ public class MCMC extends Runnable {
                     }
                     state.restore();
                     state.restoreCalculationNodes();
-                    //System.out.print(" reject");
+                    //System.err.print(" reject");
                 }
                 state.setEverythingDirty(false);
             } else {
@@ -470,42 +449,43 @@ public class MCMC extends Runnable {
                     state.setEverythingDirty(false);
                     state.restoreCalculationNodes();
 				}
-                //System.out.print(" direct reject");
+				//System.err.print(" direct reject");
             }
             log(sampleNr);
 
             if (debugFlag && sampleNr % 3 == 0 || sampleNr % 10000 == 0) {
                 // check that the posterior is correctly calculated at every third
                 // sample, as long as we are in debug mode
-            	final double fNonStochasticLogP = posterior.getNonStochasticLogP();
-                final double fLogLikelihood = state.robustlyCalcNonStochasticPosterior(posterior);
-                if (Math.abs(fLogLikelihood - fNonStochasticLogP) > 1e-6) {
+            	final double originalLogP = isStochastic ? posterior.getNonStochasticLogP() : oldLogLikelihood;
+                final double logLikelihood = isStochastic ? state.robustlyCalcNonStochasticPosterior(posterior) : state.robustlyCalcPosterior(posterior);
+                if (isTooDifferent(logLikelihood, originalLogP)) {
                     reportLogLikelihoods(posterior, "");
-                    System.err.println("At sample " + sampleNr + "\nLikelihood incorrectly calculated: " + fNonStochasticLogP + " != " + fLogLikelihood
+                    Log.err.println("At sample " + sampleNr + "\nLikelihood incorrectly calculated: " + originalLogP + " != " + logLikelihood
+                    		+ "(" + (originalLogP - logLikelihood) + ")"
                             + " Operator: " + operator.getClass().getName());
                 }
                 if (sampleNr > NR_OF_DEBUG_SAMPLES * 3) {
                     // switch off debug mode once a sufficient large sample is checked
                     debugFlag = false;
-                    if (Math.abs(fLogLikelihood - fNonStochasticLogP) > 1e-6) {
+                    if (isTooDifferent(logLikelihood, originalLogP)) {
                         // incorrect calculation outside debug period.
                         // This happens infrequently enough that it should repair itself after a robust posterior calculation
                         corrections++;
                         if (corrections > 100) {
                             // after 100 repairs, there must be something seriously wrong with the implementation
-                            System.err.println("Too many corrections. There is something seriously wrong that cannot be corrected");
+                        	Log.err.println("Too many corrections. There is something seriously wrong that cannot be corrected");
                             state.storeToFile(sampleNr);
                             operatorSchedule.storeToFile();
-                            System.exit(0);
+                            System.exit(1);
                         }
                         oldLogLikelihood = state.robustlyCalcPosterior(posterior);;
                     }
                 } else {
-                    if (Math.abs(fLogLikelihood - fNonStochasticLogP) > 1e-6) {
+                    if (isTooDifferent(logLikelihood, originalLogP)) {
                         // halt due to incorrect posterior during intial debug period
                         state.storeToFile(sampleNr);
                         operatorSchedule.storeToFile();
-                        System.exit(0);
+                        System.exit(1);
                     }
                 }
             } else {
@@ -517,25 +497,31 @@ public class MCMC extends Runnable {
 
             // make sure we always save just before exiting
             if (storeEvery > 0 && (sampleNr + 1) % storeEvery == 0 || sampleNr == chainLength) {
-                /*final double fLogLikelihood = */
+                /*final double logLikelihood = */
                 state.robustlyCalcNonStochasticPosterior(posterior);
                 state.storeToFile(sampleNr);
                 operatorSchedule.storeToFile();
             }
         }
         if (corrections > 0) {
-            System.err.println("\n\nNB: " + corrections + " posterior calculation corrections were required. This analysis may not be valid!\n\n");
+        	Log.err.println("\n\nNB: " + corrections + " posterior calculation corrections were required. This analysis may not be valid!\n\n");
         }
     }
 
-    /**
+    private boolean isTooDifferent(double logLikelihood, double originalLogP) {
+    	//return Math.abs((logLikelihood - originalLogP)/originalLogP) > 1e-6;
+    	return Math.abs(logLikelihood - originalLogP) > 1e-6;
+	}
+
+
+	/*
      * report posterior and subcomponents recursively, for debugging
      * incorrectly recalculated posteriors *
      */
     protected void reportLogLikelihoods(final Distribution distr, final String tabString) {
         final double full =  distr.logP, last = distr.storedLogP;
         final String changed = full == last ? "" : "  **";
-        System.err.println(tabString + "P(" + distr.getID() + ") = " + full + " (was " + last + ")" + changed);
+        Log.err.println(tabString + "P(" + distr.getID() + ") = " + full + " (was " + last + ")" + changed);
         if (distr instanceof CompoundDistribution) {
             for (final Distribution distr2 : ((CompoundDistribution) distr).pDistributions.get()) {
                 reportLogLikelihoods(distr2, tabString + "\t");
@@ -543,7 +529,7 @@ public class MCMC extends Runnable {
         }
     }
 
-    protected void callUserFunction(final int iSample) {
+    protected void callUserFunction(final int sample) {
     }
 
 
@@ -551,7 +537,7 @@ public class MCMC extends Runnable {
      * Calculate posterior by setting all StateNodes and CalculationNodes dirty.
      * Clean everything afterwards.
      */
-    public double robustlyCalcPosterior(final Distribution posterior) throws Exception {
+    public double robustlyCalcPosterior(final Distribution posterior) {
         return state.robustlyCalcPosterior(posterior);
     }
 
@@ -560,18 +546,8 @@ public class MCMC extends Runnable {
      * Calculate posterior by setting all StateNodes and CalculationNodes dirty.
      * Clean everything afterwards.
      */
-    public double robustlyCalcNonStochasticPosterior(final Distribution posterior) throws Exception {
+    public double robustlyCalcNonStochasticPosterior(final Distribution posterior) {
         return state.robustlyCalcNonStochasticPosterior(posterior);
     }
-    //        state.store(-1);
-//        state.setEverythingDirty(true);
-//        //state.storeCalculationNodes();
-//        state.checkCalculationNodesDirtiness();
-//        double fLogLikelihood = posterior.calculateLogP();
-//        state.setEverythingDirty(false);
-//        state.acceptCalculationNodes();
-//        return fLogLikelihood;
-//    }
-
 } // class MCMC
 
diff --git a/src/beast/core/Operator.java b/src/beast/core/Operator.java
index 5100c50..d0feb8a 100644
--- a/src/beast/core/Operator.java
+++ b/src/beast/core/Operator.java
@@ -25,19 +25,21 @@
 package beast.core;
 
 
-import beast.core.Input.Validate;
-import beast.core.util.Evaluator;
-import org.json.JSONObject;
-import org.json.JSONWriter;
-
 import java.io.PrintWriter;
-import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.List;
 
+import org.json.JSONException;
+import org.json.JSONObject;
+//import org.json.JSONWriter;
+import org.json.JSONStringer;
+
+import beast.core.Input.Validate;
+import beast.core.util.Evaluator;
+
 @Description("Proposes a move in state space.")
 public abstract class Operator extends BEASTObject {
-    public Input<Double> m_pWeight = new Input<Double>("weight", "weight with which this operator is selected", Validate.REQUIRED);
+    final public Input<Double> m_pWeight = new Input<>("weight", "weight with which this operator is selected", Validate.REQUIRED);
 
     private final String STANDARD_OPERATOR_PACKAGE = "beast.evolution.operators";
 
@@ -71,7 +73,7 @@ public abstract class Operator extends BEASTObject {
      * always be accepted, the method should return Double.POSITIVE_INFINITY.
      *
      * @param evaluator An evaluator object that can be use to repetitively
-     *                  used to evaluate the distributribution returned by getEvaluatorDistribution().
+     *                  used to evaluate the distribution returned by getEvaluatorDistribution().
      * @return log of Hastings Ratio, or Double.NEGATIVE_INFINITY if proposal
      * should not be accepted (because the proposal is invalid) or
      * Double.POSITIVE_INFINITY if the proposal should always be accepted
@@ -189,9 +191,9 @@ public abstract class Operator extends BEASTObject {
     /**
      * set value that changed through automatic operator optimisation
      *
-     * @param fValue
+     * @param value
      */
-    public void setCoercableParameterValue(final double fValue) {
+    public void setCoercableParameterValue(final double value) {
     }
 
     /**
@@ -208,10 +210,10 @@ public abstract class Operator extends BEASTObject {
      * state nodes that are input to the operator but are never changed
      * in a proposal should not be listed
      */
-    public List<StateNode> listStateNodes() throws Exception {
+    public List<StateNode> listStateNodes() {
         // pick up all inputs that are stateNodes that are estimated
-        final List<StateNode> list = new ArrayList<StateNode>();
-        for (BEASTInterface o : listActivePlugins()) {
+        final List<StateNode> list = new ArrayList<>();
+        for (BEASTInterface o : listActiveBEASTObjects()) {
             if (o instanceof StateNode) {
                 final StateNode stateNode = (StateNode) o;
                 if (stateNode.isEstimatedInput.get()) {
@@ -222,7 +224,8 @@ public abstract class Operator extends BEASTObject {
         return list;
     }
 
-    public String toString() {
+    @Override
+	public String toString() {
         return OperatorSchedule.prettyPrintOperator(this, 70, 10, 4, 0.0, detailedRejection);
     }
 
@@ -236,7 +239,7 @@ public abstract class Operator extends BEASTObject {
      * need to override this method to store the tuning information associated
      * with their sub-operators by generating nested JSON, for example
      * <p>
-     * {"id":"metaoperator", "p":0.5, "accept":396, "reject":355, "acceptFC":50, "rejectFC":45,
+     * {"id":"metaOperator", "p":0.5, "accept":396, "reject":355, "acceptFC":50, "rejectFC":45,
      * operators [
      * {"id":"kappaScaler1", "p":0.5, "accept":39, "reject":35, "acceptFC":0, "rejectFC":0}
      * {"id":"kappaScaler2", "p":0.5, "accept":39, "reject":35, "acceptFC":0, "rejectFC":0}
@@ -245,58 +248,68 @@ public abstract class Operator extends BEASTObject {
      * *
      */
     public void storeToFile(final PrintWriter out) {
-
-        StringWriter writer = new StringWriter();
-        JSONWriter json = new JSONWriter(writer);
-        json.object();
-
-        if (getID()==null)
-           setID("unknown");
-
-        json.key("id").value(getID());
-
-        double p = getCoercableParameterValue();
-        if (Double.isNaN(p)) {
-            json.key("p").value("NaN");
-        } else if (Double.isInfinite(p)) {
-        	if (p > 0) {
-        		json.key("p").value("Infinity");
-        	} else {
-        		json.key("p").value("-Infinity");
-        	}
-        } else {
-            json.key("p").value(p);
-        }
-        json.key("accept").value(m_nNrAccepted);
-        json.key("reject").value(m_nNrRejected);
-        json.key("acceptFC").value(m_nNrAcceptedForCorrection);
-        json.key("rejectFC").value(m_nNrRejectedForCorrection);
-        json.key("rejectIv").value(m_nNrRejectedInvalid);
-        json.key("rejectOp").value(m_nNrRejectedOperator);
-        json.endObject();
-        out.print(writer.toString());
+    	try {
+	        JSONStringer json = new JSONStringer();
+	        json.object();
+	
+	        if (getID()==null)
+	           setID("unknown");
+	
+	        json.key("id").value(getID());
+	
+	        double p = getCoercableParameterValue();
+	        if (Double.isNaN(p)) {
+	            json.key("p").value("NaN");
+	        } else if (Double.isInfinite(p)) {
+	        	if (p > 0) {
+	        		json.key("p").value("Infinity");
+	        	} else {
+	        		json.key("p").value("-Infinity");
+	        	}
+	        } else {
+	            json.key("p").value(p);
+	        }
+	        json.key("accept").value(m_nNrAccepted);
+	        json.key("reject").value(m_nNrRejected);
+	        json.key("acceptFC").value(m_nNrAcceptedForCorrection);
+	        json.key("rejectFC").value(m_nNrRejectedForCorrection);
+	        json.key("rejectIv").value(m_nNrRejectedInvalid);
+	        json.key("rejectOp").value(m_nNrRejectedOperator);
+	        json.endObject();
+	        out.print(json.toString());
+    	} catch (JSONException e) {
+    		// failed to log operator in state file
+    		// report and continue
+    		e.printStackTrace();
+    	}
     }
 
     /**
      * Restore tuning information from file
-     * Override this method fo meta-operators (see also storeToFile).
+     * Override this method for meta-operators (see also storeToFile).
      */
     public void restoreFromFile(JSONObject o) {
-        if (!Double.isNaN(o.getDouble("p"))) {
-            setCoercableParameterValue(o.getDouble("p"));
-        }
-        m_nNrAccepted = o.getInt("accept");
-        m_nNrRejected = o.getInt("reject");
-        m_nNrAcceptedForCorrection = o.getInt("acceptFC");
-        m_nNrRejectedForCorrection = o.getInt("rejectFC");
-
-        m_nNrRejectedInvalid = o.has("rejectIv") ? o.getInt("rejectIv") : 0;
-        m_nNrRejectedOperator = o.has("rejectOp") ? o.getInt("rejectOp") : 0;
+    	try {
+	        if (!Double.isNaN(o.getDouble("p"))) {
+	            setCoercableParameterValue(o.getDouble("p"));
+	        }
+	        m_nNrAccepted = o.getInt("accept");
+	        m_nNrRejected = o.getInt("reject");
+	        m_nNrAcceptedForCorrection = o.getInt("acceptFC");
+	        m_nNrRejectedForCorrection = o.getInt("rejectFC");
+	
+	        m_nNrRejectedInvalid = o.has("rejectIv") ? o.getInt("rejectIv") : 0;
+	        m_nNrRejectedOperator = o.has("rejectOp") ? o.getInt("rejectOp") : 0;
+    	} catch (JSONException e) {
+    		// failed to restore from state file
+    		// report and continue
+    		e.printStackTrace();
+    	}
     }
 
 
     /**
-     * indicates that the state needs to be initialises so that
+     * indicates that the state needs to be initialised so that
      * BEASTObjects can be identified that need updating. This
      * almost always needs to happen, except for cases where the
      * operator already initialised the state, e.g. for delayed
diff --git a/src/beast/core/OperatorSchedule.java b/src/beast/core/OperatorSchedule.java
index 6529a82..a2e191c 100644
--- a/src/beast/core/OperatorSchedule.java
+++ b/src/beast/core/OperatorSchedule.java
@@ -1,6 +1,12 @@
 package beast.core;
 
-import java.io.*;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Formatter;
@@ -18,21 +24,21 @@ public class OperatorSchedule extends BEASTObject {
 
     enum OptimisationTransform {none, log, sqrt}
 
-    public Input<OptimisationTransform> transformInput = new Input<OperatorSchedule.OptimisationTransform>("transform",
+    final public Input<OptimisationTransform> transformInput = new Input<>("transform",
             "transform optimisation schedule (default none) This can be "
                     + Arrays.toString(OptimisationTransform.values()) + " (default 'none')",
             OptimisationTransform.none, OptimisationTransform.values());
-    public Input<Boolean> autoOptimiseInput = new Input<Boolean>("autoOptimize", "whether to automatically optimise operator settings", true);
+    final public Input<Boolean> autoOptimiseInput = new Input<>("autoOptimize", "whether to automatically optimise operator settings", true);
 
-    public Input<Boolean> detailedRejectionInput = new Input<Boolean>("detailedRejection", "true if detailed rejection statistics should be included. (default=false)", false);
+    final public Input<Boolean> detailedRejectionInput = new Input<>("detailedRejection", "true if detailed rejection statistics should be included. (default=false)", false);
 
-    public Input<Integer> autoOptimizeDelayInput = new Input<Integer>("autoOptimizeDelay", "number of samples to skip before auto optimisation kicks in (default=10000)", 10000);
+    final public Input<Integer> autoOptimizeDelayInput = new Input<>("autoOptimizeDelay", "number of samples to skip before auto optimisation kicks in (default=10000)", 10000);
 
     /**
      * list of operators in the schedule *
      */
     // temporary for play
-    public List<Operator> operators = new ArrayList<Operator>();
+    public List<Operator> operators = new ArrayList<>();
 
     /**
      * sum of weight of operators *
@@ -60,7 +66,7 @@ public class OperatorSchedule extends BEASTObject {
     boolean detailedRejection = false;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         transform = transformInput.get();
         autoOptimise = autoOptimiseInput.get();
         autoOptimizeDelay = autoOptimizeDelayInput.get();
@@ -92,8 +98,8 @@ public class OperatorSchedule extends BEASTObject {
      * @return
      */
     public Operator selectOperator() {
-        final int iOperator = Randomizer.randomChoice(cumulativeProbs);
-        return operators.get(iOperator);
+        final int operatorIndex = Randomizer.randomChoice(cumulativeProbs);
+        return operators.get(operatorIndex);
     }
 
     private static final String TUNING = "Tuning";
@@ -148,6 +154,8 @@ 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(
@@ -187,17 +195,19 @@ public class OperatorSchedule extends BEASTObject {
 
         sb.append(" " + op.getPerformanceSuggestion());
 
+        formatter.close();
+   
         return sb.toString();
     }
 
     /**
      * store operator optimisation specific information to file *
-     * @throws Exception
+     * @throws IOException
      */
-    public void storeToFile() throws Exception {
+    public void storeToFile() throws IOException {
         // appends state of operator set to state file
-        File aFile = new File(stateFileName);
-        PrintWriter out = new PrintWriter(new FileWriter(aFile, true));
+        File file = new File(stateFileName);
+        PrintWriter out = new PrintWriter(new FileWriter(file, true));
 
         out.println("<!--");
         out.println("{\"operators\":[");
@@ -216,23 +226,23 @@ public class OperatorSchedule extends BEASTObject {
 
     /**
      * restore operator optimisation specific information from file *
-     * @throws Exception
+     * @throws IOException
      */
-    public void restoreFromFile() throws Exception {
+    public void restoreFromFile() throws IOException {
         // reads state of operator set from state file
-        String sXML = "";
+        String xml = "";
         final BufferedReader fin = new BufferedReader(new FileReader(stateFileName));
         while (fin.ready()) {
-            sXML += fin.readLine() + "\n";
+            xml += fin.readLine() + "\n";
         }
         fin.close();
-        int start = sXML.indexOf("</itsabeastystatewerein>") + 25 + 5;
-        if (start >= sXML.length() - 4) {
+        int start = xml.indexOf("</itsabeastystatewerein>") + 25 + 5;
+        if (start >= xml.length() - 4) {
         	return;
         }
-        sXML = sXML.substring(sXML.indexOf("</itsabeastystatewerein>") + 25 + 5, sXML.length() - 4);
+        xml = xml.substring(xml.indexOf("</itsabeastystatewerein>") + 25 + 5, xml.length() - 4);
         try {
-	        JSONObject o = new JSONObject(sXML);
+	        JSONObject o = new JSONObject(xml);
 	        JSONArray operatorlist = o.getJSONArray("operators");
 	        autoOptimizeDelayCount = 0;
 	        for (int i = 0; i < operatorlist.length(); i++) {
@@ -260,23 +270,23 @@ public class OperatorSchedule extends BEASTObject {
 	    	}    
         } catch (JSONException e) {
         	// it is not a JSON file -- probably a version 2.0.X state file
-	        String[] sStrs = sXML.split("\n");
+	        String[] strs = xml.split("\n");
             autoOptimizeDelayCount = 0;
-	        for (int i = 0; i < operators.size() && i + 2 < sStrs.length; i++) {
-	            String[] sStrs2 = sStrs[i + 1].split(" ");
+	        for (int i = 0; i < operators.size() && i + 2 < strs.length; i++) {
+	            String[] strs2 = strs[i + 1].split(" ");
 	            Operator operator = operators.get(i);
-	            if ((operator.getID() == null && sStrs2[0].equals("null")) || operator.getID().equals(sStrs2[0])) {
-	                cumulativeProbs[i] = Double.parseDouble(sStrs2[1]);
-	                if (!sStrs2[2].equals("NaN")) {
-	                    operator.setCoercableParameterValue(Double.parseDouble(sStrs2[2]));
+	            if ((operator.getID() == null && strs2[0].equals("null")) || operator.getID().equals(strs2[0])) {
+	                cumulativeProbs[i] = Double.parseDouble(strs2[1]);
+	                if (!strs2[2].equals("NaN")) {
+	                    operator.setCoercableParameterValue(Double.parseDouble(strs2[2]));
 	                }
-	                operator.m_nNrAccepted = Integer.parseInt(sStrs2[3]);
-	                operator.m_nNrRejected = Integer.parseInt(sStrs2[4]);
+	                operator.m_nNrAccepted = Integer.parseInt(strs2[3]);
+	                operator.m_nNrRejected = Integer.parseInt(strs2[4]);
 	                autoOptimizeDelayCount += operator.m_nNrAccepted + operator.m_nNrRejected;
-	                operator.m_nNrAcceptedForCorrection = Integer.parseInt(sStrs2[5]);
-	                operator.m_nNrRejectedForCorrection = Integer.parseInt(sStrs2[6]);
+	                operator.m_nNrAcceptedForCorrection = Integer.parseInt(strs2[5]);
+	                operator.m_nNrRejectedForCorrection = Integer.parseInt(strs2[6]);
 	            } else {
-	                throw new Exception("Cannot resume: operator order or set changed from previous run");
+	                throw new RuntimeException("Cannot resume: operator order or set changed from previous run");
 	            }
 	        }
 	    }
diff --git a/src/beast/core/Param.java b/src/beast/core/Param.java
index 6cc9e2b..40854a0 100644
--- a/src/beast/core/Param.java
+++ b/src/beast/core/Param.java
@@ -8,36 +8,58 @@ import java.lang.annotation.Target;
 
 /**
  * This annotation should be used to provide information about parameters in the constructor of a BEAST object,
- * as an alternative way to represent inputs -- still under development!
+ * as an alternative way to represent inputs.
+ * 
+ * Note that any object with a constructor with Param annotations should also have a 
+ * public default constructor without arguments to facilitate cloning models in BEAUti.
+ * 
+ * Furthermore, every Param annotation should come with a public getter and setter, using 
+ * camelcase for name, with annotation CTor(@Param(name="shape",...) double shape) these 
+ * getter and setter signatures should be in the class: 
+ * 
+ * public double getShape() 
+ * public void setShape(double shape)
+ * 
  */
 @Target({ElementType.PARAMETER})
 @Retention(RetentionPolicy.RUNTIME)
 public @interface Param {
 
     /**
-     * The name of this parameter
-     *
-     * @return
+     * The name of this parameter, typically the same as the name
+     * of the constructor argument.
      */
     String name();
 
 
     /**
-     * The description of this parameter
-     *
-     * @return
+     * The description of this parameter. Must be specified and contain
+     * at least 4 words to pass the unit tests.
      */
     String description();
 
     /**
-     * @return the default value as a string
+     * @return the default value as a string. An attempt is made to 
+     * convert the String value defaultValue() to the type associated 
+     * with the constructor argument.
      */
     String defaultValue() default "";
 
+	/**
+	 * Indicates the value can be omitted, in which case the default 
+	 * value is used (an attempt is made to convert the String value 
+	 * defaultValue() to the type associated with the constructor 
+	 * argument).
+	 * 
+	 * Note that if there are different constructors and an argument 
+	 * does not appear in the other constructor it has to be marked 
+	 * as optional.
+	 */
     boolean optional() default false;
 
     /**
-     * @return true to indicate this description applies to all its inherited classes as well, false otherwise
+     * @return true to indicate this description applies to all its 
+     * inherited classes as well, false otherwise
      */
     boolean isInheritable() default true;
 }
\ No newline at end of file
diff --git a/src/beast/core/Runnable.java b/src/beast/core/Runnable.java
index 5c20cd5..d8e4474 100644
--- a/src/beast/core/Runnable.java
+++ b/src/beast/core/Runnable.java
@@ -12,20 +12,20 @@ public abstract class Runnable extends BEASTObject {
      * Set up information related to the file for (re)storing the State.
      * The Runnable implementation is responsible for making its
      * State synchronising with the file *
-     * @param sFileName
-     * @param bRestoreFromFile
+     * @param fileName
+     * @param isRestoreFromFile
      */
-    public void setStateFile(final String sFileName, final boolean bRestoreFromFile) {
+    public void setStateFile(final String fileName, final boolean isRestoreFromFile) {
     	if (System.getProperty("state.file.name") != null) {
     		stateFileName = System.getProperty("state.file.name");
     	} else {
             if (System.getProperty("file.name.prefix") != null) {
-            	stateFileName = System.getProperty("file.name.prefix") + "/" + sFileName;
+            	stateFileName = System.getProperty("file.name.prefix") + "/" + fileName;
             } else {
-            	stateFileName = sFileName;
+            	stateFileName = fileName;
             }
     	}
-        restoreFromFile = bRestoreFromFile;
+        restoreFromFile = isRestoreFromFile;
     }
 
     /**
diff --git a/src/beast/core/State.java b/src/beast/core/State.java
index 1973bae..fff32f3 100644
--- a/src/beast/core/State.java
+++ b/src/beast/core/State.java
@@ -27,18 +27,22 @@ package beast.core;
 
 import java.io.ByteArrayInputStream;
 import java.io.File;
+import java.io.IOException;
 import java.io.PrintStream;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 
 import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
 
-import beast.core.Input;
+import beast.core.util.Log;
 
 
 
@@ -50,12 +54,12 @@ import beast.core.Input;
 public class State extends BEASTObject {
 
     public final Input<List<StateNode>> stateNodeInput =
-            new Input<List<StateNode>>("stateNode", "anything that is part of the state", new ArrayList<StateNode>());
-    public Input<Integer> m_storeEvery =
-            new Input<Integer>("storeEvery", "store the state to disk every X number of samples so that we can " +
+            new Input<>("stateNode", "anything that is part of the state", new ArrayList<>());
+    final public Input<Integer> m_storeEvery =
+            new Input<>("storeEvery", "store the state to disk every X number of samples so that we can " +
                     "resume computation later on if the process failed half-way.", -1);
 //    public Input<Boolean> m_checkPoint =
-//            new Input<Boolean>("checkpoint", "keep saved states (every X samples).", false);
+//            new Input<>("checkpoint", "keep saved states (every X samples).", false);
 
     /**
      * The components of the state, for instance tree & parameters.
@@ -96,7 +100,7 @@ public class State extends BEASTObject {
      */
 
     /**
-     * Maps a Plugin to a list of Outputs.
+     * Maps a BEASTObject to a list of Outputs.
      * This map only contains those plug-ins that have a path to the posterior *
      */
     private HashMap<BEASTInterface, List<BEASTInterface>> outputMap;
@@ -104,7 +108,7 @@ public class State extends BEASTObject {
     /**
      * Same as m_outputMap, but only for StateNodes indexed by the StateNode number
      * We need this since the StateNode changes regularly, so unlike the output map
-     * for Plugins cannot be accessed by the current StateNode as key.
+     * for BEASTObjects cannot be accessed by the current StateNode as key.
      */
     private List<CalculationNode>[] stateNodeOutputs;
 
@@ -113,7 +117,7 @@ public class State extends BEASTObject {
      * during an operation.
      * <p/>
      * Every time an operation requests a StateNode, an entry is added to changeStateNodes
-     * nChangeStateNodes records how many StateNodes are changed.
+     * changeStateNodes records how many StateNodes are changed.
      * The code is reset when the state is stored, and every time a StateNode
      * is requested by an operator, changeStateNodes is updated.
      */
@@ -140,33 +144,33 @@ public class State extends BEASTObject {
 
         /**
          * get entry from Trie, return null if no entry is present yet *
-         * @param iPos
+         * @param pos
          */
-        List<CalculationNode> get(final int iPos) {
-            if (iPos == 0) {
+        List<CalculationNode> get(final int pos) {
+            if (pos == 0) {
                 return list;
             }
-            final Trie child = children[changeStateNodes[iPos - 1]];
+            final Trie child = children[changeStateNodes[pos - 1]];
             if (child == null) {
                 return null;
             }
-            return child.get(iPos - 1);
+            return child.get(pos - 1);
         }
 
         /**
          * set entry int Trie, create new entries if no entry is present yet *
          */
-        void set(final List<CalculationNode> list, final int iPos) {
-            if (iPos == 0) {
+        void set(final List<CalculationNode> list, final int pos) {
+            if (pos == 0) {
                 this.list = list;
                 return;
             }
-            Trie child = children[changeStateNodes[iPos - 1]];
+            Trie child = children[changeStateNodes[pos - 1]];
             if (child == null) {
                 child = new Trie();
-                children[changeStateNodes[iPos - 1]] = child;
+                children[changeStateNodes[pos - 1]] = child;
             }
-            child.set(list, iPos - 1);
+            child.set(list, pos - 1);
         }
     }
 
@@ -200,7 +204,7 @@ public class State extends BEASTObject {
         nrOfChangedStateNodes = 0;
         trie = new Trie();
         // add the empty list for the case none of the StateNodes have changed
-        trie.list = new ArrayList<CalculationNode>();
+        trie.list = new ArrayList<>();
     } // initAndValidate
 
 
@@ -210,8 +214,8 @@ public class State extends BEASTObject {
      * changing it. To change a StateNode, say from an Operator,
      * getEditableStateNode() should be called. *
      */
-    public StateNode getStateNode(final int nID) {
-        return stateNode[nID];
+    public StateNode getStateNode(final int _id) {
+        return stateNode[_id];
     }
 
     /**
@@ -223,14 +227,14 @@ public class State extends BEASTObject {
      * change the particular StateNode through the Input.get(Operator)
      * method on the input associated with this StateNode.
      */
-    protected StateNode getEditableStateNode(int nID, Operator operator) {
+    protected StateNode getEditableStateNode(int _id, Operator operator) {
         for (int i = 0; i < nrOfChangedStateNodes; i++) {
-            if (changeStateNodes[i] == nID) {
-                return stateNode[nID];
+            if (changeStateNodes[i] == _id) {
+                return stateNode[_id];
             }
         }
-        changeStateNodes[nrOfChangedStateNodes++] = nID;
-        return stateNode[nID];
+        changeStateNodes[nrOfChangedStateNodes++] = _id;
+        return stateNode[_id];
     }
 
     /**
@@ -241,10 +245,10 @@ public class State extends BEASTObject {
      * <p/>
      * Also, store the state to disk for resumption of analysis later on.
      *
-     * @param iSample chain state number
+     * @param sample chain state number
      * @return  true if stored  to disk
      */
-    public void store(final int iSample) {
+    public void store(final int sample) {
         //Arrays.fill(changeStateNodes, -1);
         nrOfChangedStateNodes = 0;
     }
@@ -261,7 +265,7 @@ public class State extends BEASTObject {
     }
 
     /**
-     * Visit all calculation nodes in partial order determined by the Plugin-input relations
+     * Visit all calculation nodes in partial order determined by the BEASTObject-input relations
      * (i.e. if A is input of B then A < B). There are 4 operations that can be propagated this
      * way:
      * <p/>
@@ -307,9 +311,9 @@ public class State extends BEASTObject {
     /**
      * set name of state file, used when storing/restoring the state to disk *
      */
-    public void setStateFileName(final String sFileName) {
-        if (sFileName != null) {
-            stateFileName = sFileName;
+    public void setStateFileName(final String fileName) {
+        if (fileName != null) {
+            stateFileName = fileName;
         }
     }
 
@@ -317,18 +321,19 @@ public class State extends BEASTObject {
      * Print state to file. This is called either periodically or at the end
      * of an MCMC chain, so that the state can be resumed later on.
      *
-     * @param iSample TODO
+     * @param sample TODO
      */
-    public void storeToFile(final int iSample) {
+    public void storeToFile(final int sample) {
         try {
             PrintStream out = new PrintStream(stateFileName + ".new");
-            out.print(toXML(iSample));
+            out.print(toXML(sample));
             //out.print(new XMLProducer().toXML(this));
             out.close();
             File newStateFile = new File(stateFileName + ".new");
             File oldStateFile = new File(stateFileName);
             oldStateFile.delete();
-            newStateFile.renameTo(oldStateFile);
+            // newStateFile.renameTo(oldStateFile); -- unstable under windows
+            Files.move(newStateFile.toPath(), oldStateFile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
         } catch (Exception e) {
             e.printStackTrace();
         }
@@ -338,11 +343,11 @@ public class State extends BEASTObject {
      * convert state to XML string,
      * The state can be reconstructed using the fromXML() method
      *
-     * @param iSample TODO*
+     * @param sample TODO*
      */
-    public String toXML(final int iSample) {
+    public String toXML(final int sample) {
         final StringBuilder buf = new StringBuilder();
-        buf.append("<itsabeastystatewerein version='2.0' sample='").append(iSample).append("'>\n");
+        buf.append("<itsabeastystatewerein version='2.0' sample='").append(sample).append("'>\n");
         for (final StateNode node : stateNode) {
             buf.append(node.toXML());
         }
@@ -353,64 +358,67 @@ public class State extends BEASTObject {
     /**
      * Restore state from an XML fragment *
      */
-    public void fromXML(final String sXML) {
+    public void fromXML(final String xml) {
         try {
             final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-            final Document doc = factory.newDocumentBuilder().parse(new ByteArrayInputStream(sXML.getBytes()));
+            final Document doc = factory.newDocumentBuilder().parse(new ByteArrayInputStream(xml.getBytes()));
             doc.normalize();
             final NodeList nodes = doc.getElementsByTagName("*");
             final Node topNode = nodes.item(0);
             final NodeList children = topNode.getChildNodes();
-            for (int iChild = 0; iChild < children.getLength(); iChild++) {
-                final Node child = children.item(iChild);
+            for (int childIndex = 0; childIndex < children.getLength(); childIndex++) {
+                final Node child = children.item(childIndex);
                 if (child.getNodeType() == Node.ELEMENT_NODE) {
-                    final String sID = child.getAttributes().getNamedItem("id").getNodeValue();
-                    int iStateNode = 0;
-                    while (!stateNode[iStateNode].getID().equals(sID)) {
-                        iStateNode++;
+                    final String id = child.getAttributes().getNamedItem("id").getNodeValue();
+                    int stateNodeIndex = 0;
+                    while (!stateNode[stateNodeIndex].getID().equals(id)) {
+                        stateNodeIndex++;
                     }
-                    final StateNode stateNode2 = stateNode[iStateNode].copy();
+                    final StateNode stateNode2 = stateNode[stateNodeIndex].copy();
                     stateNode2.fromXML(child);
-                    stateNode[iStateNode].assignFromFragile(stateNode2);
+                    stateNode[stateNodeIndex].assignFromFragile(stateNode2);
                 }
             }
         } catch (Exception e) {
             e.printStackTrace();
-            System.exit(0);
+            System.exit(1);
         }
     }
 
     /**
-     * restore a state from file for resuming an MCMC chain *
+     * restore a state from file for resuming an MCMC chain 
+     * @throws ParserConfigurationException 
+     * @throws IOException 
+     * @throws SAXException *
      */
-    public void restoreFromFile() throws Exception {
-        System.out.println("Restoring from file");
+    public void restoreFromFile() throws SAXException, IOException, ParserConfigurationException  {
+        Log.info.println("Restoring from file");
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
         Document doc = factory.newDocumentBuilder().parse(new File(stateFileName));
         doc.normalize();
         final NodeList nodes = doc.getElementsByTagName("*");
         final Node topNode = nodes.item(0);
         final NodeList children = topNode.getChildNodes();
-        for (int iChild = 0; iChild < children.getLength(); iChild++) {
-            final Node child = children.item(iChild);
+        for (int childIndex = 0; childIndex < children.getLength(); childIndex++) {
+            final Node child = children.item(childIndex);
             if (child.getNodeType() == Node.ELEMENT_NODE) {
-                final String sID = child.getAttributes().getNamedItem("id").getNodeValue();
-                int iStateNode = 0;
+                final String id = child.getAttributes().getNamedItem("id").getNodeValue();
+                int stateNodeIndex = 0;
 
                 // An init node without ID - should not bring the house down, does it?
                 // I have not checked if the state is restored correctly or not (JH)
-                while (stateNode[iStateNode].getID() != null &&
-                        !stateNode[iStateNode].getID().equals(sID)) {
-                    iStateNode++;
-                    if (iStateNode >= stateNode.length) {
-                    	System.err.println("Cannot resotre statenode sID");
+                while (stateNode[stateNodeIndex].getID() != null &&
+                        !stateNode[stateNodeIndex].getID().equals(id)) {
+                    stateNodeIndex++;
+                    if (stateNodeIndex >= stateNode.length) {
+                    	Log.warning.println("Cannot restore statenode id");
                     	break;
                     }
                 }
-                if (iStateNode < stateNode.length) {
-	                final StateNode stateNode2 = stateNode[iStateNode].copy();
+                if (stateNodeIndex < stateNode.length) {
+	                final StateNode stateNode2 = stateNode[stateNodeIndex].copy();
 	                stateNode2.fromXML(child);
-	                stateNode[iStateNode].assignFromFragile(stateNode2);
+	                stateNode[stateNodeIndex].assignFromFragile(stateNode2);
                 }
             }
         }
@@ -453,38 +461,38 @@ public class State extends BEASTObject {
     /**
      * Sets the posterior, needed to calculate paths of CalculationNode
      * that need store/restore/requireCalculation checks.
-     * As a side effect, outputs for every plugin in the model are calculated.
-     * NB the output map only contains outputs on a path to the posterior Plugin!
+     * As a side effect, outputs for every beastObject in the model are calculated.
+     * NB the output map only contains outputs on a path to the posterior BEASTObject!
      */
     @SuppressWarnings("unchecked")
-    public void setPosterior(BEASTObject posterior) throws Exception {
-        // first, calculate output map that maps Plugins on a path
-        // to the posterior to the list of output Plugins. Strictly
+    public void setPosterior(BEASTObject posterior) {
+        // first, calculate output map that maps BEASTObjects on a path
+        // to the posterior to the list of output BEASTObjects. Strictly
         // speaking, this is a bit of overkill, since only
         // CalculationNodes need to be taken in account, but for
         // debugging purposes (developer forgot to derive from CalculationNode)
         // we keep track of the lot.
-        outputMap = new HashMap<BEASTInterface, List<BEASTInterface>>();
-        outputMap.put(posterior, new ArrayList<BEASTInterface>());
-        boolean bProgress = true;
-        List<BEASTInterface> plugins = new ArrayList<BEASTInterface>();
-        plugins.add(posterior);
-        while (bProgress) {
-            bProgress = false;
+        outputMap = new HashMap<>();
+        outputMap.put(posterior, new ArrayList<>());
+        boolean progress = true;
+        List<BEASTInterface> beastObjects = new ArrayList<>();
+        beastObjects.add(posterior);
+        while (progress) {
+            progress = false;
             // loop over plug-ins, till no more plug-ins can be added
             // efficiency is no issue here
-            for (int iPlugin = 0; iPlugin < plugins.size(); iPlugin++) {
-            	BEASTInterface plugin = plugins.get(iPlugin);
+            for (int i = 0; i < beastObjects.size(); i++) {
+            	BEASTInterface beastObject = beastObjects.get(i);
                 try {
-                    for (BEASTInterface inputPlugin : plugin.listActivePlugins()) {
-                        if (!outputMap.containsKey(inputPlugin)) {
-                            outputMap.put(inputPlugin, new ArrayList<BEASTInterface>());
-                            plugins.add(inputPlugin);
-                            bProgress = true;
+                    for (BEASTInterface inputBEASTObject : beastObject.listActiveBEASTObjects()) {
+                        if (!outputMap.containsKey(inputBEASTObject)) {
+                            outputMap.put(inputBEASTObject, new ArrayList<>());
+                            beastObjects.add(inputBEASTObject);
+                            progress = true;
                         }
-                        if (!outputMap.get(inputPlugin).contains(plugin)) {
-                            outputMap.get(inputPlugin).add(plugin);
-                            bProgress = true;
+                        if (!outputMap.get(inputBEASTObject).contains(beastObject)) {
+                            outputMap.get(inputBEASTObject).add(beastObject);
+                            progress = true;
                         }
                     }
                 } catch (Exception e) {
@@ -497,17 +505,17 @@ public class State extends BEASTObject {
         // to use another method to find the outputs, an array in this case.
         stateNodeOutputs = new List[stateNode.length];
         for (int i = 0; i < stateNode.length; i++) {
-            stateNodeOutputs[i] = new ArrayList<CalculationNode>();
+            stateNodeOutputs[i] = new ArrayList<>();
             if (outputMap.containsKey(stateNode[i])) {
-                for (BEASTInterface plugin : outputMap.get(stateNode[i])) {
-                    if (plugin instanceof CalculationNode) {
-                        stateNodeOutputs[i].add((CalculationNode) plugin);
+                for (BEASTInterface beastObject : outputMap.get(stateNode[i])) {
+                    if (beastObject instanceof CalculationNode) {
+                        stateNodeOutputs[i].add((CalculationNode) beastObject);
                     } else {
-                        throw new Exception("DEVELOPER ERROR: output of StateNode (" + stateNode[i].getID() + ") should be a CalculationNode, but " + plugin.getClass().getName() + " is not.");
+                        throw new RuntimeException("DEVELOPER ERROR: output of StateNode (" + stateNode[i].getID() + ") should be a CalculationNode, but " + beastObject.getClass().getName() + " is not.");
                     }
                 }
             } else {
-                System.out.println("\nWARNING: StateNode (" + stateNode[i].getID() + ") found that has no effect on posterior!\n");
+                Log.warning.println("\nWARNING: StateNode (" + stateNode[i].getID() + ") found that has no effect on posterior!\n");
             }
         }
     } // setPosterior
@@ -533,7 +541,7 @@ public class State extends BEASTObject {
 
 //    	System.err.print(Arrays.toString(changeStateNodes) + ":");
 //    	for (CalculationNode node : calcNodes) {
-//    		System.err.print(node.m_sID + " ");
+//    		Log.warning.print(node.m_sID + " ");
 //    	}
 //    	System.err.println();
 
@@ -544,40 +552,42 @@ public class State extends BEASTObject {
     /**
      * Collect all CalculationNodes on a path from any StateNode that is changed (as
      * indicated by m_changedStateNodeCode) to the posterior. Return the list in
-     * partial order as determined by the Plugins input relations.
+     * partial order as determined by the BEASTObjects input relations.
+     * @throws IllegalAccessException 
+     * @throws IllegalArgumentException 
      */
-    private List<CalculationNode> calculateCalcNodePath() throws Exception {
-        final List<CalculationNode> calcNodes = new ArrayList<CalculationNode>();
+    private List<CalculationNode> calculateCalcNodePath() throws IllegalArgumentException, IllegalAccessException {
+        final List<CalculationNode> calcNodes = new ArrayList<>();
 //    	for (int i = 0; i < stateNode.length; i++) {
 //    		if (m_changedStateNodeCode.get(i)) {
         for (int k = 0; k < nrOfChangedStateNodes; k++) {
             int i = changeStateNodes[k];
             // go grab the path to the Runnable
             // first the outputs of the StateNodes that is changed
-            boolean bProgress = false;
+            boolean progress = false;
             for (CalculationNode node : stateNodeOutputs[i]) {
                 if (!calcNodes.contains(node)) {
                     calcNodes.add(node);
-                    bProgress = true;
+                    progress = true;
                 }
             }
             // next the path following the outputs
-            while (bProgress) {
-                bProgress = false;
-                // loop over plugins till no more plugins can be added
+            while (progress) {
+                progress = false;
+                // loop over beastObjects till no more beastObjects can be added
                 // efficiency is no issue here, assuming the graph remains 
                 // constant
-                for (int iCalcNode = 0; iCalcNode < calcNodes.size(); iCalcNode++) {
-                    CalculationNode node = calcNodes.get(iCalcNode);
+                for (int calcNodeIndex = 0; calcNodeIndex < calcNodes.size(); calcNodeIndex++) {
+                    CalculationNode node = calcNodes.get(calcNodeIndex);
                     for (BEASTInterface output : outputMap.get(node)) {
                         if (output instanceof CalculationNode) {
                             final CalculationNode calcNode = (CalculationNode) output;
                             if (!calcNodes.contains(calcNode)) {
                                 calcNodes.add(calcNode);
-                                bProgress = true;
+                                progress = true;
                             }
                         } else {
-                            throw new Exception("DEVELOPER ERROR: found a"
+                            throw new RuntimeException("DEVELOPER ERROR: found a"
                                     + " non-CalculatioNode ("
                                     +output.getClass().getName()
                                     +") on path between StateNode and Runnable");
@@ -591,7 +601,7 @@ public class State extends BEASTObject {
         // put calc nodes in partial order
         for (int i = 0; i < calcNodes.size(); i++) {
             CalculationNode node = calcNodes.get(i);
-            List<BEASTInterface> inputList = node.listActivePlugins();
+            List<BEASTInterface> inputList = node.listActiveBEASTObjects();
             for (int j = calcNodes.size() - 1; j > i; j--) {
                 if (inputList.contains(calcNodes.get(j))) {
                     // swap
@@ -608,25 +618,25 @@ public class State extends BEASTObject {
     } // calculateCalcNodePath
 
 
-    public double robustlyCalcPosterior(final Distribution posterior) throws Exception {
+    public double robustlyCalcPosterior(final Distribution posterior) {
         store(-1);
         setEverythingDirty(true);
         //state.storeCalculationNodes();
         checkCalculationNodesDirtiness();
-        final double fLogLikelihood = posterior.calculateLogP();
+        final double logLikelihood = posterior.calculateLogP();
         setEverythingDirty(false);
         acceptCalculationNodes();
-        return fLogLikelihood;
+        return logLikelihood;
     }
 
-	public double robustlyCalcNonStochasticPosterior(Distribution posterior) throws Exception {
+	public double robustlyCalcNonStochasticPosterior(Distribution posterior)  {
         store(-1);
         setEverythingDirty(true);
         storeCalculationNodes();
         checkCalculationNodesDirtiness();
-        final double fLogLikelihood = posterior.getNonStochasticLogP();
+        final double logLikelihood = posterior.getNonStochasticLogP();
         setEverythingDirty(false);
         acceptCalculationNodes();
-        return fLogLikelihood;
+        return logLikelihood;
 	}
 } // class State
diff --git a/src/beast/core/StateNode.java b/src/beast/core/StateNode.java
index 4fba54f..6bb3938 100644
--- a/src/beast/core/StateNode.java
+++ b/src/beast/core/StateNode.java
@@ -1,9 +1,9 @@
 package beast.core;
 
-import org.w3c.dom.Node;
-
 import java.io.PrintStream;
 
+import org.w3c.dom.Node;
+
 /**
  * This class represents a node of the state. Concrete classes include Parameters and Trees.
  * StateNodes differ from CalculationNodes in that they
@@ -18,7 +18,7 @@ public abstract class StateNode extends CalculationNode implements Loggable, Clo
      * Flag to indicate the StateNode is not constant.
      * This is particularly useful for Beauti *
      */
-    public Input<Boolean> isEstimatedInput = new Input<Boolean>("estimate", "whether to estimate this item or keep constant to its initial value", true);
+    final public Input<Boolean> isEstimatedInput = new Input<>("estimate", "whether to estimate this item or keep constant to its initial value", true);
 
     /**
      * @return this StateNode if it is not in the State.
@@ -93,9 +93,9 @@ public abstract class StateNode extends CalculationNode implements Loggable, Clo
      * NB: Should only be used for initialisation!
      */
     public void assignFromWithoutID(StateNode other) {
-        final String sID = getID();
+        final String id = getID();
         assignFrom(other);
-        setID(sID);
+        setID(id);
     }
 
     /**
@@ -148,17 +148,17 @@ public abstract class StateNode extends CalculationNode implements Loggable, Clo
 //    boolean isStochastic = true;
 
     /**
-     * Scale StateNode with amount fScale and
+     * Scale StateNode with amount scale and
      *
-     * @param fScale scaling factor
+     * @param scale scaling factor
      * @return the number of degrees of freedom used in this operation. This number varies
      *         for the different types of StateNodes. For example, for real
      *         valued n-dimensional parameters, it is n, for a tree it is the
      *         number of internal nodes being scaled.
-     * @throws Exception when StateNode become not valid, e.g. has
+     * @throws IllegalArgumentException when StateNode become not valid, e.g. has
      *                   values outside bounds or negative branch lengths.
      */
-    abstract public int scale(double fScale) throws Exception;
+    abstract public int scale(double scale);
 
     /**
      * Pointer to state, null if not part of a State.
@@ -220,8 +220,10 @@ public abstract class StateNode extends CalculationNode implements Loggable, Clo
         return true;
     }
 
-    abstract protected void store();
+    @Override
+	abstract protected void store();
 
-    abstract public void restore();
+    @Override
+	abstract public void restore();
 
 } // class StateNode
diff --git a/src/beast/core/StateNodeInitialiser.java b/src/beast/core/StateNodeInitialiser.java
index 5afa4f6..10fa529 100644
--- a/src/beast/core/StateNodeInitialiser.java
+++ b/src/beast/core/StateNodeInitialiser.java
@@ -5,14 +5,14 @@ import java.util.List;
 /**
  * Typically, StateNodes are initialised through their inputs. However, there are initialisation scenarios
  * too complex for this approach to work. For example, initialisation may require additional information not
- * provided by the inputs, or several dependent plugins need to initialise together,
+ * provided by the inputs, or several dependent beastObjects need to initialise together,
  * such as gene trees and a species tree.
  * <p/>
  * StateNodeInitialisers take one or more StateNodes as input and  initializes them in initStateNodes().
  * getInitialisedStateNodes() reports back which nodes has been initialized, but this is currently only used to
  * check for multiple initialiser for the same object.
  *  <p/>
- * Like any other iBEASTObject, a state initialiser must have an initAndValidate(), which is called once.
+ * Like any other isEASTObject, a state initialiser must have an initAndValidate(), which is called once.
  * getInitialisedStateNodes(), on the other hand,  may be called multiple times as its inputs change while the system
  * tries to establish a valid starting state. initAndValidate is executed in order that the XML parser see objects,
  * so the inputs are not guaranteed to be initialized at this time. initStateNodes is executed in order of appearance
@@ -25,7 +25,7 @@ public interface StateNodeInitialiser {
     /**
      * Called to set up start state. May be called multiple times. *
      */
-    void initStateNodes() throws Exception;
+    void initStateNodes();
 
     /**
      * @return list of StateNodes that are initialised
diff --git a/src/beast/core/parameter/BooleanParameter.java b/src/beast/core/parameter/BooleanParameter.java
index 556c00f..e408de4 100644
--- a/src/beast/core/parameter/BooleanParameter.java
+++ b/src/beast/core/parameter/BooleanParameter.java
@@ -25,10 +25,11 @@
 package beast.core.parameter;
 
 
-import beast.core.Description;
-
 import java.io.PrintStream;
 
+import beast.core.Description;
+import beast.core.util.Log;
+
 
 /**
  * @author Joseph Heled
@@ -40,16 +41,16 @@ public class BooleanParameter extends Parameter.Base<java.lang.Boolean> {
         m_fUpper = true;
     }
 
-    public BooleanParameter(Boolean[] fValues) {
-        super(fValues);
+    public BooleanParameter(Boolean[] values) {
+        super(values);
         m_fUpper = true;
     }
 
     /**
      * Constructor used by Input.setValue(String) *
      */
-    public BooleanParameter(String sValue) throws Exception {
-        init(sValue, 1);
+    public BooleanParameter(String value) {
+        init(value, 1);
         m_fUpper = true;
     }
 
@@ -80,20 +81,20 @@ public class BooleanParameter extends Parameter.Base<java.lang.Boolean> {
     }
 
     @Override
-    public double getArrayValue(int iValue) {
-        return (values[iValue] ? 1 : 0);
+    public double getArrayValue(int value) {
+        return (values[value] ? 1 : 0);
     }
 
     /**
      * Loggable implementation follows *
      */
     @Override
-    public void log(int nSample, PrintStream out) {
+    public void log(int sampleNr, PrintStream out) {
         BooleanParameter var = (BooleanParameter) getCurrent();
-        int nValues = var.getDimension();
-        for (int iValue = 0; iValue < nValues; iValue++) {
+        int valueCount = var.getDimension();
+        for (int i = 0; i < valueCount; i++) {
             // Output 0/1 for tracer
-            out.print((var.getValue(iValue) ? '1' : '0') + "\t");
+            out.print((var.getValue(i) ? '1' : '0') + "\t");
         }
     }
 
@@ -101,17 +102,17 @@ public class BooleanParameter extends Parameter.Base<java.lang.Boolean> {
      * StateNode methods *
      */
     @Override
-    public int scale(double fScale) {
+    public int scale(double scale) {
         // nothing to do
-        System.err.println("Attempt to scale Boolean parameter " + getID() + "  has no effect");
+        Log.warning.println("Attempt to scale Boolean parameter " + getID() + "  has no effect");
         return 0;
     }
 
     @Override
-    void fromXML(int nDimension, String sLower, String sUpper, String[] sValues) {
-        values = new Boolean[nDimension];
-        for (int i = 0; i < sValues.length; i++) {
-            values[i] = Boolean.parseBoolean(sValues[i]);
+    void fromXML(int dimension, String lower, String upper, String[] valueStrings) {
+        values = new Boolean[dimension];
+        for (int i = 0; i < valueStrings.length; i++) {
+            values[i] = Boolean.parseBoolean(valueStrings[i]);
         }
     }
 }
diff --git a/src/beast/core/parameter/BooleanParameterList.java b/src/beast/core/parameter/BooleanParameterList.java
index 309fd3a..e1aedf4 100644
--- a/src/beast/core/parameter/BooleanParameterList.java
+++ b/src/beast/core/parameter/BooleanParameterList.java
@@ -1,9 +1,9 @@
 package beast.core.parameter;
 
-import beast.core.Description;
-import beast.core.Input;
 import java.util.List;
 
+import beast.core.Description;
+
 /**
  * @author Tim Vaughan <tgvaughan at gmail.com>
  */
diff --git a/src/beast/core/parameter/CompoundValuable.java b/src/beast/core/parameter/CompoundValuable.java
index 35e8304..1c70d1e 100644
--- a/src/beast/core/parameter/CompoundValuable.java
+++ b/src/beast/core/parameter/CompoundValuable.java
@@ -3,21 +3,21 @@ package beast.core.parameter;
 import java.util.ArrayList;
 import java.util.List;
 
+import beast.core.BEASTObject;
 import beast.core.CalculationNode;
 import beast.core.Description;
 import beast.core.Function;
 import beast.core.Input;
-import beast.core.StateNode;
-import beast.core.BEASTObject;
 import beast.core.Input.Validate;
+import beast.core.StateNode;
 
 
 
 @Description("Summarizes a set of valuables so that for example a rate matrix can be " +
         "specified that uses a parameter in various places in the matrix.")
 public class CompoundValuable extends CalculationNode implements Function {
-    public Input<List<BEASTObject>> m_values = new Input<List<BEASTObject>>("var", "reference to a valuable",
-            new ArrayList<BEASTObject>(), Validate.REQUIRED, Function.class);
+    final public Input<List<BEASTObject>> m_values = new Input<>("var", "reference to a valuable",
+            new ArrayList<>(), Validate.REQUIRED, Function.class);
 
     boolean m_bRecompute = true;
     /**
@@ -26,16 +26,16 @@ public class CompoundValuable extends CalculationNode implements Function {
     double[] m_fValues;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         // determine dimension
-        int nDimension = 0;
-        for (BEASTObject plugin : m_values.get()) {
-            if (!(plugin instanceof Function)) {
-                throw new Exception("Input does not implement Valuable");
+        int dimension = 0;
+        for (BEASTObject beastObject : m_values.get()) {
+            if (!(beastObject instanceof Function)) {
+                throw new IllegalArgumentException("Input does not implement Valuable");
             }
-            nDimension += ((Function) plugin).getDimension();
+            dimension += ((Function) beastObject).getDimension();
         }
-        m_fValues = new double[nDimension];
+        m_fValues = new double[dimension];
     }
 
     /**
@@ -55,11 +55,11 @@ public class CompoundValuable extends CalculationNode implements Function {
     }
 
     @Override
-    public double getArrayValue(int iDim) {
+    public double getArrayValue(int dim) {
         if (m_bRecompute) {
             recompute();
         }
-        return m_fValues[iDim];
+        return m_fValues[dim];
     }
 
     /**
@@ -67,13 +67,13 @@ public class CompoundValuable extends CalculationNode implements Function {
      */
     private void recompute() {
         int k = 0;
-        for (BEASTObject plugin : m_values.get()) {
-            Function valuable = (Function) plugin;
-            if (plugin instanceof StateNode) {
-                valuable = ((StateNode) plugin).getCurrent();
+        for (BEASTObject beastObject : m_values.get()) {
+            Function valuable = (Function) beastObject;
+            if (beastObject instanceof StateNode) {
+                valuable = ((StateNode) beastObject).getCurrent();
             }
-            int nDimension = valuable.getDimension();
-            for (int i = 0; i < nDimension; i++) {
+            int dimension = valuable.getDimension();
+            for (int i = 0; i < dimension; i++) {
                 m_fValues[k++] = valuable.getArrayValue(i);
             }
         }
diff --git a/src/beast/core/parameter/GeneralParameterList.java b/src/beast/core/parameter/GeneralParameterList.java
index a44bd63..3f1dbc9 100644
--- a/src/beast/core/parameter/GeneralParameterList.java
+++ b/src/beast/core/parameter/GeneralParameterList.java
@@ -18,19 +18,20 @@
  */
 package beast.core.parameter;
 
-import beast.core.Description;
-import beast.core.Input;
-import beast.core.StateNode;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.TreeSet;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+
 import org.w3c.dom.Node;
 
+import beast.core.Description;
+import beast.core.Input;
+import beast.core.StateNode;
+import beast.core.util.Log;
+
 /**
  * @author Tim Vaughan <tgvaughan at gmail.com>
  * @param <T> Type of parameters in list.
@@ -42,15 +43,15 @@ import org.w3c.dom.Node;
         + "parameters must have identical dimensions and bounds.")
 public abstract class GeneralParameterList<T> extends StateNode {
     
-    public Input<List<Parameter.Base>> initialParamsInput = new Input<List<Parameter.Base>>(
+    final public Input<List<Parameter.Base<T>>> initialParamsInput = new Input<>(
             "initialParam",
             "Parameter whose value will initially be in parameter list.",
-            new ArrayList<Parameter.Base>());
+            new ArrayList<>());
     
-    public Input<Integer> dimensionInput = new Input<Integer>("dimension",
+    final public Input<Integer> dimensionInput = new Input<>("dimension",
             "Dimension of individual parameters in list.  Default 1.", 1);
     
-    public Input<Integer> minorDimensionInput = new Input<Integer>("minordimension",
+    final public Input<Integer> minorDimensionInput = new Input<>("minordimension",
             "Minor dimension of individual parameters in list. Default 1.", 1);
     
 
@@ -67,17 +68,17 @@ public abstract class GeneralParameterList<T> extends StateNode {
     
     @Override
     public void initAndValidate() {
-        pList = new ArrayList<QuietParameter>();
-        pListStored = new ArrayList<QuietParameter>();
-        deallocatedKeys = new TreeSet<Integer>();
-        deallocatedKeysStored = new TreeSet<Integer>();
+        pList = new ArrayList<>();
+        pListStored = new ArrayList<>();
+        deallocatedKeys = new TreeSet<>();
+        deallocatedKeysStored = new TreeSet<>();
         nextUnallocatedKey = 0;
         nextUnallocatedKeyStored = 0;
         
         dimension = dimensionInput.get();
         minorDimension = minorDimensionInput.get();
         
-        for (Parameter param : initialParamsInput.get()) {
+        for (Parameter<?> param : initialParamsInput.get()) {
             if (param.getDimension() != dimension)
                 throw new IllegalArgumentException("Parameter dimension does not equal"
                         + " dimension specified in enclosing ParameterList.");
@@ -187,7 +188,7 @@ public abstract class GeneralParameterList<T> extends StateNode {
      * @param otherParam
      * @return New parameter.
      */
-    public QuietParameter createNewParam(Parameter otherParam) {
+    public QuietParameter createNewParam(Parameter<?> otherParam) {
         QuietParameter param = new QuietParameter(otherParam);
         allocateKey(param);
         return param;
@@ -212,7 +213,7 @@ public abstract class GeneralParameterList<T> extends StateNode {
      * @param otherParam
      * @return New parameter.
      */
-    public QuietParameter addNewParam(Parameter otherParam) {
+    public QuietParameter addNewParam(Parameter<?> otherParam) {
         startEditing(null);
         QuietParameter param = new QuietParameter(otherParam);
         allocateKey(param);
@@ -238,7 +239,8 @@ public abstract class GeneralParameterList<T> extends StateNode {
     public StateNode copy() {
 
         try {
-            GeneralParameterList<T> copy = (GeneralParameterList<T>) this.clone();
+            @SuppressWarnings("unchecked")
+			GeneralParameterList<T> copy = (GeneralParameterList<T>) this.clone();
             copy.initAndValidate();
                     
             copy.pList.clear();
@@ -257,7 +259,7 @@ public abstract class GeneralParameterList<T> extends StateNode {
             return copy;
         
         } catch (CloneNotSupportedException ex) {
-            Logger.getLogger(GeneralParameterList.class.getName()).log(Level.SEVERE, null, ex);
+            Log.err(ex.getMessage());
         }
         
         return null;
@@ -269,7 +271,8 @@ public abstract class GeneralParameterList<T> extends StateNode {
             throw new RuntimeException("Incompatible statenodes in assignTo "
                     + "call.");
         
-        GeneralParameterList otherParamList = (GeneralParameterList)other;
+        @SuppressWarnings("unchecked")
+		GeneralParameterList<T> otherParamList = (GeneralParameterList<T>)other;
         
         otherParamList.pList.clear();
         for (QuietParameter param : pList)
@@ -279,27 +282,28 @@ public abstract class GeneralParameterList<T> extends StateNode {
         otherParamList.minorDimension = minorDimension;
         otherParamList.lowerBound = lowerBound;
         otherParamList.upperBound = upperBound;
-        otherParamList.deallocatedKeys = new TreeSet<Integer>(deallocatedKeys);
+        otherParamList.deallocatedKeys = new TreeSet<>(deallocatedKeys);
         otherParamList.nextUnallocatedKey = nextUnallocatedKey;
     }
 
-    @Override
+    @SuppressWarnings("unchecked")
+	@Override
     public void assignFrom(StateNode other) {
         if (!(other instanceof GeneralParameterList))
             throw new RuntimeException("Incompatible statenodes in assignFrom "
                     + "call.");
         
-        GeneralParameterList<T> otherParamList = (GeneralParameterList<T>)other;
+		GeneralParameterList<T> otherParamList = (GeneralParameterList<T>)other;
         
         pList.clear();
         for (Object paramObj : otherParamList.pList)
-            pList.add((QuietParameter)paramObj);
+            pList.add((QuietParameter) paramObj);
         
         dimension = otherParamList.dimension;
         minorDimension = otherParamList.minorDimension;
         lowerBound = otherParamList.lowerBound;
         upperBound = otherParamList.upperBound;
-        deallocatedKeys = new TreeSet<Integer>(otherParamList.deallocatedKeys);
+        deallocatedKeys = new TreeSet<>(otherParamList.deallocatedKeys);
         nextUnallocatedKey = otherParamList.nextUnallocatedKey;
     }
 
@@ -387,7 +391,7 @@ public abstract class GeneralParameterList<T> extends StateNode {
         // non-abstract classes (where type T is known).
         String [] boundsStr = matcher.group(2).split(",");
         
-        List<String[]> parameterValueStrings = new ArrayList<String[]>();
+        List<String[]> parameterValueStrings = new ArrayList<>();
         String parameterListString = matcher.group(5).trim();
         
         pattern = Pattern.compile("\\[([^]]*)]");
@@ -397,7 +401,7 @@ public abstract class GeneralParameterList<T> extends StateNode {
             parameterValueStrings.add(parameterMatcher.group(1).split(","));
         
         // Parse key strings:
-        List<Integer> keys = new ArrayList<Integer>();
+        List<Integer> keys = new ArrayList<>();
         for (String keyString : matcher.group(6).split(","))
             keys.add(Integer.parseInt(keyString.trim()));
         
@@ -418,7 +422,7 @@ public abstract class GeneralParameterList<T> extends StateNode {
             List<Integer> keys);
 
     @Override
-    public int scale(double fScale) throws Exception {
+    public int scale(double scale) {
         throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
     }
 
@@ -459,12 +463,12 @@ public abstract class GeneralParameterList<T> extends StateNode {
     */
     
     @Override
-    public void init(PrintStream out) throws Exception {
+    public void init(PrintStream out) {
         out.print(getID() + ".size\t");
     }
 
     @Override
-    public void log(int nSample, PrintStream out) {
+    public void log(int sample, PrintStream out) {
         out.print(pList.size() + "\t");
     }
 
@@ -519,7 +523,7 @@ public abstract class GeneralParameterList<T> extends StateNode {
          * 
          * @param param 
          */
-        QuietParameter(Parameter param) {
+        QuietParameter(Parameter<?> param) {
             if (param.getDimension() != dimension)
                 throw new IllegalArgumentException("Cannot construct "
                         + "ParameterList parameter with a dimension not equal "
@@ -536,12 +540,14 @@ public abstract class GeneralParameterList<T> extends StateNode {
             return key;
         }
         
-        @Override
+        @SuppressWarnings("unchecked")
+		@Override
         public T getValue(int i) {
             return (T)values[i];
         }
 
-        @Override
+        @SuppressWarnings("unchecked")
+		@Override
         public T getValue() {
             return (T)values[0];
         }
@@ -578,7 +584,8 @@ public abstract class GeneralParameterList<T> extends StateNode {
             upperBound = upper;
         }
 
-        @Override
+        @SuppressWarnings("unchecked")
+		@Override
         public T[] getValues() {
             return (T[])values;
         }
@@ -599,7 +606,8 @@ public abstract class GeneralParameterList<T> extends StateNode {
         }
         
         
-        @Override
+        @SuppressWarnings("unchecked")
+		@Override
         public T getMatrixValue(int i, int j) {
             return (T)values[i*minorDimension+j];
         }
diff --git a/src/beast/core/parameter/IntegerParameter.java b/src/beast/core/parameter/IntegerParameter.java
index 688f397..72dc5b6 100644
--- a/src/beast/core/parameter/IntegerParameter.java
+++ b/src/beast/core/parameter/IntegerParameter.java
@@ -1,10 +1,11 @@
 package beast.core.parameter;
 
 
+import java.io.PrintStream;
+
 import beast.core.Description;
 import beast.core.Input;
-
-import java.io.PrintStream;
+import beast.core.util.Log;
 
 
 /**
@@ -14,25 +15,25 @@ import java.io.PrintStream;
 @Description("An integer-valued parameter represents a value (or array of values if the dimension is larger than one) " +
         "in the state space that can be changed by operators.")
 public class IntegerParameter extends Parameter.Base<java.lang.Integer> {
-    public Input<Integer> lowerValueInput = new Input<Integer>("lower", "lower value for this parameter (default -infinity)");
-    public Input<Integer> upperValueInput = new Input<Integer>("upper", "upper value for this parameter  (default +infinity)");
+    final public Input<Integer> lowerValueInput = new Input<>("lower", "lower value for this parameter (default -infinity)");
+    final public Input<Integer> upperValueInput = new Input<>("upper", "upper value for this parameter  (default +infinity)");
 
     public IntegerParameter() {
     }
 
-    public IntegerParameter(Integer[] fValues) {
-        super(fValues);
+    public IntegerParameter(Integer[] values) {
+        super(values);
     }
 
     /**
      * Constructor used by Input.setValue(String) *
      */
-    public IntegerParameter(String sValue) throws Exception {
-        init(0, 0, sValue, 1);
+    public IntegerParameter(String value) {
+        init(0, 0, value, 1);
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         if (lowerValueInput.get() != null) {
             m_fLower = lowerValueInput.get();
         } else {
@@ -46,11 +47,13 @@ public class IntegerParameter extends Parameter.Base<java.lang.Integer> {
         super.initAndValidate();
     }
 
-    Integer getMax() {
+    @Override
+	Integer getMax() {
         return Integer.MAX_VALUE - 1;
     }
 
-    Integer getMin() {
+    @Override
+	Integer getMin() {
         return Integer.MIN_VALUE + 1;
     }
 
@@ -66,27 +69,27 @@ public class IntegerParameter extends Parameter.Base<java.lang.Integer> {
 
     @Override
     public double getArrayValue() {
-        return (double) values[0];
+        return values[0];
     }
 
-    public int getNativeValue(final int iValue) {
-        return values[iValue];
+    public int getNativeValue(final int value) {
+        return values[value];
     }
 
     @Override
-    public double getArrayValue(int iValue) {
-        return (double) values[iValue];
+    public double getArrayValue(int value) {
+        return values[value];
     }
 
     /**
      * Loggable implementation follows *
      */
     @Override
-    public void log(int nSample, PrintStream out) {
+    public void log(int sampleNr, PrintStream out) {
         IntegerParameter var = (IntegerParameter) getCurrent();
-        int nValues = var.getDimension();
-        for (int iValue = 0; iValue < nValues; iValue++) {
-            out.print(var.getValue(iValue) + "\t");
+        int valueCount = var.getDimension();
+        for (int i = 0; i < valueCount; i++) {
+            out.print(var.getValue(i) + "\t");
         }
     }
 
@@ -94,19 +97,19 @@ public class IntegerParameter extends Parameter.Base<java.lang.Integer> {
      * StateNode methods *
      */
     @Override
-    public int scale(double fScale) {
+    public int scale(double scale) {
         // nothing to do
-        System.err.println("Attempt to scale Integer parameter " + getID() + "  has no effect");
+        Log.warning.println("Attempt to scale Integer parameter " + getID() + "  has no effect");
         return 0;
     }
 
     @Override
-    void fromXML(int nDimension, String sLower, String sUpper, String[] sValues) {
-        setLower(Integer.parseInt(sLower));
-        setUpper(Integer.parseInt(sUpper));
-        values = new Integer[nDimension];
-        for (int i = 0; i < sValues.length; i++) {
-            values[i] = Integer.parseInt(sValues[i]);
+    void fromXML(int dimension, String lower, String upper, String[] valueStrings) {
+        setLower(Integer.parseInt(lower));
+        setUpper(Integer.parseInt(upper));
+        values = new Integer[dimension];
+        for (int i = 0; i < values.length; i++) {
+            values[i] = Integer.parseInt(valueStrings[i]);
         }
     }
 }
diff --git a/src/beast/core/parameter/IntegerParameterList.java b/src/beast/core/parameter/IntegerParameterList.java
index 638d424..e4c1917 100644
--- a/src/beast/core/parameter/IntegerParameterList.java
+++ b/src/beast/core/parameter/IntegerParameterList.java
@@ -1,8 +1,9 @@
 package beast.core.parameter;
 
+import java.util.List;
+
 import beast.core.Description;
 import beast.core.Input;
-import java.util.List;
 
 /**
  * @author Tim Vaughan <tgvaughan at gmail.com>
@@ -10,9 +11,9 @@ import java.util.List;
 @Description("State node describing a list of integer-valued parameters.")
 public class IntegerParameterList extends GeneralParameterList<Integer> {
     
-    public Input<Integer> lowerBoundInput = new Input<Integer>("lower",
+    final public Input<Integer> lowerBoundInput = new Input<>("lower",
             "Lower bound on parameter values.", Integer.MIN_VALUE+1);
-    public Input<Integer> upperBoundInput = new Input<Integer>("upper",
+    final public Input<Integer> upperBoundInput = new Input<>("upper",
             "Upper bound on parameter values.", Integer.MAX_VALUE-1);
     
     @Override
diff --git a/src/beast/core/parameter/Map.java b/src/beast/core/parameter/Map.java
index cf43218..f7d0172 100644
--- a/src/beast/core/parameter/Map.java
+++ b/src/beast/core/parameter/Map.java
@@ -1,18 +1,18 @@
 package beast.core.parameter;
 
-import beast.core.CalculationNode;
-import beast.core.Description;
-import beast.core.Input;
-
 import java.util.ArrayList;
 import java.util.LinkedHashMap;
 import java.util.List;
 
+import beast.core.CalculationNode;
+import beast.core.Description;
+import beast.core.Input;
+
 @Description("Unordered set mapping keys to values")
 abstract public class Map<T> extends CalculationNode {
 
-    public Input<java.util.Map<java.lang.String, T>> defaultInput = new Input<java.util.Map<java.lang.String, T>>("*",
-            "Input containing the map", new LinkedHashMap<java.lang.String, T>());
+    final public Input<java.util.Map<java.lang.String, T>> defaultInput = new Input<>("*",
+            "Input containing the map", new LinkedHashMap<>());
 
     public java.util.Map<java.lang.String, T> map;
 
@@ -24,31 +24,31 @@ abstract public class Map<T> extends CalculationNode {
     abstract protected Class<?> mapType();
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         map = defaultInput.get();
     }
 
     @SuppressWarnings("unchecked")
     @Override
     public void setInputValue(java.lang.String name, Object value) {
-        try {
+        //try {
             for (Input<?> input : listInputs()) {
                 if (input != defaultInput && input.getName().equals(name)) {
                     input.setValue(value, this);
                     return;
                 }
             }
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();
-            throw new RuntimeException("Failed to set input named '" + name + "' with value '" + value + "'");
-        }
+        //} catch (IllegalAccessException e) {
+        //    e.printStackTrace();
+        //    throw new RuntimeException("Failed to set input named '" + name + "' with value '" + value + "'");
+        //}
         map = defaultInput.get();
         if (defaultInput.getType().equals(List.class)) {
             if (defaultInput.get().containsKey(name)) {
-                List list = (List) defaultInput.get().get(name);
+                List<Object> list = (List<Object>) defaultInput.get().get(name);
                 list.add(value);
             } else {
-                List list = new ArrayList();
+                List<Object> list = new ArrayList<>();
                 list.add(value);
                 defaultInput.get().put(name, (T) list);
             }
@@ -61,17 +61,17 @@ abstract public class Map<T> extends CalculationNode {
     ;
 
     @Override
-    public Input<?> getInput(java.lang.String name) {
-        try {
+    final public Input<?> getInput(java.lang.String name) {
+        //try {
             for (Input<?> input : listInputs()) {
                 if (input != defaultInput && input.getName().equals(name)) {
                     return input;
                 }
             }
-        } catch (IllegalAccessException e) {
-            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
-            throw new RuntimeException("Failed to get input named '" + name + "'");
-        }
+        //} catch (IllegalAccessException e) {
+        //    e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+        //    throw new RuntimeException("Failed to get input named '" + name + "'");
+        //}
         return defaultInput;
     }
 
diff --git a/src/beast/core/parameter/Parameter.java b/src/beast/core/parameter/Parameter.java
index 7d320ec..8f69ee1 100644
--- a/src/beast/core/parameter/Parameter.java
+++ b/src/beast/core/parameter/Parameter.java
@@ -2,16 +2,19 @@ package beast.core.parameter;
 
 import java.io.PrintStream;
 import java.lang.reflect.Array;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 
-import beast.core.*;
+import beast.core.Description;
+import beast.core.Function;
+import beast.core.Input;
+import beast.core.StateNode;
 
 public interface Parameter<T> extends Function {
 
@@ -21,15 +24,15 @@ public interface Parameter<T> extends Function {
 
     public void setValue(int i, T value);
     
-    public void setValue(T fValue);
+    public void setValue(T value);
 
     public T getLower();
 
-    public void setLower(final T fLower);
+    public void setLower(final T lower);
 
     public T getUpper();
 
-    public void setUpper(final T fUpper);
+    public void setUpper(final T upper);
 
     public T[] getValues();
 
@@ -59,10 +62,10 @@ public interface Parameter<T> extends Function {
          * wants to set the dimension, say, this will make it the responsibility
          * of the other class to maintain internal consistency of the parameter.
          */
-        public Input<List<T>> valuesInput = new Input<List<T>>("value", "start value(s) for this parameter. If multiple values are specified, they should be separated by whitespace.", new ArrayList<T>(), beast.core.Input.Validate.REQUIRED, getMax().getClass());
+        final public Input<List<T>> valuesInput = new Input<>("value", "start value(s) for this parameter. If multiple values are specified, they should be separated by whitespace.", new ArrayList<>(), beast.core.Input.Validate.REQUIRED, getMax().getClass());
         public final Input<java.lang.Integer> dimensionInput =
-                new Input<java.lang.Integer>("dimension", "dimension of the parameter (default 1, i.e scalar)", 1);
-        public final Input<Integer> minorDimensionInput = new Input<Integer>("minordimension", "minor-dimension when the parameter is interpreted as a matrix (default 1)", 1);
+                new Input<>("dimension", "dimension of the parameter (default 1, i.e scalar)", 1);
+        public final Input<Integer> minorDimensionInput = new Input<>("minordimension", "minor-dimension when the parameter is interpreted as a matrix (default 1)", 1);
 
         /**
          * constructors *
@@ -81,23 +84,24 @@ public interface Parameter<T> extends Function {
             }
         }
 
-        @Override
-        public void initAndValidate() throws Exception {
-            T[] sValues = valuesInput.get().toArray((T[]) Array.newInstance(getMax().getClass(), 0));
-
-            int nDimension = Math.max(dimensionInput.get(), sValues.length);
-            dimensionInput.setValue(nDimension, this);
-            values = (T[]) Array.newInstance(getMax().getClass(), nDimension);
-            storedValues = (T[]) Array.newInstance(getMax().getClass(), nDimension);
+        @SuppressWarnings("unchecked")
+		@Override
+        public void initAndValidate() {
+            T[] valuesString = valuesInput.get().toArray((T[]) Array.newInstance(getMax().getClass(), 0));
+
+            int dimension = Math.max(dimensionInput.get(), valuesString.length);
+            dimensionInput.setValue(dimension, this);
+            values = (T[]) Array.newInstance(getMax().getClass(), dimension);
+            storedValues = (T[]) Array.newInstance(getMax().getClass(), dimension);
             for (int i = 0; i < values.length; i++) {
-                values[i] = sValues[i % sValues.length];
+                values[i] = valuesString[i % valuesString.length];
             }
 
             m_bIsDirty = new boolean[dimensionInput.get()];
 
             minorDimension = minorDimensionInput.get();
             if (minorDimension > 0 && dimensionInput.get() % minorDimension > 0) {
-                throw new Exception("Dimension must be divisible by stride");
+                throw new IllegalArgumentException("Dimension must be divisible by stride");
             }
             this.storedValues = values.clone();
         }
@@ -131,11 +135,11 @@ public interface Parameter<T> extends Function {
         protected int m_nLastDirty;
 
         /**
-         * @param iParam dimention to check
-         * @return true if the iParam-th element has changed
+         * @param index dimension to check
+         * @return true if the param-th element has changed
          */
-        public boolean isDirty(final int iParam) {
-            return m_bIsDirty[iParam];
+        public boolean isDirty(final int index) {
+            return m_bIsDirty[index];
         }
 
         /**
@@ -164,35 +168,35 @@ public interface Parameter<T> extends Function {
          * Change the dimension of a parameter
          * <p/>
          * This should only be called from initAndValidate() when a parent
-         * plugin can easily calculate the dimension of a parameter, but it is
+         * beastObject can easily calculate the dimension of a parameter, but it is
          * awkward to do this by hand.
          * <p/>
          * Values are sourced from the original parameter values.
          *
-         * @param nDimension
+         * @param dimension
          */
         @SuppressWarnings("unchecked")
-        public void setDimension(final int nDimension) {
-            if (getDimension() != nDimension) {
-                final T[] values2 = (T[]) Array.newInstance(getMax().getClass(), nDimension);
-                for (int i = 0; i < nDimension; i++) {
+        public void setDimension(final int dimension) {
+            if (getDimension() != dimension) {
+                final T[] values2 = (T[]) Array.newInstance(getMax().getClass(), dimension);
+                for (int i = 0; i < dimension; i++) {
                     values2[i] = values[i % getDimension()];
                 }
-                values = (T[]) values2;
-                //storedValues = (T[]) Array.newInstance(m_fUpper.getClass(), nDimension);
+                values = values2;
+                //storedValues = (T[]) Array.newInstance(m_fUpper.getClass(), dimension);
             }
-            m_bIsDirty = new boolean[nDimension];
+            m_bIsDirty = new boolean[dimension];
             try {
-                dimensionInput.setValue(nDimension, this);
+                dimensionInput.setValue(dimension, this);
             } catch (Exception e) {
                 // ignore
             }
         }
 
-        public void setMinorDimension(final int nDimension) throws Exception {
-            minorDimension = nDimension;
+        public void setMinorDimension(final int dimension) {
+            minorDimension = dimension;
             if (minorDimension > 0 && dimensionInput.get() % minorDimension > 0) {
-                throw new Exception("Dimension must be divisible by stride");
+                throw new IllegalArgumentException("Dimension must be divisible by stride");
             }
         }
 
@@ -207,8 +211,8 @@ public interface Parameter<T> extends Function {
         }
 
         @Override
-        public void setLower(final T fLower) {
-            m_fLower = fLower;
+        public void setLower(final T lower) {
+            m_fLower = lower;
         }
 
         @Override
@@ -217,13 +221,13 @@ public interface Parameter<T> extends Function {
         }
 
         @Override
-        public void setUpper(final T fUpper) {
-            m_fUpper = fUpper;
+        public void setUpper(final T upper) {
+            m_fUpper = upper;
         }
 
         @Override
-        public T getValue(final int iParam) {
-            return values[iParam];
+        public T getValue(final int param) {
+            return values[param];
         }
 
         @Override
@@ -231,38 +235,38 @@ public interface Parameter<T> extends Function {
             return Arrays.copyOf(values, values.length);
         }
 
-        public void setBounds(final T fLower, final T fUpper) {
-            m_fLower = fLower;
-            m_fUpper = fUpper;
+        public void setBounds(final T lower, final T upper) {
+            m_fLower = lower;
+            m_fUpper = upper;
         }
 
         @Override
-        public void setValue(final T fValue) {
+        public void setValue(final T value) {
             startEditing(null);
 
-            values[0] = fValue;
+            values[0] = value;
             m_bIsDirty[0] = true;
             m_nLastDirty = 0;
         }
 
         @Override
-        public void setValue(final int iParam, final T fValue) {
+        public void setValue(final int param, final T value) {
             startEditing(null);
 
-            values[iParam] = fValue;
-            m_bIsDirty[iParam] = true;
-            m_nLastDirty = iParam;
+            values[param] = value;
+            m_bIsDirty[param] = true;
+            m_nLastDirty = param;
 
         }
 
         @Override
-        public void swap(final int iLeft, final int iRight) {
+        public void swap(final int left, final int right) {
             startEditing(null);
-            final T tmp = values[iLeft];
-            values[iLeft] = values[iRight];
-            values[iRight] = tmp;
-            m_bIsDirty[iLeft] = true;
-            m_bIsDirty[iRight] = true;
+            final T tmp = values[left];
+            values[left] = values[right];
+            values[right] = tmp;
+            m_bIsDirty[left] = true;
+            m_bIsDirty[right] = true;
         }
 
         /**
@@ -337,13 +341,13 @@ public interface Parameter<T> extends Function {
          * of values happens in derived classes) *
          */
         @Override
-        public void init(final PrintStream out) throws Exception {
-            final int nValues = getDimension();
-            if (nValues == 1) {
+        public void init(final PrintStream out) {
+            final int valueCount = getDimension();
+            if (valueCount == 1) {
                 out.print(getID() + "\t");
             } else {
-                for (int iValue = 0; iValue < nValues; iValue++) {
-                    out.print(getID() + (iValue + 1) + "\t");
+                for (int value = 0; value < valueCount; value++) {
+                    out.print(getID() + (value + 1) + "\t");
                 }
             }
         }
@@ -360,30 +364,30 @@ public interface Parameter<T> extends Function {
         public void fromXML(final Node node) {
             final NamedNodeMap atts = node.getAttributes();
             setID(atts.getNamedItem("id").getNodeValue());
-            final String sStr = node.getTextContent();
+            final String str = node.getTextContent();
             Pattern pattern = Pattern.compile(".*\\[(.*) (.*)\\].*\\((.*),(.*)\\): (.*) ");
-            Matcher matcher = pattern.matcher(sStr);
+            Matcher matcher = pattern.matcher(str);
 
             if (matcher.matches()) {
-                final String sDimension = matcher.group(1);
-                final String sStride = matcher.group(2);
-                final String sLower = matcher.group(3);
-                final String sUpper = matcher.group(4);
-                final String sValuesAsString = matcher.group(5);
-                final String[] sValues = sValuesAsString.split(" ");
-                minorDimension = Integer.parseInt(sStride);
-                fromXML(Integer.parseInt(sDimension), sLower, sUpper, sValues);
+                final String dimension = matcher.group(1);
+                final String stride = matcher.group(2);
+                final String lower = matcher.group(3);
+                final String upper = matcher.group(4);
+                final String valuesAsString = matcher.group(5);
+                final String[] values = valuesAsString.split(" ");
+                minorDimension = Integer.parseInt(stride);
+                fromXML(Integer.parseInt(dimension), lower, upper, values);
             } else {
                 pattern = Pattern.compile(".*\\[(.*)\\].*\\((.*),(.*)\\): (.*) ");
-                matcher = pattern.matcher(sStr);
+                matcher = pattern.matcher(str);
                 if (matcher.matches()) {
-                    final String sDimension = matcher.group(1);
-                    final String sLower = matcher.group(2);
-                    final String sUpper = matcher.group(3);
-                    final String sValuesAsString = matcher.group(4);
-                    final String[] sValues = sValuesAsString.split(" ");
+                    final String dimension = matcher.group(1);
+                    final String lower = matcher.group(2);
+                    final String upper = matcher.group(3);
+                    final String valuesAsString = matcher.group(4);
+                    final String[] values = valuesAsString.split(" ");
                     minorDimension = 0;
-                    fromXML(Integer.parseInt(sDimension), sLower, sUpper, sValues);
+                    fromXML(Integer.parseInt(dimension), lower, upper, values);
                 } else {
                     throw new RuntimeException("parameter could not be parsed");
                 }
@@ -394,12 +398,12 @@ public interface Parameter<T> extends Function {
          * Restore a saved parameter from string representation. This cannot be
          * a template method since it requires creation of an array of T...
          *
-         * @param nDimension parameter dimension
-         * @param sLower lower bound
-         * @param sUpper upper bound
-         * @param sValues values
+         * @param dimension parameter dimension
+         * @param lower lower bound
+         * @param upper upper bound
+         * @param values values
          */
-        abstract void fromXML(int nDimension, String sLower, String sUpper, String[] sValues);
+        abstract void fromXML(int dimension, String lower, String upper, String[] values);
 
         /**
          * matrix implementation *
diff --git a/src/beast/core/parameter/RealParameter.java b/src/beast/core/parameter/RealParameter.java
index 236a645..760a0af 100644
--- a/src/beast/core/parameter/RealParameter.java
+++ b/src/beast/core/parameter/RealParameter.java
@@ -1,11 +1,11 @@
 package beast.core.parameter;
 
 
+import java.io.PrintStream;
+
 import beast.core.Description;
 import beast.core.Input;
 
-import java.io.PrintStream;
-
 
 /**
  * @author Alexei Drummond
@@ -14,25 +14,25 @@ import java.io.PrintStream;
 @Description("A real-valued parameter represents a value (or array of values if the dimension is larger than one) " +
         "in the state space that can be changed by operators.")
 public class RealParameter extends Parameter.Base<Double> {
-    public Input<Double> lowerValueInput = new Input<Double>("lower", "lower value for this parameter (default -infinity)");
-    public Input<Double> upperValueInput = new Input<Double>("upper", "upper value for this parameter (default +infinity)");
+    final public Input<Double> lowerValueInput = new Input<>("lower", "lower value for this parameter (default -infinity)");
+    final public Input<Double> upperValueInput = new Input<>("upper", "upper value for this parameter (default +infinity)");
 
     public RealParameter() {
     }
 
-    public RealParameter(final Double[] fValues) {
-        super(fValues);
+    public RealParameter(final Double[] values) {
+        super(values);
     }
 
     /**
      * Constructor used by Input.setValue(String) *
      */
-    public RealParameter(final String sValue) throws Exception {
-        init(0.0, 0.0, sValue, 1);
+    public RealParameter(final String value) {
+        init(0.0, 0.0, value, 1);
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         if (lowerValueInput.get() != null) {
             m_fLower = lowerValueInput.get();
         } else {
@@ -72,19 +72,19 @@ public class RealParameter extends Parameter.Base<Double> {
     }
 
     @Override
-    public double getArrayValue(final int iValue) {
-        return values[iValue];
+    public double getArrayValue(final int index) {
+        return values[index];
     }
 
     /**
      * Loggable implementation *
      */
     @Override
-    public void log(final int nSample, final PrintStream out) {
+    public void log(final int sample, final PrintStream out) {
         final RealParameter var = (RealParameter) getCurrent();
-        final int nValues = var.getDimension();
-        for (int iValue = 0; iValue < nValues; iValue++) {
-            out.print(var.getValue(iValue) + "\t");
+        final int values = var.getDimension();
+        for (int value = 0; value < values; value++) {
+            out.print(var.getValue(value) + "\t");
         }
     }
 
@@ -92,11 +92,11 @@ public class RealParameter extends Parameter.Base<Double> {
      * StateNode methods *
      */
     @Override
-    public int scale(final double fScale) throws Exception {
+    public int scale(final double scale) {
         for (int i = 0; i < values.length; i++) {
-            values[i] *= fScale;
+            values[i] *= scale;
             if (values[i] < m_fLower || values[i] > m_fUpper) {
-                throw new Exception("parameter scaled our of range");
+                throw new IllegalArgumentException("parameter scaled our of range");
             }
         }
         return values.length;
@@ -104,12 +104,12 @@ public class RealParameter extends Parameter.Base<Double> {
 
 
     @Override
-    void fromXML(final int nDimension, final String sLower, final String sUpper, final String[] sValues) {
-        setLower(Double.parseDouble(sLower));
-        setUpper(Double.parseDouble(sUpper));
-        values = new Double[nDimension];
-        for (int i = 0; i < sValues.length; i++) {
-            values[i] = Double.parseDouble(sValues[i]);
+    void fromXML(final int dimension, final String lower, final String upper, final String[] valuesString) {
+        setLower(Double.parseDouble(lower));
+        setUpper(Double.parseDouble(upper));
+        values = new Double[dimension];
+        for (int i = 0; i < valuesString.length; i++) {
+            values[i] = Double.parseDouble(valuesString[i]);
         }
     }
 
diff --git a/src/beast/core/parameter/RealParameterList.java b/src/beast/core/parameter/RealParameterList.java
index d71cb0d..cfd8b1c 100644
--- a/src/beast/core/parameter/RealParameterList.java
+++ b/src/beast/core/parameter/RealParameterList.java
@@ -1,8 +1,9 @@
 package beast.core.parameter;
 
+import java.util.List;
+
 import beast.core.Description;
 import beast.core.Input;
-import java.util.List;
 
 /**
  * @author Tim Vaughan <tgvaughan at gmail.com>
@@ -10,9 +11,9 @@ import java.util.List;
 @Description("State node describing a list of real-valued parameters.")
 public class RealParameterList extends GeneralParameterList<Double> {
     
-    public Input<Double> lowerBoundInput = new Input<Double>("lower",
+    final public Input<Double> lowerBoundInput = new Input<>("lower",
             "Lower bound on parameter values.", Double.NEGATIVE_INFINITY);
-    public Input<Double> upperBoundInput = new Input<Double>("upper",
+    final public Input<Double> upperBoundInput = new Input<>("upper",
             "Upper bound on parameter values.", Double.POSITIVE_INFINITY);
     
     @Override
diff --git a/src/beast/core/util/CompoundDistribution.java b/src/beast/core/util/CompoundDistribution.java
index 31b4b3b..2759d66 100644
--- a/src/beast/core/util/CompoundDistribution.java
+++ b/src/beast/core/util/CompoundDistribution.java
@@ -36,12 +36,11 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.RejectedExecutionException;
 
 import beast.app.BeastMCMC;
+import beast.core.BEASTInterface;
 import beast.core.Description;
 import beast.core.Distribution;
 import beast.core.Input;
 import beast.core.State;
-import beast.core.BEASTObject;
-import beast.core.BEASTInterface;
 
 
 @Description("Takes a collection of distributions, typically a number of likelihoods " +
@@ -50,13 +49,13 @@ import beast.core.BEASTInterface;
 public class CompoundDistribution extends Distribution {
     // no need to make this input REQUIRED. If no distribution input is
     // specified the class just returns probability 1.
-    public Input<List<Distribution>> pDistributions =
-            new Input<List<Distribution>>("distribution",
+    final public Input<List<Distribution>> pDistributions =
+            new Input<>("distribution",
                     "individual probability distributions, e.g. the likelihood and prior making up a posterior",
-                    new ArrayList<Distribution>());
-    public Input<Boolean> useThreadsInput = new Input<Boolean>("useThreads", "calculated the distributions in parallel using threads (default false)", false);
-    public Input<Integer> maxNrOfThreadsInput = new Input<Integer>("threads","maximum number of threads to use, if less than 1 the number of threads in BeastMCMC is used (default -1)", -1);
-    public Input<Boolean> ignoreInput = new Input<Boolean>("ignore", "ignore all distributions and return 1 as distribution (default false)", false);
+                    new ArrayList<>());
+    final public Input<Boolean> useThreadsInput = new Input<>("useThreads", "calculated the distributions in parallel using threads (default false)", false);
+    final public Input<Integer> maxNrOfThreadsInput = new Input<>("threads","maximum number of threads to use, if less than 1 the number of threads in BeastMCMC is used (default -1)", -1);
+    final public Input<Boolean> ignoreInput = new Input<>("ignore", "ignore all distributions and return 1 as distribution (default false)", false);
     
     /**
      * flag to indicate threads should be used. Only effective if the useThreadsInput is
@@ -68,7 +67,7 @@ public class CompoundDistribution extends Distribution {
     public static ExecutorService exec;
     
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
         useThreads = useThreadsInput.get() && (BeastMCMC.m_nThreads > 1);
 		nrOfThreads = useThreads ? BeastMCMC.m_nThreads : 1;
@@ -94,7 +93,7 @@ public class CompoundDistribution extends Distribution {
      * Distribution implementation follows *
      */
     @Override
-    public double calculateLogP() throws Exception {
+    public double calculateLogP() {
         logP = 0;
         if (ignore) {
         	return logP;
@@ -123,7 +122,8 @@ public class CompoundDistribution extends Distribution {
             distr = core;
         }
 
-        public void run() {
+        @Override
+		public void run() {
             try {
                 if (distr.isDirtyCalculation()) {
                     logP += distr.calculateLogP();
@@ -131,9 +131,9 @@ public class CompoundDistribution extends Distribution {
                     logP += distr.getCurrentLogP();
                 }
             } catch (Exception e) {
-                System.err.println("Something went wrong in a calculation of " + distr.getID());
+                Log.err.println("Something went wrong in a calculation of " + distr.getID());
                 e.printStackTrace();
-                System.exit(0);
+                System.exit(1);
             }
             countDown.countDown();
         }
@@ -142,16 +142,16 @@ public class CompoundDistribution extends Distribution {
 
     CountDownLatch countDown;
 
-    private double calculateLogPUsingThreads() throws Exception {
+    private double calculateLogPUsingThreads() {
         try {
 
-            int nrOfDirtyDistrs = 0;
+            int dirtyDistrs = 0;
             for (Distribution dists : pDistributions.get()) {
                 if (dists.isDirtyCalculation()) {
-                    nrOfDirtyDistrs++;
+                    dirtyDistrs++;
                 }
             }
-            countDown = new CountDownLatch(nrOfDirtyDistrs);
+            countDown = new CountDownLatch(dirtyDistrs);
             // kick off the threads
             for (Distribution dists : pDistributions.get()) {
                 if (dists.isDirtyCalculation()) {
@@ -165,9 +165,9 @@ public class CompoundDistribution extends Distribution {
                 logP += distr.getCurrentLogP();
             }
             return logP;
-        } catch (RejectedExecutionException e) {
+        } catch (RejectedExecutionException | InterruptedException e) {
             useThreads = false;
-            System.err.println("Stop using threads: " + e.getMessage());
+            Log.err.println("Stop using threads: " + e.getMessage());
             return calculateLogP();
         }
     }
@@ -182,7 +182,7 @@ public class CompoundDistribution extends Distribution {
 
     @Override
     public List<String> getArguments() {
-        List<String> arguments = new ArrayList<String>();
+        List<String> arguments = new ArrayList<>();
         for (Distribution distribution : pDistributions.get()) {
             arguments.addAll(distribution.getArguments());
         }
@@ -191,7 +191,7 @@ public class CompoundDistribution extends Distribution {
 
     @Override
     public List<String> getConditions() {
-        List<String> conditions = new ArrayList<String>();
+        List<String> conditions = new ArrayList<>();
         for (Distribution distribution : pDistributions.get()) {
             conditions.addAll(distribution.getConditions());
         }
@@ -199,11 +199,11 @@ public class CompoundDistribution extends Distribution {
     }
 
     @Override
-    public List<BEASTInterface> listActivePlugins() throws IllegalArgumentException, IllegalAccessException {
+    public List<BEASTInterface> listActiveBEASTObjects() {
     	if (ignoreInput.get()) {
-    		return new ArrayList<BEASTInterface>();
+    		return new ArrayList<>();
     	} else {
-    		return super.listActivePlugins();
+    		return super.listActiveBEASTObjects();
     	}
     }
 
@@ -218,7 +218,7 @@ public class CompoundDistribution extends Distribution {
     }
     
     @Override
-    public double getNonStochasticLogP() throws Exception {
+    public double getNonStochasticLogP() {
         double logP = 0;
         if (ignore) {
         	return logP;
diff --git a/src/beast/core/util/ESS.java b/src/beast/core/util/ESS.java
index 1bc3f6c..e65ece1 100644
--- a/src/beast/core/util/ESS.java
+++ b/src/beast/core/util/ESS.java
@@ -4,12 +4,12 @@ import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.List;
 
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Function;
 import beast.core.Input;
-import beast.core.Loggable;
-import beast.core.BEASTObject;
 import beast.core.Input.Validate;
+import beast.core.Loggable;
 
 
 //import beast.core.Distribution;
@@ -17,8 +17,8 @@ import beast.core.Input.Validate;
 @Description("Report effective sample size of a parameter or log values from a distribution. " +
         "This uses the same criterion as Tracer and assumes 10% burn in.")
 public class ESS extends BEASTObject implements Loggable {
-    public Input<Function> functionInput =
-            new Input<Function>("arg", "value (e.g. parameter or distribution) to report ESS for", Validate.REQUIRED);
+    final public Input<Function> functionInput =
+            new Input<>("arg", "value (e.g. parameter or distribution) to report ESS for", Validate.REQUIRED);
 
     /**
      * values from which the ESS is calculated *
@@ -35,14 +35,14 @@ public class ESS extends BEASTObject implements Loggable {
 
     @Override
     public void initAndValidate() {
-        trace = new ArrayList<Double>();
-        squareLaggedSums = new ArrayList<Double>();
+        trace = new ArrayList<>();
+        squareLaggedSums = new ArrayList<>();
     }
 
     @Override
-    public void init(PrintStream out) throws Exception {
-        final String sID = ((BEASTObject) functionInput.get()).getID();
-        out.print("ESS(" + sID + ")\t");
+    public void init(PrintStream out) {
+        final String id = ((BEASTObject) functionInput.get()).getID();
+        out.print("ESS(" + id + ")\t");
     }
 
     final static int MAX_LAG = 2000;
@@ -63,64 +63,63 @@ public class ESS extends BEASTObject implements Loggable {
 //  basic numerical integration technique.
 
     @Override
-    public void log(final int nSample, PrintStream out) {
-//		final Double fNewValue = (m_distribution == null? m_pParam.get().getValue() : m_distribution.getCurrentLogP());
-        final Double fNewValue = functionInput.get().getArrayValue();
-        trace.add(fNewValue);
-        sum += fNewValue;
+    public void log(final int sample, PrintStream out) {
+        final Double newValue = functionInput.get().getArrayValue();
+        trace.add(newValue);
+        sum += newValue;
 
-        final int nTotalSamples = trace.size();
+        final int totalSamples = trace.size();
 
         // take 10% burn in
-        final int iStart = nTotalSamples / 10;
-        if (iStart != ((nTotalSamples - 1) / 10)) {
+        final int start = totalSamples / 10;
+        if (start != ((totalSamples - 1) / 10)) {
             // compensate for 10% burnin
-            sum -= trace.get((nTotalSamples - 1) / 10);
+            sum -= trace.get((totalSamples - 1) / 10);
         }
-        final int nSamples = nTotalSamples - iStart;
-        final int nMaxLag = Math.min(nSamples, MAX_LAG);
+        final int sampleCount = totalSamples - start;
+        final int maxLag = Math.min(sampleCount, MAX_LAG);
 
         // calculate mean
-        final double fMean = sum / nSamples;
+        final double mean = sum / sampleCount;
 
-        if (iStart != ((nTotalSamples - 1) / 10)) {
+        if (start != ((totalSamples - 1) / 10)) {
             // compensate for 10% burnin
-            int iTrace = ((nTotalSamples - 1) / 10);
-            for (int iLag = 0; iLag < squareLaggedSums.size(); iLag++) {
-                squareLaggedSums.set(iLag, squareLaggedSums.get(iLag) - trace.get(iTrace) * trace.get(iTrace + iLag));
+            int traceIndex = ((totalSamples - 1) / 10);
+            for (int lagIndex = 0; lagIndex < squareLaggedSums.size(); lagIndex++) {
+                squareLaggedSums.set(lagIndex, squareLaggedSums.get(lagIndex) - trace.get(traceIndex) * trace.get(traceIndex + lagIndex));
             }
         }
 
-        while (squareLaggedSums.size() < nMaxLag) {
+        while (squareLaggedSums.size() < maxLag) {
             squareLaggedSums.add(0.0);
         }
 
         // calculate auto correlation for selected lag times
-        double[] fAutoCorrelation = new double[nMaxLag];
-        // fSum1 = \sum_{iStart ... nTotalSamples-iLag-1} trace
-        double fSum1 = sum;
-        // fSum1 = \sum_{iStart+iLag ... nTotalSamples-1} trace
-        double fSum2 = sum;
-        for (int iLag = 0; iLag < nMaxLag; iLag++) {
-            squareLaggedSums.set(iLag, squareLaggedSums.get(iLag) + trace.get(nTotalSamples - iLag - 1) * trace.get(nTotalSamples - 1));
+        double[] autoCorrelation = new double[maxLag];
+        // sum1 = \sum_{start ... totalSamples-lagIndex-1} trace
+        double sum1 = sum;
+        // sum2 = \sum_{start+lagIndex ... totalSamples-1} trace
+        double sum2 = sum;
+        for (int lag = 0; lag < maxLag; lag++) {
+            squareLaggedSums.set(lag, squareLaggedSums.get(lag) + trace.get(totalSamples - lag - 1) * trace.get(totalSamples - 1));
             // The following line is the same approximation as in Tracer 
-            // (valid since fMean *(nSamples - iLag), fSum1, and fSum2 are approximately the same)
+            // (valid since mean *(samples - lag), sum1, and sum2 are approximately the same)
             // though a more accurate estimate would be
-            // fAutoCorrelation[iLag] = m_fSquareLaggedSums.get(iLag) - fSum1 * fSum2
-            fAutoCorrelation[iLag] = squareLaggedSums.get(iLag) - (fSum1 + fSum2) * fMean + fMean * fMean * (nSamples - iLag);
-            fAutoCorrelation[iLag] /= ((double) (nSamples - iLag));
-            fSum1 -= trace.get(nTotalSamples - 1 - iLag);
-            fSum2 -= trace.get(iStart + iLag);
+            // autoCorrelation[lag] = m_fSquareLaggedSums.get(lag) - sum1 * sum2
+            autoCorrelation[lag] = squareLaggedSums.get(lag) - (sum1 + sum2) * mean + mean * mean * (sampleCount - lag);
+            autoCorrelation[lag] /= (sampleCount - lag);
+            sum1 -= trace.get(totalSamples - 1 - lag);
+            sum2 -= trace.get(start + lag);
         }
 
         double integralOfACFunctionTimes2 = 0.0;
-        for (int iLag = 0; iLag < nMaxLag; iLag++) {
-            if (iLag == 0) {
-                integralOfACFunctionTimes2 = fAutoCorrelation[0];
-            } else if (iLag % 2 == 0) {
+        for (int lagIndex = 0; lagIndex < maxLag; lagIndex++) {
+            if (lagIndex == 0) {
+                integralOfACFunctionTimes2 = autoCorrelation[0];
+            } else if (lagIndex % 2 == 0) {
                 // fancy stopping criterion - see main comment
-                if (fAutoCorrelation[iLag - 1] + fAutoCorrelation[iLag] > 0) {
-                    integralOfACFunctionTimes2 += 2.0 * (fAutoCorrelation[iLag - 1] + fAutoCorrelation[iLag]);
+                if (autoCorrelation[lagIndex - 1] + autoCorrelation[lagIndex] > 0) {
+                    integralOfACFunctionTimes2 += 2.0 * (autoCorrelation[lagIndex - 1] + autoCorrelation[lagIndex]);
                 } else {
                     // stop
                     break;
@@ -129,13 +128,13 @@ public class ESS extends BEASTObject implements Loggable {
         }
 
         // auto correlation time
-        final double fACT = integralOfACFunctionTimes2 / fAutoCorrelation[0];
+        final double act = integralOfACFunctionTimes2 / autoCorrelation[0];
 
         // effective sample size
-        final double fESS = nSamples / fACT;
-        String sStr = fESS + "";
-        sStr = sStr.substring(0, sStr.indexOf('.') + 2);
-        out.print(sStr + "\t");
+        final double ess = sampleCount / act;
+        String str = ess + "";
+        str = str.substring(0, str.indexOf('.') + 2);
+        out.print(str + "\t");
     } // log
 
     @Override
@@ -148,55 +147,55 @@ public class ESS extends BEASTObject implements Loggable {
      * return ESS time of a sample, batch version.
      * Can be used to calculate effective sample size
      *
-     * @param fTrace:         values from which the ACT is calculated
-     * @param nSampleInterval time between samples *
+     * @param trace:         values from which the ACT is calculated
+     * @param sampleInterval time between samples *
      */
-    public static double calcESS(List<Double> fTrace) {
-        return calcESS(fTrace.toArray(new Double[0]), 1);
+    public static double calcESS(List<Double> trace) {
+        return calcESS(trace.toArray(new Double[0]), 1);
     }
 
-    public static double calcESS(Double[] fTrace, int nSampleInterval) {
-        return fTrace.length / (ACT(fTrace, nSampleInterval) / nSampleInterval);
+    public static double calcESS(Double[] trace, int sampleInterval) {
+        return trace.length / (ACT(trace, sampleInterval) / sampleInterval);
     }
 
-    public static double ACT(Double[] fTrace, int nSampleInterval) {
+    public static double ACT(Double[] trace, int sampleInterval) {
         /** sum of trace, excluding burn-in **/
-        double fSum = 0.0;
+        double sum = 0.0;
         /** keep track of sums of trace(i)*trace(i_+ lag) for all lags, excluding burn-in  **/
-        double[] fSquareLaggedSums = new double[MAX_LAG];
-        double[] fAutoCorrelation = new double[MAX_LAG];
-        for (int i = 0; i < fTrace.length; i++) {
-            fSum += fTrace[i];
+        double[] squareLaggedSums = new double[MAX_LAG];
+        double[] autoCorrelation = new double[MAX_LAG];
+        for (int i = 0; i < trace.length; i++) {
+            sum += trace[i];
             // calculate mean
-            final double fMean = fSum / (i + 1);
+            final double mean = sum / (i + 1);
 
             // calculate auto correlation for selected lag times
-            // fSum1 = \sum_{iStart ... nTotalSamples-iLag-1} trace
-            double fSum1 = fSum;
-            // fSum1 = \sum_{iStart+iLag ... nTotalSamples-1} trace
-            double fSum2 = fSum;
-            for (int iLag = 0; iLag < Math.min(i + 1, MAX_LAG); iLag++) {
-                fSquareLaggedSums[iLag] = fSquareLaggedSums[iLag] + fTrace[i - iLag] * fTrace[i];
+            // sum1 = \sum_{start ... totalSamples-lag-1} trace
+            double sum1 = sum;
+            // sum2 = \sum_{start+lag ... totalSamples-1} trace
+            double sum2 = sum;
+            for (int lagIndex = 0; lagIndex < Math.min(i + 1, MAX_LAG); lagIndex++) {
+                squareLaggedSums[lagIndex] = squareLaggedSums[lagIndex] + trace[i - lagIndex] * trace[i];
                 // The following line is the same approximation as in Tracer
-                // (valid since fMean *(nSamples - iLag), fSum1, and fSum2 are approximately the same)
+                // (valid since mean *(samples - lag), sum1, and sum2 are approximately the same)
                 // though a more accurate estimate would be
-                // fAutoCorrelation[iLag] = m_fSquareLaggedSums.get(iLag) - fSum1 * fSum2
-                fAutoCorrelation[iLag] = fSquareLaggedSums[iLag] - (fSum1 + fSum2) * fMean + fMean * fMean * (i + 1 - iLag);
-                fAutoCorrelation[iLag] /= ((double) (i + 1 - iLag));
-                fSum1 -= fTrace[i - iLag];
-                fSum2 -= fTrace[iLag];
+                // autoCorrelation[lag] = m_fSquareLaggedSums.get(lag) - sum1 * sum2
+                autoCorrelation[lagIndex] = squareLaggedSums[lagIndex] - (sum1 + sum2) * mean + mean * mean * (i + 1 - lagIndex);
+                autoCorrelation[lagIndex] /= (i + 1 - lagIndex);
+                sum1 -= trace[i - lagIndex];
+                sum2 -= trace[lagIndex];
             }
         }
 
-        final int nMaxLag = Math.min(fTrace.length, MAX_LAG);
-        double fIntegralOfACFunctionTimes2 = 0.0;
-        for (int iLag = 0; iLag < nMaxLag; iLag++) //{
-            if (iLag == 0) //{
-                fIntegralOfACFunctionTimes2 = fAutoCorrelation[0];
-            else if (iLag % 2 == 0)
+        final int maxLag = Math.min(trace.length, MAX_LAG);
+        double integralOfACFunctionTimes2 = 0.0;
+        for (int lagIndex = 0; lagIndex < maxLag; lagIndex++) //{
+            if (lagIndex == 0) //{
+                integralOfACFunctionTimes2 = autoCorrelation[0];
+            else if (lagIndex % 2 == 0)
                 // fancy stopping criterion - see main comment in Tracer code of BEAST 1
-                if (fAutoCorrelation[iLag - 1] + fAutoCorrelation[iLag] > 0) //{
-                    fIntegralOfACFunctionTimes2 += 2.0 * (fAutoCorrelation[iLag - 1] + fAutoCorrelation[iLag]);
+                if (autoCorrelation[lagIndex - 1] + autoCorrelation[lagIndex] > 0) //{
+                    integralOfACFunctionTimes2 += 2.0 * (autoCorrelation[lagIndex - 1] + autoCorrelation[lagIndex]);
                 else
                     // stop
                     break;
@@ -205,47 +204,47 @@ public class ESS extends BEASTObject implements Loggable {
         //}
 
         // auto correlation time
-        return nSampleInterval * fIntegralOfACFunctionTimes2 / fAutoCorrelation[0];
+        return sampleInterval * integralOfACFunctionTimes2 / autoCorrelation[0];
     }
 
-    public static double stdErrorOfMean(Double[] fTrace, int nSampleInterval) {
+    public static double stdErrorOfMean(Double[] trace, int sampleInterval) {
         /** sum of trace, excluding burn-in **/
-        double fSum = 0.0;
+        double sum = 0.0;
         /** keep track of sums of trace(i)*trace(i_+ lag) for all lags, excluding burn-in  **/
-        double[] fSquareLaggedSums = new double[MAX_LAG];
-        double[] fAutoCorrelation = new double[MAX_LAG];
-        for (int i = 0; i < fTrace.length; i++) {
-            fSum += fTrace[i];
+        double[] squareLaggedSums = new double[MAX_LAG];
+        double[] autoCorrelation = new double[MAX_LAG];
+        for (int i = 0; i < trace.length; i++) {
+            sum += trace[i];
             // calculate mean
-            final double fMean = fSum / (i + 1);
+            final double mean = sum / (i + 1);
 
             // calculate auto correlation for selected lag times
-            // fSum1 = \sum_{iStart ... nTotalSamples-iLag-1} trace
-            double fSum1 = fSum;
-            // fSum1 = \sum_{iStart+iLag ... nTotalSamples-1} trace
-            double fSum2 = fSum;
-            for (int iLag = 0; iLag < Math.min(i + 1, MAX_LAG); iLag++) {
-                fSquareLaggedSums[iLag] = fSquareLaggedSums[iLag] + fTrace[i - iLag] * fTrace[i];
+            // sum1 = \sum_{start ... totalSamples-lag-1} trace
+            double sum1 = sum;
+            // sum2 = \sum_{start+lag ... totalSamples-1} trace
+            double sum2 = sum;
+            for (int lagIndex = 0; lagIndex < Math.min(i + 1, MAX_LAG); lagIndex++) {
+                squareLaggedSums[lagIndex] = squareLaggedSums[lagIndex] + trace[i - lagIndex] * trace[i];
                 // The following line is the same approximation as in Tracer
-                // (valid since fMean *(nSamples - iLag), fSum1, and fSum2 are approximately the same)
+                // (valid since mean *(samples - lag), sum1, and sum2 are approximately the same)
                 // though a more accurate estimate would be
-                // fAutoCorrelation[iLag] = m_fSquareLaggedSums.get(iLag) - fSum1 * fSum2
-                fAutoCorrelation[iLag] = fSquareLaggedSums[iLag] - (fSum1 + fSum2) * fMean + fMean * fMean * (i + 1 - iLag);
-                fAutoCorrelation[iLag] /= ((double) (i + 1 - iLag));
-                fSum1 -= fTrace[i - iLag];
-                fSum2 -= fTrace[iLag];
+                // autoCorrelation[lag] = m_fSquareLaggedSums.get(lag) - sum1 * sum2
+                autoCorrelation[lagIndex] = squareLaggedSums[lagIndex] - (sum1 + sum2) * mean + mean * mean * (i + 1 - lagIndex);
+                autoCorrelation[lagIndex] /= (i + 1 - lagIndex);
+                sum1 -= trace[i - lagIndex];
+                sum2 -= trace[lagIndex];
             }
         }
 
-        final int nMaxLag = Math.min(fTrace.length, MAX_LAG);
-        double fIntegralOfACFunctionTimes2 = 0.0;
-        for (int iLag = 0; iLag < nMaxLag; iLag++) //{
-            if (iLag == 0) //{
-                fIntegralOfACFunctionTimes2 = fAutoCorrelation[0];
-            else if (iLag % 2 == 0)
+        final int maxLag = Math.min(trace.length, MAX_LAG);
+        double integralOfACFunctionTimes2 = 0.0;
+        for (int lagIndex = 0; lagIndex < maxLag; lagIndex++) //{
+            if (lagIndex == 0) //{
+                integralOfACFunctionTimes2 = autoCorrelation[0];
+            else if (lagIndex % 2 == 0)
                 // fancy stopping criterion - see main comment in Tracer code of BEAST 1
-                if (fAutoCorrelation[iLag - 1] + fAutoCorrelation[iLag] > 0) //{
-                    fIntegralOfACFunctionTimes2 += 2.0 * (fAutoCorrelation[iLag - 1] + fAutoCorrelation[iLag]);
+                if (autoCorrelation[lagIndex - 1] + autoCorrelation[lagIndex] > 0) //{
+                    integralOfACFunctionTimes2 += 2.0 * (autoCorrelation[lagIndex - 1] + autoCorrelation[lagIndex]);
                 else
                     // stop
                     break;
@@ -254,7 +253,7 @@ public class ESS extends BEASTObject implements Loggable {
         //}
 
         // auto correlation time
-        return Math.sqrt(fIntegralOfACFunctionTimes2 / fTrace.length);
+        return Math.sqrt(integralOfACFunctionTimes2 / trace.length);
     }
 
 } // class ESS
diff --git a/src/beast/core/util/Log.java b/src/beast/core/util/Log.java
index 6dec2fe..2a89dd6 100644
--- a/src/beast/core/util/Log.java
+++ b/src/beast/core/util/Log.java
@@ -12,6 +12,14 @@ import java.util.Arrays;
  * info, 
  * debug, 
  * trace
+ * 
+ * To log a message, refer to one of the streams, e.g.
+ * Log.info.println("Hello world!");
+ * 
+ * or pass message directly through method
+ * Log.info("Hello world!");
+ * 
+ * The former gives better control of newlines, while the latter always adds a newline to the string.
  **/ 
 public class Log {
 	static PrintStream nullStream = new PrintStream(new OutputStream() {
@@ -36,10 +44,15 @@ public class Log {
     }
 	
 	static public PrintStream err;
+	static public void err(String msg) {err.println(msg);}
 	static public PrintStream warning;
+	static public void warning(String msg) {warning.println(msg);}
 	static public PrintStream info;
+	static public void info(String msg) {info.println(msg);}
 	static public PrintStream debug;
+	static public void debug(String msg) {debug.println(msg);}
 	static public PrintStream trace;
+	static public void trace(String msg) {trace.println(msg);}
 
 	static private PrintStream errIfOpen;
 	static private PrintStream warningIfOpen;
diff --git a/src/beast/core/util/Sum.java b/src/beast/core/util/Sum.java
index db294b1..5213225 100644
--- a/src/beast/core/util/Sum.java
+++ b/src/beast/core/util/Sum.java
@@ -2,13 +2,13 @@ package beast.core.util;
 
 import java.io.PrintStream;
 
+import beast.core.BEASTObject;
 import beast.core.CalculationNode;
 import beast.core.Description;
 import beast.core.Function;
 import beast.core.Input;
-import beast.core.Loggable;
-import beast.core.BEASTObject;
 import beast.core.Input.Validate;
+import beast.core.Loggable;
 import beast.core.parameter.BooleanParameter;
 import beast.core.parameter.IntegerParameter;
 
@@ -16,7 +16,7 @@ import beast.core.parameter.IntegerParameter;
 
 @Description("calculates sum of a valuable")
 public class Sum extends CalculationNode implements Function, Loggable {
-    public Input<Function> functionInput = new Input<Function>("arg", "argument to be summed", Validate.REQUIRED);
+    final public Input<Function> functionInput = new Input<>("arg", "argument to be summed", Validate.REQUIRED);
 
     enum Mode {integer_mode, double_mode}
 
@@ -62,8 +62,8 @@ public class Sum extends CalculationNode implements Function, Loggable {
     }
 
     @Override
-    public double getArrayValue(int iDim) {
-        if (iDim == 0) {
+    public double getArrayValue(int dim) {
+        if (dim == 0) {
             return getArrayValue();
         }
         return Double.NaN;
@@ -94,22 +94,22 @@ public class Sum extends CalculationNode implements Function, Loggable {
      * Loggable interface implementation follows
      */
     @Override
-    public void init(PrintStream out) throws Exception {
+    public void init(PrintStream out) {
         out.print("sum(" + ((BEASTObject) functionInput.get()).getID() + ")\t");
     }
 
     @Override
-    public void log(int nSample, PrintStream out) {
+    public void log(int sampleNr, PrintStream out) {
         Function valuable = functionInput.get();
-        final int nDimension = valuable.getDimension();
-        double fSum = 0;
-        for (int iValue = 0; iValue < nDimension; iValue++) {
-            fSum += valuable.getArrayValue(iValue);
+        final int dimension = valuable.getDimension();
+        double sum = 0;
+        for (int i = 0; i < dimension; i++) {
+            sum += valuable.getArrayValue(i);
         }
         if (mode == Mode.integer_mode) {
-            out.print((int) fSum + "\t");
+            out.print((int) sum + "\t");
         } else {
-            out.print(fSum + "\t");
+            out.print(sum + "\t");
         }
     }
 
diff --git a/src/beast/evolution/alignment/Alignment.java b/src/beast/evolution/alignment/Alignment.java
index 57d55c8..e31a198 100644
--- a/src/beast/evolution/alignment/Alignment.java
+++ b/src/beast/evolution/alignment/Alignment.java
@@ -24,7 +24,13 @@
 */
 package beast.evolution.alignment;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 import beast.core.Description;
 import beast.core.Input;
@@ -38,7 +44,8 @@ import beast.util.AddOnManager;
 @Description("Class representing alignment data")
 public class Alignment extends Map<String> {
 
-    protected Class<?> mapType() {
+    @Override
+	protected Class<?> mapType() {
         return String.class;
     }
 
@@ -55,7 +62,7 @@ public class Alignment extends Map<String> {
     /**
      * list of data type descriptions, obtained from DataType classes *
      */
-    static List<String> types = new ArrayList<String>();
+    static List<String> types = new ArrayList<>();
 
     static {
         findDataTypes();
@@ -64,13 +71,13 @@ public class Alignment extends Map<String> {
     static public void findDataTypes() {
         // build up list of data types
         List<String> m_sDataTypes = AddOnManager.find(beast.evolution.datatype.DataType.class, IMPLEMENTATION_DIR);
-        for (String sDataType : m_sDataTypes) {
+        for (String dataTypeName : m_sDataTypes) {
             try {
-                DataType dataType = (DataType) Class.forName(sDataType).newInstance();
+                DataType dataType = (DataType) Class.forName(dataTypeName).newInstance();
                 if (dataType.isStandard()) {
-                    String sDescription = dataType.getTypeDescription();
-                    if (!types.contains(sDescription)) {
-                        types.add(sDescription);
+                    String description = dataType.getTypeDescription();
+                    if (!types.contains(description)) {
+                        types.add(description);
                     }
                 }
             } catch (Exception e) {
@@ -79,26 +86,26 @@ public class Alignment extends Map<String> {
         }
     }
 
-    public Input<List<Sequence>> sequenceInput =
+    final public Input<List<Sequence>> sequenceInput =
             new Input<>("sequence", "sequence and meta data for particular taxon", new ArrayList<>(), Validate.OPTIONAL);
 
-    public Input<TaxonSet> taxonSetInput =
+    final public Input<TaxonSet> taxonSetInput =
             new Input<>("taxa", "An optional taxon-set used only to sort the sequences into the same order as they appear in the taxon-set.", new TaxonSet(), Validate.OPTIONAL);
 
-    public Input<Integer> stateCountInput = new Input<>("statecount", "maximum number of states in all sequences");
-    public Input<String> dataTypeInput = new Input<>("dataType", "data type, one of " + types, NUCLEOTIDE, types.toArray(new String[0]));
-    public Input<DataType.Base> userDataTypeInput = new Input<>("userDataType", "non-standard, user specified data type, if specified 'dataType' is ignored");
-    public Input<Boolean> stripInvariantSitesInput = new Input<>("strip", "sets weight to zero for sites that are invariant (e.g. all 1, all A or all unkown)", false);
-    public Input<String> siteWeightsInput = new Input<>("weights", "comma separated list of weights, one for each site in the sequences. If not specified, each site has weight 1");
+    final public Input<Integer> stateCountInput = new Input<>("statecount", "maximum number of states in all sequences");
+    final public Input<String> dataTypeInput = new Input<>("dataType", "data type, one of " + types, NUCLEOTIDE, types.toArray(new String[0]));
+    final public Input<DataType.Base> userDataTypeInput = new Input<>("userDataType", "non-standard, user specified data type, if specified 'dataType' is ignored");
+    final public Input<Boolean> stripInvariantSitesInput = new Input<>("strip", "sets weight to zero for sites that are invariant (e.g. all 1, all A or all unkown)", false);
+    final public Input<String> siteWeightsInput = new Input<>("weights", "comma separated list of weights, one for each site in the sequences. If not specified, each site has weight 1");
 
-    public Input<Boolean> isAscertainedInput = new Input<>("ascertained", "is true if the alignment allows ascertainment correction, i.e., conditioning the " +
+    final public Input<Boolean> isAscertainedInput = new Input<>("ascertained", "is true if the alignment allows ascertainment correction, i.e., conditioning the " +
             "Felsenstein likelihood on excluding constant sites from the alignment", false);
     /**
      * Inputs from AscertainedAlignment
      */
-    public Input<Integer> excludefromInput = new Input<>("excludefrom", "first site to condition on, default 0", 0);
-    public Input<Integer> excludetoInput = new Input<>("excludeto", "last site to condition on (but excluding this site), default 0", 0);
-    public Input<Integer> excludeeveryInput = new Input<>("excludeevery", "interval between sites to condition on (default 1)", 1);
+    final public Input<Integer> excludefromInput = new Input<>("excludefrom", "first site to condition on, default 0", 0);
+    final public Input<Integer> excludetoInput = new Input<>("excludeto", "last site to condition on (but excluding this site), default 0", 0);
+    final public Input<Integer> excludeeveryInput = new Input<>("excludeevery", "interval between sites to condition on (default 1)", 1);
 
     /**
      * list of sequences in the alignment *
@@ -145,7 +152,7 @@ public class Alignment extends Map<String> {
      * Probabilities associated with each tip of the tree, for use when the
      * characters are uncertain.
      */
-    public List<double[][]> tipLikelihoods = new ArrayList<double[][]>(); // #taxa x #sites x #states
+    public List<double[][]> tipLikelihoods = new ArrayList<>(); // #taxa x #sites x #states
     private boolean usingTipLikelihoods = false;
     
     /**
@@ -177,12 +184,11 @@ public class Alignment extends Map<String> {
      * @param sequences
      * @param stateCount
      * @param dataType
-     * @throws Exception when validation fails
      * @deprecated This is the deprecated legacy form and will be removed
      * at some point. Use {@link #Alignment(List, String)} instead.
      */
     @Deprecated
-    public Alignment(List<Sequence> sequences, Integer stateCount, String dataType) throws Exception {
+    public Alignment(List<Sequence> sequences, Integer stateCount, String dataType) {
         this(sequences, dataType);
     }
 
@@ -191,10 +197,8 @@ public class Alignment extends Map<String> {
      *
      * @param sequences
      * @param dataType
-     * @throws Exception when validation fails
      */
-    public Alignment(List<Sequence> sequences, String dataType) throws Exception {
-
+    public Alignment(List<Sequence> sequences, String dataType) {
         for (Sequence sequence : sequences) {
             sequenceInput.setValue(sequence, this);
         }
@@ -203,15 +207,15 @@ public class Alignment extends Map<String> {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
 
         if (sequenceInput.get().size() == 0 && defaultInput.get().size() == 0) {
-            throw new Exception("Either a sequence input must be specified, or a map of strings must be specified");
+            throw new IllegalArgumentException("Either a sequence input must be specified, or a map of strings must be specified");
         }
 
         if (siteWeightsInput.get() != null) {
-            String sStr = siteWeightsInput.get().trim();
-            String[] strs = sStr.split(",");
+            String str = siteWeightsInput.get().trim();
+            String[] strs = str.split(",");
             siteWeights = new int[strs.length];
             for (int i = 0; i < strs.length; i++) {
                 siteWeights[i] = Integer.parseInt(strs[i].trim());
@@ -223,17 +227,22 @@ public class Alignment extends Map<String> {
             m_dataType = userDataTypeInput.get();
         } else {
             if (types.indexOf(dataTypeInput.get()) < 0) {
-                throw new Exception("data type + '" + dataTypeInput.get() + "' cannot be found. " +
+                throw new IllegalArgumentException("data type + '" + dataTypeInput.get() + "' cannot be found. " +
                         "Choose one of " + Arrays.toString(types.toArray(new String[0])));
             }
             // seems to spend forever in there??
-            List<String> sDataTypes = AddOnManager.find(beast.evolution.datatype.DataType.class, IMPLEMENTATION_DIR);
-            for (String sDataType : sDataTypes) {
-                DataType dataType = (DataType) Class.forName(sDataType).newInstance();
-                if (dataTypeInput.get().equals(dataType.getTypeDescription())) {
-                    m_dataType = dataType;
-                    break;
-                }
+            List<String> dataTypes = AddOnManager.find(beast.evolution.datatype.DataType.class, IMPLEMENTATION_DIR);
+            for (String dataTypeName : dataTypes) {
+                DataType dataType;
+				try {
+					dataType = (DataType) Class.forName(dataTypeName).newInstance();
+	                if (dataTypeInput.get().equals(dataType.getTypeDescription())) {
+	                    m_dataType = dataType;
+	                    break;
+	                }
+				} catch (InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+					throw new IllegalArgumentException(e.getMessage());
+				}
             }
         }
 
@@ -298,7 +307,7 @@ public class Alignment extends Map<String> {
             }
         } catch (Exception e) {
             e.printStackTrace();
-            System.exit(0);
+            System.exit(1);
         }
         sanityCheckCalcPatternsSetUpAscertainment(log);
     }
@@ -308,16 +317,16 @@ public class Alignment extends Map<String> {
      */
     private void sanityCheckCalcPatternsSetUpAscertainment(boolean log) {
         // Sanity check: make sure sequences are of same length
-        int nLength = counts.get(0).size();
+        int length = counts.get(0).size();
         if (!(m_dataType instanceof StandardData)) {
             for (List<Integer> seq : counts) {
-                if (seq.size() != nLength) {
-                    throw new RuntimeException("Two sequences with different length found: " + nLength + " != " + seq.size());
+                if (seq.size() != length) {
+                    throw new RuntimeException("Two sequences with different length found: " + length + " != " + seq.size());
                 }
             }
         }
-        if (siteWeights != null && siteWeights.length != nLength) {
-            throw new RuntimeException("Number of weights (" + siteWeights.length + ") does not match sequence length (" + nLength + ")");
+        if (siteWeights != null && siteWeights.length != length) {
+            throw new RuntimeException("Number of weights (" + siteWeights.length + ") does not match sequence length (" + length + ")");
         }
 
         calcPatterns(log);
@@ -334,12 +343,10 @@ public class Alignment extends Map<String> {
 
         List<Sequence> sortedSeqs = new ArrayList<>();
         sortedSeqs.addAll(sequences);
-        Collections.sort(sortedSeqs, new Comparator<Sequence>() {
-            @Override
-            public int compare(Sequence o1, Sequence o2) {
+        Collections.sort(sortedSeqs, (Sequence o1, Sequence o2) -> {
                 return Integer.compare(toSortBy.getTaxonIndex(o1.getTaxon()), toSortBy.getTaxonIndex(o2.getTaxon()));
             }
-        });
+        );
         initializeWithSequenceList(sortedSeqs, false);
     }
 
@@ -348,21 +355,21 @@ public class Alignment extends Map<String> {
 
         if (isAscertained) {
             //From AscertainedAlignment
-            int iFrom = excludefromInput.get();
-            int iTo = excludetoInput.get();
-            int iEvery = excludeeveryInput.get();
-            excludedPatterns = new HashSet<Integer>();
-            for (int i = iFrom; i < iTo; i += iEvery) {
-                int iPattern = patternIndex[i];
+            int from = excludefromInput.get();
+            int to = excludetoInput.get();
+            int every = excludeeveryInput.get();
+            excludedPatterns = new HashSet<>();
+            for (int i = from; i < to; i += every) {
+                int patternIndex_ = patternIndex[i];
                 // reduce weight, so it does not confuse the tree likelihood
-                patternWeight[iPattern] = 0;
-                excludedPatterns.add(iPattern);
+                patternWeight[patternIndex_] = 0;
+                excludedPatterns.add(patternIndex_);
             }
         } else {
         	// sanity check
-            int iFrom = excludefromInput.get();
-            int iTo = excludetoInput.get();
-            if (iFrom != excludefromInput.defaultValue || iTo != excludetoInput.defaultValue) {
+            int from = excludefromInput.get();
+            int to = excludetoInput.get();
+            if (from != excludefromInput.defaultValue || to != excludetoInput.defaultValue) {
             	Log.warning.println("WARNING: excludefrom or excludeto is specified, but 'ascertained' flag is not set to true");
             	Log.warning.println("WARNING: to suppress this warning, remove the excludefrom or excludeto attributes (if no astertainment correction is required)");
             	Log.warning.println("WARNING: or set the 'ascertained' flag to true on element with id=" + getID());
@@ -373,16 +380,16 @@ public class Alignment extends Map<String> {
 
     static String getSequence(Alignment data, int taxonIndex) {
 
-        int[] nStates = new int[data.getPatternCount()];
+        int[] states = new int[data.getPatternCount()];
         for (int i = 0; i < data.getPatternCount(); i++) {
             int[] sitePattern = data.getPattern(i);
-            nStates[i] = sitePattern[taxonIndex];
+            states[i] = sitePattern[taxonIndex];
         }
         try {
-            return data.getDataType().state2string(nStates);
+            return data.getDataType().state2string(states);
         } catch (Exception e) {
             e.printStackTrace();
-            System.exit(0);
+            System.exit(1);
         }
         return null;
     }
@@ -443,8 +450,8 @@ public class Alignment extends Map<String> {
         return getTaxonCount();
     }
 
-    public int getTaxonIndex(String sID) {
-        return taxaNames.indexOf(sID);
+    public int getTaxonIndex(String id) {
+        return taxaNames.indexOf(id);
     }
 
     /**
@@ -454,23 +461,23 @@ public class Alignment extends Map<String> {
         return sitePatterns.length;
     }
 
-    public int[] getPattern(int iPattern) {
-        return sitePatterns[iPattern];
+    public int[] getPattern(int patternIndex_) {
+        return sitePatterns[patternIndex_];
     }
 
-    public int getPattern(int taxonIndex, int iPattern) {
-        return sitePatterns[iPattern][taxonIndex];
+    public int getPattern(int taxonIndex, int patternIndex_) {
+        return sitePatterns[patternIndex_][taxonIndex];
     }
 
     /**
      * Retrieve the "weight" of a particular pattern: the number of sites
      * having that pattern.
      *
-     * @param iPattern Index into pattern array.
+     * @param patternIndex_ Index into pattern array.
      * @return pattern weight
      */
-    public int getPatternWeight(int iPattern) {
-        return patternWeight[iPattern];
+    public int getPatternWeight(int patternIndex_) {
+        return patternWeight[patternIndex_];
     }
 
     public int getMaxStateCount() {
@@ -480,11 +487,11 @@ public class Alignment extends Map<String> {
     /**
      * Retrieve index of pattern corresponding to a particular site.
      *
-     * @param iSite Index of site.
+     * @param site Index of site.
      * @return Index of pattern.
      */
-    public int getPatternIndex(int iSite) {
-        return patternIndex[iSite];
+    public int getPatternIndex(int site) {
+        return patternIndex[site];
     }
 
     /**
@@ -510,7 +517,8 @@ public class Alignment extends Map<String> {
      * which makes it easy to identify patterns.
      */
     class SiteComparator implements Comparator<int[]> {
-        public int compare(int[] o1, int[] o2) {
+        @Override
+		public int compare(int[] o1, int[] o2) {
             for (int i = 0; i < o1.length; i++) {
                 if (o1[i] > o2[i]) {
                     return 1;
@@ -533,50 +541,50 @@ public class Alignment extends Map<String> {
          * *
          */
     private void calcPatterns(boolean log) {
-        int nTaxa = counts.size();
-        int nSites = counts.get(0).size();
+        int taxonCount = counts.size();
+        int siteCount = counts.get(0).size();
 
         // convert data to transposed int array
-        int[][] nData = new int[nSites][nTaxa];
-        for (int i = 0; i < nTaxa; i++) {
+        int[][] data = new int[siteCount][taxonCount];
+        for (int i = 0; i < taxonCount; i++) {
             List<Integer> sites = counts.get(i);
-            for (int j = 0; j < nSites; j++) {
-                nData[j][i] = sites.get(j);
+            for (int j = 0; j < siteCount; j++) {
+                data[j][i] = sites.get(j);
             }
         }
 
         // sort data
         SiteComparator comparator = new SiteComparator();
-        Arrays.sort(nData, comparator);
+        Arrays.sort(data, comparator);
 
         // count patterns in sorted data
         // if (siteWeights != null) the weights are recalculated below
-        int nPatterns = 1;
-        int[] weights = new int[nSites];
+        int patterns = 1;
+        int[] weights = new int[siteCount];
         weights[0] = 1;
-        for (int i = 1; i < nSites; i++) {
-            if (usingTipLikelihoods || comparator.compare(nData[i - 1], nData[i]) != 0) {
+        for (int i = 1; i < siteCount; i++) {
+            if (usingTipLikelihoods || comparator.compare(data[i - 1], data[i]) != 0) {
             	// In the case where we're using tip probabilities, we need to treat each 
             	// site as a unique pattern, because it could have a unique probability vector.
-                nPatterns++;
-                nData[nPatterns - 1] = nData[i];
+                patterns++;
+                data[patterns - 1] = data[i];
             }
-            weights[nPatterns - 1]++;
+            weights[patterns - 1]++;
         }
 
         // reserve memory for patterns
-        patternWeight = new int[nPatterns];
-        sitePatterns = new int[nPatterns][nTaxa];
-        for (int i = 0; i < nPatterns; i++) {
+        patternWeight = new int[patterns];
+        sitePatterns = new int[patterns][taxonCount];
+        for (int i = 0; i < patterns; i++) {
             patternWeight[i] = weights[i];
-            sitePatterns[i] = nData[i];
+            sitePatterns[i] = data[i];
         }
 
         // find patterns for the sites
-        patternIndex = new int[nSites];
-        for (int i = 0; i < nSites; i++) {
-            int[] sites = new int[nTaxa];
-            for (int j = 0; j < nTaxa; j++) {
+        patternIndex = new int[siteCount];
+        for (int i = 0; i < siteCount; i++) {
+            int[] sites = new int[taxonCount];
+            for (int j = 0; j < taxonCount; j++) {
                 sites[j] = counts.get(j).get(i);
             }
             patternIndex[i] = Arrays.binarySearch(sitePatterns, sites, comparator);
@@ -584,7 +592,7 @@ public class Alignment extends Map<String> {
 
         if (siteWeights != null) {
             Arrays.fill(patternWeight, 0);
-            for (int i = 0; i < nSites; i++) {
+            for (int i = 0; i < siteCount; i++) {
                 patternWeight[patternIndex[i]] += siteWeights[i];
             }
         }
@@ -608,21 +616,21 @@ public class Alignment extends Map<String> {
             if (log) Log.info.println("Stripping invariant sites");
 
             int removedSites = 0;
-            for (int i = 0; i < nPatterns; i++) {
-                int[] nPattern = sitePatterns[i];
-                int iValue = nPattern[0];
-                boolean bIsInvariant = true;
-                for (int k = 1; k < nPattern.length; k++) {
-                    if (nPattern[k] != iValue) {
-                        bIsInvariant = false;
+            for (int i = 0; i < patterns; i++) {
+                int[] pattern = sitePatterns[i];
+                int value = pattern[0];
+                boolean isInvariant = true;
+                for (int k = 1; k < pattern.length; k++) {
+                    if (pattern[k] != value) {
+                        isInvariant = false;
                         break;
                     }
                 }
-                if (bIsInvariant) {
+                if (isInvariant) {
                     removedSites += patternWeight[i];
                     patternWeight[i] = 0;
 
-                    if (log) Log.info.print(" <" + iValue + "> ");
+                    if (log) Log.info.print(" <" + value + "> ");
                 }
             }
             if (log) Log.info.println(" removed " + removedSites + " sites ");
@@ -671,22 +679,22 @@ public class Alignment extends Map<String> {
         return builder.toString();
     }
 
-    public double[] getTipLikelihoods(int iTaxon, int iPattern) {
-    	if (iTaxon >= tipLikelihoods.size() || tipLikelihoods.get(iTaxon) == null) { 
+    public double[] getTipLikelihoods(int taxonIndex, int patternIndex_) {
+    	if (taxonIndex >= tipLikelihoods.size() || tipLikelihoods.get(taxonIndex) == null) { 
     		return null; 
     	} else { 
-    		return tipLikelihoods.get(iTaxon)[iPattern];
+    		return tipLikelihoods.get(taxonIndex)[patternIndex_];
     	}
     	
     }
     /**
      * returns an array containing the non-ambiguous states that this state represents.
      */
-    public boolean[] getStateSet(int iState) {
-        return m_dataType.getStateSet(iState);
-//        if (!isAmbiguousState(iState)) {
+    public boolean[] getStateSet(int state) {
+        return m_dataType.getStateSet(state);
+//        if (!isAmbiguousState(state)) {
 //            boolean[] stateSet = new boolean[m_nMaxStateCount];
-//            stateSet[iState] = true;
+//            stateSet[state] = true;
 //            return stateSet;
 //        } else {
 //        }
@@ -727,11 +735,32 @@ public class Alignment extends Map<String> {
      */
     @Deprecated
     static public void sortByTaxonName(List<Sequence> seqs) {
-        Collections.sort(seqs, new Comparator<Sequence>() {
-            @Override
-            public int compare(Sequence o1, Sequence o2) {
+        Collections.sort(seqs, (Sequence o1, Sequence o2) -> {
                 return o1.taxonInput.get().compareTo(o2.taxonInput.get());
             }
-        });
-    }
+        );
+    }
+
+    /** 
+     * Get String representation of a sequence according to the current datatype
+     * @param taxon the name of the taxon to get the sequence from in the alignment
+     * @return sequence in String representation
+     */
+	public String getSequenceAsString(String taxon) {
+		int i = getTaxonIndex(taxon);		
+
+		// build up string from underlying data using the current datatype
+		int [] states = new int[getSiteCount()];
+		for (int k = 0; k < getSiteCount(); k++) {
+			int d = sitePatterns[patternIndex[k]][i];
+			states[k] = d;
+		}
+		String seq = null;
+		try {
+			seq = m_dataType.state2string(states);
+		} catch (Exception e) {
+			e.printStackTrace();
+		}
+		return seq;
+	}
 } // class Data
diff --git a/src/beast/evolution/alignment/AscertainedAlignment.java b/src/beast/evolution/alignment/AscertainedAlignment.java
index 8002fb8..1d5b354 100644
--- a/src/beast/evolution/alignment/AscertainedAlignment.java
+++ b/src/beast/evolution/alignment/AscertainedAlignment.java
@@ -4,7 +4,6 @@ import java.util.HashSet;
 import java.util.Set;
 
 import beast.core.Description;
-import beast.core.Input;
 
 
 
@@ -15,15 +14,15 @@ import beast.core.Input;
  */
 @Deprecated
 public class AscertainedAlignment extends Alignment {
-//    public Input<Integer> excludefromInput = new Input<Integer>("excludefrom", "first site to condition on, default 0", 0);
-//    public Input<Integer> excludetoInput = new Input<Integer>("excludeto", "last site to condition on (but excluding this site), default 0", 0);
-//    public Input<Integer> excludeeveryInput = new Input<Integer>("excludeevery", "interval between sites to condition on (default 1)", 1);
+//    public Input<Integer> excludefromInput = new Input<>("excludefrom", "first site to condition on, default 0", 0);
+//    public Input<Integer> excludetoInput = new Input<>("excludeto", "last site to condition on (but excluding this site), default 0", 0);
+//    public Input<Integer> excludeeveryInput = new Input<>("excludeevery", "interval between sites to condition on (default 1)", 1);
 
 // RRB: Note that all commented code is stuff to support inclusion-sites,
 // so don't delete them.
-//	public Input<Integer> m_includefrom = new Input<Integer>("includefrom","first site to condition on, default 0", 0);
-//	public Input<Integer> m_includeto = new Input<Integer>("includeto","last site to condition on, default 0", 0);
-//	public Input<Integer> m_includeevery = new Input<Integer>("includeevery","interval between sites to condition on (default 1)", 1);
+//	public Input<Integer> m_includefrom = new Input<>("includefrom","first site to condition on, default 0", 0);
+//	public Input<Integer> m_includeto = new Input<>("includeto","last site to condition on, default 0", 0);
+//	public Input<Integer> m_includeevery = new Input<>("includeevery","interval between sites to condition on (default 1)", 1);
 
     /**
      * indices of patterns that are excluded from the likelihood calculation
@@ -33,37 +32,39 @@ public class AscertainedAlignment extends Alignment {
 //	List<Integer> m_nIncluded;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
 
-        int iFrom = excludefromInput.get();
-        int iTo = excludetoInput.get();
-        int iEvery = excludeeveryInput.get();
-        excludedPatterns = new HashSet<Integer>();
-        for (int i = iFrom; i < iTo; i += iEvery) {
-            int iPattern = patternIndex[i];
+        int from = excludefromInput.get();
+        int to = excludetoInput.get();
+        int every = excludeeveryInput.get();
+        excludedPatterns = new HashSet<>();
+        for (int i = from; i < to; i += every) {
+            int patternIndex_ = patternIndex[i];
             // reduce weight, so it does not confuse the tree likelihood
-            patternWeight[iPattern] = 0;
-            excludedPatterns.add(iPattern);
+            patternWeight[patternIndex_] = 0;
+            excludedPatterns.add(patternIndex_);
         }
 
-//		iFrom = m_includefrom.get();
-//		iTo = m_includeto.get();
-//		iEvery = m_includeevery.get();
-//		m_nIncluded = new ArrayList<Integer>();
-//		for (int i = iFrom; i < iTo; i += iEvery) {
-//			int iPattern = m_nPatternIndex[i];
+//		from = m_includefrom.get();
+//		to = m_includeto.get();
+//		every = m_includeevery.get();
+//		m_nIncluded = new ArrayList<>();
+//		for (int i = from; i < to; i += every) {
+//			int patternIndex_ = m_nPatternIndex[i];
 //			// reduce weight, so it does not confuse the tree likelihood
-//			m_nWeight[iPattern] = 0;
-//			m_nIncluded.add(iPattern);
+//			m_nWeight[patternIndex_] = 0;
+//			m_nIncluded.add(patternIndex_);
 //		}
     } // initAndValidate
 
-    public Set<Integer> getExcludedPatternIndices() {
+    @Override
+	public Set<Integer> getExcludedPatternIndices() {
         return excludedPatterns;
     }
 
-    public int getExcludedPatternCount() {
+    @Override
+	public int getExcludedPatternCount() {
         return excludedPatterns.size();
     }
 
@@ -71,7 +72,8 @@ public class AscertainedAlignment extends Alignment {
 //		return m_nIncluded;
 //	}
 
-    public double getAscertainmentCorrection(double[] patternLogProbs) {
+    @Override
+	public double getAscertainmentCorrection(double[] patternLogProbs) {
         double excludeProb = 0, includeProb = 0, returnProb = 1.0;
 
 //        for (int i = 0; i < m_nIncluded.size(); i++) {
diff --git a/src/beast/evolution/alignment/FilteredAlignment.java b/src/beast/evolution/alignment/FilteredAlignment.java
index 3f77a74..1a75dde 100644
--- a/src/beast/evolution/alignment/FilteredAlignment.java
+++ b/src/beast/evolution/alignment/FilteredAlignment.java
@@ -15,15 +15,15 @@ import beast.evolution.datatype.DataType;
 
 @Description("Alignemnt based on a filter operation on another alignment")
 public class FilteredAlignment extends Alignment {
-    public Input<String> filterInput = new Input<String>("filter", "specifies which of the sites in the input alignment should be selected " +
+    final public Input<String> filterInput = new Input<>("filter", "specifies which of the sites in the input alignment should be selected " +
             "First site is 1." +
             "Filter specs are comma separated, either a singleton, a range [from]-[to] or iteration [from]:[to]:[step]; " +
             "1-100 defines a range, " +
             "1-100\3 or 1:100:3 defines every third in range 1-100, " +
             "1::3,2::3 removes every third site. " +
             "Default for range [1]-[last site], default for iterator [1]:[last site]:[1]", Validate.REQUIRED);
-    public Input<Alignment> alignmentInput = new Input<Alignment>("data", "alignment to be filtered", Validate.REQUIRED);
-    public Input<IntegerParameter> constantSiteWeightsInput = new Input<IntegerParameter>("constantSiteWeights", "if specified, constant " +
+    final public Input<Alignment> alignmentInput = new Input<>("data", "alignment to be filtered", Validate.REQUIRED);
+    final public Input<IntegerParameter> constantSiteWeightsInput = new Input<>("constantSiteWeights", "if specified, constant " +
     		"sites will be added with weights specified by the input. The dimension and order of weights must match the datatype. " +
     		"For example for nucleotide data, a 4 dimensional " +
     		"parameter with weights for A, C, G and T respectively need to be specified.");
@@ -46,7 +46,7 @@ public class FilteredAlignment extends Alignment {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         parseFilterSpec();
         calcFilter();
         Alignment data = alignmentInput.get();
@@ -59,7 +59,7 @@ public class FilteredAlignment extends Alignment {
 
         if (constantSiteWeightsInput.get() != null) {
         	if (constantSiteWeightsInput.get().getDimension() != m_dataType.getStateCount()) {
-        		throw new Exception("constantSiteWeights should be of the same dimension as the datatype " +
+        		throw new IllegalArgumentException("constantSiteWeights should be of the same dimension as the datatype " +
         				"(" + constantSiteWeightsInput.get().getDimension() + "!="+ m_dataType.getStateCount() +")");
         	}
     	}
@@ -74,8 +74,8 @@ public class FilteredAlignment extends Alignment {
         }
 
         if (alignmentInput.get().siteWeightsInput.get() != null) {
-    		String sStr = alignmentInput.get().siteWeightsInput.get().trim();
-    		String [] strs = sStr.split(",");
+    		String str = alignmentInput.get().siteWeightsInput.get().trim();
+    		String [] strs = str.split(",");
     		siteWeights = new int[strs.length];
     		for (int i = 0; i< strs.length; i++) {
     			siteWeights[i] = Integer.parseInt(strs[i].trim());
@@ -86,7 +86,7 @@ public class FilteredAlignment extends Alignment {
         setupAscertainment();
     }
 
-    private void parseFilterSpec() throws Exception {
+    private void parseFilterSpec() {
         // parse filter specification
         String filterString = filterInput.get();
         String[] filters = filterString.split(",");
@@ -118,7 +118,7 @@ public class FilteredAlignment extends Alignment {
                 to[i] = from[i];
             	step[i] = 1;
             } else {
-                throw new Exception("Don't know how to parse filter " + filterString);
+                throw new IllegalArgumentException("Don't know how to parse filter " + filterString);
             }
         }
     }
@@ -234,12 +234,12 @@ public class FilteredAlignment extends Alignment {
         		}
         		// if this is a constant site, and it is not an ambiguous site
         		if (isContant) {
-                    System.err.print(" <" + data[i][0] + "> ");
+        			Log.warning.print(" <" + data[i][0] + "> ");
                    	removedSites += weights[i]; 
             		weights[i] = 0;
         		}
         	}
-            System.err.println(" removed " + removedSites + " sites ");
+        	Log.warning.println(" removed " + removedSites + " sites ");
         }
         
         // addjust weight of constant sites, if specified
@@ -262,7 +262,7 @@ public class FilteredAlignment extends Alignment {
         		}
         	}
         	
-        	// need to decrease nSites for mapping sites to patterns in m_nPatternIndex
+        	// need to decrease siteCount for mapping sites to patterns in m_nPatternIndex
         	nrOfSites -= constantWeights.length; 
         }        
         
diff --git a/src/beast/evolution/alignment/Sequence.java b/src/beast/evolution/alignment/Sequence.java
index 154afbd..1e056f0 100644
--- a/src/beast/evolution/alignment/Sequence.java
+++ b/src/beast/evolution/alignment/Sequence.java
@@ -25,22 +25,22 @@
 package beast.evolution.alignment;
 
 import java.util.ArrayList;
-import java.util.List;
 import java.util.Collection;
+import java.util.List;
 
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.BEASTObject;
 import beast.evolution.datatype.DataType;
 
 @Description("Single sequence in an alignment.")
 public class Sequence extends BEASTObject {
-    public Input<Integer> totalCountInput = new Input<Integer>("totalcount", "number of states or the number of lineages for this species in SNAPP analysis");
-    public Input<String> taxonInput = new Input<String>("taxon", "name of this species", Input.Validate.REQUIRED);
-    public Input<String> dataInput = new Input<String>("value",
+    final public Input<Integer> totalCountInput = new Input<>("totalcount", "number of states or the number of lineages for this species in SNAPP analysis");
+    final public Input<String> taxonInput = new Input<>("taxon", "name of this species", Input.Validate.REQUIRED);
+    final public Input<String> dataInput = new Input<>("value",
             "sequence data, either encoded as a string or as comma separated list of integers, or comma separated likelihoods/probabilities for each site if uncertain=true." +
                     "In either case, whitespace is ignored.", Input.Validate.REQUIRED);
-    public Input<Boolean> uncertainInput = new Input<Boolean>("uncertain", "if true, sequence is provided as comma separated probabilities for each character, with sites separated by a semi-colons. In this formulation, gaps are coded as 1/K,...,1/K, where K is the number of states in the model.");
+    final public Input<Boolean> uncertainInput = new Input<>("uncertain", "if true, sequence is provided as comma separated probabilities for each character, with sites separated by a semi-colons. In this formulation, gaps are coded as 1/K,...,1/K, where K is the number of states in the model.");
 
     protected boolean uncertain = false;
     protected double[][] likelihoods = null;    
@@ -56,30 +56,29 @@ public class Sequence extends BEASTObject {
      *
      * @param taxon
      * @param sequence
-     * @throws Exception
      */
-    public Sequence(String taxon, String sequence) throws Exception {
+    public Sequence(String taxon, String sequence) {
         taxonInput.setValue(taxon, this);
         dataInput.setValue(sequence, this);
         initAndValidate();
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
     	if (uncertainInput.get() != null)  {
     		uncertain = uncertainInput.get();    		
     		if (uncertain) initProbabilities();    		
     	}
     } // initAndValidate
     
-    public void initProbabilities() throws Exception {
+    public void initProbabilities() {
     	   	
     	String data = dataInput.get();
         // remove spaces
         data = data.replaceAll("\\s", "");
         
-        String sStr = data.trim();		
-		String[] strs = sStr.split(";");		
+        String str = data.trim();		
+		String[] strs = str.split(";");		
 		for (int i=0; i<strs.length; i++) {
 			String[] pr = strs[i].split(",");
 			//double total = 0;
@@ -91,11 +90,11 @@ public class Sequence extends BEASTObject {
 		}
     }
 
-    public List<Integer> getSequence(DataType dataType) throws Exception {
+    public List<Integer> getSequence(DataType dataType) {
         
     	List<Integer> sequence;
     	if (uncertain) {
-            sequence = new ArrayList<Integer>();
+            sequence = new ArrayList<>();
             for (int i=0; i<likelihoods.length; i++) {
             	double m = likelihoods[i][0];
             	int index = 0;
@@ -157,7 +156,8 @@ public class Sequence extends BEASTObject {
         return null;
     }
 
-    public String toString() {
+    @Override
+	public String toString() {
         return getTaxon() + ":" + getData();
     }
 
diff --git a/src/beast/evolution/alignment/Taxon.java b/src/beast/evolution/alignment/Taxon.java
index e6401fb..58afd81 100644
--- a/src/beast/evolution/alignment/Taxon.java
+++ b/src/beast/evolution/alignment/Taxon.java
@@ -2,10 +2,12 @@ package beast.evolution.alignment;
 
 
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
 
-import beast.core.Description;
 import beast.core.BEASTObject;
+import beast.core.Description;
 
 
 @Description("For identifying a single taxon")
@@ -13,9 +15,9 @@ public class Taxon extends BEASTObject {
     // we can use the ID to identify a taxon name/taxon label
     // if there are multiple taxaset with the same taxa, use
     // idref to refer to the single taxon.
-//	public Input<String> m_sLabel = new Input<String>("label", "name of the taxon", Validate.REQUIRED);
+//	public Input<String> m_sLabel = new Input<>("label", "name of the taxon", Validate.REQUIRED);
 
-    public Taxon(final String id) throws Exception {
+    public Taxon(final String id) {
         setID(id);
         initAndValidate();
     }
@@ -24,7 +26,7 @@ public class Taxon extends BEASTObject {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
 
     }
 
@@ -37,7 +39,7 @@ public class Taxon extends BEASTObject {
      * @param taxaNames a list of taxa names
      * @return a list of Taxon objects with corresponding names
      */
-    public static List<Taxon> createTaxonList(final List<String> taxaNames) throws Exception {
+    public static List<Taxon> createTaxonList(final List<String> taxaNames) {
         final List<Taxon> taxa = new ArrayList<>();
         for (final String taxaName : taxaNames) {
             taxa.add(new Taxon(taxaName));
@@ -51,12 +53,12 @@ public class Taxon extends BEASTObject {
 //     * @return a list of Taxon objects with corresponding names
 //     */
 //    @Deprecated
-//    public static List<Taxon> createSortedTaxonList(final List<String> taxaNames) throws Exception {
+//    public static List<Taxon> createSortedTaxonList(final List<String> taxaNames) {
 //        final List<Taxon> taxa = new ArrayList<>();
 //        for (final String taxaName : taxaNames) {
 //            taxa.add(new Taxon(taxaName));
 //        }
-//        Collections.sort(taxa, new Comparator<Taxon>() {
+//        Collections.sort(taxa, new Comparator<>() {
 //            @Override // assumes IDs are not null
 //            public int compare(Taxon o1, Taxon o2) {
 //                return o1.getID().compareTo(o2.getID());
diff --git a/src/beast/evolution/alignment/TaxonSet.java b/src/beast/evolution/alignment/TaxonSet.java
index 49980d3..79034b2 100644
--- a/src/beast/evolution/alignment/TaxonSet.java
+++ b/src/beast/evolution/alignment/TaxonSet.java
@@ -2,19 +2,25 @@ package beast.evolution.alignment;
 
 
 
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
+
 import beast.core.Description;
 import beast.core.Input;
 
-import java.util.*;
-
 
 @Description("A TaxonSet is an ordered set of taxa. The order on the taxa is provided at the time of construction" +
         " either from a list of taxon objects or an alignment.")
 public class TaxonSet extends Taxon {
 
-    public Input<List<Taxon>> taxonsetInput = new Input<>("taxon", "list of taxa making up the set", new ArrayList<>());
+    final public Input<List<Taxon>> taxonsetInput = new Input<>("taxon", "list of taxa making up the set", new ArrayList<>());
 
-    public Input<Alignment> alignmentInput = new Input<Alignment>("alignment", "alignment where each sequence represents a taxon");
+    final public Input<Alignment> alignmentInput = new Input<>("alignment", "alignment where each sequence represents a taxon");
 
     protected List<String> taxaNames;
     protected List<Taxon> taxonList;
@@ -22,34 +28,34 @@ public class TaxonSet extends Taxon {
     public TaxonSet() {
     }
 
-    public TaxonSet(final List<Taxon> taxa) throws Exception {
+    public TaxonSet(final List<Taxon> taxa) {
         taxonsetInput.setValue(taxa, this);
         initAndValidate();
     }
     
-    public TaxonSet(final Alignment alignment) throws Exception {
+    public TaxonSet(final Alignment alignment) {
         alignmentInput.setValue(alignment, this);
         initAndValidate();
     }
 
     // for testing purposes (Huw)
-    public TaxonSet(final String id, final List<Taxon> taxa) throws Exception {
+    public TaxonSet(final String id, final List<Taxon> taxa) {
         setID(id);
         taxonsetInput.setValue(taxa, this);
         initAndValidate();
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         taxonList = taxonsetInput.get();
         if (alignmentInput.get() != null) {
             if (taxonList.size() > 0) {
-                throw new Exception("Only one of taxon and alignment should be specified, not both.");
+                throw new IllegalArgumentException("Only one of taxon and alignment should be specified, not both.");
             }
             taxaNames = alignmentInput.get().taxaNames;
         } else {
             if (taxonList.size() == 0) {
-                throw new Exception("Either taxon or alignment should be specified.");
+                throw new IllegalArgumentException("Either taxon or alignment should be specified.");
             }
             taxaNames = new ArrayList<>();
             for (final Taxon taxon : taxonList) {
@@ -163,7 +169,7 @@ public class TaxonSet extends Taxon {
 		final StringBuilder buf = new StringBuilder();
 		buf.append(indent).append(getID()).append("\n");
 		indent += "\t";
-		for (final Taxon taxon : taxonList) {
+		for (final Taxon taxon : taxonsetInput.get()) {
 			buf.append(taxon.toString(indent));
 		}
 		return buf.toString();
diff --git a/src/beast/evolution/alignment/distance/Distance.java b/src/beast/evolution/alignment/distance/Distance.java
index 0896cb8..0aca634 100644
--- a/src/beast/evolution/alignment/distance/Distance.java
+++ b/src/beast/evolution/alignment/distance/Distance.java
@@ -1,7 +1,7 @@
 package beast.evolution.alignment.distance;
 
-import beast.core.Description;
 import beast.core.BEASTObject;
+import beast.core.Description;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.alignment.TaxonSet;
 import beast.evolution.datatype.DataType;
@@ -20,7 +20,7 @@ public interface Distance {
 	    public static final double MAX_DISTANCE = 5.0;
 	
 	    @Override
-	    public void initAndValidate() throws Exception {
+	    public void initAndValidate() {
 	        // nothing to do
 	    }
 	
@@ -35,7 +35,7 @@ public interface Distance {
 	            e.printStackTrace();
 	        }
 	        this.patterns = patterns;
-	        dimension = patterns.getNrTaxa();
+	        dimension = patterns.getTaxonCount();
 	        dataType = patterns.getDataType();
 	        distancesKnown = false;
 	    }
diff --git a/src/beast/evolution/alignment/distance/HammingDistance.java b/src/beast/evolution/alignment/distance/HammingDistance.java
index efeeaa9..9f9a3b3 100644
--- a/src/beast/evolution/alignment/distance/HammingDistance.java
+++ b/src/beast/evolution/alignment/distance/HammingDistance.java
@@ -9,13 +9,13 @@ public class HammingDistance extends Distance.Base {
 
     @Override
     public double pairwiseDistance(int taxon1, int taxon2) {
-        double fDist = 0;
+        double dist = 0;
         for (int i = 0; i < patterns.getPatternCount(); i++) {
             if (patterns.getPattern(taxon1, i) != patterns.getPattern(taxon2, i)) {
-                fDist += patterns.getPatternWeight(i);
+                dist += patterns.getPatternWeight(i);
             }
         }
-        return fDist / patterns.getSiteCount();
+        return dist / patterns.getSiteCount();
     }
 
 }
diff --git a/src/beast/evolution/branchratemodel/BranchRateModel.java b/src/beast/evolution/branchratemodel/BranchRateModel.java
index b98b404..e06e212 100644
--- a/src/beast/evolution/branchratemodel/BranchRateModel.java
+++ b/src/beast/evolution/branchratemodel/BranchRateModel.java
@@ -16,7 +16,7 @@ public interface BranchRateModel {
 
     @Description(value = "Base implementation of a clock model.", isInheritable = false)
     public abstract class Base extends CalculationNode implements BranchRateModel {
-        public Input<RealParameter> meanRateInput = new Input<RealParameter>("clock.rate", "mean clock rate (defaults to 1.0)");
+        final public Input<RealParameter> meanRateInput = new Input<>("clock.rate", "mean clock rate (defaults to 1.0)");
 
         // empty at the moment but brings together the required interfaces
     }
diff --git a/src/beast/evolution/branchratemodel/RandomLocalClockModel.java b/src/beast/evolution/branchratemodel/RandomLocalClockModel.java
index 661fffa..fa5b80b 100644
--- a/src/beast/evolution/branchratemodel/RandomLocalClockModel.java
+++ b/src/beast/evolution/branchratemodel/RandomLocalClockModel.java
@@ -5,6 +5,7 @@ import beast.core.Description;
 import beast.core.Input;
 import beast.core.parameter.BooleanParameter;
 import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
 import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
 
@@ -14,33 +15,33 @@ import beast.evolution.tree.Tree;
 @Description("Random Local Clock Model, whatever that is....")
 public class RandomLocalClockModel extends BranchRateModel.Base {
 
-    public Input<BooleanParameter> indicatorParamInput =
-            new Input<BooleanParameter>("indicators",
+    final public Input<BooleanParameter> indicatorParamInput =
+            new Input<>("indicators",
                     "the indicators associated with nodes in the tree for sampling of individual rate changes among branches.",
                     Input.Validate.REQUIRED);
-    public Input<RealParameter> rateParamInput =
-            new Input<RealParameter>("rates",
+    final public Input<RealParameter> rateParamInput =
+            new Input<>("rates",
                     "the rate parameters associated with nodes in the tree for sampling of individual rates among branches.",
                     Input.Validate.REQUIRED);
     //    public Input<RealParameter> meanRateInput =
-//            new Input<RealParameter>("meanRate",
+//            new Input<>("meanRate",
 //                    "an optional parameter to set the mean rate across the whole tree");
-    public Input<Tree> treeInput =
-            new Input<Tree>("tree", "the tree this relaxed clock is associated with.", Input.Validate.REQUIRED);
-    public Input<Boolean> ratesAreMultipliersInput =
-            new Input<Boolean>("ratesAreMultipliers", "true if the rates should be treated as multipliers (default false).", false);
+    final public Input<Tree> treeInput =
+            new Input<>("tree", "the tree this relaxed clock is associated with.", Input.Validate.REQUIRED);
+    final public Input<Boolean> ratesAreMultipliersInput =
+            new Input<>("ratesAreMultipliers", "true if the rates should be treated as multipliers (default false).", false);
 
     Tree m_tree;
     RealParameter meanRate;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         m_tree = treeInput.get();
 
         BooleanParameter indicators = indicatorParamInput.get();
 
         if (indicators.getDimension() != m_tree.getNodeCount() - 1) {
-            System.out.println("RandomLocalClockModel::Setting dimension of indicators to " + (m_tree.getNodeCount() - 1));
+            Log.warning.println("RandomLocalClockModel::Setting dimension of indicators to " + (m_tree.getNodeCount() - 1));
             indicators.setDimension(m_tree.getNodeCount() - 1);
         }
 
@@ -54,7 +55,7 @@ public class RandomLocalClockModel extends BranchRateModel.Base {
             rates.setUpper(Double.MAX_VALUE);
         }
         if (rates.getDimension() != m_tree.getNodeCount() - 1) {
-            System.out.println("RandomLocalClockModel::Setting dimension of rates to " + (m_tree.getNodeCount() - 1));
+        	Log.warning.println("RandomLocalClockModel::Setting dimension of rates to " + (m_tree.getNodeCount() - 1));
             rates.setDimension(m_tree.getNodeCount() - 1);
         }
 
@@ -139,11 +140,11 @@ public class RandomLocalClockModel extends BranchRateModel.Base {
     }
 
     private int getNr(Node node) {
-        int nNodeNr = node.getNr();
-        if (nNodeNr > m_tree.getRoot().getNr()) {
-            nNodeNr--;
+        int nodeNr = node.getNr();
+        if (nodeNr > m_tree.getRoot().getNr()) {
+            nodeNr--;
         }
-        return nNodeNr;
+        return nodeNr;
     }
 
     @Override
diff --git a/src/beast/evolution/branchratemodel/RateStatistic.java b/src/beast/evolution/branchratemodel/RateStatistic.java
index 10051be..6ffd028 100644
--- a/src/beast/evolution/branchratemodel/RateStatistic.java
+++ b/src/beast/evolution/branchratemodel/RateStatistic.java
@@ -28,12 +28,12 @@ package beast.evolution.branchratemodel;
 
 import java.io.PrintStream;
 
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Function;
 import beast.core.Input;
-import beast.core.Loggable;
-import beast.core.BEASTObject;
 import beast.core.Input.Validate;
+import beast.core.Loggable;
 import beast.evolution.likelihood.GenericTreeLikelihood;
 import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
@@ -46,11 +46,11 @@ import beast.math.statistic.DiscreteStatistics;
         "It has three dimensions, one for each statistic.")
 public class RateStatistic extends BEASTObject implements Loggable, Function {
 	
-    public Input<GenericTreeLikelihood> likelihoodInput = new Input<GenericTreeLikelihood>("treeLikelihood", "TreeLikelihood containing branch rate model that provides rates for a tree");
-    public Input<BranchRateModel> branchRateModelInput = new Input<BranchRateModel>("branchratemodel", "model that provides rates for a tree", Validate.XOR, likelihoodInput);
-    public Input<Tree> treeInput = new Input<Tree>("tree", "tree for which the rates apply");
-    public Input<Boolean> internalInput = new Input<Boolean>("internal", "consider internal nodes, default true", true);
-    public Input<Boolean> externalInput = new Input<Boolean>("external", "consider external nodes, default true", true);
+    final public Input<GenericTreeLikelihood> likelihoodInput = new Input<>("treeLikelihood", "TreeLikelihood containing branch rate model that provides rates for a tree");
+    final public Input<BranchRateModel> branchRateModelInput = new Input<>("branchratemodel", "model that provides rates for a tree", Validate.XOR, likelihoodInput);
+    final public Input<Tree> treeInput = new Input<>("tree", "tree for which the rates apply");
+    final public Input<Boolean> internalInput = new Input<>("internal", "consider internal nodes, default true", true);
+    final public Input<Boolean> externalInput = new Input<>("external", "consider external nodes, default true", true);
 
     private Tree tree = null;
     private BranchRateModel branchRateModel = null;
@@ -62,7 +62,7 @@ public class RateStatistic extends BEASTObject implements Loggable, Function {
     final static int COEFFICIENT_OF_VARIATION = 2;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         tree = treeInput.get();
         branchRateModel = branchRateModelInput.get();
         if (branchRateModel == null) {
@@ -154,11 +154,11 @@ public class RateStatistic extends BEASTObject implements Loggable, Function {
     }
 
     @Override
-    public double getArrayValue(final int iDim) {
-        if (iDim > 3) {
+    public double getArrayValue(final int dim) {
+        if (dim > 3) {
             throw new IllegalArgumentException();
         }
-        return calcValues()[iDim];
+        return calcValues()[dim];
     }
 
 
@@ -167,17 +167,17 @@ public class RateStatistic extends BEASTObject implements Loggable, Function {
      */
 
     @Override
-    public void init(final PrintStream out) throws Exception {
-        String sID = getID();
-        if (sID == null) {
-            sID = "";
+    public void init(final PrintStream out) {
+        String id = getID();
+        if (id == null) {
+            id = "";
         }
-        out.print(sID + ".mean\t" + sID + ".variance\t" + sID + ".coefficientOfVariation\t");
+        out.print(id + ".mean\t" + id + ".variance\t" + id + ".coefficientOfVariation\t");
     }
 
 
     @Override
-    public void log(final int nSample, final PrintStream out) {
+    public void log(final int sample, final PrintStream out) {
         final double[] values = calcValues();
         out.print(values[0] + "\t" + values[1] + "\t" + values[2] + "\t");
     }
diff --git a/src/beast/evolution/branchratemodel/StrictClockModel.java b/src/beast/evolution/branchratemodel/StrictClockModel.java
index 45eb85e..cb31d02 100644
--- a/src/beast/evolution/branchratemodel/StrictClockModel.java
+++ b/src/beast/evolution/branchratemodel/StrictClockModel.java
@@ -11,12 +11,12 @@ import beast.evolution.tree.Node;
 @Description("Defines a mean rate for each branch in the beast.tree.")
 public class StrictClockModel extends BranchRateModel.Base {
 
-    //public Input<RealParameter> muParameterInput = new Input<RealParameter>("clock.rate", "the clock rate (defaults to 1.0)");
+    //public Input<RealParameter> muParameterInput = new Input<>("clock.rate", "the clock rate (defaults to 1.0)");
 
     RealParameter muParameter;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         muParameter = meanRateInput.get();
         if (muParameter != null) {
             muParameter.setBounds(Math.max(0.0, muParameter.getLower()), muParameter.getUpper());
diff --git a/src/beast/evolution/branchratemodel/UCRelaxedClockModel.java b/src/beast/evolution/branchratemodel/UCRelaxedClockModel.java
index 9e8c819..d5a9cc6 100644
--- a/src/beast/evolution/branchratemodel/UCRelaxedClockModel.java
+++ b/src/beast/evolution/branchratemodel/UCRelaxedClockModel.java
@@ -1,6 +1,10 @@
 package beast.evolution.branchratemodel;
 
 
+import java.util.Arrays;
+
+import org.apache.commons.math.MathException;
+
 import beast.core.Citation;
 import beast.core.Description;
 import beast.core.Input;
@@ -11,9 +15,6 @@ import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
 import beast.math.distributions.ParametricDistribution;
 import beast.util.Randomizer;
-import org.apache.commons.math.MathException;
-
-import java.util.Arrays;
 
 /**
  * @author Alexei Drummond
@@ -26,16 +27,16 @@ import java.util.Arrays;
         year = 2006, firstAuthorSurname = "drummond")
 public class UCRelaxedClockModel extends BranchRateModel.Base {
 
-    public Input<ParametricDistribution> rateDistInput = new Input<ParametricDistribution>("distr", "the distribution governing the rates among branches. Must have mean of 1. The clock.rate parameter can be used to change the mean rate.", Input.Validate.REQUIRED);
-    public Input<IntegerParameter> categoryInput = new Input<IntegerParameter>("rateCategories", "the rate categories associated with nodes in the tree for sampling of individual rates among branches.", Input.Validate.REQUIRED);
+    final public Input<ParametricDistribution> rateDistInput = new Input<>("distr", "the distribution governing the rates among branches. Must have mean of 1. The clock.rate parameter can be used to change the mean rate.", Input.Validate.REQUIRED);
+    final public Input<IntegerParameter> categoryInput = new Input<>("rateCategories", "the rate categories associated with nodes in the tree for sampling of individual rates among branches.", Input.Validate.REQUIRED);
 
-    public Input<Integer> numberOfDiscreteRates = new Input<Integer>("numberOfDiscreteRates", "the number of discrete rate categories to approximate the rate distribution by. A value <= 0 will cause the number of categories to be set equal to the number of branches in the tree. (default = -1)", -1);
+    final public Input<Integer> numberOfDiscreteRates = new Input<>("numberOfDiscreteRates", "the number of discrete rate categories to approximate the rate distribution by. A value <= 0 will cause the number of categories to be set equal to the number of branches in the tree. (default = -1)", -1);
 
-    public Input<RealParameter> quantileInput = new Input<RealParameter>("rateQuantiles", "the rate quantiles associated with nodes in the tree for sampling of individual rates among branches.", Input.Validate.XOR, categoryInput);
+    final public Input<RealParameter> quantileInput = new Input<>("rateQuantiles", "the rate quantiles associated with nodes in the tree for sampling of individual rates among branches.", Input.Validate.XOR, categoryInput);
 
-    public Input<Tree> treeInput = new Input<Tree>("tree", "the tree this relaxed clock is associated with.", Input.Validate.REQUIRED);
-    public Input<Boolean> normalizeInput = new Input<Boolean>("normalize", "Whether to normalize the average rate (default false).", false);
-//    public Input<Boolean> initialiseInput = new Input<Boolean>("initialise", "Whether to initialise rates by a heuristic instead of random (default false).", false);
+    final public Input<Tree> treeInput = new Input<>("tree", "the tree this relaxed clock is associated with.", Input.Validate.REQUIRED);
+    final public Input<Boolean> normalizeInput = new Input<>("normalize", "Whether to normalize the average rate (default false).", false);
+//    public Input<Boolean> initialiseInput = new Input<>("initialise", "Whether to initialise rates by a heuristic instead of random (default false).", false);
 
     RealParameter meanRate;
 //    boolean initialise;
@@ -48,7 +49,7 @@ public class UCRelaxedClockModel extends BranchRateModel.Base {
     private int branchCount;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
 
         tree = treeInput.get();
         branchCount = tree.getNodeCount() - 1;
@@ -118,7 +119,8 @@ public class UCRelaxedClockModel extends BranchRateModel.Base {
         }
     }
 
-    public double getRateForBranch(Node node) {
+    @Override
+	public double getRateForBranch(Node node) {
         if (node.isRoot()) {
             // root has no rate
             return 1;
@@ -299,24 +301,24 @@ public class UCRelaxedClockModel extends BranchRateModel.Base {
 //    class TreeLikelihoodD extends TreeLikelihood {
 //    
 //    	double calcDistance(Node node) {
-//    		int iNode = node.getNr();
+//    		int nodeIndex = node.getNr();
 //    		int patterncount = dataInput.get().getPatternCount();
 //    		int statecount = dataInput.get().getDataType().getStateCount();
-//            double [] fParentPartials = new double[patterncount * statecount];
-//    		likelihoodCore.getNodePartials(node.getParent().getNr(), fParentPartials);
+//            double [] parentPartials = new double[patterncount * statecount];
+//    		likelihoodCore.getNodePartials(node.getParent().getNr(), parentPartials);
 //    		if (node.isLeaf()) {
 //        		// distance of leaf to its parent, ignores ambiguities
-//    			int [] nStates = new int[patterncount ];
-//        		likelihoodCore.getNodeStates(iNode, nStates);
+//    			int [] states = new int[patterncount ];
+//        		likelihoodCore.getNodeStates(nodeIndex, states);
 //        		double distance = 0;
 //        		for (int i = 0; i < patterncount; i++) {
-//        			int k = nStates[i];
+//        			int k = states[i];
 //        			double d = 0;
 //        			for (int j = 0; j < statecount; j++) {
 //        				if (j == k) {
-//        					d += 1.0 - fParentPartials[i * statecount + j];
+//        					d += 1.0 - parentPartials[i * statecount + j];
 //        				} else {
-//        					d += fParentPartials[i * statecount + j];
+//        					d += parentPartials[i * statecount + j];
 //        				}
 //        			}
 //        			distance += d * dataInput.get().getPatternWeight(i);
@@ -324,13 +326,13 @@ public class UCRelaxedClockModel extends BranchRateModel.Base {
 //    			return distance;
 //    		} else {
 //        		// L1 distance of internal node partials to its parent partials
-//                double [] fPartials = new double[fParentPartials.length];
-//        		likelihoodCore.getNodePartials(iNode, fPartials);
+//                double [] partials = new double[parentPartials.length];
+//        		likelihoodCore.getNodePartials(nodeIndex, partials);
 //        		double distance = 0;
 //        		for (int i = 0; i < patterncount; i++) {
 //        			double d = 0;
 //        			for (int j = 0; j < statecount; j++) {
-//       					d += Math.abs(fPartials[i * statecount + j] - fParentPartials[i * statecount + j]);
+//       					d += Math.abs(partials[i * statecount + j] - parentPartials[i * statecount + j]);
 //        			}
 //        			distance += d * dataInput.get().getPatternWeight(i);
 //        		}
diff --git a/src/beast/evolution/datatype/DataType.java b/src/beast/evolution/datatype/DataType.java
index 12b4211..9c5f998 100644
--- a/src/beast/evolution/datatype/DataType.java
+++ b/src/beast/evolution/datatype/DataType.java
@@ -26,28 +26,28 @@ public interface DataType {
      * Ambiguous states should be represented by integer numbers higher than getStateCount()
      * throws exception when parsing error occur *
      */
-    List<Integer> string2state(String sSequence) throws Exception;
+    List<Integer> string2state(String sequence);
 
     /**
      * Convert an array of states into a sequence represented by a string.
      * This is the inverse of string2state()
      * throws exception when State cannot be mapped *
      */
-    String state2string(List<Integer> nStates) throws Exception;
+    String state2string(List<Integer> states);
 
-    String state2string(int[] nStates) throws Exception;
+    String state2string(int[] states);
 
     /**
      * returns an array of length getStateCount() containing the (possibly ambiguous) states
      * that this state represents.
      */
-    public boolean[] getStateSet(int iState);
+    public boolean[] getStateSet(int state);
 
     /**
      * returns an array with all non-ambiguous states represented by
      * a state.
      */
-    public int[] getStatesForCode(int iState);
+    public int[] getStatesForCode(int state);
 
     boolean isAmbiguousState(int state);
 
@@ -108,10 +108,10 @@ public interface DataType {
         protected int[][] mapCodeToStateSet;
 
         @Override
-        public void initAndValidate() throws Exception {
+        public void initAndValidate() {
             if (mapCodeToStateSet != null) {
                 if (mapCodeToStateSet.length != codeMap.length() / codeLength) {
-                    throw new Exception("m_sCodeMap and m_mapCodeToStateSet have incompatible lengths");
+                    throw new IllegalArgumentException("codeMap and mapCodeToStateSet have incompatible lengths");
                 }
             }
         }
@@ -125,19 +125,19 @@ public interface DataType {
          * implementation for single character per state encoding *
          */
         @Override
-        public List<Integer> string2state(String data) throws Exception {
+        public List<Integer> string2state(String data) {
             List<Integer> sequence;
-            sequence = new ArrayList<Integer>();
+            sequence = new ArrayList<>();
             // remove spaces
             data = data.replaceAll("\\s", "");
             data = data.toUpperCase();
             if (codeMap == null) {
                 if (data.contains(",")) {
                     // assume it is a comma separated string of integers
-                    String[] sStrs = data.split(",");
-                    for (String sStr : sStrs) {
+                    String[] strs = data.split(",");
+                    for (String str : strs) {
                     	try {
-                    		sequence.add(Integer.parseInt(sStr));
+                    		sequence.add(Integer.parseInt(str));
                     	} catch (NumberFormatException e) {
                     		sequence.add(-1);
                     	}
@@ -160,17 +160,17 @@ public interface DataType {
                     // single character codes
                     for (int i = 0; i < data.length(); i++) {
                         char cCode = data.charAt(i);
-                        int nState = codeMap.indexOf(cCode);
-                        if (nState < 0) {
-                            throw new Exception("Unknown code found in sequence: " + cCode);
+                        int stateCount = codeMap.indexOf(cCode);
+                        if (stateCount < 0) {
+                            throw new IllegalArgumentException("Unknown code found in sequence: " + cCode);
                         }
-                        sequence.add(nState);
+                        sequence.add(stateCount);
                     }
                 } else if (codeLength > 1) {
                     // multi-character codes of fixed length
 
                     // use code map to resolve state codes
-                    Map<String, Integer> map = new HashMap<String, Integer>();
+                    Map<String, Integer> map = new HashMap<>();
                     // fixed length code
                     for (int i = 0; i < codeMap.length(); i += codeLength) {
                         String code = codeMap.substring(i, i + codeLength);
@@ -182,7 +182,7 @@ public interface DataType {
                         if (map.containsKey(code)) {
                             sequence.add(map.get(code));
                         } else {
-                            throw new Exception("Unknown code found in sequence: " + code);
+                            throw new IllegalArgumentException("Unknown code found in sequence: " + code);
                         }
                     }
                 } else {
@@ -190,15 +190,15 @@ public interface DataType {
                     String[] codes = codeMap.toUpperCase().split(",");
                     for (String code : data.split(",")) {
                         boolean isFound = false;
-                        for (int iCode = 0; iCode < codes.length; iCode++) {
-                            if (code.equals(codes[iCode])) {
-                                sequence.add(iCode);
+                        for (int codeIndex = 0; codeIndex < codes.length; codeIndex++) {
+                            if (code.equals(codes[codeIndex])) {
+                                sequence.add(codeIndex);
                                 isFound = true;
                                 break;
                             }
                         }
                         if (!isFound) {
-                            throw new Exception("Could not find code " + code + " in codemap");
+                            throw new RuntimeException("Could not find code " + code + " in codemap");
                         }
                     }
                 }
@@ -222,9 +222,9 @@ public interface DataType {
         public String state2string(int[] nrOfStates) {
             StringBuffer buf = new StringBuffer();
             if (codeMap != null) {
-                for (int iState : nrOfStates) {
-                    String sCode = codeMap.substring(iState * codeLength, iState * codeLength + codeLength);
-                    buf.append(sCode);
+                for (int state : nrOfStates) {
+                    String code = codeMap.substring(state * codeLength, state * codeLength + codeLength);
+                    buf.append(code);
                 }
             } else {
                 // produce a comma separated string of integers
@@ -238,8 +238,8 @@ public interface DataType {
 
 
         @Override
-        public int[] getStatesForCode(int iState) {
-            return mapCodeToStateSet[iState];
+        public int[] getStatesForCode(int state) {
+            return mapCodeToStateSet[state];
         }
 
         @Override
@@ -283,7 +283,7 @@ public interface DataType {
         }
         
         /** return state associated with a character */
-        public Integer char2state(String character) throws Exception {
+        public Integer char2state(String character) {
         	return string2state(character).get(0);
         }
     } // class Base
diff --git a/src/beast/evolution/datatype/StandardData.java b/src/beast/evolution/datatype/StandardData.java
index 3c653d8..e5d7c0d 100644
--- a/src/beast/evolution/datatype/StandardData.java
+++ b/src/beast/evolution/datatype/StandardData.java
@@ -2,21 +2,21 @@ package beast.evolution.datatype;
 
 
 
-import beast.core.Description;
-import beast.core.Input;
-
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import beast.core.Description;
+import beast.core.Input;
+
 @Description("Integer data type to describe discrete morphological characters with polymorphisms")
 public class StandardData extends DataType.Base {
 
-    public Input<Integer> maxNrOfStatesInput = new Input<Integer>("nrOfStates", "specifies the maximum number of " +
+    final public Input<Integer> maxNrOfStatesInput = new Input<>("nrOfStates", "specifies the maximum number of " +
             "character states in data matrix or in the filtered alignment");
-    public Input<String> listOfAmbiguitiesInput = new Input<String>("ambiguities", "all possible ambiguities presented " +
+    final public Input<String> listOfAmbiguitiesInput = new Input<>("ambiguities", "all possible ambiguities presented " +
             "as space separated sets of ordered elements. Elements are digits 0..9.");
-    public Input<List<UserDataType>> charStateLabelsInput = new Input<List<UserDataType>>("charstatelabels",
+    final public Input<List<UserDataType>> charStateLabelsInput = new Input<>("charstatelabels",
             "list of morphological character descriptions. Position in the list corresponds to the position of the" +
                     "character in the alignment", new ArrayList<>());
 
@@ -27,7 +27,7 @@ public class StandardData extends DataType.Base {
 
 
 	@Override
-	public void initAndValidate() throws Exception {
+	public void initAndValidate() {
         if (maxNrOfStatesInput.get() != null && maxNrOfStatesInput.get() != 0) {
             stateCount = maxNrOfStatesInput.get();
         } else {
@@ -46,7 +46,7 @@ public class StandardData extends DataType.Base {
         }
 
         ambCount = ambiguities.length;
-        codeMapping = new ArrayList<String>();
+        codeMapping = new ArrayList<>();
         for (int i=0; i<stateCount; i++) {
             codeMapping.add(Integer.toString(i));
         }
@@ -78,9 +78,9 @@ public class StandardData extends DataType.Base {
     }
     
     @Override
-    public int[] getStatesForCode(int iState) {
-    	if (iState >= 0) {
-    		return mapCodeToStateSet[iState];
+    public int[] getStatesForCode(int state) {
+    	if (state >= 0) {
+    		return mapCodeToStateSet[state];
     	} else {
     		return mapCodeToStateSet[mapCodeToStateSet.length - 1];
     	}
@@ -88,13 +88,13 @@ public class StandardData extends DataType.Base {
 
 
     @Override
-    public List<Integer> string2state(String data) throws Exception {
+    public List<Integer> string2state(String data) {
         List<Integer> sequence;
-        sequence = new ArrayList<Integer>();
+        sequence = new ArrayList<>();
         // remove spaces
         data = data.replaceAll("\\s", "");
 
-        ArrayList<Integer> amb = new ArrayList<Integer>();
+        ArrayList<Integer> amb = new ArrayList<>();
         boolean readingAmb=false;
         for (byte c : data.getBytes()) {
             if (!readingAmb) {
@@ -152,7 +152,7 @@ public class StandardData extends DataType.Base {
 //    @Description("A class to store the description of a character")
 //    public class CharStateLabels extends BEASTObject {
 //
-//        public Input<Integer> nrOfStatesInput = new Input<Integer>("states", "number of states fro this character");
+//        public Input<Integer> nrOfStatesInput = new Input<>("states", "number of states fro this character");
 //        public Input<String> characterNameInput = new Input<>("characterName", "the name of the charcter");
 //        public Input<List<String>> stateNamesInput = new Input<>("stateNames", "the list of the state names ordered " +
 //                "according to codes given, that is the first in the list is coded by 0, second, by 1 and so forth.", new ArrayList<>());
@@ -181,7 +181,7 @@ public class StandardData extends DataType.Base {
 //        public ArrayList<String> getStateNames() { return stateNames; }
 //
 //        @Override
-//        public void initAndValidate() throws Exception {
+//        public void initAndValidate() {
 //        }
 //
 //    }
diff --git a/src/beast/evolution/datatype/UserDataType.java b/src/beast/evolution/datatype/UserDataType.java
index 8fdd295..c3677d8 100644
--- a/src/beast/evolution/datatype/UserDataType.java
+++ b/src/beast/evolution/datatype/UserDataType.java
@@ -13,15 +13,15 @@ import beast.evolution.datatype.DataType.Base;
 
 @Description("User defined datatype. Allows custom symbols to map onto statesets.")
 public class UserDataType extends Base {
-    public Input<Integer> stateCountInput = new Input<Integer>("states", "total number of states", Validate.REQUIRED);
-    public Input<Integer> codeLengthInput = new Input<Integer>("codelength", "length of code, if negative a variable length code is assumed, default 1", 1);
-    public Input<String> codeMapInput = new Input<String>("codeMap", "mapping of codes to states. " +
+    final public Input<Integer> stateCountInput = new Input<>("states", "total number of states", Validate.REQUIRED);
+    final public Input<Integer> codeLengthInput = new Input<>("codelength", "length of code, if negative a variable length code is assumed, default 1", 1);
+    final public Input<String> codeMapInput = new Input<>("codeMap", "mapping of codes to states. " +
             "A comma separated string of codes with a subset of states. " +
             "A state set is a space separates list of zero based integers, up to the number of states, " +
             "e.g. A=0, C=1, R=0 2, ? = 0 1 2 3", Validate.REQUIRED);
     
-    public Input<String> characterNameInput = new Input<>("characterName", "the name of the character");
-    public Input<String> stateNamesInput = new Input<>("value", "the list of the state names ordered " +
+    final public Input<String> characterNameInput = new Input<>("characterName", "the name of the character");
+    final public Input<String> stateNamesInput = new Input<>("value", "the list of the state names ordered " +
     		"according to codes given, that is the first in the list is coded by 0, second, by 1 and so forth.");
 
     public UserDataType() {} // default c'tor
@@ -52,37 +52,37 @@ public class UserDataType extends Base {
     }
     
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         stateCount = stateCountInput.get();
         codeLength = codeLengthInput.get();
 
-        String sCodeMap = codeMapInput.get();
+        String codeMapString = codeMapInput.get();
         if (!codeMapInput.get().equals("")) {
-            String[] sStrs = sCodeMap.split(",");
+            String[] strs = codeMapString.split(",");
             codeMap = "";
-            mapCodeToStateSet = new int[sStrs.length][];
+            mapCodeToStateSet = new int[strs.length][];
             int k = 0;
-            for (String sStr : sStrs) {
-                String[] sStrs2 = sStr.split("=");
+            for (String str : strs) {
+                String[] strs2 = str.split("=");
                 // parse the code
-                String sCode = sStrs2[0].replaceAll("\\s", "");
+                String code = strs2[0].replaceAll("\\s", "");
 
-                codeMap += sCode;
+                codeMap += code;
                 if (codeLength > 0) {
-                    if (sCode.length() != codeLength) {
-                        throw new Exception("Invalide code '" + sCode + "'. Expected code of length " + codeLength);
+                    if (code.length() != codeLength) {
+                        throw new IllegalArgumentException("Invalide code '" + code + "'. Expected code of length " + codeLength);
                     }
                 } else {
                     codeMap += ",";
                 }
                 // parse the state set
-                List<Integer> stateSet = new ArrayList<Integer>();
-                sStrs2 = sStrs2[1].split("\\s+");
-                for (String sStr2 : sStrs2) {
-                    if (sStr2.length() > 0) {
-                        int i = Integer.parseInt(sStr2);
+                List<Integer> stateSet = new ArrayList<>();
+                strs2 = strs2[1].split("\\s+");
+                for (String str2 : strs2) {
+                    if (str2.length() > 0) {
+                        int i = Integer.parseInt(str2);
                         if (i < 0 || (stateCount > 0 && i >= stateCount)) {
-                            throw new Exception("state index should be from 0 to statecount, not " + i);
+                            throw new IllegalArgumentException("state index should be from 0 to statecount, not " + i);
                         }
                         stateSet.add(i);
                     }
diff --git a/src/beast/evolution/likelihood/BeagleTreeLikelihood.java b/src/beast/evolution/likelihood/BeagleTreeLikelihood.java
index 6250d8c..8fd9a67 100644
--- a/src/beast/evolution/likelihood/BeagleTreeLikelihood.java
+++ b/src/beast/evolution/likelihood/BeagleTreeLikelihood.java
@@ -25,8 +25,17 @@
 
 package beast.evolution.likelihood;
 
-import beagle.*;
+import java.util.ArrayList;
+import java.util.List;
+
+import beagle.Beagle;
+import beagle.BeagleFactory;
+import beagle.BeagleFlag;
+import beagle.BeagleInfo;
+import beagle.InstanceDetails;
+import beagle.ResourceDetails;
 import beast.core.Description;
+import beast.core.util.Log;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.branchratemodel.StrictClockModel;
 import beast.evolution.sitemodel.SiteModel;
@@ -34,8 +43,6 @@ import beast.evolution.substitutionmodel.EigenDecomposition;
 import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
 
-import java.util.*;
-
 
 /**
  * BeagleTreeLikelihoodModel - implements a Likelihood Function for sequences on a tree.
@@ -74,9 +81,11 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
     boolean m_bUseAmbiguities, m_bUseTipLikelihoods;
     int m_nStateCount;
     int m_nNodeCount;
+    
+    private int invariantCategory = -1;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         boolean forceJava = Boolean.valueOf(System.getProperty("java.only"));
         if (forceJava) {
         	return;
@@ -84,12 +93,12 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
         initialize();
     }
 
-    private boolean initialize() throws Exception {
+    private boolean initialize() {
         m_nNodeCount = treeInput.get().getNodeCount();
         m_bUseAmbiguities = m_useAmbiguities.get();
         m_bUseTipLikelihoods = m_useTipLikelihoods.get();
         if (!(siteModelInput.get() instanceof SiteModel.Base)) {
-        	throw new Exception ("siteModel input should be of type SiteModel.Base");
+        	throw new IllegalArgumentException("siteModel input should be of type SiteModel.Base");
         }
         m_siteModel = (SiteModel.Base) siteModelInput.get();
         m_siteModel.setDataType(dataInput.get().getDataType());
@@ -108,7 +117,31 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
 
         eigenCount = 1;//this.branchSubstitutionModel.getEigenCount();
 
-        this.categoryCount = m_siteModel.getCategoryCount();
+        double[] categoryRates = m_siteModel.getCategoryRates(null);
+        // check for invariant rates category
+        if (m_siteModel.hasPropInvariantCategory) {
+	        for (int i = 0; i < categoryRates.length; i++) {
+	        	if (categoryRates[i] == 0) {
+	        		proportionInvariant = m_siteModel.getRateForCategory(i, null);
+	                int stateCount = dataInput.get().getMaxStateCount();
+	                int patterns = dataInput.get().getPatternCount();
+	                calcConstantPatternIndices(patterns, stateCount);
+	                invariantCategory = i;
+	                
+	                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;
+	        		break;
+	        	}
+	        }
+        }        
+
+        this.categoryCount = m_siteModel.getCategoryCount() - (invariantCategory >= 0 ? 1 : 0);
         tipCount = treeInput.get().getLeafNodeCount();
 
         internalNodeCount = m_nNodeCount - tipCount;
@@ -259,20 +292,20 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
                     }
                 }
                 sb.append("    with instance flags: ").append(instanceDetails.toString());
-                System.out.println(sb.toString());
+                Log.info.println(sb.toString());
             } else {
-                System.err.println("  Error retrieving BEAGLE resource for instance: " + instanceDetails.toString());
+                Log.warning.println("  Error retrieving BEAGLE resource for instance: " + instanceDetails.toString());
                 beagle = null;
                 return false;
             }
         } else {
-            System.err.println("  No external BEAGLE resources available, or resource list/requirements not met, using Java implementation");
+        	Log.warning.println("  No external BEAGLE resources available, or resource list/requirements not met, using Java implementation");
             beagle = null;
             return false;
         }
-        System.err.println("  " + (m_bUseAmbiguities ? "Using" : "Ignoring") + " ambiguities in tree likelihood.");
-        System.err.println("  " + (m_bUseTipLikelihoods ? "Using" : "Ignoring") + " character uncertainty in tree likelihood.");
-        System.err.println("  With " + patternCount + " unique site patterns.");
+        Log.warning.println("  " + (m_bUseAmbiguities ? "Using" : "Ignoring") + " ambiguities in tree likelihood.");
+        Log.warning.println("  " + (m_bUseTipLikelihoods ? "Using" : "Ignoring") + " character uncertainty in tree likelihood.");
+        Log.warning.println("  With " + patternCount + " unique site patterns.");
 
         
         Node [] nodes = treeInput.get().getNodesAsArray();
@@ -289,20 +322,20 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
             ascertainedSitePatterns = true;
         }
 
-        double[] fPatternWeights = new double[patternCount];
+        double[] patternWeights = new double[patternCount];
         for (int i = 0; i < patternCount; i++) {
-            fPatternWeights[i] = dataInput.get().getPatternWeight(i);
+            patternWeights[i] = dataInput.get().getPatternWeight(i);
         }
-        beagle.setPatternWeights(fPatternWeights);
+        beagle.setPatternWeights(patternWeights);
 
         if (this.rescalingScheme == PartialsRescalingScheme.AUTO &&
                 resourceDetails != null &&
                 (resourceDetails.getFlags() & BeagleFlag.SCALING_AUTO.getMask()) == 0) {
             // If auto scaling in BEAGLE is not supported then do it here
             this.rescalingScheme = PartialsRescalingScheme.DYNAMIC;
-            System.err.println("  Auto rescaling not supported in BEAGLE, using : " + this.rescalingScheme.getText());
+            Log.warning.println("  Auto rescaling not supported in BEAGLE, using : " + this.rescalingScheme.getText());
         } else {
-            System.err.println("  Using rescaling scheme : " + this.rescalingScheme.getText());
+        	Log.warning.println("  Using rescaling scheme : " + this.rescalingScheme.getText());
         }
 
         if (this.rescalingScheme == PartialsRescalingScheme.DYNAMIC) {
@@ -314,24 +347,15 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
         // some subst models (e.g. WAG) never become dirty, so set up subst models right now
         setUpSubstModel();
         // set up sitemodel
-        double[] categoryRates = m_siteModel.getCategoryRates(null);
+        
         beagle.setCategoryRates(categoryRates);
 
-
-//            m_fProportionInvariant = m_siteModel.getProportianInvariant();
-//            double [] fProportionInvariantCorrection = new double[m_nPatternCount * m_nStateCount];
-//            if (!SiteModel.g_bUseOriginal && m_fProportionInvariant > 0) {
-//            	calcConstantPatternIndices(m_nPatternCount, m_nStateCount);
-//            	for (int i : m_iConstantPattern) {
-//            		fProportionInvariantCorrection[i] = m_fProportionInvariant;
-//            	}
-//            }
-//            beagle.setProportionInvariantCorrection(fProportionInvariantCorrection);
         return true;
     }
 
+    
     private static List<Integer> parseSystemPropertyIntegerArray(String propertyName) {
-        List<Integer> order = new ArrayList<Integer>();
+        List<Integer> order = new ArrayList<>();
         String r = System.getProperty(propertyName);
         if (r != null) {
             String[] parts = r.split(",");
@@ -340,7 +364,7 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
                     int n = Integer.parseInt(part.trim());
                     order.add(n);
                 } catch (NumberFormatException nfe) {
-                    System.err.println("Invalid entry '" + part + "' in " + propertyName);
+                	Log.warning.println("Invalid entry '" + part + "' in " + propertyName);
                 }
             }
         }
@@ -349,7 +373,7 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
 
     private static List<String> parseSystemPropertyStringArray(String propertyName) {
 
-        List<String> order = new ArrayList<String>();
+        List<String> order = new ArrayList<>();
 
         String r = System.getProperty(propertyName);
         if (r != null) {
@@ -359,7 +383,7 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
                     String s = part.trim();
                     order.add(s);
                 } catch (NumberFormatException nfe) {
-                    System.err.println("Invalid getEigenDecompositionentry '" + part + "' in " + propertyName);
+                	Log.warning.println("Invalid getEigenDecompositionentry '" + part + "' in " + propertyName);
                 }
             }
         }
@@ -389,15 +413,15 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
 
         	double[] tipProbabilities = data.getTipLikelihoods(taxon,i);
             if (tipProbabilities != null) {
-            	for (int iState = 0; iState < m_nStateCount; iState++) {
-            		partials[v++] = tipProbabilities[iState];
+            	for (int state = 0; state < m_nStateCount; state++) {
+            		partials[v++] = tipProbabilities[state];
             	}
             }
             else {
-            	int nState = data.getPattern(taxon, i);
-                boolean[] stateSet = data.getStateSet(nState);
-                for (int iState = 0; iState < m_nStateCount; iState++) {
-                	 partials[v++] = (stateSet[iState] ? 1.0 : 0.0);                
+            	int stateCount = data.getPattern(taxon, i);
+                boolean[] stateSet = data.getStateSet(stateCount);
+                for (int state = 0; state < m_nStateCount; state++) {
+                	 partials[v++] = (stateSet[state] ? 1.0 : 0.0);                
                 }
             }
         }
@@ -546,7 +570,7 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
      * @return the log likelihood.
      */
     @Override
-    public double calculateLogP() throws Exception {
+    public double calculateLogP() {
 
         if (patternLogLikelihoods == null) {
             patternLogLikelihoods = new double[patternCount];
@@ -607,6 +631,16 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
 
         if (updateSiteModel) {
             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;
+	        }
             beagle.setCategoryRates(categoryRates);
         }
 
@@ -643,6 +677,16 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
             int rootIndex = partialBufferHelper.getOffsetIndex(root.getNr());
 
             double[] categoryWeights = m_siteModel.getCategoryProportions(null);
+            if (constantPattern != null) {
+	            double [] tmp = new double [categoryWeights.length - 1];
+	            for (int k = 0; k < invariantCategory; k++) {
+	            	tmp[k] = categoryWeights[k];
+	            }
+	            for (int k = invariantCategory + 1; k < categoryWeights.length; k++) {
+	            	tmp[k-1] = categoryWeights[k];
+	            }
+	            categoryWeights = tmp;
+            }
             double[] frequencies = substitutionModel.getFrequencies();
 
             int cumulateScaleBufferIndex = Beagle.NONE;
@@ -675,7 +719,16 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
                 // Need to correct for ascertainedSitePatterns
                 beagle.getSiteLogLikelihoods(patternLogLikelihoods);
                 logL = getAscertainmentCorrectedLogLikelihood(dataInput.get(),
-                        patternLogLikelihoods, dataInput.get().getWeights());
+                        patternLogLikelihoods, dataInput.get().getWeights(), frequencies);
+            } else if (invariantCategory >= 0) {
+                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]);
+                }
             }
 
             if (Double.isNaN(logL) || Double.isInfinite(logL)) {
@@ -741,7 +794,17 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
 
     private double getAscertainmentCorrectedLogLikelihood(Alignment patternList,
                                                           double[] patternLogLikelihoods,
-                                                          int[] patternWeights) {
+                                                          int[] patternWeights,
+                                                          double [] frequencies) {
+    	if (constantPattern != null) {
+	        proportionInvariant = m_siteModel.getProportionInvariant();
+	        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]));
+	        }
+    	}
+    	
         double logL = 0.0;
         double ascertainmentCorrection = patternList.getAscertainmentCorrection(patternLogLikelihoods);
         for (int i = 0; i < patternCount; i++) {
@@ -762,7 +825,7 @@ public class BeagleTreeLikelihood extends TreeLikelihood {
 
         int nodeNum = node.getNr();
 
-        Node parent = node.getParent();
+        //Node parent = node.getParent();
 
         if (operatorNumber != null) {
             operatorNumber[0] = -1;
diff --git a/src/beast/evolution/likelihood/BeerLikelihoodCore.java b/src/beast/evolution/likelihood/BeerLikelihoodCore.java
index a277c6c..19f3339 100644
--- a/src/beast/evolution/likelihood/BeerLikelihoodCore.java
+++ b/src/beast/evolution/likelihood/BeerLikelihoodCore.java
@@ -40,17 +40,17 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Calculates partial likelihoods at a node when both children have states.
      */
-    protected void calculateStatesStatesPruning(int[] iStates1, double[] fMatrices1,
-                                                int[] iStates2, double[] fMatrices2,
-                                                double[] fPartials3) {
+    protected void calculateStatesStatesPruning(int[] stateIndex1, double[] matrices1,
+                                                int[] stateIndex2, double[] matrices2,
+                                                double[] partials3) {
         int v = 0;
 
         for (int l = 0; l < nrOfMatrices; l++) {
 
             for (int k = 0; k < nrOfPatterns; k++) {
 
-                int state1 = iStates1[k];
-                int state2 = iStates2[k];
+                int state1 = stateIndex1[k];
+                int state2 = stateIndex2[k];
 
                 int w = l * matrixSize;
 
@@ -58,7 +58,7 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
                     for (int i = 0; i < nrOfStates; i++) {
 
-                        fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+                        partials3[v] = matrices1[w + state1] * matrices2[w + state2];
 
                         v++;
                         w += nrOfStates;
@@ -69,7 +69,7 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
                     for (int i = 0; i < nrOfStates; i++) {
 
-                        fPartials3[v] = fMatrices1[w + state1];
+                        partials3[v] = matrices1[w + state1];
 
                         v++;
                         w += nrOfStates;
@@ -79,7 +79,7 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
                     for (int i = 0; i < nrOfStates; i++) {
 
-                        fPartials3[v] = fMatrices2[w + state2];
+                        partials3[v] = matrices2[w + state2];
 
                         v++;
                         w += nrOfStates;
@@ -88,7 +88,7 @@ public class BeerLikelihoodCore extends LikelihoodCore {
                     // both children have a gap or unknown state so set partials to 1
 
                     for (int j = 0; j < nrOfStates; j++) {
-                        fPartials3[v] = 1.0;
+                        partials3[v] = 1.0;
                         v++;
                     }
                 }
@@ -99,9 +99,9 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Calculates partial likelihoods at a node when one child has states and one has partials.
      */
-    protected void calculateStatesPartialsPruning(int[] iStates1, double[] fMatrices1,
-                                                  double[] fPartials2, double[] fMatrices2,
-                                                  double[] fPartials3) {
+    protected void calculateStatesPartialsPruning(int[] stateIndex1, double[] matrices1,
+                                                  double[] partials2, double[] matrices2,
+                                                  double[] partials3) {
 
         double sum, tmp;
 
@@ -111,7 +111,7 @@ public class BeerLikelihoodCore extends LikelihoodCore {
         for (int l = 0; l < nrOfMatrices; l++) {
             for (int k = 0; k < nrOfPatterns; k++) {
 
-                int state1 = iStates1[k];
+                int state1 = stateIndex1[k];
 
                 int w = l * matrixSize;
 
@@ -120,15 +120,15 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
                     for (int i = 0; i < nrOfStates; i++) {
 
-                        tmp = fMatrices1[w + state1];
+                        tmp = matrices1[w + state1];
 
                         sum = 0.0;
                         for (int j = 0; j < nrOfStates; j++) {
-                            sum += fMatrices2[w] * fPartials2[v + j];
+                            sum += matrices2[w] * partials2[v + j];
                             w++;
                         }
 
-                        fPartials3[u] = tmp * sum;
+                        partials3[u] = tmp * sum;
                         u++;
                     }
 
@@ -140,11 +140,11 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
                         sum = 0.0;
                         for (int j = 0; j < nrOfStates; j++) {
-                            sum += fMatrices2[w] * fPartials2[v + j];
+                            sum += matrices2[w] * partials2[v + j];
                             w++;
                         }
 
-                        fPartials3[u] = sum;
+                        partials3[u] = sum;
                         u++;
                     }
 
@@ -157,9 +157,9 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Calculates partial likelihoods at a node when both children have partials.
      */
-    protected void calculatePartialsPartialsPruning(double[] fPartials1, double[] fMatrices1,
-                                                    double[] fPartials2, double[] fMatrices2,
-                                                    double[] fPartials3) {
+    protected void calculatePartialsPartialsPruning(double[] partials1, double[] matrices1,
+                                                    double[] partials2, double[] matrices2,
+                                                    double[] partials3) {
         double sum1, sum2;
 
         int u = 0;
@@ -176,13 +176,13 @@ public class BeerLikelihoodCore extends LikelihoodCore {
                     sum1 = sum2 = 0.0;
 
                     for (int j = 0; j < nrOfStates; j++) {
-                        sum1 += fMatrices1[w] * fPartials1[v + j];
-                        sum2 += fMatrices2[w] * fPartials2[v + j];
+                        sum1 += matrices1[w] * partials1[v + j];
+                        sum2 += matrices2[w] * partials2[v + j];
 
                         w++;
                     }
 
-                    fPartials3[u] = sum1 * sum2;
+                    partials3[u] = sum1 * sum2;
                     u++;
                 }
                 v += nrOfStates;
@@ -193,23 +193,23 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Calculates partial likelihoods at a node when both children have states.
      */
-    protected void calculateStatesStatesPruning(int[] iStates1, double[] fMatrices1,
-                                                int[] iStates2, double[] fMatrices2,
-                                                double[] fPartials3, int[] iMatrixMap) {
+    protected void calculateStatesStatesPruning(int[] stateIndex1, double[] matrices1,
+                                                int[] stateIndex2, double[] matrices2,
+                                                double[] partials3, int[] matrixMap) {
         int v = 0;
 
         for (int k = 0; k < nrOfPatterns; k++) {
 
-            int state1 = iStates1[k];
-            int state2 = iStates2[k];
+            int state1 = stateIndex1[k];
+            int state2 = stateIndex2[k];
 
-            int w = iMatrixMap[k] * matrixSize;
+            int w = matrixMap[k] * matrixSize;
 
             if (state1 < nrOfStates && state2 < nrOfStates) {
 
                 for (int i = 0; i < nrOfStates; i++) {
 
-                    fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+                    partials3[v] = matrices1[w + state1] * matrices2[w + state2];
 
                     v++;
                     w += nrOfStates;
@@ -220,7 +220,7 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
                 for (int i = 0; i < nrOfStates; i++) {
 
-                    fPartials3[v] = fMatrices1[w + state1];
+                    partials3[v] = matrices1[w + state1];
 
                     v++;
                     w += nrOfStates;
@@ -230,7 +230,7 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
                 for (int i = 0; i < nrOfStates; i++) {
 
-                    fPartials3[v] = fMatrices2[w + state2];
+                    partials3[v] = matrices2[w + state2];
 
                     v++;
                     w += nrOfStates;
@@ -239,7 +239,7 @@ public class BeerLikelihoodCore extends LikelihoodCore {
                 // both children have a gap or unknown state so set partials to 1
 
                 for (int j = 0; j < nrOfStates; j++) {
-                    fPartials3[v] = 1.0;
+                    partials3[v] = 1.0;
                     v++;
                 }
             }
@@ -249,9 +249,9 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Calculates partial likelihoods at a node when one child has states and one has partials.
      */
-    protected void calculateStatesPartialsPruning(int[] iStates1, double[] fMatrices1,
-                                                  double[] fPartials2, double[] fMatrices2,
-                                                  double[] fPartials3, int[] iMatrixMap) {
+    protected void calculateStatesPartialsPruning(int[] stateIndex1, double[] matrices1,
+                                                  double[] partials2, double[] matrices2,
+                                                  double[] partials3, int[] matrixMap) {
 
         double sum, tmp;
 
@@ -260,23 +260,23 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
         for (int k = 0; k < nrOfPatterns; k++) {
 
-            int state1 = iStates1[k];
+            int state1 = stateIndex1[k];
 
-            int w = iMatrixMap[k] * matrixSize;
+            int w = matrixMap[k] * matrixSize;
 
             if (state1 < nrOfStates) {
 
                 for (int i = 0; i < nrOfStates; i++) {
 
-                    tmp = fMatrices1[w + state1];
+                    tmp = matrices1[w + state1];
 
                     sum = 0.0;
                     for (int j = 0; j < nrOfStates; j++) {
-                        sum += fMatrices2[w] * fPartials2[v + j];
+                        sum += matrices2[w] * partials2[v + j];
                         w++;
                     }
 
-                    fPartials3[u] = tmp * sum;
+                    partials3[u] = tmp * sum;
                     u++;
                 }
 
@@ -288,11 +288,11 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
                     sum = 0.0;
                     for (int j = 0; j < nrOfStates; j++) {
-                        sum += fMatrices2[w] * fPartials2[v + j];
+                        sum += matrices2[w] * partials2[v + j];
                         w++;
                     }
 
-                    fPartials3[u] = sum;
+                    partials3[u] = sum;
                     u++;
                 }
 
@@ -304,9 +304,9 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Calculates partial likelihoods at a node when both children have partials.
      */
-    protected void calculatePartialsPartialsPruning(double[] fPartials1, double[] fMatrices1,
-                                                    double[] fPartials2, double[] fMatrices2,
-                                                    double[] fPartials3, int[] iMatrixMap) {
+    protected void calculatePartialsPartialsPruning(double[] partials1, double[] matrices1,
+                                                    double[] partials2, double[] matrices2,
+                                                    double[] partials3, int[] matrixMap) {
         double sum1, sum2;
 
         int u = 0;
@@ -314,20 +314,20 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
         for (int k = 0; k < nrOfPatterns; k++) {
 
-            int w = iMatrixMap[k] * matrixSize;
+            int w = matrixMap[k] * matrixSize;
 
             for (int i = 0; i < nrOfStates; i++) {
 
                 sum1 = sum2 = 0.0;
 
                 for (int j = 0; j < nrOfStates; j++) {
-                    sum1 += fMatrices1[w] * fPartials1[v + j];
-                    sum2 += fMatrices2[w] * fPartials2[v + j];
+                    sum1 += matrices1[w] * partials1[v + j];
+                    sum2 += matrices2[w] * partials2[v + j];
 
                     w++;
                 }
 
-                fPartials3[u] = sum1 * sum2;
+                partials3[u] = sum1 * sum2;
                 u++;
             }
             v += nrOfStates;
@@ -337,11 +337,12 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Integrates partials across categories.
      *
-     * @param fInPartials  the array of partials to be integrated
-     * @param fProportions the proportions of sites in each category
-     * @param fOutPartials an array into which the partials will go
+     * @param inPartials  the array of partials to be integrated
+     * @param proportions the proportions of sites in each category
+     * @param outPartials an array into which the partials will go
      */
-    protected void calculateIntegratePartials(double[] fInPartials, double[] fProportions, double[] fOutPartials) {
+    @Override
+	protected void calculateIntegratePartials(double[] inPartials, double[] proportions, double[] outPartials) {
 
         int u = 0;
         int v = 0;
@@ -349,7 +350,7 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
             for (int i = 0; i < nrOfStates; i++) {
 
-                fOutPartials[u] = fInPartials[v] * fProportions[0];
+                outPartials[u] = inPartials[v] * proportions[0];
                 u++;
                 v++;
             }
@@ -363,7 +364,7 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
                 for (int i = 0; i < nrOfStates; i++) {
 
-                    fOutPartials[u] += fInPartials[v] * fProportions[l];
+                    outPartials[u] += inPartials[v] * proportions[l];
                     u++;
                     v++;
                 }
@@ -374,21 +375,22 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Calculates pattern log likelihoods at a node.
      *
-     * @param fPartials          the partials used to calculate the likelihoods
-     * @param fFrequencies       an array of state frequencies
-     * @param fOutLogLikelihoods an array into which the likelihoods will go
+     * @param partials          the partials used to calculate the likelihoods
+     * @param frequencies       an array of state frequencies
+     * @param outLogLikelihoods an array into which the likelihoods will go
      */
-    public void calculateLogLikelihoods(double[] fPartials, double[] fFrequencies, double[] fOutLogLikelihoods) {
+    @Override
+	public void calculateLogLikelihoods(double[] partials, double[] frequencies, double[] outLogLikelihoods) {
         int v = 0;
         for (int k = 0; k < nrOfPatterns; k++) {
 
             double sum = 0.0;
             for (int i = 0; i < nrOfStates; i++) {
 
-                sum += fFrequencies[i] * fPartials[v];
+                sum += frequencies[i] * partials[v];
                 v++;
             }
-            fOutLogLikelihoods[k] = Math.log(sum) + getLogScalingFactor(k);
+            outLogLikelihoods[k] = Math.log(sum) + getLogScalingFactor(k);
         }
     }
 
@@ -396,36 +398,37 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * initializes partial likelihood arrays.
      *
-     * @param nNodeCount           the number of nodes in the tree
-     * @param nPatternCount        the number of patterns
-     * @param nMatrixCount         the number of matrices (i.e., number of categories)
-     * @param bIntegrateCategories whether sites are being integrated over all matrices
+     * @param nodeCount           the number of nodes in the tree
+     * @param patternCount        the number of patterns
+     * @param matrixCount         the number of matrices (i.e., number of categories)
+     * @param integrateCategories whether sites are being integrated over all matrices
      */
-    public void initialize(int nNodeCount, int nPatternCount, int nMatrixCount, boolean bIntegrateCategories, boolean bUseAmbiguities) {
+    @Override
+	public void initialize(int nodeCount, int patternCount, int matrixCount, boolean integrateCategories, boolean useAmbiguities) {
 
-        this.nrOfNodes = nNodeCount;
-        this.nrOfPatterns = nPatternCount;
-        this.nrOfMatrices = nMatrixCount;
+        this.nrOfNodes = nodeCount;
+        this.nrOfPatterns = patternCount;
+        this.nrOfMatrices = matrixCount;
 
-        this.integrateCategories = bIntegrateCategories;
+        this.integrateCategories = integrateCategories;
 
-        if (bIntegrateCategories) {
-            partialsSize = nPatternCount * nrOfStates * nMatrixCount;
+        if (integrateCategories) {
+            partialsSize = patternCount * nrOfStates * matrixCount;
         } else {
-            partialsSize = nPatternCount * nrOfStates;
+            partialsSize = patternCount * nrOfStates;
         }
 
-        partials = new double[2][nNodeCount][];
+        partials = new double[2][nodeCount][];
 
-        currentMatrixIndex = new int[nNodeCount];
-        storedMatrixIndex = new int[nNodeCount];
+        currentMatrixIndex = new int[nodeCount];
+        storedMatrixIndex = new int[nodeCount];
 
-        currentPartialsIndex = new int[nNodeCount];
-        storedPartialsIndex = new int[nNodeCount];
+        currentPartialsIndex = new int[nodeCount];
+        storedPartialsIndex = new int[nodeCount];
 
-        states = new int[nNodeCount][];
+        states = new int[nodeCount][];
 
-        for (int i = 0; i < nNodeCount; i++) {
+        for (int i = 0; i < nodeCount; i++) {
             partials[0][i] = null;
             partials[1][i] = null;
 
@@ -434,13 +437,14 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
         matrixSize = nrOfStates * nrOfStates;
 
-        matrices = new double[2][nNodeCount][nMatrixCount * matrixSize];
+        matrices = new double[2][nodeCount][matrixCount * matrixSize];
     }
 
     /**
      * cleans up and deallocates arrays.
      */
-    public void finalize() throws java.lang.Throwable {
+    @Override
+	public void finalize() throws java.lang.Throwable {
         nrOfNodes = 0;
         nrOfPatterns = 0;
         nrOfMatrices = 0;
@@ -457,8 +461,8 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     }
 
     @Override
-    public void setUseScaling(double fScale) {
-        useScaling = (fScale != 1.0);
+    public void setUseScaling(double scale) {
+        useScaling = (scale != 1.0);
 
         if (useScaling) {
             scalingFactors = new double[2][nrOfNodes][nrOfPatterns];
@@ -468,65 +472,69 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Allocates partials for a node
      */
-    public void createNodePartials(int iNodeIndex) {
+    @Override
+	public void createNodePartials(int nodeIndex) {
 
-        this.partials[0][iNodeIndex] = new double[partialsSize];
-        this.partials[1][iNodeIndex] = new double[partialsSize];
+        this.partials[0][nodeIndex] = new double[partialsSize];
+        this.partials[1][nodeIndex] = new double[partialsSize];
     }
 
     /**
      * Sets partials for a node
      */
-    public void setNodePartials(int iNodeIndex, double[] fPartials) {
+    @Override
+	public void setNodePartials(int nodeIndex, double[] partials) {
 
-        if (this.partials[0][iNodeIndex] == null) {
-            createNodePartials(iNodeIndex);
+        if (this.partials[0][nodeIndex] == null) {
+            createNodePartials(nodeIndex);
         }
-        if (fPartials.length < partialsSize) {
+        if (partials.length < partialsSize) {
             int k = 0;
             for (int i = 0; i < nrOfMatrices; i++) {
-                System.arraycopy(fPartials, 0, this.partials[0][iNodeIndex], k, fPartials.length);
-                k += fPartials.length;
+                System.arraycopy(partials, 0, this.partials[0][nodeIndex], k, partials.length);
+                k += partials.length;
             }
         } else {
-            System.arraycopy(fPartials, 0, this.partials[0][iNodeIndex], 0, fPartials.length);
+            System.arraycopy(partials, 0, this.partials[0][nodeIndex], 0, partials.length);
         }
     }
 
     @Override
-    public void getNodePartials(int iNodeIndex, double[] fPartials) {
-        System.arraycopy(partials[currentPartialsIndex[iNodeIndex]][iNodeIndex], 0, fPartials, 0, fPartials.length);
+    public void getNodePartials(int nodeIndex, double[] partialsOut) {
+        System.arraycopy(partials[currentPartialsIndex[nodeIndex]][nodeIndex], 0, partialsOut, 0, partialsOut.length);
     }
 
     /**
      * Allocates states for a node
      */
-    public void createNodeStates(int iNodeIndex) {
+    public void createNodeStates(int nodeIndex) {
 
-        this.states[iNodeIndex] = new int[nrOfPatterns];
+        this.states[nodeIndex] = new int[nrOfPatterns];
     }
 
     /**
      * Sets states for a node
      */
-    public void setNodeStates(int iNodeIndex, int[] iStates) {
+    @Override
+	public void setNodeStates(int nodeIndex, int[] states) {
 
-        if (this.states[iNodeIndex] == null) {
-            createNodeStates(iNodeIndex);
+        if (this.states[nodeIndex] == null) {
+            createNodeStates(nodeIndex);
         }
-        System.arraycopy(iStates, 0, this.states[iNodeIndex], 0, nrOfPatterns);
+        System.arraycopy(states, 0, this.states[nodeIndex], 0, nrOfPatterns);
     }
 
     /**
      * Gets states for a node
      */
-    public void getNodeStates(int iNodeIndex, int[] iStates) {
-        System.arraycopy(this.states[iNodeIndex], 0, iStates, 0, nrOfPatterns);
+    @Override
+	public void getNodeStates(int nodeIndex, int[] states) {
+        System.arraycopy(this.states[nodeIndex], 0, states, 0, nrOfPatterns);
     }
 
     @Override
-    public void setNodeMatrixForUpdate(int iNodeIndex) {
-        currentMatrixIndex[iNodeIndex] = 1 - currentMatrixIndex[iNodeIndex];
+    public void setNodeMatrixForUpdate(int nodeIndex) {
+        currentMatrixIndex[nodeIndex] = 1 - currentMatrixIndex[nodeIndex];
 
     }
 
@@ -534,13 +542,14 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Sets probability matrix for a node
      */
-    public void setNodeMatrix(int iNodeIndex, int iMatrixIndex, double[] fMatrix) {
-        System.arraycopy(fMatrix, 0, matrices[currentMatrixIndex[iNodeIndex]][iNodeIndex],
-                iMatrixIndex * matrixSize, matrixSize);
+    @Override
+	public void setNodeMatrix(int nodeIndex, int matrixIndex, double[] matrix) {
+        System.arraycopy(matrix, 0, matrices[currentMatrixIndex[nodeIndex]][nodeIndex],
+                matrixIndex * matrixSize, matrixSize);
     }
 
-    public void setPaddedNodeMatrices(int iNode, double[] fMatrix) {
-        System.arraycopy(fMatrix, 0, matrices[currentMatrixIndex[iNode]][iNode],
+    public void setPaddedNodeMatrices(int nodeIndex, double[] matrix) {
+        System.arraycopy(matrix, 0, matrices[currentMatrixIndex[nodeIndex]][nodeIndex],
                 0, nrOfMatrices * matrixSize);
     }
 
@@ -548,65 +557,67 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Gets probability matrix for a node
      */
-    public void getNodeMatrix(int iNodeIndex, int iMatrixIndex, double[] fMatrix) {
-        System.arraycopy(matrices[currentMatrixIndex[iNodeIndex]][iNodeIndex],
-                iMatrixIndex * matrixSize, fMatrix, 0, matrixSize);
+    @Override
+	public void getNodeMatrix(int nodeIndex, int matrixIndex, double[] matrix) {
+        System.arraycopy(matrices[currentMatrixIndex[nodeIndex]][nodeIndex],
+                matrixIndex * matrixSize, matrix, 0, matrixSize);
     }
 
     @Override
-    public void setNodePartialsForUpdate(int iNodeIndex) {
-        currentPartialsIndex[iNodeIndex] = 1 - currentPartialsIndex[iNodeIndex];
+    public void setNodePartialsForUpdate(int nodeIndex) {
+        currentPartialsIndex[nodeIndex] = 1 - currentPartialsIndex[nodeIndex];
     }
 
     /**
      * Sets the currently updating node partials for node nodeIndex. This may
      * need to repeatedly copy the partials for the different category partitions
      */
-    public void setCurrentNodePartials(int iNodeIndex, double[] fPartials) {
-        if (fPartials.length < partialsSize) {
+    public void setCurrentNodePartials(int nodeIndex, double[] partials) {
+        if (partials.length < partialsSize) {
             int k = 0;
             for (int i = 0; i < nrOfMatrices; i++) {
-                System.arraycopy(fPartials, 0, this.partials[currentPartialsIndex[iNodeIndex]][iNodeIndex], k, fPartials.length);
-                k += fPartials.length;
+                System.arraycopy(partials, 0, this.partials[currentPartialsIndex[nodeIndex]][nodeIndex], k, partials.length);
+                k += partials.length;
             }
         } else {
-            System.arraycopy(fPartials, 0, this.partials[currentPartialsIndex[iNodeIndex]][iNodeIndex], 0, fPartials.length);
+            System.arraycopy(partials, 0, this.partials[currentPartialsIndex[nodeIndex]][nodeIndex], 0, partials.length);
         }
     }
 
     /**
      * Calculates partial likelihoods at a node.
      *
-     * @param iNodeIndex1 the 'child 1' node
-     * @param iNodeIndex2 the 'child 2' node
-     * @param iNodeIndex3 the 'parent' node
+     * @param nodeIndex1 the 'child 1' node
+     * @param nodeIndex2 the 'child 2' node
+     * @param nodeIndex3 the 'parent' node
      */
-    public void calculatePartials(int iNodeIndex1, int iNodeIndex2, int iNodeIndex3) {
-        if (states[iNodeIndex1] != null) {
-            if (states[iNodeIndex2] != null) {
+    @Override
+	public void calculatePartials(int nodeIndex1, int nodeIndex2, int nodeIndex3) {
+        if (states[nodeIndex1] != null) {
+            if (states[nodeIndex2] != null) {
                 calculateStatesStatesPruning(
-                        states[iNodeIndex1], matrices[currentMatrixIndex[iNodeIndex1]][iNodeIndex1],
-                        states[iNodeIndex2], matrices[currentMatrixIndex[iNodeIndex2]][iNodeIndex2],
-                        partials[currentPartialsIndex[iNodeIndex3]][iNodeIndex3]);
+                        states[nodeIndex1], matrices[currentMatrixIndex[nodeIndex1]][nodeIndex1],
+                        states[nodeIndex2], matrices[currentMatrixIndex[nodeIndex2]][nodeIndex2],
+                        partials[currentPartialsIndex[nodeIndex3]][nodeIndex3]);
             } else {
-                calculateStatesPartialsPruning(states[iNodeIndex1], matrices[currentMatrixIndex[iNodeIndex1]][iNodeIndex1],
-                        partials[currentPartialsIndex[iNodeIndex2]][iNodeIndex2], matrices[currentMatrixIndex[iNodeIndex2]][iNodeIndex2],
-                        partials[currentPartialsIndex[iNodeIndex3]][iNodeIndex3]);
+                calculateStatesPartialsPruning(states[nodeIndex1], matrices[currentMatrixIndex[nodeIndex1]][nodeIndex1],
+                        partials[currentPartialsIndex[nodeIndex2]][nodeIndex2], matrices[currentMatrixIndex[nodeIndex2]][nodeIndex2],
+                        partials[currentPartialsIndex[nodeIndex3]][nodeIndex3]);
             }
         } else {
-            if (states[iNodeIndex2] != null) {
-                calculateStatesPartialsPruning(states[iNodeIndex2], matrices[currentMatrixIndex[iNodeIndex2]][iNodeIndex2],
-                        partials[currentPartialsIndex[iNodeIndex1]][iNodeIndex1], matrices[currentMatrixIndex[iNodeIndex1]][iNodeIndex1],
-                        partials[currentPartialsIndex[iNodeIndex3]][iNodeIndex3]);
+            if (states[nodeIndex2] != null) {
+                calculateStatesPartialsPruning(states[nodeIndex2], matrices[currentMatrixIndex[nodeIndex2]][nodeIndex2],
+                        partials[currentPartialsIndex[nodeIndex1]][nodeIndex1], matrices[currentMatrixIndex[nodeIndex1]][nodeIndex1],
+                        partials[currentPartialsIndex[nodeIndex3]][nodeIndex3]);
             } else {
-                calculatePartialsPartialsPruning(partials[currentPartialsIndex[iNodeIndex1]][iNodeIndex1], matrices[currentMatrixIndex[iNodeIndex1]][iNodeIndex1],
-                        partials[currentPartialsIndex[iNodeIndex2]][iNodeIndex2], matrices[currentMatrixIndex[iNodeIndex2]][iNodeIndex2],
-                        partials[currentPartialsIndex[iNodeIndex3]][iNodeIndex3]);
+                calculatePartialsPartialsPruning(partials[currentPartialsIndex[nodeIndex1]][nodeIndex1], matrices[currentMatrixIndex[nodeIndex1]][nodeIndex1],
+                        partials[currentPartialsIndex[nodeIndex2]][nodeIndex2], matrices[currentMatrixIndex[nodeIndex2]][nodeIndex2],
+                        partials[currentPartialsIndex[nodeIndex3]][nodeIndex3]);
             }
         }
 
         if (useScaling) {
-            scalePartials(iNodeIndex3);
+            scalePartials(nodeIndex3);
         }
 
 //
@@ -627,46 +638,47 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Calculates partial likelihoods at a node.
      *
-     * @param iNodeIndex1 the 'child 1' node
-     * @param iNodeIndex2 the 'child 2' node
-     * @param iNodeIndex3 the 'parent' node
-     * @param iMatrixMap  a map of which matrix to use for each pattern (can be null if integrating over categories)
+     * @param nodeIndex1 the 'child 1' node
+     * @param nodeIndex2 the 'child 2' node
+     * @param nodeIndex3 the 'parent' node
+     * @param matrixMap  a map of which matrix to use for each pattern (can be null if integrating over categories)
      */
-    public void calculatePartials(int iNodeIndex1, int iNodeIndex2, int iNodeIndex3, int[] iMatrixMap) {
-        if (states[iNodeIndex1] != null) {
-            if (states[iNodeIndex2] != null) {
+    public void calculatePartials(int nodeIndex1, int nodeIndex2, int nodeIndex3, int[] matrixMap) {
+        if (states[nodeIndex1] != null) {
+            if (states[nodeIndex2] != null) {
                 calculateStatesStatesPruning(
-                        states[iNodeIndex1], matrices[currentMatrixIndex[iNodeIndex1]][iNodeIndex1],
-                        states[iNodeIndex2], matrices[currentMatrixIndex[iNodeIndex2]][iNodeIndex2],
-                        partials[currentPartialsIndex[iNodeIndex3]][iNodeIndex3], iMatrixMap);
+                        states[nodeIndex1], matrices[currentMatrixIndex[nodeIndex1]][nodeIndex1],
+                        states[nodeIndex2], matrices[currentMatrixIndex[nodeIndex2]][nodeIndex2],
+                        partials[currentPartialsIndex[nodeIndex3]][nodeIndex3], matrixMap);
             } else {
                 calculateStatesPartialsPruning(
-                        states[iNodeIndex1], matrices[currentMatrixIndex[iNodeIndex1]][iNodeIndex1],
-                        partials[currentPartialsIndex[iNodeIndex2]][iNodeIndex2], matrices[currentMatrixIndex[iNodeIndex2]][iNodeIndex2],
-                        partials[currentPartialsIndex[iNodeIndex3]][iNodeIndex3], iMatrixMap);
+                        states[nodeIndex1], matrices[currentMatrixIndex[nodeIndex1]][nodeIndex1],
+                        partials[currentPartialsIndex[nodeIndex2]][nodeIndex2], matrices[currentMatrixIndex[nodeIndex2]][nodeIndex2],
+                        partials[currentPartialsIndex[nodeIndex3]][nodeIndex3], matrixMap);
             }
         } else {
-            if (states[iNodeIndex2] != null) {
+            if (states[nodeIndex2] != null) {
                 calculateStatesPartialsPruning(
-                        states[iNodeIndex2], matrices[currentMatrixIndex[iNodeIndex2]][iNodeIndex2],
-                        partials[currentPartialsIndex[iNodeIndex1]][iNodeIndex1], matrices[currentMatrixIndex[iNodeIndex1]][iNodeIndex1],
-                        partials[currentPartialsIndex[iNodeIndex3]][iNodeIndex3], iMatrixMap);
+                        states[nodeIndex2], matrices[currentMatrixIndex[nodeIndex2]][nodeIndex2],
+                        partials[currentPartialsIndex[nodeIndex1]][nodeIndex1], matrices[currentMatrixIndex[nodeIndex1]][nodeIndex1],
+                        partials[currentPartialsIndex[nodeIndex3]][nodeIndex3], matrixMap);
             } else {
                 calculatePartialsPartialsPruning(
-                        partials[currentPartialsIndex[iNodeIndex1]][iNodeIndex1], matrices[currentMatrixIndex[iNodeIndex1]][iNodeIndex1],
-                        partials[currentPartialsIndex[iNodeIndex2]][iNodeIndex2], matrices[currentMatrixIndex[iNodeIndex2]][iNodeIndex2],
-                        partials[currentPartialsIndex[iNodeIndex3]][iNodeIndex3], iMatrixMap);
+                        partials[currentPartialsIndex[nodeIndex1]][nodeIndex1], matrices[currentMatrixIndex[nodeIndex1]][nodeIndex1],
+                        partials[currentPartialsIndex[nodeIndex2]][nodeIndex2], matrices[currentMatrixIndex[nodeIndex2]][nodeIndex2],
+                        partials[currentPartialsIndex[nodeIndex3]][nodeIndex3], matrixMap);
             }
         }
 
         if (useScaling) {
-            scalePartials(iNodeIndex3);
+            scalePartials(nodeIndex3);
         }
     }
 
 
-    public void integratePartials(int iNodeIndex, double[] fProportions, double[] fOutPartials) {
-        calculateIntegratePartials(partials[currentPartialsIndex[iNodeIndex]][iNodeIndex], fProportions, fOutPartials);
+    @Override
+	public void integratePartials(int nodeIndex, double[] proportions, double[] outPartials) {
+        calculateIntegratePartials(partials[currentPartialsIndex[nodeIndex]][nodeIndex], proportions, outPartials);
     }
 
 
@@ -683,15 +695,15 @@ public class BeerLikelihoodCore extends LikelihoodCore {
      * but this sounded like a headache to organize (and he doesn't use the threshold idea
      * which improves the performance quite a bit).
      *
-     * @param iNodeIndex
+     * @param nodeIndex
      */
-    protected void scalePartials(int iNodeIndex) {
+    protected void scalePartials(int nodeIndex) {
 //        int v = 0;
-//    	double [] fPartials = m_fPartials[m_iCurrentPartialsIndices[iNodeIndex]][iNodeIndex];
+//    	double [] partials = m_fPartials[m_iCurrentPartialsIndices[nodeIndex]][nodeIndex];
 //        for (int i = 0; i < m_nPatternCount; i++) {
 //            for (int k = 0; k < m_nMatrixCount; k++) {
 //                for (int j = 0; j < m_nStateCount; j++) {
-//                	fPartials[v] *= SCALE;
+//                	partials[v] *= SCALE;
 //                	v++;
 //                }
 //            }
@@ -704,8 +716,8 @@ public class BeerLikelihoodCore extends LikelihoodCore {
             int v = u;
             for (int k = 0; k < nrOfMatrices; k++) {
                 for (int j = 0; j < nrOfStates; j++) {
-                    if (partials[currentPartialsIndex[iNodeIndex]][iNodeIndex][v] > scaleFactor) {
-                        scaleFactor = partials[currentPartialsIndex[iNodeIndex]][iNodeIndex][v];
+                    if (partials[currentPartialsIndex[nodeIndex]][nodeIndex][v] > scaleFactor) {
+                        scaleFactor = partials[currentPartialsIndex[nodeIndex]][nodeIndex][v];
                     }
                     v++;
                 }
@@ -717,15 +729,15 @@ public class BeerLikelihoodCore extends LikelihoodCore {
                 v = u;
                 for (int k = 0; k < nrOfMatrices; k++) {
                     for (int j = 0; j < nrOfStates; j++) {
-                        partials[currentPartialsIndex[iNodeIndex]][iNodeIndex][v] /= scaleFactor;
+                        partials[currentPartialsIndex[nodeIndex]][nodeIndex][v] /= scaleFactor;
                         v++;
                     }
                     v += (nrOfPatterns - 1) * nrOfStates;
                 }
-                scalingFactors[currentPartialsIndex[iNodeIndex]][iNodeIndex][i] = Math.log(scaleFactor);
+                scalingFactors[currentPartialsIndex[nodeIndex]][nodeIndex][i] = Math.log(scaleFactor);
 
             } else {
-                scalingFactors[currentPartialsIndex[iNodeIndex]][iNodeIndex][i] = 0.0;
+                scalingFactors[currentPartialsIndex[nodeIndex]][nodeIndex][i] = 0.0;
             }
             u += nrOfStates;
 
@@ -740,7 +752,8 @@ public class BeerLikelihoodCore extends LikelihoodCore {
      *
      * @return the log scaling factor
      */
-    public double getLogScalingFactor(int iPattern) {
+    @Override
+	public double getLogScalingFactor(int patternIndex_) {
 //    	if (m_bUseScaling) {
 //    		return -(m_nNodeCount/2) * Math.log(SCALE);
 //    	} else {
@@ -749,7 +762,7 @@ public class BeerLikelihoodCore extends LikelihoodCore {
         double logScalingFactor = 0.0;
         if (useScaling) {
             for (int i = 0; i < nrOfNodes; i++) {
-                logScalingFactor += scalingFactors[currentPartialsIndex[i]][i][iPattern];
+                logScalingFactor += scalingFactors[currentPartialsIndex[i]][i][patternIndex_];
             }
         }
         return logScalingFactor;
@@ -758,13 +771,13 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     /**
      * Gets the partials for a particular node.
      *
-     * @param iNodeIndex   the node
-     * @param fOutPartials an array into which the partials will go
+     * @param nodeIndex   the node
+     * @param outPartials an array into which the partials will go
      */
-    public void getPartials(int iNodeIndex, double[] fOutPartials) {
-        double[] partials1 = partials[currentPartialsIndex[iNodeIndex]][iNodeIndex];
+    public void getPartials(int nodeIndex, double[] outPartials) {
+        double[] partials1 = partials[currentPartialsIndex[nodeIndex]][nodeIndex];
 
-        System.arraycopy(partials1, 0, fOutPartials, 0, partialsSize);
+        System.arraycopy(partials1, 0, outPartials, 0, partialsSize);
     }
 
     /**
@@ -773,16 +786,17 @@ public class BeerLikelihoodCore extends LikelihoodCore {
     @Override
     public void restore() {
         // Rather than copying the stored stuff back, just swap the pointers...
-        int[] iTmp1 = currentMatrixIndex;
+        int[] tmp1 = currentMatrixIndex;
         currentMatrixIndex = storedMatrixIndex;
-        storedMatrixIndex = iTmp1;
+        storedMatrixIndex = tmp1;
 
-        int[] iTmp2 = currentPartialsIndex;
+        int[] tmp2 = currentPartialsIndex;
         currentPartialsIndex = storedPartialsIndex;
-        storedPartialsIndex = iTmp2;
+        storedPartialsIndex = tmp2;
     }
 
-    public void unstore() {
+    @Override
+	public void unstore() {
         System.arraycopy(storedMatrixIndex, 0, currentMatrixIndex, 0, nrOfNodes);
         System.arraycopy(storedPartialsIndex, 0, currentPartialsIndex, 0, nrOfNodes);
     }
@@ -798,50 +812,50 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 
 
 //	@Override
-//    public void calcRootPsuedoRootPartials(double[] fFrequencies, int iNode, double [] fPseudoPartials) {
+//    public void calcRootPsuedoRootPartials(double[] frequencies, int nodeIndex, double [] pseudoPartials) {
 //		int u = 0;
-//		double [] fInPartials = m_fPartials[m_iCurrentPartials[iNode]][iNode];
+//		double [] inPartials = m_fPartials[m_iCurrentPartials[nodeIndex]][nodeIndex];
 //		for (int k = 0; k < m_nPatterns; k++) {
 //			for (int l = 0; l < m_nMatrices; l++) {
 //				for (int i = 0; i < m_nStates; i++) {
-//					fPseudoPartials[u] = fInPartials[u] * fFrequencies[i];
+//					pseudoPartials[u] = inPartials[u] * frequencies[i];
 //					u++;
 //				}
 //			}
 //		}
 //    }
 //	@Override
-//    public void calcNodePsuedoRootPartials(double[] fInPseudoPartials, int iNode, double [] fOutPseudoPartials) {
-//		double [] fPartials = m_fPartials[m_iCurrentPartials[iNode]][iNode];
-//		double [] fOldPartials = m_fPartials[m_iStoredPartials[iNode]][iNode];
-//		int nMaxK = m_nPatterns * m_nMatrices * m_nStates; 
-//		for (int k = 0; k < nMaxK; k++) {
-//			fOutPseudoPartials[k] = fInPseudoPartials[k] * fPartials[k] / fOldPartials[k];
+//    public void calcNodePsuedoRootPartials(double[] inPseudoPartials, int nodeIndex, double [] outPseudoPartials) {
+//		double [] partials = m_fPartials[m_iCurrentPartials[nodeIndex]][nodeIndex];
+//		double [] oldPartials = m_fPartials[m_iStoredPartials[nodeIndex]][nodeIndex];
+//		int maxK = m_nPatterns * m_nMatrices * m_nStates; 
+//		for (int k = 0; k < maxK; k++) {
+//			outPseudoPartials[k] = inPseudoPartials[k] * partials[k] / oldPartials[k];
 //		}
 //	}
 //    
 //	@Override
-//    public void calcPsuedoRootPartials(double [] fParentPseudoPartials, int iNode, double [] fPseudoPartials) {
+//    public void calcPsuedoRootPartials(double [] parentPseudoPartials, int nodeIndex, double [] pseudoPartials) {
 //		int v = 0;
 //		int u = 0;
-//		double [] fMatrices = m_fMatrices[m_iCurrentMatrices[iNode]][iNode];
+//		double [] matrices = m_fMatrices[m_iCurrentMatrices[nodeIndex]][nodeIndex];
 //		for (int k = 0; k < m_nPatterns; k++) {
 //			for (int l = 0; l < m_nMatrices; l++) {
 //				for (int i = 0; i < m_nStates; i++) {
 //					int w = 0;
-//					double fSum = 0;
+//					double sum = 0;
 //					for (int j = 0; j < m_nStates; j++) {
-//					      fSum += fParentPseudoPartials[u+j] * fMatrices[w + i];
+//					      sum += parentPseudoPartials[u+j] * matrices[w + i];
 //					      w+=m_nStates;
 //					}
-//					fPseudoPartials[v] = fSum;
+//					pseudoPartials[v] = sum;
 //					v++;
 ////					int w = l * m_nMatrixSize;
-////					double fSum = 0;
+////					double sum = 0;
 ////					for (int j = 0; j < m_nStates; j++) {
-////					      fSum += fParentPseudoPartials[u+j] * fMatrices[w+j];
+////					      sum += parentPseudoPartials[u+j] * matrices[w+j];
 ////					}
-////					fPseudoPartials[v] = fSum;
+////					pseudoPartials[v] = sum;
 ////					v++;
 //				}
 //				u += m_nStates;
@@ -851,37 +865,37 @@ public class BeerLikelihoodCore extends LikelihoodCore {
 //
 //
 //    @Override
-//    void integratePartialsP(double [] fInPartials, double [] fProportions, double [] m_fRootPartials) {
-//		int nMaxK = m_nPatterns * m_nStates;
-//		for (int k = 0; k < nMaxK; k++) {
-//			m_fRootPartials[k] = fInPartials[k] * fProportions[0];
+//    void integratePartialsP(double [] inPartials, double [] proportions, double [] m_fRootPartials) {
+//		int maxK = m_nPatterns * m_nStates;
+//		for (int k = 0; k < maxK; k++) {
+//			m_fRootPartials[k] = inPartials[k] * proportions[0];
 //		}
 //
 //		for (int l = 1; l < m_nMatrices; l++) {
-//			int n = nMaxK * l;
-//			for (int k = 0; k < nMaxK; k++) {
-//				m_fRootPartials[k] += fInPartials[n+k] * fProportions[l];
+//			int n = maxK * l;
+//			for (int k = 0; k < maxK; k++) {
+//				m_fRootPartials[k] += inPartials[n+k] * proportions[l];
 //			}
 //		}
 //    } // integratePartials
 //
 //	/**
 //	 * Calculates pattern log likelihoods at a node.
-//	 * @param fPartials the partials used to calculate the likelihoods
-//	 * @param fFrequencies an array of state frequencies
-//	 * @param fOutLogLikelihoods an array into which the likelihoods will go
+//	 * @param partials the partials used to calculate the likelihoods
+//	 * @param frequencies an array of state frequencies
+//	 * @param outLogLikelihoods an array into which the likelihoods will go
 //	 */
 //    @Override
-//	public void calculateLogLikelihoodsP(double[] fPartials,double[] fOutLogLikelihoods)
+//	public void calculateLogLikelihoodsP(double[] partials,double[] outLogLikelihoods)
 //	{
 //        int v = 0;
 //		for (int k = 0; k < m_nPatterns; k++) {
 //            double sum = 0.0;
 //			for (int i = 0; i < m_nStates; i++) {
-//				sum += fPartials[v];
+//				sum += partials[v];
 //				v++;
 //			}
-//            fOutLogLikelihoods[k] = Math.log(sum) + getLogScalingFactor(k);
+//            outLogLikelihoods[k] = Math.log(sum) + getLogScalingFactor(k);
 //		}
 //	}
 //	
diff --git a/src/beast/evolution/likelihood/BeerLikelihoodCore4.java b/src/beast/evolution/likelihood/BeerLikelihoodCore4.java
index 5812b6e..82b2ed3 100644
--- a/src/beast/evolution/likelihood/BeerLikelihoodCore4.java
+++ b/src/beast/evolution/likelihood/BeerLikelihoodCore4.java
@@ -12,75 +12,76 @@ public class BeerLikelihoodCore4 extends BeerLikelihoodCore {
     /**
      * Calculates partial likelihoods at a node when both children have states.
      */
-    protected void calculateStatesStatesPruning(int[] iStates1, double[] fMatrices1,
-                                                int[] iStates2, double[] fMatrices2,
-                                                double[] fPartials3) {
+    @Override
+	protected void calculateStatesStatesPruning(int[] stateIndex1, double[] matrices1,
+                                                int[] stateIndex2, double[] matrices2,
+                                                double[] partials3) {
         int v = 0;
 
         for (int l = 0; l < nrOfMatrices; l++) {
 
             for (int k = 0; k < nrOfPatterns; k++) {
 
-                int state1 = iStates1[k];
-                int state2 = iStates2[k];
+                int state1 = stateIndex1[k];
+                int state2 = stateIndex2[k];
 
                 int w = l * matrixSize;
 
                 if (state1 < 4 && state2 < 4) {
 
-                    fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+                    partials3[v] = matrices1[w + state1] * matrices2[w + state2];
                     v++;
                     w += 4;
-                    fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+                    partials3[v] = matrices1[w + state1] * matrices2[w + state2];
                     v++;
                     w += 4;
-                    fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+                    partials3[v] = matrices1[w + state1] * matrices2[w + state2];
                     v++;
                     w += 4;
-                    fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+                    partials3[v] = matrices1[w + state1] * matrices2[w + state2];
                     v++;
                     w += 4;
 
                 } else if (state1 < 4) {
                     // child 2 has a gap or unknown state so don't use it
 
-                    fPartials3[v] = fMatrices1[w + state1];
+                    partials3[v] = matrices1[w + state1];
                     v++;
                     w += 4;
-                    fPartials3[v] = fMatrices1[w + state1];
+                    partials3[v] = matrices1[w + state1];
                     v++;
                     w += 4;
-                    fPartials3[v] = fMatrices1[w + state1];
+                    partials3[v] = matrices1[w + state1];
                     v++;
                     w += 4;
-                    fPartials3[v] = fMatrices1[w + state1];
+                    partials3[v] = matrices1[w + state1];
                     v++;
                     w += 4;
 
                 } else if (state2 < 4) {
                     // child 2 has a gap or unknown state so don't use it
-                    fPartials3[v] = fMatrices2[w + state2];
+                    partials3[v] = matrices2[w + state2];
                     v++;
                     w += 4;
-                    fPartials3[v] = fMatrices2[w + state2];
+                    partials3[v] = matrices2[w + state2];
                     v++;
                     w += 4;
-                    fPartials3[v] = fMatrices2[w + state2];
+                    partials3[v] = matrices2[w + state2];
                     v++;
                     w += 4;
-                    fPartials3[v] = fMatrices2[w + state2];
+                    partials3[v] = matrices2[w + state2];
                     v++;
                     w += 4;
 
                 } else {
                     // both children have a gap or unknown state so set partials to 1
-                    fPartials3[v] = 1.0;
+                    partials3[v] = 1.0;
                     v++;
-                    fPartials3[v] = 1.0;
+                    partials3[v] = 1.0;
                     v++;
-                    fPartials3[v] = 1.0;
+                    partials3[v] = 1.0;
                     v++;
-                    fPartials3[v] = 1.0;
+                    partials3[v] = 1.0;
                     v++;
                 }
             }
@@ -90,9 +91,10 @@ public class BeerLikelihoodCore4 extends BeerLikelihoodCore {
     /**
      * Calculates partial likelihoods at a node when one child has states and one has partials.
      */
-    protected void calculateStatesPartialsPruning(int[] iStates1, double[] fMatrices1,
-                                                  double[] fPartials2, double[] fMatrices2,
-                                                  double[] fPartials3) {
+    @Override
+	protected void calculateStatesPartialsPruning(int[] stateIndex1, double[] matrices1,
+                                                  double[] partials2, double[] matrices2,
+                                                  double[] partials3) {
 
         double sum;//, tmp;
 
@@ -102,39 +104,39 @@ public class BeerLikelihoodCore4 extends BeerLikelihoodCore {
         for (int l = 0; l < nrOfMatrices; l++) {
             for (int k = 0; k < nrOfPatterns; k++) {
 
-                int state1 = iStates1[k];
+                int state1 = stateIndex1[k];
 
                 int w = l * matrixSize;
 
                 if (state1 < 4) {
 
 
-                    sum = fMatrices2[w] * fPartials2[v];
-                    sum += fMatrices2[w + 1] * fPartials2[v + 1];
-                    sum += fMatrices2[w + 2] * fPartials2[v + 2];
-                    sum += fMatrices2[w + 3] * fPartials2[v + 3];
-                    fPartials3[u] = fMatrices1[w + state1] * sum;
+                    sum = matrices2[w] * partials2[v];
+                    sum += matrices2[w + 1] * partials2[v + 1];
+                    sum += matrices2[w + 2] * partials2[v + 2];
+                    sum += matrices2[w + 3] * partials2[v + 3];
+                    partials3[u] = matrices1[w + state1] * sum;
                     u++;
 
-                    sum = fMatrices2[w + 4] * fPartials2[v];
-                    sum += fMatrices2[w + 5] * fPartials2[v + 1];
-                    sum += fMatrices2[w + 6] * fPartials2[v + 2];
-                    sum += fMatrices2[w + 7] * fPartials2[v + 3];
-                    fPartials3[u] = fMatrices1[w + 4 + state1] * sum;
+                    sum = matrices2[w + 4] * partials2[v];
+                    sum += matrices2[w + 5] * partials2[v + 1];
+                    sum += matrices2[w + 6] * partials2[v + 2];
+                    sum += matrices2[w + 7] * partials2[v + 3];
+                    partials3[u] = matrices1[w + 4 + state1] * sum;
                     u++;
 
-                    sum = fMatrices2[w + 8] * fPartials2[v];
-                    sum += fMatrices2[w + 9] * fPartials2[v + 1];
-                    sum += fMatrices2[w + 10] * fPartials2[v + 2];
-                    sum += fMatrices2[w + 11] * fPartials2[v + 3];
-                    fPartials3[u] = fMatrices1[w + 8 + state1] * sum;
+                    sum = matrices2[w + 8] * partials2[v];
+                    sum += matrices2[w + 9] * partials2[v + 1];
+                    sum += matrices2[w + 10] * partials2[v + 2];
+                    sum += matrices2[w + 11] * partials2[v + 3];
+                    partials3[u] = matrices1[w + 8 + state1] * sum;
                     u++;
 
-                    sum = fMatrices2[w + 12] * fPartials2[v];
-                    sum += fMatrices2[w + 13] * fPartials2[v + 1];
-                    sum += fMatrices2[w + 14] * fPartials2[v + 2];
-                    sum += fMatrices2[w + 15] * fPartials2[v + 3];
-                    fPartials3[u] = fMatrices1[w + 12 + state1] * sum;
+                    sum = matrices2[w + 12] * partials2[v];
+                    sum += matrices2[w + 13] * partials2[v + 1];
+                    sum += matrices2[w + 14] * partials2[v + 2];
+                    sum += matrices2[w + 15] * partials2[v + 3];
+                    partials3[u] = matrices1[w + 12 + state1] * sum;
                     u++;
 
                     v += 4;
@@ -143,32 +145,32 @@ public class BeerLikelihoodCore4 extends BeerLikelihoodCore {
                     // Child 1 has a gap or unknown state so don't use it
 
 
-                    sum = fMatrices2[w] * fPartials2[v];
-                    sum += fMatrices2[w + 1] * fPartials2[v + 1];
-                    sum += fMatrices2[w + 2] * fPartials2[v + 2];
-                    sum += fMatrices2[w + 3] * fPartials2[v + 3];
-                    fPartials3[u] = sum;
+                    sum = matrices2[w] * partials2[v];
+                    sum += matrices2[w + 1] * partials2[v + 1];
+                    sum += matrices2[w + 2] * partials2[v + 2];
+                    sum += matrices2[w + 3] * partials2[v + 3];
+                    partials3[u] = sum;
                     u++;
 
-                    sum = fMatrices2[w + 4] * fPartials2[v];
-                    sum += fMatrices2[w + 5] * fPartials2[v + 1];
-                    sum += fMatrices2[w + 6] * fPartials2[v + 2];
-                    sum += fMatrices2[w + 7] * fPartials2[v + 3];
-                    fPartials3[u] = sum;
+                    sum = matrices2[w + 4] * partials2[v];
+                    sum += matrices2[w + 5] * partials2[v + 1];
+                    sum += matrices2[w + 6] * partials2[v + 2];
+                    sum += matrices2[w + 7] * partials2[v + 3];
+                    partials3[u] = sum;
                     u++;
 
-                    sum = fMatrices2[w + 8] * fPartials2[v];
-                    sum += fMatrices2[w + 9] * fPartials2[v + 1];
-                    sum += fMatrices2[w + 10] * fPartials2[v + 2];
-                    sum += fMatrices2[w + 11] * fPartials2[v + 3];
-                    fPartials3[u] = sum;
+                    sum = matrices2[w + 8] * partials2[v];
+                    sum += matrices2[w + 9] * partials2[v + 1];
+                    sum += matrices2[w + 10] * partials2[v + 2];
+                    sum += matrices2[w + 11] * partials2[v + 3];
+                    partials3[u] = sum;
                     u++;
 
-                    sum = fMatrices2[w + 12] * fPartials2[v];
-                    sum += fMatrices2[w + 13] * fPartials2[v + 1];
-                    sum += fMatrices2[w + 14] * fPartials2[v + 2];
-                    sum += fMatrices2[w + 15] * fPartials2[v + 3];
-                    fPartials3[u] = sum;
+                    sum = matrices2[w + 12] * partials2[v];
+                    sum += matrices2[w + 13] * partials2[v + 1];
+                    sum += matrices2[w + 14] * partials2[v + 2];
+                    sum += matrices2[w + 15] * partials2[v + 3];
+                    partials3[u] = sum;
                     u++;
 
                     v += 4;
@@ -180,9 +182,10 @@ public class BeerLikelihoodCore4 extends BeerLikelihoodCore {
     /**
      * Calculates partial likelihoods at a node when both children have partials.
      */
-    protected void calculatePartialsPartialsPruning(double[] fPartials1, double[] fMatrices1,
-                                                    double[] fPartials2, double[] fMatrices2,
-                                                    double[] fPartials3) {
+    @Override
+	protected void calculatePartialsPartialsPruning(double[] partials1, double[] matrices1,
+                                                    double[] partials2, double[] matrices2,
+                                                    double[] partials3) {
         double sum1, sum2;
 
         int u = 0;
@@ -194,48 +197,48 @@ public class BeerLikelihoodCore4 extends BeerLikelihoodCore {
 
                 int w = l * matrixSize;
 
-                sum1 = fMatrices1[w] * fPartials1[v];
-                sum2 = fMatrices2[w] * fPartials2[v];
-                sum1 += fMatrices1[w + 1] * fPartials1[v + 1];
-                sum2 += fMatrices2[w + 1] * fPartials2[v + 1];
-                sum1 += fMatrices1[w + 2] * fPartials1[v + 2];
-                sum2 += fMatrices2[w + 2] * fPartials2[v + 2];
-                sum1 += fMatrices1[w + 3] * fPartials1[v + 3];
-                sum2 += fMatrices2[w + 3] * fPartials2[v + 3];
-                fPartials3[u] = sum1 * sum2;
+                sum1 = matrices1[w] * partials1[v];
+                sum2 = matrices2[w] * partials2[v];
+                sum1 += matrices1[w + 1] * partials1[v + 1];
+                sum2 += matrices2[w + 1] * partials2[v + 1];
+                sum1 += matrices1[w + 2] * partials1[v + 2];
+                sum2 += matrices2[w + 2] * partials2[v + 2];
+                sum1 += matrices1[w + 3] * partials1[v + 3];
+                sum2 += matrices2[w + 3] * partials2[v + 3];
+                partials3[u] = sum1 * sum2;
                 u++;
 
-                sum1 = fMatrices1[w + 4] * fPartials1[v];
-                sum2 = fMatrices2[w + 4] * fPartials2[v];
-                sum1 += fMatrices1[w + 5] * fPartials1[v + 1];
-                sum2 += fMatrices2[w + 5] * fPartials2[v + 1];
-                sum1 += fMatrices1[w + 6] * fPartials1[v + 2];
-                sum2 += fMatrices2[w + 6] * fPartials2[v + 2];
-                sum1 += fMatrices1[w + 7] * fPartials1[v + 3];
-                sum2 += fMatrices2[w + 7] * fPartials2[v + 3];
-                fPartials3[u] = sum1 * sum2;
+                sum1 = matrices1[w + 4] * partials1[v];
+                sum2 = matrices2[w + 4] * partials2[v];
+                sum1 += matrices1[w + 5] * partials1[v + 1];
+                sum2 += matrices2[w + 5] * partials2[v + 1];
+                sum1 += matrices1[w + 6] * partials1[v + 2];
+                sum2 += matrices2[w + 6] * partials2[v + 2];
+                sum1 += matrices1[w + 7] * partials1[v + 3];
+                sum2 += matrices2[w + 7] * partials2[v + 3];
+                partials3[u] = sum1 * sum2;
                 u++;
 
-                sum1 = fMatrices1[w + 8] * fPartials1[v];
-                sum2 = fMatrices2[w + 8] * fPartials2[v];
-                sum1 += fMatrices1[w + 9] * fPartials1[v + 1];
-                sum2 += fMatrices2[w + 9] * fPartials2[v + 1];
-                sum1 += fMatrices1[w + 10] * fPartials1[v + 2];
-                sum2 += fMatrices2[w + 10] * fPartials2[v + 2];
-                sum1 += fMatrices1[w + 11] * fPartials1[v + 3];
-                sum2 += fMatrices2[w + 11] * fPartials2[v + 3];
-                fPartials3[u] = sum1 * sum2;
+                sum1 = matrices1[w + 8] * partials1[v];
+                sum2 = matrices2[w + 8] * partials2[v];
+                sum1 += matrices1[w + 9] * partials1[v + 1];
+                sum2 += matrices2[w + 9] * partials2[v + 1];
+                sum1 += matrices1[w + 10] * partials1[v + 2];
+                sum2 += matrices2[w + 10] * partials2[v + 2];
+                sum1 += matrices1[w + 11] * partials1[v + 3];
+                sum2 += matrices2[w + 11] * partials2[v + 3];
+                partials3[u] = sum1 * sum2;
                 u++;
 
-                sum1 = fMatrices1[w + 12] * fPartials1[v];
-                sum2 = fMatrices2[w + 12] * fPartials2[v];
-                sum1 += fMatrices1[w + 13] * fPartials1[v + 1];
-                sum2 += fMatrices2[w + 13] * fPartials2[v + 1];
-                sum1 += fMatrices1[w + 14] * fPartials1[v + 2];
-                sum2 += fMatrices2[w + 14] * fPartials2[v + 2];
-                sum1 += fMatrices1[w + 15] * fPartials1[v + 3];
-                sum2 += fMatrices2[w + 15] * fPartials2[v + 3];
-                fPartials3[u] = sum1 * sum2;
+                sum1 = matrices1[w + 12] * partials1[v];
+                sum2 = matrices2[w + 12] * partials2[v];
+                sum1 += matrices1[w + 13] * partials1[v + 1];
+                sum2 += matrices2[w + 13] * partials2[v + 1];
+                sum1 += matrices1[w + 14] * partials1[v + 2];
+                sum2 += matrices2[w + 14] * partials2[v + 2];
+                sum1 += matrices1[w + 15] * partials1[v + 3];
+                sum2 += matrices2[w + 15] * partials2[v + 3];
+                partials3[u] = sum1 * sum2;
                 u++;
 
                 v += 4;
@@ -246,45 +249,45 @@ public class BeerLikelihoodCore4 extends BeerLikelihoodCore {
 
 //
 //	@Override
-//    public void calcRootPseudoRootPartials(double[] fFrequencies, int iNode, double [] fPseudoPartials) {
+//    public void calcRootPseudoRootPartials(double[] frequencies, int nodeIndex, double [] pseudoPartials) {
 //		int u = 0;
-//		double [] fInPartials = m_fPartials[m_iCurrentPartials[iNode]][iNode];
+//		double [] inPartials = m_fPartials[m_iCurrentPartials[nodeIndex]][nodeIndex];
 //		for (int k = 0; k < m_nPatterns * m_nMatrices; k++) {
-//			fPseudoPartials[u] = fInPartials[u] * fFrequencies[0];
-//			fPseudoPartials[u+1] = fInPartials[u+1] * fFrequencies[1];
-//			fPseudoPartials[u+2] = fInPartials[u+2] * fFrequencies[2];
-//			fPseudoPartials[u+3] = fInPartials[u+3] * fFrequencies[3];
+//			pseudoPartials[u] = inPartials[u] * frequencies[0];
+//			pseudoPartials[u+1] = inPartials[u+1] * frequencies[1];
+//			pseudoPartials[u+2] = inPartials[u+2] * frequencies[2];
+//			pseudoPartials[u+3] = inPartials[u+3] * frequencies[3];
 //			u+=4;
 //		}
 //    }
 //    
 //	@Override
-//    public void calcPseudoRootPartials(double [] fParentPseudoPartials, int iNode, double [] fPseudoPartials) {
+//    public void calcPseudoRootPartials(double [] parentPseudoPartials, int nodeIndex, double [] pseudoPartials) {
 //		int v = 0;
 //		int u = 0;
-//		double [] fMatrices = m_fMatrices[m_iCurrentMatrices[iNode]][iNode];
+//		double [] matrices = m_fMatrices[m_iCurrentMatrices[nodeIndex]][nodeIndex];
 //		for (int k = 0; k < m_nPatterns; k++) {
 //			for (int l = 0; l < m_nMatrices; l++) {
 //				int w = l * m_nMatrixSize;
-//				fPseudoPartials[v] = fParentPseudoPartials[u] * fMatrices[w] +
-//					fParentPseudoPartials[u+1] * fMatrices[w+1] +
-//					fParentPseudoPartials[u+2] * fMatrices[w+2] +
-//					fParentPseudoPartials[u+3] * fMatrices[w+3];
+//				pseudoPartials[v] = parentPseudoPartials[u] * matrices[w] +
+//					parentPseudoPartials[u+1] * matrices[w+1] +
+//					parentPseudoPartials[u+2] * matrices[w+2] +
+//					parentPseudoPartials[u+3] * matrices[w+3];
 //				w += 4;
-//				fPseudoPartials[v+1] = fParentPseudoPartials[u] * fMatrices[w] +
-//						fParentPseudoPartials[u+1] * fMatrices[w+1] +
-//						fParentPseudoPartials[u+2] * fMatrices[w+2] +
-//						fParentPseudoPartials[u+3] * fMatrices[w+3];
+//				pseudoPartials[v+1] = parentPseudoPartials[u] * matrices[w] +
+//						parentPseudoPartials[u+1] * matrices[w+1] +
+//						parentPseudoPartials[u+2] * matrices[w+2] +
+//						parentPseudoPartials[u+3] * matrices[w+3];
 //				w += 4;
-//				fPseudoPartials[v+1] = fParentPseudoPartials[u] * fMatrices[w] +
-//					fParentPseudoPartials[u+1] * fMatrices[w+1] +
-//					fParentPseudoPartials[u+2] * fMatrices[w+2] +
-//					fParentPseudoPartials[u+3] * fMatrices[w+3];
+//				pseudoPartials[v+1] = parentPseudoPartials[u] * matrices[w] +
+//					parentPseudoPartials[u+1] * matrices[w+1] +
+//					parentPseudoPartials[u+2] * matrices[w+2] +
+//					parentPseudoPartials[u+3] * matrices[w+3];
 //				w += 4;
-//				fPseudoPartials[v+1] = fParentPseudoPartials[u] * fMatrices[w] +
-//					fParentPseudoPartials[u+1] * fMatrices[w+1] +
-//					fParentPseudoPartials[u+2] * fMatrices[w+2] +
-//					fParentPseudoPartials[u+3] * fMatrices[w+3];
+//				pseudoPartials[v+1] = parentPseudoPartials[u] * matrices[w] +
+//					parentPseudoPartials[u+1] * matrices[w+1] +
+//					parentPseudoPartials[u+2] * matrices[w+2] +
+//					parentPseudoPartials[u+3] * matrices[w+3];
 //				v += 4;
 //				u += 4;
 //			}
@@ -293,18 +296,18 @@ public class BeerLikelihoodCore4 extends BeerLikelihoodCore {
 //
 //	/**
 //	 * Calculates pattern log likelihoods at a node.
-//	 * @param fPartials the partials used to calculate the likelihoods
-//	 * @param fFrequencies an array of state frequencies
-//	 * @param fOutLogLikelihoods an array into which the likelihoods will go
+//	 * @param partials the partials used to calculate the likelihoods
+//	 * @param frequencies an array of state frequencies
+//	 * @param outLogLikelihoods an array into which the likelihoods will go
 //	 */
 //    @Override
-//	public void calculateLogLikelihoodsP(double[] fPartials,double[] fOutLogLikelihoods)
+//	public void calculateLogLikelihoodsP(double[] partials,double[] outLogLikelihoods)
 //	{
 //        int v = 0;
 //		for (int k = 0; k < m_nPatterns; k++) {
-//            double sum = fPartials[v] + fPartials[v+1] + fPartials[v + 2] + fPartials[v + 3];
+//            double sum = partials[v] + partials[v+1] + partials[v + 2] + partials[v + 3];
 //            v +=4;
-//            fOutLogLikelihoods[k] = Math.log(sum) + getLogScalingFactor(k);
+//            outLogLikelihoods[k] = Math.log(sum) + getLogScalingFactor(k);
 //		}
 //	}
 
diff --git a/src/beast/evolution/likelihood/GenericTreeLikelihood.java b/src/beast/evolution/likelihood/GenericTreeLikelihood.java
index f24c86f..70b913b 100644
--- a/src/beast/evolution/likelihood/GenericTreeLikelihood.java
+++ b/src/beast/evolution/likelihood/GenericTreeLikelihood.java
@@ -7,8 +7,8 @@ import java.util.Random;
 import beast.core.Description;
 import beast.core.Distribution;
 import beast.core.Input;
-import beast.core.State;
 import beast.core.Input.Validate;
+import beast.core.State;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.branchratemodel.BranchRateModel;
 import beast.evolution.sitemodel.SiteModelInterface;
@@ -27,13 +27,13 @@ import beast.evolution.tree.TreeInterface;
 //
 public class GenericTreeLikelihood extends Distribution {
     
-    public Input<Alignment> dataInput = new Input<Alignment>("data", "sequence data for the beast.tree", Validate.REQUIRED);
+    final public Input<Alignment> dataInput = new Input<>("data", "sequence data for the beast.tree", Validate.REQUIRED);
 
-    public Input<TreeInterface> treeInput = new Input<TreeInterface>("tree", "phylogenetic beast.tree with sequence data in the leafs", Validate.REQUIRED);
+    final public Input<TreeInterface> treeInput = new Input<>("tree", "phylogenetic beast.tree with sequence data in the leafs", Validate.REQUIRED);
 
-    public Input<SiteModelInterface> siteModelInput = new Input<SiteModelInterface>("siteModel", "site model for leafs in the beast.tree", Validate.REQUIRED);
+    final public Input<SiteModelInterface> siteModelInput = new Input<>("siteModel", "site model for leafs in the beast.tree", Validate.REQUIRED);
     
-    public Input<BranchRateModel.Base> branchRateModelInput = new Input<BranchRateModel.Base>("branchRateModel",
+    final public Input<BranchRateModel.Base> branchRateModelInput = new Input<>("branchRateModel",
             "A model describing the rates on the branches of the beast.tree.");
 
     
diff --git a/src/beast/evolution/likelihood/LikelihoodCore.java b/src/beast/evolution/likelihood/LikelihoodCore.java
index cd0c0fd..2b2464e 100644
--- a/src/beast/evolution/likelihood/LikelihoodCore.java
+++ b/src/beast/evolution/likelihood/LikelihoodCore.java
@@ -46,67 +46,68 @@ abstract public class LikelihoodCore {
      * reserve memory for partials, indices and other
      * data structures required by the core *
      */
-    abstract public void initialize(int nNodeCount, int nPatternCount, int nMatrixCount, boolean bIntegrateCategories, boolean bUseAmbiguities);
+    abstract public void initialize(int nodeCount, int patternCount, int matrixCount, boolean integrateCategories, boolean useAmbiguities);
 
     /**
      * clean up after last likelihood calculation, if at all required *
      */
-    abstract public void finalize() throws java.lang.Throwable;
+    @Override
+	abstract public void finalize() throws java.lang.Throwable;
 
     /**
-     * reserve memory for partials for node with number iNode *
+     * reserve memory for partials for node with number nodeIndex *
      */
-    abstract public void createNodePartials(int iNode);
+    abstract public void createNodePartials(int nodeIndex);
 
 
     /**
      * indicate that the partials for node
-     * iNode is about the be changed, that is, that the stored
-     * state for node iNode cannot be reused *
+     * nodeIndex is about the be changed, that is, that the stored
+     * state for node nodeIndex cannot be reused *
      */
-    abstract public void setNodePartialsForUpdate(int iNode);
+    abstract public void setNodePartialsForUpdate(int nodeIndex);
 
     /**
-     * assign values of partials for node with number iNode *
+     * assign values of partials for node with number nodeIndex *
      */
-    abstract public void setNodePartials(int iNode, double[] fPartials);
+    abstract public void setNodePartials(int nodeIndex, double[] partials);
 
-    abstract public void getNodePartials(int iNode, double[] fPartials);
-    //abstract public void setCurrentNodePartials(int iNode, double[] fPartials);
+    abstract public void getNodePartials(int nodeIndex, double[] partials);
+    //abstract public void setCurrentNodePartials(int nodeIndex, double[] partials);
 
-    /** reserve memory for states for node with number iNode **/
-    //abstract public void createNodeStates(int iNode);
+    /** reserve memory for states for node with number nodeIndex **/
+    //abstract public void createNodeStates(int nodeIndex);
 
     /**
-     * assign values of states for node with number iNode *
+     * assign values of states for node with number nodeIndex *
      */
-    abstract public void setNodeStates(int iNode, int[] iStates);
+    abstract public void setNodeStates(int nodeIndex, int[] states);
 
-    abstract public void getNodeStates(int iNode, int[] iStates);
+    abstract public void getNodeStates(int nodeIndex, int[] states);
 
     /**
      * indicate that the probability transition matrix for node
-     * iNode is about the be changed, that is, that the stored
-     * state for node iNode cannot be reused *
+     * nodeIndex is about the be changed, that is, that the stored
+     * state for node nodeIndex cannot be reused *
      */
-    abstract public void setNodeMatrixForUpdate(int iNode);
+    abstract public void setNodeMatrixForUpdate(int nodeIndex);
 
     /**
-     * assign values of states for probability transition matrix for node with number iNode *
+     * assign values of states for probability transition matrix for node with number nodeIndex *
      */
-    abstract public void setNodeMatrix(int iNode, int iMatrixIndex, double[] fMatrix);
+    abstract public void setNodeMatrix(int nodeIndex, int matrixIndex, double[] matrix);
 
-    abstract public void getNodeMatrix(int iNode, int iMatrixIndex, double[] fMatrix);
+    abstract public void getNodeMatrix(int nodeIndex, int matrixIndex, double[] matrix);
     /** assign values of states for probability transition matrices 
-     * padded with 1s for dealing with unknown characters for node with number iNode **/
-//	abstract public void setPaddedNodeMatrices(int iNode, double[] fMatrix);
+     * padded with 1s for dealing with unknown characters for node with number nodeIndex **/
+//	abstract public void setPaddedNodeMatrices(int nodeIndex, double[] matrix);
 
 
     /**
      * indicate that the topology of the tree chanced so the cache
      * data structures cannot be reused *
      */
-    public void setNodeStatesForUpdate(int iNode) {
+    public void setNodeStatesForUpdate(int nodeIndex) {
     }
 
     ;
@@ -119,7 +120,7 @@ abstract public class LikelihoodCore {
      */
     boolean m_bUseScaling = false;
 
-    abstract public void setUseScaling(double fScale);
+    abstract public void setUseScaling(double scale);
 
     public boolean getUseScaling() {
         return m_bUseScaling;
@@ -128,39 +129,39 @@ abstract public class LikelihoodCore {
     /**
      * return the cumulative scaling effect. Should be zero if no scaling is used *
      */
-    abstract public double getLogScalingFactor(int iPattern);
+    abstract public double getLogScalingFactor(int patternIndex_);
 
     /**
-     * Calculate partials for node iNode3, with children iNode1 and iNode2.
+     * Calculate partials for node node3, with children node1 and node2Index.
      * NB Depending on whether the child nodes contain states or partials, the
      * calculation differs-*
      */
-    abstract public void calculatePartials(int iNode1, int iNode2, int iNode3);
-    //abstract public void calculatePartials(int iNode1, int iNode2, int iNode3, int[] iMatrixMap);
+    abstract public void calculatePartials(int node1, int node2Index, int node3);
+    //abstract public void calculatePartials(int node1, int node2Index, int node3, int[] matrixMap);
 
     /**
      * integrate partials over categories (if any). *
      */
-    abstract public void integratePartials(int iNode, double[] fProportions, double[] fOutPartials);
+    abstract public void integratePartials(int nodeIndex, double[] proportions, double[] outPartials);
 
     /**
      * calculate log likelihoods at the root of the tree,
-     * using fFrequencies as root node distribution.
-     * fOutLogLikelihoods contains the resulting probabilities for each of
+     * using frequencies as root node distribution.
+     * outLogLikelihoods contains the resulting probabilities for each of
      * the patterns *
      */
-    abstract public void calculateLogLikelihoods(double[] fPartials, double[] fFrequencies, double[] fOutLogLikelihoods);
+    abstract public void calculateLogLikelihoods(double[] partials, double[] frequencies, double[] outLogLikelihoods);
 
 
     public void processStack() {
     }
 
-    abstract protected void calculateIntegratePartials(double[] fInPartials, double[] fProportions, double[] fOutPartials);
-//    abstract public void calcRootPsuedoRootPartials(double[] fFrequencies, int iNode, double [] fPseudoPartials);
-//    abstract public void calcNodePsuedoRootPartials(double[] fInPseudoPartials, int iNode, double [] fOutPseudoPartials);
-//    abstract public void calcPsuedoRootPartials(double [] fParentPseudoPartials, int iNode, double [] fPseudoPartials);
-//    abstract void integratePartialsP(double [] fInPartials, double [] fProportions, double [] m_fRootPartials);
-//    abstract void calculateLogLikelihoodsP(double[] fPartials,double[] fOutLogLikelihoods);
+    abstract protected void calculateIntegratePartials(double[] inPartials, double[] proportions, double[] outPartials);
+//    abstract public void calcRootPsuedoRootPartials(double[] frequencies, int nodeIndex, double [] pseudoPartials);
+//    abstract public void calcNodePsuedoRootPartials(double[] inPseudoPartials, int nodeIndex, double [] outPseudoPartials);
+//    abstract public void calcPsuedoRootPartials(double [] parentPseudoPartials, int nodeIndex, double [] pseudoPartials);
+//    abstract void integratePartialsP(double [] inPartials, double [] proportions, double [] m_fRootPartials);
+//    abstract void calculateLogLikelihoodsP(double[] partials,double[] outLogLikelihoods);
 
     /**
      * store current state *
diff --git a/src/beast/evolution/likelihood/ThreadedBeerLikelihoodCore.java b/src/beast/evolution/likelihood/ThreadedBeerLikelihoodCore.java
new file mode 100644
index 0000000..c7dccf9
--- /dev/null
+++ b/src/beast/evolution/likelihood/ThreadedBeerLikelihoodCore.java
@@ -0,0 +1,984 @@
+package beast.evolution.likelihood;
+
+import java.util.List;
+
+
+/** standard likelihood core, uses no caching **/
+public class ThreadedBeerLikelihoodCore extends ThreadedLikelihoodCore {
+    protected int m_nStates;
+    protected int m_nNodes;
+    protected int m_nPatterns;
+    protected int m_nPartialsSize;
+    protected int m_nMatrixSize;
+    protected int m_nMatrices;
+
+    protected boolean m_bIntegrateCategories;
+
+    protected double[][][] m_fPartials;
+
+    protected int[][] m_iStates;
+
+    protected double[][][] m_fMatrices;
+
+    protected int[] m_iCurrentMatrices;
+    protected int[] m_iStoredMatrices;
+    protected int[] m_iCurrentPartials;
+    protected int[] m_iStoredPartials;
+
+    protected boolean m_bUseScaling = false;
+
+    protected double[][][] m_fScalingFactors;
+
+    private double m_fScalingThreshold = 1.0E-100;
+    double SCALE = 2;
+
+    int [] weights;
+    double [] m_fPatternLogLikelihoods;
+    List<Integer> m_iConstantPattern;
+    /** memory allocation for the root partials **/
+    double[][] m_fRootPartials;
+
+    
+	public ThreadedBeerLikelihoodCore(int nStateCount) {
+		this.m_nStates = nStateCount;
+	} // c'tor
+	
+
+	/**
+	 * Calculates partial likelihoods at a node when both children have states.
+	 */
+	protected void calculateStatesStatesPruning(int[] iStates1, double[] fMatrices1,
+												int[] iStates2, double[] fMatrices2,
+												double[] fPartials3, int iFrom, int iTo)
+	{
+
+		for (int l = 0; l < m_nMatrices; l++) {
+			int v = m_nStates * iFrom  +  m_nStates * l * m_nPatterns;
+
+			for (int k = iFrom; k < iTo; k++) {
+
+				int state1 = iStates1[k];
+				int state2 = iStates2[k];
+
+				int w = l * m_nMatrixSize;
+
+                if (state1 < m_nStates && state2 < m_nStates) {
+
+					for (int i = 0; i < m_nStates; i++) {
+
+						fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+
+						v++;
+						w += m_nStates;
+					}
+
+				} else if (state1 < m_nStates) {
+					// child 2 has a gap or unknown state so treat it as unknown
+
+					for (int i = 0; i < m_nStates; i++) {
+
+						fPartials3[v] = fMatrices1[w + state1];
+
+						v++;
+						w += m_nStates;
+					}
+				} else if (state2 < m_nStates) {
+					// child 2 has a gap or unknown state so treat it as unknown
+
+					for (int i = 0; i < m_nStates; i++) {
+
+						fPartials3[v] = fMatrices2[w + state2];
+
+						v++;
+						w += m_nStates;
+					}
+				} else {
+					// both children have a gap or unknown state so set partials to 1
+
+					for (int j = 0; j < m_nStates; j++) {
+						fPartials3[v] = 1.0;
+						v++;
+					}
+				}
+			}
+		}
+	}
+
+	/**
+	 * Calculates partial likelihoods at a node when one child has states and one has partials.
+	 */
+	protected void calculateStatesPartialsPruning(	int[] iStates1, double[] fMatrices1,
+													double[] fPartials2, double[] fMatrices2,
+													double[] fPartials3, int iFrom, int iTo)
+	{
+
+		double sum, tmp;
+
+
+		for (int l = 0; l < m_nMatrices; l++) {
+			int v = m_nStates * iFrom  +  m_nStates * l * m_nPatterns;
+			int u = v;
+			for (int k = iFrom; k < iTo; k++) {
+
+				int state1 = iStates1[k];
+
+                int w = l * m_nMatrixSize;
+
+				if (state1 < m_nStates) {
+
+
+					for (int i = 0; i < m_nStates; i++) {
+
+						tmp = fMatrices1[w + state1];
+
+						sum = 0.0;
+						for (int j = 0; j < m_nStates; j++) {
+							sum += fMatrices2[w] * fPartials2[v + j];
+							w++;
+						}
+
+						fPartials3[u] = tmp * sum;
+						u++;
+					}
+
+					v += m_nStates;
+				} else {
+					// Child 1 has a gap or unknown state so don't use it
+
+					for (int i = 0; i < m_nStates; i++) {
+
+						sum = 0.0;
+						for (int j = 0; j < m_nStates; j++) {
+							sum += fMatrices2[w] * fPartials2[v + j];
+							w++;
+						}
+
+						fPartials3[u] = sum;
+						u++;
+					}
+
+					v += m_nStates;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Calculates partial likelihoods at a node when both children have partials.
+	 */
+	protected void calculatePartialsPartialsPruning(double[] fPartials1, double[] fMatrices1,
+													double[] fPartials2, double[] fMatrices2,
+													double[] fPartials3, int iFrom, int iTo)
+	{
+		double sum1, sum2;
+
+		for (int l = 0; l < m_nMatrices; l++) {
+			int v = m_nStates * iFrom  +  m_nStates * l * m_nPatterns;
+			int u = v;
+
+			for (int k = iFrom; k < iTo; k++) {
+
+                int w = l * m_nMatrixSize;
+
+				for (int i = 0; i < m_nStates; i++) {
+
+					sum1 = sum2 = 0.0;
+
+					for (int j = 0; j < m_nStates; j++) {
+						sum1 += fMatrices1[w] * fPartials1[v + j];
+						sum2 += fMatrices2[w] * fPartials2[v + j];
+
+						w++;
+					}
+
+					fPartials3[u] = sum1 * sum2;
+					u++;
+				}
+				v += m_nStates;
+			}
+		}
+	}
+
+	/**
+	 * Calculates partial likelihoods at a node when both children have states.
+	 */
+	protected void calculateStatesStatesPruning(int[] iStates1, double[] fMatrices1,
+												int[] iStates2, double[] fMatrices2,
+												double[] fPartials3, int[] iMatrixMap, int iFrom, int iTo)
+	{
+		int v = m_nStates * iFrom * m_nMatrices;
+
+		for (int k = iFrom; k < iTo; k++) {
+
+			int state1 = iStates1[k];
+			int state2 = iStates2[k];
+
+			int w = iMatrixMap[k] * m_nMatrixSize;
+
+			if (state1 < m_nStates && state2 < m_nStates) {
+
+				for (int i = 0; i < m_nStates; i++) {
+
+					fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+
+					v++;
+					w += m_nStates;
+				}
+
+			} else if (state1 < m_nStates) {
+				// child 2 has a gap or unknown state so treat it as unknown
+
+				for (int i = 0; i < m_nStates; i++) {
+
+					fPartials3[v] = fMatrices1[w + state1];
+
+					v++;
+					w += m_nStates;
+				}
+			} else if (state2 < m_nStates) {
+				// child 2 has a gap or unknown state so treat it as unknown
+
+				for (int i = 0; i < m_nStates; i++) {
+
+					fPartials3[v] = fMatrices2[w + state2];
+
+					v++;
+					w += m_nStates;
+				}
+			} else {
+				// both children have a gap or unknown state so set partials to 1
+
+				for (int j = 0; j < m_nStates; j++) {
+					fPartials3[v] = 1.0;
+					v++;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Calculates partial likelihoods at a node when one child has states and one has partials.
+	 */
+	protected void calculateStatesPartialsPruning(	int[] iStates1, double[] fMatrices1,
+													double[] fPartials2, double[] fMatrices2,
+													double[] fPartials3, int[] iMatrixMap, int iFrom, int iTo)
+	{
+
+		double sum, tmp;
+
+		int u = m_nStates * iFrom * m_nMatrices;
+		int v = u;
+
+		for (int k = iFrom; k < iTo; k++) {
+
+			int state1 = iStates1[k];
+
+			int w = iMatrixMap[k] * m_nMatrixSize;
+
+			if (state1 < m_nStates) {
+
+				for (int i = 0; i < m_nStates; i++) {
+
+					tmp = fMatrices1[w + state1];
+
+					sum = 0.0;
+					for (int j = 0; j < m_nStates; j++) {
+						sum += fMatrices2[w] * fPartials2[v + j];
+						w++;
+					}
+
+					fPartials3[u] = tmp * sum;
+					u++;
+				}
+
+				v += m_nStates;
+			} else {
+				// Child 1 has a gap or unknown state so don't use it
+
+				for (int i = 0; i < m_nStates; i++) {
+
+					sum = 0.0;
+					for (int j = 0; j < m_nStates; j++) {
+						sum += fMatrices2[w] * fPartials2[v + j];
+						w++;
+					}
+
+					fPartials3[u] = sum;
+					u++;
+				}
+
+				v += m_nStates;
+			}
+		}
+	}
+
+	/**
+	 * Calculates partial likelihoods at a node when both children have partials.
+	 */
+	protected void calculatePartialsPartialsPruning(double[] fPartials1, double[] fMatrices1,
+													double[] fPartials2, double[] fMatrices2,
+													double[] fPartials3, int[] iMatrixMap, int iFrom, int iTo)
+	{
+		double sum1, sum2;
+
+		int u = m_nStates * iFrom * m_nMatrices;
+		int v = u;
+
+		for (int k = iFrom; k < iTo; k++) {
+
+			int w = iMatrixMap[k] * m_nMatrixSize;
+
+			for (int i = 0; i < m_nStates; i++) {
+
+				sum1 = sum2 = 0.0;
+
+				for (int j = 0; j < m_nStates; j++) {
+					sum1 += fMatrices1[w] * fPartials1[v + j];
+					sum2 += fMatrices2[w] * fPartials2[v + j];
+
+					w++;
+				}
+
+				fPartials3[u] = sum1 * sum2;
+				u++;
+			}
+			v += m_nStates;
+		}
+	}
+
+	/**
+	 * Integrates partials across categories.
+     * @param fInPartials the array of partials to be integrated
+	 * @param fProportions the proportions of sites in each category
+	 * @param fOutPartials an array into which the partials will go
+	 */
+	protected void calculateIntegratePartials(double[] fInPartials, double[] fProportions, double[] fOutPartials, int iFrom, int iTo)
+	{
+
+		int u = iFrom * m_nStates;
+		int v = iFrom * m_nStates;
+		for (int k = iFrom; k < iTo; k++) {
+
+			for (int i = 0; i < m_nStates; i++) {
+
+				fOutPartials[u] = fInPartials[v] * fProportions[0];
+				u++;
+				v++;
+			}
+		}
+
+
+		for (int l = 1; l < m_nMatrices; l++) {
+			u = iFrom * m_nStates;
+			v = iFrom * m_nStates + l * m_nPatterns * m_nStates;
+			
+			for (int k = iFrom; k < iTo; k++) {
+
+				for (int i = 0; i < m_nStates; i++) {
+
+					fOutPartials[u] += fInPartials[v] * fProportions[l];
+					u++;
+					v++;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Calculates pattern log likelihoods at a node.
+	 * @param fPartials the partials used to calculate the likelihoods
+	 * @param fFrequencies an array of state frequencies
+	 * @param fOutLogLikelihoods an array into which the likelihoods will go
+	 */
+	//@Override
+	public void calculateLogLikelihoods(int iThread, double[] fFrequencies, int iFrom, int iTo)
+	{
+		double[] fPartials = m_fRootPartials[iThread];
+        int v = m_nStates * iFrom;
+		for (int k = iFrom; k < iTo; k++) {
+
+            double sum = 0.0;
+			for (int i = 0; i < m_nStates; i++) {
+
+				sum += fFrequencies[i] * fPartials[v];
+				v++;
+			}
+            m_fPatternLogLikelihoods[k] = Math.log(sum) + getLogScalingFactor(k);
+		}
+	}
+
+
+
+    /**
+     * initializes partial likelihood arrays.
+     *
+     * @param nNodeCount           the number of nodes in the tree
+     * @param nPatternCount        the number of patterns
+     * @param nMatrixCount         the number of matrices (i.e., number of categories)
+     * @param bIntegrateCategories whether sites are being integrated over all matrices
+     */
+	@Override
+    public void initialize(int nNodeCount, int nPatternCount, int nMatrixCount, 
+    		int [] weights, 
+    		List<Integer> iConstantPattern,
+			int nThreads,
+    		boolean bIntegrateCategories) {
+
+		this.weights = weights;
+		m_iConstantPattern = iConstantPattern;;
+        this.m_nNodes = nNodeCount;
+        this.m_nPatterns = nPatternCount;
+        this.m_nMatrices = nMatrixCount;
+
+        this.m_bIntegrateCategories = bIntegrateCategories;
+
+        if (bIntegrateCategories) {
+            m_nPartialsSize = nPatternCount * m_nStates * nMatrixCount;
+        } else {
+            m_nPartialsSize = nPatternCount * m_nStates;
+        }
+
+        m_fPartials = new double[2][nNodeCount][];
+
+        m_iCurrentMatrices = new int[nNodeCount];
+        m_iStoredMatrices = new int[nNodeCount];
+
+        m_iCurrentPartials = new int[nNodeCount];
+        m_iStoredPartials = new int[nNodeCount];
+
+        m_iStates = new int[nNodeCount][];
+
+        for (int i = 0; i < nNodeCount; i++) {
+            m_fPartials[0][i] = null;
+            m_fPartials[1][i] = null;
+
+            m_iStates[i] = null;
+        }
+
+        m_nMatrixSize = m_nStates * m_nStates;
+
+        m_fMatrices = new double[2][nNodeCount][nMatrixCount * m_nMatrixSize];
+        m_fPatternLogLikelihoods = new double[nPatternCount];
+        m_fRootPartials = new double[nThreads][nPatternCount * m_nStates];
+
+    }
+
+    /**
+     * cleans up and deallocates arrays.
+     */
+    public void finalize() throws java.lang.Throwable  {
+        m_nNodes = 0;
+        m_nPatterns = 0;
+        m_nMatrices = 0;
+
+        m_fPartials = null;
+        m_iCurrentPartials = null;
+        m_iStoredPartials = null;
+        m_iStates = null;
+        m_fMatrices = null;
+        m_iCurrentMatrices = null;
+        m_iStoredMatrices = null;
+
+        m_fScalingFactors = null;
+    }
+
+    @Override
+    public void setUseScaling(double  fScale) {
+   		m_bUseScaling = Math.abs(fScale - 1.0) < 1e-10;
+
+        if (m_bUseScaling) {
+            m_fScalingFactors = new double[2][m_nNodes][m_nPatterns];
+        }
+    }
+
+    /**
+     * Allocates partials for a node
+     */
+    public void createNodePartials(int iNodeIndex) {
+
+        this.m_fPartials[0][iNodeIndex] = new double[m_nPartialsSize];
+        this.m_fPartials[1][iNodeIndex] = new double[m_nPartialsSize];
+    }
+
+    /**
+     * Sets partials for a node
+     */
+    public void setNodePartials(int iNodeIndex, double[] fPartials) {
+
+        if (this.m_fPartials[0][iNodeIndex] == null) {
+            createNodePartials(iNodeIndex);
+        }
+        if (fPartials.length < m_nPartialsSize) {
+            int k = 0;
+            for (int i = 0; i < m_nMatrices; i++) {
+                System.arraycopy(fPartials, 0, this.m_fPartials[0][iNodeIndex], k, fPartials.length);
+                k += fPartials.length;
+            }
+        } else {
+            System.arraycopy(fPartials, 0, this.m_fPartials[0][iNodeIndex], 0, fPartials.length);
+        }
+    }
+
+    @Override
+    public void getNodePartials(int iNodeIndex, double[] fPartials) {
+        System.arraycopy(m_fPartials[m_iCurrentPartials[iNodeIndex]][iNodeIndex], 0, fPartials, 0, fPartials.length);
+    }
+
+    
+    /**
+     * Allocates states for a node
+     */
+    public void createNodeStates(int iNodeIndex) {
+
+        this.m_iStates[iNodeIndex] = new int[m_nPatterns];
+    }
+
+    /**
+     * Sets states for a node
+     */
+    public void setNodeStates(int iNodeIndex, int[] iStates) {
+
+        if (this.m_iStates[iNodeIndex] == null) {
+            createNodeStates(iNodeIndex);
+        }
+        System.arraycopy(iStates, 0, this.m_iStates[iNodeIndex], 0, m_nPatterns);
+    }
+
+    /**
+     * Gets states for a node
+     */
+    public void getNodeStates(int iNodeIndex, int[] iStates) {
+        System.arraycopy(this.m_iStates[iNodeIndex], 0, iStates, 0, m_nPatterns);
+    }
+    
+    @Override
+    public void setNodeMatrixForUpdate(int iNodeIndex) {
+        m_iCurrentMatrices[iNodeIndex] = 1 - m_iCurrentMatrices[iNodeIndex];
+
+    }
+
+
+    /**
+     * Sets probability matrix for a node
+     */
+    public void setNodeMatrix(int iNodeIndex, int iMatrixIndex, double[] fMatrix) {
+        System.arraycopy(fMatrix, 0, m_fMatrices[m_iCurrentMatrices[iNodeIndex]][iNodeIndex],
+                iMatrixIndex * m_nMatrixSize, m_nMatrixSize);
+    }
+
+	public void setPaddedNodeMatrices(int iNode, double[] fMatrix) {
+        System.arraycopy(fMatrix, 0, m_fMatrices[m_iCurrentMatrices[iNode]][iNode],
+                0, m_nMatrices * m_nMatrixSize);
+    }
+    
+    
+
+    /**
+     * Gets probability matrix for a node
+     */
+    public void getNodeMatrix(int iNodeIndex, int iMatrixIndex, double[] fMatrix) {
+        System.arraycopy(m_fMatrices[m_iCurrentMatrices[iNodeIndex]][iNodeIndex],
+                iMatrixIndex * m_nMatrixSize, fMatrix, 0, m_nMatrixSize);
+    }
+
+//    @Override
+//    public void setNodePartialsForUpdate(int iNodeIndex) {
+//        m_iCurrentPartials[iNodeIndex] = 1 - m_iCurrentPartials[iNodeIndex];
+//    }
+
+    /**
+     * Sets the currently updating node partials for node nodeIndex. This may
+     * need to repeatedly copy the partials for the different category partitions
+     */
+    public void setCurrentNodePartials(int iNodeIndex, double[] fPartials) {
+        if (fPartials.length < m_nPartialsSize) {
+            int k = 0;
+            for (int i = 0; i < m_nMatrices; i++) {
+                System.arraycopy(fPartials, 0, this.m_fPartials[m_iCurrentPartials[iNodeIndex]][iNodeIndex], k, fPartials.length);
+                k += fPartials.length;
+            }
+        } else {
+            System.arraycopy(fPartials, 0, this.m_fPartials[m_iCurrentPartials[iNodeIndex]][iNodeIndex], 0, fPartials.length);
+        }
+    }
+
+    /**
+     * Calculates partial likelihoods at a node.
+     *
+     * @param iNodeIndex1 the 'child 1' node
+     * @param iNodeIndex2 the 'child 2' node
+     * @param iNodeIndex3 the 'parent' node
+     */
+    public void calculateAllPartials(int [] cacheNode1, int [] cacheNode2, int [] cacheNode3, int cacheNodeCount, int iFrom, int iTo) {
+    	for (int i = 0; i < cacheNodeCount; i++) {
+    		calculatePartials(cacheNode1[i], cacheNode2[i], cacheNode3[i], iFrom, iTo);
+    	}
+    }
+    
+    public void calculatePartials(int iNodeIndex1, int iNodeIndex2, int iNodeIndex3, int iFrom, int iTo) {
+        m_iCurrentPartials[iNodeIndex3] = 1 - m_iStoredPartials[iNodeIndex3];
+        
+        if (m_iStates[iNodeIndex1] != null) {
+            if (m_iStates[iNodeIndex2] != null) {
+                calculateStatesStatesPruning(
+                        m_iStates[iNodeIndex1], m_fMatrices[m_iCurrentMatrices[iNodeIndex1]][iNodeIndex1],
+                        m_iStates[iNodeIndex2], m_fMatrices[m_iCurrentMatrices[iNodeIndex2]][iNodeIndex2],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex3]][iNodeIndex3], iFrom, iTo);
+            } else {
+                calculateStatesPartialsPruning(m_iStates[iNodeIndex1], m_fMatrices[m_iCurrentMatrices[iNodeIndex1]][iNodeIndex1],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex2]][iNodeIndex2], m_fMatrices[m_iCurrentMatrices[iNodeIndex2]][iNodeIndex2],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex3]][iNodeIndex3], iFrom, iTo);
+            }
+        } else {
+            if (m_iStates[iNodeIndex2] != null) {
+                calculateStatesPartialsPruning(m_iStates[iNodeIndex2], m_fMatrices[m_iCurrentMatrices[iNodeIndex2]][iNodeIndex2],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex1]][iNodeIndex1], m_fMatrices[m_iCurrentMatrices[iNodeIndex1]][iNodeIndex1],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex3]][iNodeIndex3], iFrom, iTo);
+            } else {
+                calculatePartialsPartialsPruning(m_fPartials[m_iCurrentPartials[iNodeIndex1]][iNodeIndex1], m_fMatrices[m_iCurrentMatrices[iNodeIndex1]][iNodeIndex1],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex2]][iNodeIndex2], m_fMatrices[m_iCurrentMatrices[iNodeIndex2]][iNodeIndex2],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex3]][iNodeIndex3], iFrom, iTo);
+            }
+        }
+
+        if (m_bUseScaling) {
+            scalePartials(iNodeIndex3, iFrom, iTo);
+        }
+
+//
+//        int k =0;
+//        for (int i = 0; i < patternCount; i++) {
+//            double f = 0.0;
+//
+//            for (int j = 0; j < stateCount; j++) {
+//                f += partials[currentPartialsIndices[nodeIndex3]][nodeIndex3][k];
+//                k++;
+//            }
+//            if (f == 0.0) {
+//                Logger.getLogger("error").severe("A partial likelihood (node index = " + nodeIndex3 + ", pattern = "+ i +") is zero for all states.");
+//            }
+//        }
+    }
+
+    /**
+     * Calculates partial likelihoods at a node.
+     *
+     * @param iNodeIndex1 the 'child 1' node
+     * @param iNodeIndex2 the 'child 2' node
+     * @param iNodeIndex3 the 'parent' node
+     * @param iMatrixMap  a map of which matrix to use for each pattern (can be null if integrating over categories)
+     */
+    public void calculatePartials(int iNodeIndex1, int iNodeIndex2, int iNodeIndex3, int[] iMatrixMap, int iFrom, int iTo) {
+        if (m_iStates[iNodeIndex1] != null) {
+            if (m_iStates[iNodeIndex2] != null) {
+                calculateStatesStatesPruning(
+                        m_iStates[iNodeIndex1], m_fMatrices[m_iCurrentMatrices[iNodeIndex1]][iNodeIndex1],
+                        m_iStates[iNodeIndex2], m_fMatrices[m_iCurrentMatrices[iNodeIndex2]][iNodeIndex2],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex3]][iNodeIndex3], iMatrixMap, iFrom, iTo);
+            } else {
+                calculateStatesPartialsPruning(
+                        m_iStates[iNodeIndex1], m_fMatrices[m_iCurrentMatrices[iNodeIndex1]][iNodeIndex1],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex2]][iNodeIndex2], m_fMatrices[m_iCurrentMatrices[iNodeIndex2]][iNodeIndex2],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex3]][iNodeIndex3], iMatrixMap, iFrom, iTo);
+            }
+        } else {
+            if (m_iStates[iNodeIndex2] != null) {
+                calculateStatesPartialsPruning(
+                        m_iStates[iNodeIndex2], m_fMatrices[m_iCurrentMatrices[iNodeIndex2]][iNodeIndex2],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex1]][iNodeIndex1], m_fMatrices[m_iCurrentMatrices[iNodeIndex1]][iNodeIndex1],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex3]][iNodeIndex3], iMatrixMap, iFrom, iTo);
+            } else {
+                calculatePartialsPartialsPruning(
+                        m_fPartials[m_iCurrentPartials[iNodeIndex1]][iNodeIndex1], m_fMatrices[m_iCurrentMatrices[iNodeIndex1]][iNodeIndex1],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex2]][iNodeIndex2], m_fMatrices[m_iCurrentMatrices[iNodeIndex2]][iNodeIndex2],
+                        m_fPartials[m_iCurrentPartials[iNodeIndex3]][iNodeIndex3], iMatrixMap, iFrom, iTo);
+            }
+        }
+
+        if (m_bUseScaling) {
+            scalePartials(iNodeIndex3, iFrom, iTo);
+        }
+    }
+
+
+
+    public void integratePartials(int iNodeIndex, double[] fProportions, int iThread, int iFrom, int iTo) {
+    	double [] fOutPartials = m_fRootPartials[iThread];
+        calculateIntegratePartials(m_fPartials[m_iCurrentPartials[iNodeIndex]][iNodeIndex], fProportions, fOutPartials, iFrom, iTo);
+    }
+
+
+    /**
+     * Scale the partials at a given node. This uses a scaling suggested by Ziheng Yang in
+     * Yang (2000) J. Mol. Evol. 51: 423-432
+     * <p/>
+     * This function looks over the partial likelihoods for each state at each pattern
+     * and finds the largest. If this is less than the scalingThreshold (currently set
+     * to 1E-40) then it rescales the partials for that pattern by dividing by this number
+     * (i.e., normalizing to between 0, 1). It then stores the log of this scaling.
+     * This is called for every internal node after the partials are calculated so provides
+     * most of the performance hit. Ziheng suggests only doing this on a proportion of nodes
+     * but this sounded like a headache to organize (and he doesn't use the threshold idea
+     * which improves the performance quite a bit).
+     *
+     * @param iNodeIndex
+     */
+    protected void scalePartials(int iNodeIndex, int iFrom, int iTo) {
+//        int v = 0;
+//    	double [] fPartials = m_fPartials[m_iCurrentPartialsIndices[iNodeIndex]][iNodeIndex];
+//        for (int i = 0; i < m_nPatternCount; i++) {
+//            for (int k = 0; k < m_nMatrixCount; k++) {
+//                for (int j = 0; j < m_nStateCount; j++) {
+//                	fPartials[v] *= SCALE;
+//                	v++;
+//                }
+//            }
+//        }
+        int u = m_nStates * iFrom;
+
+        for (int i = iFrom; i < iTo; i++) {
+
+            double scaleFactor = 0.0;
+            int v = u;
+            for (int k = 0; k < m_nMatrices; k++) {
+                for (int j = 0; j < m_nStates; j++) {
+                    if (m_fPartials[m_iCurrentPartials[iNodeIndex]][iNodeIndex][v] > scaleFactor) {
+                        scaleFactor = m_fPartials[m_iCurrentPartials[iNodeIndex]][iNodeIndex][v];
+                    }
+                    v++;
+                }
+                v += (m_nPatterns - 1) * m_nStates;
+            }
+
+            if (scaleFactor < m_fScalingThreshold) {
+
+                v = u;
+                for (int k = 0; k < m_nMatrices; k++) {
+                    for (int j = 0; j < m_nStates; j++) {
+                        m_fPartials[m_iCurrentPartials[iNodeIndex]][iNodeIndex][v] /= scaleFactor;
+                        v++;
+                    }
+                    v += (m_nPatterns - 1) * m_nStates;
+                }
+                m_fScalingFactors[m_iCurrentPartials[iNodeIndex]][iNodeIndex][i] = Math.log(scaleFactor);
+
+            } else {
+                m_fScalingFactors[m_iCurrentPartials[iNodeIndex]][iNodeIndex][i] = 0.0;
+            }
+            u += m_nStates;
+
+
+        }
+    }
+
+    /**
+     * This function returns the scaling factor for that pattern by summing over
+     * the log scalings used at each node. If scaling is off then this just returns
+     * a 0.
+     *
+     * @return the log scaling factor
+     */
+    public double getLogScalingFactor(int iPattern) {
+//    	if (m_bUseScaling) {
+//    		return -(m_nNodeCount/2) * Math.log(SCALE);
+//    	} else {
+//    		return 0;
+//    	}        
+    	double logScalingFactor = 0.0;
+        if (m_bUseScaling) {
+            for (int i = 0; i < m_nNodes; i++) {
+                logScalingFactor += m_fScalingFactors[m_iCurrentPartials[i]][i][iPattern];
+            }
+        }
+        return logScalingFactor;
+    }
+
+    /**
+     * Gets the partials for a particular node.
+     *
+     * @param iNodeIndex   the node
+     * @param fOutPartials an array into which the partials will go
+     */
+    public void getPartials(int iNodeIndex, double[] fOutPartials) {
+        double[] partials1 = m_fPartials[m_iCurrentPartials[iNodeIndex]][iNodeIndex];
+
+        System.arraycopy(partials1, 0, fOutPartials, 0, m_nPartialsSize);
+    }
+
+    /**
+     * Store current state
+     */
+	@Override
+	public void restore() {
+        // Rather than copying the stored stuff back, just swap the pointers...
+        int[] iTmp1 = m_iCurrentMatrices;
+        m_iCurrentMatrices = m_iStoredMatrices;
+        m_iStoredMatrices = iTmp1;
+
+        int[] iTmp2 = m_iCurrentPartials;
+        m_iCurrentPartials = m_iStoredPartials;
+        m_iStoredPartials = iTmp2;
+    }
+
+    public void unstore() {
+        System.arraycopy(m_iStoredMatrices, 0, m_iCurrentMatrices, 0, m_nNodes);
+        System.arraycopy(m_iStoredPartials, 0, m_iCurrentPartials, 0, m_nNodes);
+    }
+    
+    /**
+     * Restore the stored state
+     */
+	@Override
+	public void store() {
+        System.arraycopy(m_iCurrentMatrices, 0, m_iStoredMatrices, 0, m_nNodes);
+        System.arraycopy(m_iCurrentPartials, 0, m_iStoredPartials, 0, m_nNodes);
+    }
+
+
+	@Override
+	public double calcPartialLogP(int iFrom, int iTo) {
+        double logP = 0.0;
+//        if (m_bAscertainedSitePatterns) {
+//        	return 0;
+////            double ascertainmentCorrection = ((AscertainedAlignment)m_data.get()).getAscertainmentCorrection(m_fPatternLogLikelihoods);
+////            for (int i = iFrom; i < iTo; i++) {
+////            	logP += (m_fPatternLogLikelihoods[i] - ascertainmentCorrection) * m_data.get().getPatternWeight(i);
+////            }
+//        } else {
+            for (int i = iFrom; i < iTo; i++) {
+	            logP += m_fPatternLogLikelihoods[i] * weights[i];
+	        }
+//        }
+        return logP;
+	}
+
+	
+	@Override
+	public double [] getPatternLogLikelihoods() {
+		return m_fPatternLogLikelihoods;
+	}
+
+
+	//@Override
+	void calcInvarCorrection(double fProportionInvariant, int iThread) {
+    	double [] fRootPartials = m_fRootPartials[iThread];
+    	for (int i : m_iConstantPattern) {
+    		if (fRootPartials[i] != 0) {
+    			fRootPartials[i] += fProportionInvariant;
+    		}
+    	}
+	}
+
+
+	@Override
+	double calcLogP(int iThread, 
+			int [] cacheNode1, int [] cacheNode2, int [] cacheNode3, int cacheNodeCount, 
+			int iFrom, int iTo,	int rootNodeNr,
+			double[] proportions, double fProportionInvariant,
+			double[] frequencies) {
+		calculateAllPartials(cacheNode1, cacheNode2, cacheNode3, cacheNodeCount, iFrom, iTo);
+        // process root of the beast.tree -
+        integratePartials(rootNodeNr, proportions, iThread, iFrom, iTo);
+
+        if (m_iConstantPattern != null) { // && !SiteModel.g_bUseOriginal) {
+        	//double [] fRootPartials = m_fRootPartials[m_iThread];
+        	// some portion of sites is invariant, so adjust root partials for this
+        	calcInvarCorrection(fProportionInvariant, iThread);
+        }
+        calculateLogLikelihoods(iThread, frequencies, iFrom, iTo);
+        double logP = calcPartialLogP(iFrom, iTo);
+        return logP;
+	}
+
+//	@Override
+//    public void calcRootPsuedoRootPartials(double[] fFrequencies, int iNode, double [] fPseudoPartials) {
+//		int u = 0;
+//		double [] fInPartials = m_fPartials[m_iCurrentPartials[iNode]][iNode];
+//		for (int k = 0; k < m_nPatterns; k++) {
+//			for (int l = 0; l < m_nMatrices; l++) {
+//				for (int i = 0; i < m_nStates; i++) {
+//					fPseudoPartials[u] = fInPartials[u] * fFrequencies[i];
+//					u++;
+//				}
+//			}
+//		}
+//    }
+//	@Override
+//    public void calcNodePsuedoRootPartials(double[] fInPseudoPartials, int iNode, double [] fOutPseudoPartials) {
+//		double [] fPartials = m_fPartials[m_iCurrentPartials[iNode]][iNode];
+//		double [] fOldPartials = m_fPartials[m_iStoredPartials[iNode]][iNode];
+//		int nMaxK = m_nPatterns * m_nMatrices * m_nStates; 
+//		for (int k = 0; k < nMaxK; k++) {
+//			fOutPseudoPartials[k] = fInPseudoPartials[k] * fPartials[k] / fOldPartials[k];
+//		}
+//	}
+//    
+//	@Override
+//    public void calcPsuedoRootPartials(double [] fParentPseudoPartials, int iNode, double [] fPseudoPartials) {
+//		int v = 0;
+//		int u = 0;
+//		double [] fMatrices = m_fMatrices[m_iCurrentMatrices[iNode]][iNode];
+//		for (int k = 0; k < m_nPatterns; k++) {
+//			for (int l = 0; l < m_nMatrices; l++) {
+//				for (int i = 0; i < m_nStates; i++) {
+//					int w = 0;
+//					double fSum = 0;
+//					for (int j = 0; j < m_nStates; j++) {
+//					      fSum += fParentPseudoPartials[u+j] * fMatrices[w + i];
+//					      w+=m_nStates;
+//					}
+//					fPseudoPartials[v] = fSum;
+//					v++;
+////					int w = l * m_nMatrixSize;
+////					double fSum = 0;
+////					for (int j = 0; j < m_nStates; j++) {
+////					      fSum += fParentPseudoPartials[u+j] * fMatrices[w+j];
+////					}
+////					fPseudoPartials[v] = fSum;
+////					v++;
+//				}
+//				u += m_nStates;
+//			}
+//		}
+//    }
+//
+//
+//    @Override
+//    void integratePartialsP(double [] fInPartials, double [] fProportions, double [] m_fRootPartials, int iFrom, int iTo) {
+//		int nMaxK = m_nPatterns * m_nStates;
+//		for (int k = 0; k < nMaxK; k++) {
+//			m_fRootPartials[k] = fInPartials[k] * fProportions[0];
+//		}
+//
+//		for (int l = 1; l < m_nMatrices; l++) {
+//			int n = nMaxK * l;
+//			for (int k = 0; k < nMaxK; k++) {
+//				m_fRootPartials[k] += fInPartials[n+k] * fProportions[l];
+//			}
+//		}
+//    } // integratePartials
+//
+//	/**
+//	 * Calculates pattern log likelihoods at a node.
+//	 * @param fPartials the partials used to calculate the likelihoods
+//	 * @param fFrequencies an array of state frequencies
+//	 * @param fOutLogLikelihoods an array into which the likelihoods will go
+//	 */
+//    @Override
+//	public void calculateLogLikelihoodsP(double[] fPartials,double[] fOutLogLikelihoods, int iFrom, int iTo)
+//	{
+//        int v = m_nStates * iFrom;
+//		for (int k = iFrom; k < iTo; k++) {
+//            double sum = 0.0;
+//			for (int i = 0; i < m_nStates; i++) {
+//				sum += fPartials[v];
+//				v++;
+//			}
+//            fOutLogLikelihoods[k] = Math.log(sum) + getLogScalingFactor(k);
+//		}
+//	}
+//	
+//	
+//	//    @Override
+////    LikelihoodCore feelsGood() {return null;}
+} // class BeerLikelihoodCore
diff --git a/src/beast/evolution/likelihood/ThreadedBeerLikelihoodCore4.java b/src/beast/evolution/likelihood/ThreadedBeerLikelihoodCore4.java
new file mode 100644
index 0000000..e22a4e6
--- /dev/null
+++ b/src/beast/evolution/likelihood/ThreadedBeerLikelihoodCore4.java
@@ -0,0 +1,293 @@
+package beast.evolution.likelihood;
+
+/** nucleotide implementation of standard likelihood core **/
+public class ThreadedBeerLikelihoodCore4 extends ThreadedBeerLikelihoodCore {
+
+	public ThreadedBeerLikelihoodCore4() {
+		super(4);
+	}
+
+	/**
+	 * Calculates partial likelihoods at a node when both children have states.
+	 */
+	@Override
+	protected void calculateStatesStatesPruning(int[] iStates1, double[] fMatrices1,
+												int[] iStates2, double[] fMatrices2,
+												double[] fPartials3, int iFrom, int iTo)
+	{
+
+		for (int l = 0; l < m_nMatrices; l++) {
+			int v = 4 * iFrom  +  4 * l * m_nPatterns;
+
+			for (int k = iFrom; k < iTo; k++) {
+
+				int state1 = iStates1[k];
+				int state2 = iStates2[k];
+
+				int w = l * m_nMatrixSize;
+
+				if (state1 < 4 && state2 < 4) {
+
+					fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+					v++;	w += 4;
+					fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+					v++;	w += 4;
+					fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+					v++;	w += 4;
+					fPartials3[v] = fMatrices1[w + state1] * fMatrices2[w + state2];
+					v++;	w += 4;
+
+				} else if (state1 < 4) {
+					// child 2 has a gap or unknown state so don't use it
+
+					fPartials3[v] = fMatrices1[w + state1];
+					v++;	w += 4;
+					fPartials3[v] = fMatrices1[w + state1];
+					v++;	w += 4;
+					fPartials3[v] = fMatrices1[w + state1];
+					v++;	w += 4;
+					fPartials3[v] = fMatrices1[w + state1];
+					v++;	w += 4;
+
+				} else if (state2 < 4) {
+					// child 2 has a gap or unknown state so don't use it
+					fPartials3[v] = fMatrices2[w + state2];
+					v++;	w += 4;
+					fPartials3[v] = fMatrices2[w + state2];
+					v++;	w += 4;
+					fPartials3[v] = fMatrices2[w + state2];
+					v++;	w += 4;
+					fPartials3[v] = fMatrices2[w + state2];
+					v++;	w += 4;
+
+				} else {
+					// both children have a gap or unknown state so set partials to 1
+					fPartials3[v] = 1.0;
+					v++;
+					fPartials3[v] = 1.0;
+					v++;
+					fPartials3[v] = 1.0;
+					v++;
+					fPartials3[v] = 1.0;
+					v++;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Calculates partial likelihoods at a node when one child has states and one has partials.
+	 */
+	@Override
+	protected void calculateStatesPartialsPruning(	int[] iStates1, double[] fMatrices1,
+													double[] fPartials2, double[] fMatrices2,
+													double[] fPartials3, int iFrom, int iTo)
+	{
+
+		double sum;//, tmp;
+
+
+		for (int l = 0; l < m_nMatrices; l++) {
+			int v = 4 * iFrom  +  4 * l * m_nPatterns;
+			int u = v;
+			for (int k = iFrom; k < iTo; k++) {
+
+				int state1 = iStates1[k];
+
+                int w = l * m_nMatrixSize;
+
+				if (state1 < 4) {
+
+
+					sum =	fMatrices2[w] * fPartials2[v];
+					sum +=	fMatrices2[w + 1] * fPartials2[v + 1];
+					sum +=	fMatrices2[w + 2] * fPartials2[v + 2];
+					sum +=	fMatrices2[w + 3] * fPartials2[v + 3];
+					fPartials3[u] = fMatrices1[w + state1] * sum;	u++;
+
+					sum =	fMatrices2[w + 4] * fPartials2[v];
+					sum +=	fMatrices2[w + 5] * fPartials2[v + 1];
+					sum +=	fMatrices2[w + 6] * fPartials2[v + 2];
+					sum +=	fMatrices2[w + 7] * fPartials2[v + 3];
+					fPartials3[u] = fMatrices1[w + 4 + state1] * sum;	u++;
+
+					sum =	fMatrices2[w + 8] * fPartials2[v];
+					sum +=	fMatrices2[w + 9] * fPartials2[v + 1];
+					sum +=	fMatrices2[w + 10] * fPartials2[v + 2];
+					sum +=	fMatrices2[w + 11] * fPartials2[v + 3];
+					fPartials3[u] = fMatrices1[w + 8 + state1] * sum;	u++;
+
+					sum =	fMatrices2[w + 12] * fPartials2[v];
+					sum +=	fMatrices2[w + 13] * fPartials2[v + 1];
+					sum +=	fMatrices2[w + 14] * fPartials2[v + 2];
+					sum +=	fMatrices2[w + 15] * fPartials2[v + 3];
+					fPartials3[u] = fMatrices1[w + 12 + state1] * sum;	u++;
+
+					v += 4;
+
+				} else {
+					// Child 1 has a gap or unknown state so don't use it
+
+
+					sum =	fMatrices2[w] * fPartials2[v];
+					sum +=	fMatrices2[w + 1] * fPartials2[v + 1];
+					sum +=	fMatrices2[w + 2] * fPartials2[v + 2];
+					sum +=	fMatrices2[w + 3] * fPartials2[v + 3];
+					fPartials3[u] = sum;	u++;
+
+					sum =	fMatrices2[w + 4] * fPartials2[v];
+					sum +=	fMatrices2[w + 5] * fPartials2[v + 1];
+					sum +=	fMatrices2[w + 6] * fPartials2[v + 2];
+					sum +=	fMatrices2[w + 7] * fPartials2[v + 3];
+					fPartials3[u] = sum;	u++;
+
+					sum =	fMatrices2[w + 8] * fPartials2[v];
+					sum +=	fMatrices2[w + 9] * fPartials2[v + 1];
+					sum +=	fMatrices2[w + 10] * fPartials2[v + 2];
+					sum +=	fMatrices2[w + 11] * fPartials2[v + 3];
+					fPartials3[u] = sum;	u++;
+
+					sum =	fMatrices2[w + 12] * fPartials2[v];
+					sum +=	fMatrices2[w + 13] * fPartials2[v + 1];
+					sum +=	fMatrices2[w + 14] * fPartials2[v + 2];
+					sum +=	fMatrices2[w + 15] * fPartials2[v + 3];
+					fPartials3[u] = sum;	u++;
+
+					v += 4;
+				}
+			}
+		}
+	}
+
+	/**
+	 * Calculates partial likelihoods at a node when both children have partials.
+	 */
+	@Override
+	protected void calculatePartialsPartialsPruning(double[] fPartials1, double[] fMatrices1,
+													double[] fPartials2, double[] fMatrices2,
+													double[] fPartials3, int iFrom, int iTo)
+	{
+		double sum1, sum2;
+
+
+		for (int l = 0; l < m_nMatrices; l++) {
+			int v = 4 * iFrom  +  4 * l * m_nPatterns;
+			int u = v;
+
+			for (int k = iFrom; k < iTo; k++) {
+
+                int w = l * m_nMatrixSize;
+
+				sum1 = fMatrices1[w] * fPartials1[v];
+				sum2 = fMatrices2[w] * fPartials2[v];
+				sum1 += fMatrices1[w + 1] * fPartials1[v + 1];
+				sum2 += fMatrices2[w + 1] * fPartials2[v + 1];
+				sum1 += fMatrices1[w + 2] * fPartials1[v + 2];
+				sum2 += fMatrices2[w + 2] * fPartials2[v + 2];
+				sum1 += fMatrices1[w + 3] * fPartials1[v + 3];
+				sum2 += fMatrices2[w + 3] * fPartials2[v + 3];
+				fPartials3[u] = sum1 * sum2; u++;
+
+				sum1 = fMatrices1[w + 4] * fPartials1[v];
+				sum2 = fMatrices2[w + 4] * fPartials2[v];
+				sum1 += fMatrices1[w + 5] * fPartials1[v + 1];
+				sum2 += fMatrices2[w + 5] * fPartials2[v + 1];
+				sum1 += fMatrices1[w + 6] * fPartials1[v + 2];
+				sum2 += fMatrices2[w + 6] * fPartials2[v + 2];
+				sum1 += fMatrices1[w + 7] * fPartials1[v + 3];
+				sum2 += fMatrices2[w + 7] * fPartials2[v + 3];
+				fPartials3[u] = sum1 * sum2; u++;
+
+				sum1 = fMatrices1[w + 8] * fPartials1[v];
+				sum2 = fMatrices2[w + 8] * fPartials2[v];
+				sum1 += fMatrices1[w + 9] * fPartials1[v + 1];
+				sum2 += fMatrices2[w + 9] * fPartials2[v + 1];
+				sum1 += fMatrices1[w + 10] * fPartials1[v + 2];
+				sum2 += fMatrices2[w + 10] * fPartials2[v + 2];
+				sum1 += fMatrices1[w + 11] * fPartials1[v + 3];
+				sum2 += fMatrices2[w + 11] * fPartials2[v + 3];
+				fPartials3[u] = sum1 * sum2; u++;
+
+				sum1 = fMatrices1[w + 12] * fPartials1[v];
+				sum2 = fMatrices2[w + 12] * fPartials2[v];
+				sum1 += fMatrices1[w + 13] * fPartials1[v + 1];
+				sum2 += fMatrices2[w + 13] * fPartials2[v + 1];
+				sum1 += fMatrices1[w + 14] * fPartials1[v + 2];
+				sum2 += fMatrices2[w + 14] * fPartials2[v + 2];
+				sum1 += fMatrices1[w + 15] * fPartials1[v + 3];
+				sum2 += fMatrices2[w + 15] * fPartials2[v + 3];
+				fPartials3[u] = sum1 * sum2; u++;
+
+				v += 4;
+			}
+		}
+	}
+
+
+
+
+
+//	@Override
+//    public void calcRootPsuedoRootPartials(double[] fFrequencies, int iNode, double [] fPseudoPartials) {
+//		int u = 0;
+//		double [] fInPartials = m_fPartials[m_iCurrentPartials[iNode]][iNode];
+//		for (int k = 0; k < m_nPatterns * m_nMatrices; k++) {
+//			fPseudoPartials[u] = fInPartials[u] * fFrequencies[0];
+//			fPseudoPartials[u+1] = fInPartials[u+1] * fFrequencies[1];
+//			fPseudoPartials[u+2] = fInPartials[u+2] * fFrequencies[2];
+//			fPseudoPartials[u+3] = fInPartials[u+3] * fFrequencies[3];
+//			u+=4;
+//		}
+//    }
+//    
+//	@Override
+//    public void calcPsuedoRootPartials(double [] fParentPseudoPartials, int iNode, double [] fPseudoPartials) {
+//		int v = 0;
+//		int u = 0;
+//		double [] fMatrices = m_fMatrices[m_iCurrentMatrices[iNode]][iNode];
+//		for (int k = 0; k < m_nPatterns; k++) {
+//			for (int l = 0; l < m_nMatrices; l++) {
+//				int w = l * m_nMatrixSize;
+//				fPseudoPartials[v] = fParentPseudoPartials[u] * fMatrices[w] +
+//					fParentPseudoPartials[u+1] * fMatrices[w+1] +
+//					fParentPseudoPartials[u+2] * fMatrices[w+2] +
+//					fParentPseudoPartials[u+3] * fMatrices[w+3];
+//				w += 4;
+//				fPseudoPartials[v+1] = fParentPseudoPartials[u] * fMatrices[w] +
+//						fParentPseudoPartials[u+1] * fMatrices[w+1] +
+//						fParentPseudoPartials[u+2] * fMatrices[w+2] +
+//						fParentPseudoPartials[u+3] * fMatrices[w+3];
+//				w += 4;
+//				fPseudoPartials[v+1] = fParentPseudoPartials[u] * fMatrices[w] +
+//					fParentPseudoPartials[u+1] * fMatrices[w+1] +
+//					fParentPseudoPartials[u+2] * fMatrices[w+2] +
+//					fParentPseudoPartials[u+3] * fMatrices[w+3];
+//				w += 4;
+//				fPseudoPartials[v+1] = fParentPseudoPartials[u] * fMatrices[w] +
+//					fParentPseudoPartials[u+1] * fMatrices[w+1] +
+//					fParentPseudoPartials[u+2] * fMatrices[w+2] +
+//					fParentPseudoPartials[u+3] * fMatrices[w+3];
+//				v += 4;
+//				u += 4;
+//			}
+//		}
+//    }
+//
+//	/**
+//	 * Calculates pattern log likelihoods at a node.
+//	 * @param fPartials the partials used to calculate the likelihoods
+//	 * @param fFrequencies an array of state frequencies
+//	 * @param fOutLogLikelihoods an array into which the likelihoods will go
+//	 */
+//    @Override
+//	public void calculateLogLikelihoodsP(double[] fPartials,double[] fOutLogLikelihoods, int iFrom, int iTo)
+//	{
+//        int v = 4 * iFrom;
+//		for (int k = iFrom; k < iTo; k++) {
+//            double sum = fPartials[v] + fPartials[v+1] + fPartials[v + 2] + fPartials[v + 3];
+//            v +=4;
+//            fOutLogLikelihoods[k] = Math.log(sum) + getLogScalingFactor(k);
+//		}
+//	}
+
+}
diff --git a/src/beast/evolution/likelihood/ThreadedLikelihoodCore.java b/src/beast/evolution/likelihood/ThreadedLikelihoodCore.java
new file mode 100644
index 0000000..05587fc
--- /dev/null
+++ b/src/beast/evolution/likelihood/ThreadedLikelihoodCore.java
@@ -0,0 +1,152 @@
+
+/*
+ * File LikelihoodCore.java
+ *
+ * Copyright (C) 2010 Remco Bouckaert remco at cs.auckland.ac.nz
+ *
+ * This file is part of BEAST2.
+ * See the NOTICE file distributed with this work for additional
+ * information regarding copyright ownership and licensing.
+ *
+ * BEAST is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ *  BEAST is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with BEAST; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA  02110-1301  USA
+ */
+package beast.evolution.likelihood;
+
+import java.util.List;
+
+/** The likelihood core is the class that performs the calculations
+ * in the peeling algorithm (see Felsenstein, Joseph (1981). 
+ * Evolutionary trees from DNA sequences: a maximum likelihood approach. 
+ * J Mol Evol 17 (6): 368-376.). It does this by calculating the partial
+ * results for all sites, node by node. The order in which the nodes
+ * are visited is controlled by the TreeLikelihood. T
+ * 
+ * In order to reuse computations of previous likelihood calculations,
+ * a current state, and a stored state are maintained. Again, the TreeLikelihood
+ * controls when to update from current to stored and vice versa. So, in
+ * LikelihoodCore implementations, duplicates need to be kept for all partials.
+ * Also, a set of indices to indicate which of the data is stored state and which
+ * is current state is commonly the most efficient way to sort out which is which.
+ *   
+ *   
+ */
+
+abstract public class ThreadedLikelihoodCore {
+
+	/** reserve memory for partials, indices and other 
+	 * data structures required by the core **/
+	abstract public void initialize(int nNodeCount, int nPatternCount, int nMatrixCount, 
+			int [] weights,
+			List<Integer> iConstantPatterns,
+			int nThreads,
+			boolean bIntegrateCategories);
+	
+	/** clean up after last likelihood calculation, if at all required **/
+	abstract public void finalize() throws java.lang.Throwable;
+
+	/** reserve memory for partials for node with number iNode **/
+	abstract public void createNodePartials(int iNode);
+	
+	
+	/** indicate that the partials for node 
+	 * iNode is about the be changed, that is, that the stored
+	 * state for node iNode cannot be reused **/
+	//abstract public void setNodePartialsForUpdate(int iNode);
+	/** assign values of partials for node with number iNode **/
+	abstract public void setNodePartials(int iNode, double[] fPartials);
+    abstract public void getNodePartials(int iNode, double[] fPartials);
+    //abstract public void setCurrentNodePartials(int iNode, double[] fPartials);
+
+    /** reserve memory for states for node with number iNode **/
+	//abstract public void createNodeStates(int iNode);
+
+	/** assign values of states for node with number iNode **/
+	abstract public void setNodeStates(int iNode, int[] iStates);
+	
+	/** indicate that the probability transition matrix for node 
+	 * iNode is about the be changed, that is, that the stored
+	 * state for node iNode cannot be reused **/
+	abstract public void setNodeMatrixForUpdate(int iNode);
+	
+    /** assign values of states for probability transition matrix for node with number iNode **/
+	abstract public void setNodeMatrix(int iNode, int iMatrixIndex, double[] fMatrix);
+    /** assign values of states for probability transition matrices 
+     * padded with 1s for dealing with unknown characters for node with number iNode **/
+	//abstract public void setPaddedNodeMatrices(int iNode, double[] fMatrix);
+
+
+    
+    /** indicate that the topology of the tree chanced so the cache 
+	 * data structures cannot be reused **/
+    public void setNodeStatesForUpdate(int iNode) {};
+    
+
+    
+	/** flag to indicate whether scaling should be used in the
+	 * likelihood calculation. Scaling can help in dealing with
+	 * numeric issues (underflow).
+	 */
+	boolean m_bUseScaling = false;
+	abstract public void setUseScaling(double fScale);
+	public boolean getUseScaling() {return m_bUseScaling;}
+	/** return the cumulative scaling effect. Should be zero if no scaling is used **/
+    abstract public double getLogScalingFactor(int iPattern);
+
+    /** Calculate partials for node iNode3, with children iNode1 and iNode2. 
+     * NB Depending on whether the child nodes contain states or partials, the
+     * calculation differs-**/
+    abstract public void calculatePartials(int iNode1, int iNode2, int iNode3, int iFrom, int iTo);
+    abstract public void calculateAllPartials(int [] iNode1, int [] iNode2, int [] iNode3, int nCacheCount, int iFrom, int iTo);
+    //abstract public void calculatePartials(int iNode1, int iNode2, int iNode3, int[] iMatrixMap);
+    /** integrate partials over categories (if any). **/
+//    abstract public void integratePartials(int iNode, double[] fProportions, int iThread, int iFrom, int iTo);
+
+    /** calculate log likelihoods at the root of the tree,
+     * using fFrequencies as root node distribution.
+     * fOutLogLikelihoods contains the resulting probabilities for each of 
+     * the patterns **/
+//	abstract public void calculateLogLikelihoods(int iThread, double[] fFrequencies, int iFrom, int iTo);
+	
+    
+//    public void processStack() {}
+//	abstract protected void calculateIntegratePartials(double[] fInPartials, double[] fProportions, double[] fOutPartials, int iFrom, int iTo);
+//    abstract public void calcRootPsuedoRootPartials(double[] fFrequencies, int iNode, double [] fPseudoPartials);
+//    abstract public void calcNodePsuedoRootPartials(double[] fInPseudoPartials, int iNode, double [] fOutPseudoPartials);
+//    abstract public void calcPsuedoRootPartials(double [] fParentPseudoPartials, int iNode, double [] fPseudoPartials);
+//    abstract void integratePartialsP(double [] fInPartials, double [] fProportions, double [] m_fRootPartials, int iFrom, int iTo);
+//    abstract void calculateLogLikelihoodsP(double[] fPartials,double[] fOutLogLikelihoods, int iFrom, int iTo);
+    
+    /** store current state **/
+    abstract public void store();
+    /** reset current state to stored state, only used when switching from non-scaled to scaled or vice versa **/
+    abstract public void unstore();
+    /** restore state **/
+    abstract public void restore();
+//    /** do internal diagnosics, and suggest an alternative core if appropriate **/ 
+//    abstract LikelihoodCore feelsGood();
+
+	abstract public double calcPartialLogP(int iFrom, int iTo);
+
+	abstract public double [] getPatternLogLikelihoods();
+
+//	abstract void calcInvarCorrection(double fProportionInvariant, int iThread);
+
+	abstract double calcLogP(int iThread, 
+			int [] cacheNode1, int [] cacheNode2, int [] cacheNode3, int cacheNodeCount, 
+			int iFrom, int iTo,	int rootNodeNr,
+			double[] proportions, double fProportionInvariant,
+			double[] frequencies);
+}
diff --git a/src/beast/evolution/likelihood/ThreadedTreeLikelihood.java b/src/beast/evolution/likelihood/ThreadedTreeLikelihood.java
new file mode 100644
index 0000000..f584f82
--- /dev/null
+++ b/src/beast/evolution/likelihood/ThreadedTreeLikelihood.java
@@ -0,0 +1,363 @@
+/*
+* File TreeLikelihood.java
+*
+* Copyright (C) 2010 Remco Bouckaert remco at cs.auckland.ac.nz
+*
+* This file is part of BEAST2.
+* See the NOTICE file distributed with this work for additional
+* information regarding copyright ownership and licensing.
+*
+* BEAST is free software; you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+*  BEAST is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with BEAST; if not, write to the
+* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+* Boston, MA  02110-1301  USA
+*/
+
+
+
+package beast.evolution.likelihood;
+
+
+
+
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.RejectedExecutionException;
+
+import beast.app.BeastMCMC;
+import beast.app.beauti.Beauti;
+import beast.core.BEASTInterface;
+import beast.core.Description;
+import beast.core.Input;
+import beast.core.State;
+import beast.core.util.Log;
+import beast.evolution.alignment.Alignment;
+import beast.evolution.alignment.FilteredAlignment;
+import beast.evolution.sitemodel.SiteModel;
+import beast.evolution.substitutionmodel.SubstitutionModel;
+
+
+ at Description("Calculates the likelihood of sequence data on a beast.tree given a site and substitution model using " +
+		"a variant of the 'peeling algorithm'. For details, see" +
+		"Felsenstein, Joseph (1981). Evolutionary trees from DNA sequences: a maximum likelihood approach. J Mol Evol 17 (6): 368-376.")
+public class ThreadedTreeLikelihood extends GenericTreeLikelihood {
+    final public Input<Boolean> useAmbiguitiesInput = new Input<>("useAmbiguities", "flag to indicate leafs that sites containing ambigue states should be handled instead of ignored (the default)", false);
+    
+    final public Input<Integer> maxNrOfThreadsInput = new Input<>("threads","maximum number of threads to use, if less than 1 the number of threads in BeastMCMC is used (default -1)", -1);
+
+    final public Input<String> proportionsInput = new Input<>("proportions", "specifies proportions of patterns used per thread as space "
+    		+ "delimted string. This is useful when using a mixture of BEAGLE devices that run at different speeds, e.g GPU and CPU. "
+    		+ "The string is duplicated if there are more threads than proportions specified. For example, "
+    		+ "'1 2' as well as '33 66' with 2 threads specifies that the first thread gets a third of the patterns and the second "
+    		+ "two thirds. With 3 threads, it is interpreted as '1 2 1' = 25%, 50%, 25% and with 7 threads it is "
+    		+ "'1 2 1 2 1 2 1' = 10% 20% 10% 20% 10% 20% 10%. If not specified, all threads get the same proportion of patterns.");
+    
+    enum Scaling {none, always, _default};
+    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<>());
+    
+    @Override
+    public List<Input<?>> listInputs() {
+    	List<Input<?>> list =  super.listInputs();
+    	if (!Beauti.isInBeauti() && System.getProperty("beast.is.junit.testing") == null) {
+    		// do not expose internal likelihoods to BEAUti or junit tests
+    		list.add(likelihoodsInput);
+    	}
+    	return list;
+    }
+    
+    /** calculation engine **/
+    private TreeLikelihood [] treelikelihood;
+
+    private ExecutorService pool = null;
+    private final List<Callable<Double>> likelihoodCallers = new ArrayList<Callable<Double>>();
+
+    
+    /** number of threads to use, changes when threading causes problems **/
+    private int threadCount;
+    private double [] logPByThread;
+	
+	
+	// specified a set ranges of patterns assigned to each thread
+	// first patternPoints contains 0, then one point for each thread
+    private int [] patternPoints;
+	
+    @Override
+    public void initAndValidate() {
+		threadCount = BeastMCMC.m_nThreads;
+
+		if (maxNrOfThreadsInput.get() > 0) {
+			threadCount = Math.min(maxNrOfThreadsInput.get(), BeastMCMC.m_nThreads);
+		}
+        String instanceCount = System.getProperty("beast.instance.count");
+        if (instanceCount != null && instanceCount.length() > 0) {
+        	threadCount = Integer.parseInt(instanceCount);
+        }
+        
+        logPByThread = new double[threadCount];
+
+    	// sanity check: alignment should have same #taxa as tree
+    	if (dataInput.get().getTaxonCount() != treeInput.get().getLeafNodeCount()) {
+    		throw new IllegalArgumentException("The number of nodes in the tree does not match the number of sequences");
+    	}
+    	
+    	treelikelihood = new TreeLikelihood[threadCount];
+    	
+    	if (dataInput.get().isAscertained) {
+    		Log.warning.println("Note, because the alignment is ascertained -- can only use single trhead per alignment");
+    		threadCount = 1;
+    	}
+    	
+    	if (threadCount <= 1) {    		
+    		treelikelihood[0] = new TreeLikelihood();
+    		treelikelihood[0].setID(getID() + "0");
+    		treelikelihood[0].initByName("data", dataInput.get(), 
+    				"tree", treeInput.get(), 
+    				"siteModel", siteModelInput.get(), 
+    				"branchRateModel", branchRateModelInput.get(), 
+    				"useAmbiguities", useAmbiguitiesInput.get(),
+					"scaling" , scalingInput.get() + ""
+    				);
+    		treelikelihood[0].getOutputs().add(this);
+    		likelihoodsInput.get().add(treelikelihood[0]);
+    	} else {
+        	pool = Executors.newFixedThreadPool(threadCount);
+    		
+        	calcPatternPoints(dataInput.get().getSiteCount());
+        	for (int i = 0; i < threadCount; i++) {
+        		Alignment data = dataInput.get();
+        		String filterSpec = (patternPoints[i] +1) + "-" + (patternPoints[i + 1]);
+        		if (data.isAscertained) {
+        			filterSpec += data.excludefromInput.get() + "-" + data.excludetoInput.get() + "," + filterSpec;
+        		}
+        		treelikelihood[i] = new TreeLikelihood();
+        		treelikelihood[i].setID(getID() + i);
+        		treelikelihood[i].getOutputs().add(this);
+        		likelihoodsInput.get().add(treelikelihood[i]);
+
+        		FilteredAlignment filter = new FilteredAlignment();
+        		if (i == 0 && dataInput.get() instanceof FilteredAlignment && ((FilteredAlignment)dataInput.get()).constantSiteWeightsInput.get() != null) {
+        			filter.initByName("data", dataInput.get()/*, "userDataType", m_data.get().getDataType()*/, 
+        							"filter", filterSpec, 
+        							"constantSiteWeights", ((FilteredAlignment)dataInput.get()).constantSiteWeightsInput.get()
+        							);
+        		} else {
+        			filter.initByName("data", dataInput.get()/*, "userDataType", m_data.get().getDataType()*/, 
+        							"filter", filterSpec
+        							);
+        		}
+        		treelikelihood[i].initByName("data", filter, 
+        				"tree", treeInput.get(), 
+        				"siteModel", duplicate((BEASTInterface) siteModelInput.get(), i), 
+        				"branchRateModel", duplicate(branchRateModelInput.get(), i), 
+        				"useAmbiguities", useAmbiguitiesInput.get(),
+						"scaling" , scalingInput.get() + ""
+        				);
+        		
+        		likelihoodCallers.add(new TreeLikelihoodCaller(treelikelihood[i], i));
+        	}
+    	}
+    }
+    
+    
+    /** create new instance of src object, connecting all inputs from src object
+     * Note if input is a SubstModel, it is duplicated as well.
+     * @param src object to be copied
+     * @param i index used to extend ID with.
+     * @return copy of src object
+     */
+    private Object duplicate(BEASTInterface src, int i) {
+    	if (src == null) { 
+    		return null;
+    	}
+    	BEASTInterface copy;
+		try {
+			copy = src.getClass().newInstance();
+        	copy.setID(src.getID() + "_" + i);
+		} catch (InstantiationException | IllegalAccessException e) {
+			e.printStackTrace();
+			throw new RuntimeException("Programmer error: every object in the model should have a default constructor that is publicly accessible: " + src.getClass().getName());
+		}
+        for (Input<?> input : src.listInputs()) {
+            if (input.get() != null) {
+                if (input.get() instanceof List) {
+                    // handle lists
+                	//((List)copy.getInput(input.getName())).clear();
+                    for (Object o : (List<?>) input.get()) {
+                        if (o instanceof BEASTInterface) {
+                        	// make sure it is not already in the list
+                            copy.setInputValue(input.getName(), o);
+                        }
+                    }
+                } else if (input.get() instanceof SubstitutionModel) {
+                	// duplicate subst models
+                	BEASTInterface substModel = (BEASTInterface) duplicate((BEASTInterface) input.get(), i);
+            		copy.setInputValue(input.getName(), substModel);
+            	} else {
+                    // it is some other value
+            		copy.setInputValue(input.getName(), input.get());
+            	}
+            }
+        }
+        copy.initAndValidate();
+		return copy;
+	}
+
+	private void calcPatternPoints(int nPatterns) {
+		patternPoints = new int[threadCount + 1];
+		if (proportionsInput.get() == null) {
+			int range = nPatterns / threadCount;
+			for (int i = 0; i < threadCount - 1; i++) {
+				patternPoints[i+1] = range * (i+1);
+			}
+			patternPoints[threadCount] = nPatterns;
+		} else {
+			String [] strs = proportionsInput.get().split("\\s+");
+			double [] proportions = new double[threadCount];
+			for (int i = 0; i < threadCount; i++) {
+				proportions[i] = Double.parseDouble(strs[i % strs.length]);
+			}
+			// normalise
+			double sum = 0;
+			for (double d : proportions) {
+				sum += d;
+			}
+			for (int i = 0; i < threadCount; i++) {
+				proportions[i] /= sum;
+			}
+			// cummulative 
+			for (int i = 1; i < threadCount; i++) {
+				proportions[i] += proportions[i- 1];
+			}
+			// calc ranges
+			for (int i = 0; i < threadCount; i++) {
+				patternPoints[i+1] = (int) (proportions[i] * nPatterns + 0.5);
+			}
+		}
+    }
+        
+    /**
+     * This method samples the sequences based on the tree and site model.
+     */
+    @Override
+	public void sample(State state, Random random) {
+        throw new UnsupportedOperationException("Can't sample a fixed alignment!");
+    }
+
+
+    @Override
+    public double calculateLogP() {
+		logP =  calculateLogPByBeagle();
+		return logP;
+    }
+
+    class TreeLikelihoodCaller implements Callable<Double> {
+        private final TreeLikelihood likelihood;
+        private final int threadNr;
+
+        public TreeLikelihoodCaller(TreeLikelihood likelihood, int threadNr) {
+            this.likelihood = likelihood;
+            this.threadNr = threadNr;
+        }
+
+        public Double call() throws Exception {
+  		  	try {
+	            logPByThread[threadNr] = likelihood.calculateLogP();
+  		  	} catch (Exception e) {
+  		  		System.err.println("Something went wrong ith thread " + threadNr);
+				e.printStackTrace();
+				System.exit(0);
+			}
+            return logPByThread[threadNr];
+        }
+
+    }
+
+	
+	
+    private double calculateLogPByBeagle() {
+		try {
+			if (threadCount > 1) {
+                pool.invokeAll(likelihoodCallers);
+
+		    	logP = 0;
+		    	for (double f : logPByThread) {
+		    		logP += f;
+		    	}
+			} else {
+				logP = treelikelihood[0].calculateLogP();
+			}
+		} catch (RejectedExecutionException | InterruptedException e) {
+			e.printStackTrace();
+			System.exit(0);
+		}
+		return logP;
+	}
+    
+	
+    /** CalculationNode methods **/
+
+    /**
+     * check state for changed variables and update temp results if necessary *
+     */
+    @Override
+    protected boolean requiresRecalculation() {
+		boolean requiresRecalculation = false;
+		for (TreeLikelihood b : treelikelihood) {
+			requiresRecalculation |= b.requiresRecalculation();
+		}
+		return requiresRecalculation;
+    }
+
+    @Override
+    public void store() {
+//		for (TreeLikelihood b : treelikelihood) {
+//			b.store();
+//		}
+    	super.store();
+    }
+
+    @Override
+    public void restore() {
+//		for (TreeLikelihood b : treelikelihood) {
+//			b.restore();
+//		}
+    	super.restore();
+    }
+        
+    /**
+     * @return a list of unique ids for the state nodes that form the argument
+     */
+    @Override
+	public List<String> getArguments() {
+        return Collections.singletonList(dataInput.get().getID());
+    }
+
+    /**
+     * @return a list of unique ids for the state nodes that make up the conditions
+     */
+    @Override
+	public List<String> getConditions() {
+        return ((SiteModel.Base)siteModelInput.get()).getConditions();
+    }
+    
+} // class ThreadedTreeLikelihood
diff --git a/src/beast/evolution/likelihood/TreeLikelihood.java b/src/beast/evolution/likelihood/TreeLikelihood.java
index e3a28da..c30afbc 100644
--- a/src/beast/evolution/likelihood/TreeLikelihood.java
+++ b/src/beast/evolution/likelihood/TreeLikelihood.java
@@ -50,12 +50,12 @@ import beast.evolution.tree.TreeInterface;
         "Felsenstein, Joseph (1981). Evolutionary trees from DNA sequences: a maximum likelihood approach. J Mol Evol 17 (6): 368-376.")
 public class TreeLikelihood extends GenericTreeLikelihood {
 
-    public Input<Boolean> m_useAmbiguities = new Input<Boolean>("useAmbiguities", "flag to indicate that sites containing ambiguous states should be handled instead of ignored (the default)", false);
-    public Input<Boolean> m_useTipLikelihoods = new Input<Boolean>("useTipLikelihoods", "flag to indicate that partial likelihoods are provided at the tips", false);
+    final public Input<Boolean> m_useAmbiguities = new Input<>("useAmbiguities", "flag to indicate that sites containing ambiguous states should be handled instead of ignored (the default)", false);
+    final public Input<Boolean> m_useTipLikelihoods = new Input<>("useTipLikelihoods", "flag to indicate that partial likelihoods are provided at the tips", false);
     
     
     public static enum Scaling {none, always, _default};
-    public Input<Scaling> scaling = new Input<TreeLikelihood.Scaling>("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());
+    final public Input<Scaling> scaling = 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());
     
 
     /**
@@ -65,7 +65,7 @@ public class TreeLikelihood extends GenericTreeLikelihood {
     BeagleTreeLikelihood beagle;
 
     /**
-     * Plugin associated with inputs. Since none of the inputs are StateNodes, it
+     * 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;
@@ -119,10 +119,10 @@ public class TreeLikelihood extends GenericTreeLikelihood {
     List<Integer> constantPattern = null;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         // sanity check: alignment should have same #taxa as tree
         if (dataInput.get().getTaxonCount() != treeInput.get().getLeafNodeCount()) {
-            throw new Exception("The number of nodes in the tree does not match the number of sequences");
+            throw new IllegalArgumentException("The number of nodes in the tree does not match the number of sequences");
         }
         beagle = null;
         beagle = new BeagleTreeLikelihood();
@@ -143,7 +143,7 @@ public class TreeLikelihood extends GenericTreeLikelihood {
 
         int nodeCount = treeInput.get().getNodeCount();
         if (!(siteModelInput.get() instanceof SiteModel.Base)) {
-        	throw new Exception ("siteModel input should be of type SiteModel.Base");
+        	throw new IllegalArgumentException("siteModel input should be of type SiteModel.Base");
         }
         m_siteModel = (SiteModel.Base) siteModelInput.get();
         m_siteModel.setDataType(dataInput.get().getDataType());
@@ -157,12 +157,12 @@ public class TreeLikelihood extends GenericTreeLikelihood {
         m_branchLengths = new double[nodeCount];
         storedBranchLengths = new double[nodeCount];
 
-        int nStateCount = dataInput.get().getMaxStateCount();
-        int nPatterns = dataInput.get().getPatternCount();
-        if (nStateCount == 4) {
+        int stateCount = dataInput.get().getMaxStateCount();
+        int patterns = dataInput.get().getPatternCount();
+        if (stateCount == 4) {
             likelihoodCore = new BeerLikelihoodCore4();
         } else {
-            likelihoodCore = new BeerLikelihoodCore(nStateCount);
+            likelihoodCore = new BeerLikelihoodCore(stateCount);
         }
 
         String className = getClass().getSimpleName();
@@ -176,15 +176,15 @@ public class TreeLikelihood extends GenericTreeLikelihood {
         proportionInvariant = m_siteModel.getProportionInvariant();
         m_siteModel.setPropInvariantIsCategory(false);
         if (proportionInvariant > 0) {
-            calcConstantPatternIndices(nPatterns, nStateCount);
+            calcConstantPatternIndices(patterns, stateCount);
         }
 
         initCore();
 
-        patternLogLikelihoods = new double[nPatterns];
-        m_fRootPartials = new double[nPatterns * nStateCount];
-        matrixSize = (nStateCount + 1) * (nStateCount + 1);
-        probabilities = new double[(nStateCount + 1) * (nStateCount + 1)];
+        patternLogLikelihoods = new double[patterns];
+        m_fRootPartials = new double[patterns * stateCount];
+        matrixSize = (stateCount + 1) * (stateCount + 1);
+        probabilities = new double[(stateCount + 1) * (stateCount + 1)];
         Arrays.fill(probabilities, 1.0);
 
         if (dataInput.get().isAscertained) {
@@ -201,23 +201,23 @@ public class TreeLikelihood extends GenericTreeLikelihood {
      * // taking ambiguities in account, there is a contribution of 1 from
      * // the 'site invariant' category.
      */
-    void calcConstantPatternIndices(final int nPatterns, final int nStateCount) {
-        constantPattern = new ArrayList<Integer>();
-        for (int i = 0; i < nPatterns; i++) {
+    void calcConstantPatternIndices(final int patterns, final int stateCount) {
+        constantPattern = new ArrayList<>();
+        for (int i = 0; i < patterns; i++) {
             final int[] pattern = dataInput.get().getPattern(i);
-            final boolean[] bIsInvariant = new boolean[nStateCount];
-            Arrays.fill(bIsInvariant, true);
+            final boolean[] isInvariant = new boolean[stateCount];
+            Arrays.fill(isInvariant, true);
             for (final int state : pattern) {
-                final boolean[] bStateSet = dataInput.get().getStateSet(state);
+                final boolean[] isStateSet = dataInput.get().getStateSet(state);
                 if (m_useAmbiguities.get() || !dataInput.get().getDataType().isAmbiguousState(state)) {
-                    for (int k = 0; k < nStateCount; k++) {
-                        bIsInvariant[k] &= bStateSet[k];
+                    for (int k = 0; k < stateCount; k++) {
+                        isInvariant[k] &= isStateSet[k];
                     }
                 }
             }
-            for (int k = 0; k < nStateCount; k++) {
-                if (bIsInvariant[k]) {
-                    constantPattern.add(i * nStateCount + k);
+            for (int k = 0; k < stateCount; k++) {
+                if (isInvariant[k]) {
+                    constantPattern.add(i * stateCount + k);
                 }
             }
         }
@@ -249,7 +249,8 @@ public class TreeLikelihood extends GenericTreeLikelihood {
     /**
      * This method samples the sequences based on the tree and site model.
      */
-    public void sample(State state, Random random) {
+    @Override
+	public void sample(State state, Random random) {
         throw new UnsupportedOperationException("Can't sample a fixed alignment!");
     }
 
@@ -304,22 +305,22 @@ public class TreeLikelihood extends GenericTreeLikelihood {
     protected void setPartials(Node node, int patternCount) {
         if (node.isLeaf()) {
             Alignment data = dataInput.get();
-            int nStates = data.getDataType().getStateCount();
-            double[] partials = new double[patternCount * nStates];
+            int states = data.getDataType().getStateCount();
+            double[] partials = new double[patternCount * states];
             int k = 0;
-            int iTaxon = getTaxonIndex(node.getID(), data);
-            for (int iPattern = 0; iPattern < patternCount; iPattern++) {                
-                double[] tipLikelihoods = data.getTipLikelihoods(iTaxon,iPattern);
+            int taxonIndex = getTaxonIndex(node.getID(), data);
+            for (int patternIndex_ = 0; patternIndex_ < patternCount; patternIndex_++) {                
+                double[] tipLikelihoods = data.getTipLikelihoods(taxonIndex,patternIndex_);
                 if (tipLikelihoods != null) {
-                	for (int iState = 0; iState < nStates; iState++) {
-                		partials[k++] = tipLikelihoods[iState];
+                	for (int state = 0; state < states; state++) {
+                		partials[k++] = tipLikelihoods[state];
                 	}
                 }
                 else {
-                	int nState = data.getPattern(iTaxon, iPattern);
-	                boolean[] stateSet = data.getStateSet(nState);
-	                for (int iState = 0; iState < nStates; iState++) {
-	                	 partials[k++] = (stateSet[iState] ? 1.0 : 0.0);                
+                	int stateCount = data.getPattern(taxonIndex, patternIndex_);
+	                boolean[] stateSet = data.getStateSet(stateCount);
+	                for (int state = 0; state < states; state++) {
+	                	 partials[k++] = (stateSet[state] ? 1.0 : 0.0);                
 	                }
                 }
             }
@@ -341,16 +342,20 @@ public class TreeLikelihood extends GenericTreeLikelihood {
     int X = 100;
 
     @Override
-    public double calculateLogP() throws Exception {
+    public double calculateLogP() {
         if (beagle != null) {
             logP = beagle.calculateLogP();
             return logP;
         }
         final TreeInterface tree = treeInput.get();
 
-        if (traverse(tree.getRoot()) != Tree.IS_CLEAN)
-            calcLogP();
-
+        try {
+        	if (traverse(tree.getRoot()) != Tree.IS_CLEAN)
+        		calcLogP();
+        }
+        catch (ArithmeticException e) {
+        	return Double.NEGATIVE_INFINITY;
+        }
         m_nScale++;
         if (logP > 0 || (likelihoodCore.getUseScaling() && m_nScale > X)) {
 //            System.err.println("Switch off scaling");
@@ -364,7 +369,7 @@ public class TreeLikelihood extends GenericTreeLikelihood {
         } else if (logP == Double.NEGATIVE_INFINITY && m_fScale < 10 && !scaling.get().equals(Scaling.none)) { // && !m_likelihoodCore.getUseScaling()) {
             m_nScale = 0;
             m_fScale *= 1.01;
-            System.err.println("Turning on scaling to prevent numeric instability " + m_fScale);
+            Log.warning.println("Turning on scaling to prevent numeric instability " + m_fScale);
             likelihoodCore.setUseScaling(m_fScale);
             likelihoodCore.unstore();
             hasDirt = Tree.IS_FILTHY;
@@ -375,7 +380,7 @@ public class TreeLikelihood extends GenericTreeLikelihood {
         return logP;
     }
 
-    void calcLogP() throws Exception {
+    void calcLogP() {
         logP = 0.0;
         if (useAscertainedSitePatterns) {
             final double ascertainmentCorrection = dataInput.get().getAscertainmentCorrection(patternLogLikelihoods);
@@ -390,26 +395,26 @@ public class TreeLikelihood extends GenericTreeLikelihood {
     }
 
     /* Assumes there IS a branch rate model as opposed to traverse() */
-    int traverse(final Node node) throws Exception {
+    int traverse(final Node node) {
 
         int update = (node.isDirty() | hasDirt);
 
-        final int iNode = node.getNr();
+        final int nodeIndex = node.getNr();
 
         final double branchRate = branchRateModel.getRateForBranch(node);
         final double branchTime = node.getLength() * branchRate;
 
         // First update the transition probability matrix(ices) for this branch
-        //if (!node.isRoot() && (update != Tree.IS_CLEAN || branchTime != m_StoredBranchLengths[iNode])) {
-        if (!node.isRoot() && (update != Tree.IS_CLEAN || branchTime != m_branchLengths[iNode])) {
-            m_branchLengths[iNode] = branchTime;
+        //if (!node.isRoot() && (update != Tree.IS_CLEAN || branchTime != m_StoredBranchLengths[nodeIndex])) {
+        if (!node.isRoot() && (update != Tree.IS_CLEAN || branchTime != m_branchLengths[nodeIndex])) {
+            m_branchLengths[nodeIndex] = branchTime;
             final Node parent = node.getParent();
-            likelihoodCore.setNodeMatrixForUpdate(iNode);
+            likelihoodCore.setNodeMatrixForUpdate(nodeIndex);
             for (int i = 0; i < m_siteModel.getCategoryCount(); i++) {
                 final double jointBranchRate = m_siteModel.getRateForCategory(i, node) * branchRate;
                 substitutionModel.getTransitionProbabilities(node, parent.getHeight(), node.getHeight(), jointBranchRate, probabilities);
                 //System.out.println(node.getNr() + " " + Arrays.toString(m_fProbabilities));
-                likelihoodCore.setNodeMatrix(iNode, i, probabilities);
+                likelihoodCore.setNodeMatrix(nodeIndex, i, probabilities);
             }
             update |= Tree.IS_DIRTY;
         }
@@ -430,16 +435,16 @@ public class TreeLikelihood extends GenericTreeLikelihood {
                 final int childNum1 = child1.getNr();
                 final int childNum2 = child2.getNr();
 
-                likelihoodCore.setNodePartialsForUpdate(iNode);
+                likelihoodCore.setNodePartialsForUpdate(nodeIndex);
                 update |= (update1 | update2);
                 if (update >= Tree.IS_FILTHY) {
-                    likelihoodCore.setNodeStatesForUpdate(iNode);
+                    likelihoodCore.setNodeStatesForUpdate(nodeIndex);
                 }
 
                 if (m_siteModel.integrateAcrossCategories()) {
-                    likelihoodCore.calculatePartials(childNum1, childNum2, iNode);
+                    likelihoodCore.calculatePartials(childNum1, childNum2, nodeIndex);
                 } else {
-                    throw new Exception("Error TreeLikelihood 201: Site categories not supported");
+                    throw new RuntimeException("Error TreeLikelihood 201: Site categories not supported");
                     //m_pLikelihoodCore->calculatePartials(childNum1, childNum2, nodeNum, siteCategories);
                 }
 
@@ -528,14 +533,16 @@ public class TreeLikelihood extends GenericTreeLikelihood {
     /**
      * @return a list of unique ids for the state nodes that form the argument
      */
-    public List<String> getArguments() {
+    @Override
+	public List<String> getArguments() {
         return Collections.singletonList(dataInput.get().getID());
     }
 
     /**
      * @return a list of unique ids for the state nodes that make up the conditions
      */
-    public List<String> getConditions() {
+    @Override
+	public List<String> getConditions() {
         return m_siteModel.getConditions();
     }
 
diff --git a/src/beast/evolution/operators/BitFlipOperator.java b/src/beast/evolution/operators/BitFlipOperator.java
index cf366ac..4d71952 100644
--- a/src/beast/evolution/operators/BitFlipOperator.java
+++ b/src/beast/evolution/operators/BitFlipOperator.java
@@ -26,8 +26,8 @@ package beast.evolution.operators;
 
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.Operator;
 import beast.core.Input.Validate;
+import beast.core.Operator;
 import beast.core.parameter.BooleanParameter;
 import beast.util.Randomizer;
 
@@ -38,14 +38,15 @@ import beast.util.Randomizer;
 @Description("Flip one bit in an array of boolean bits. The hastings ratio is designed so that all subsets of vectors with the" +
         " same number of 'on' bits are equiprobable.")
 public class BitFlipOperator extends Operator {
-    public Input<Boolean> uniformInput = new Input<Boolean>("uniform", "when on, total probability of combinations with k" +
+    final public Input<Boolean> uniformInput = new Input<>("uniform", "when on, total probability of combinations with k" +
             " 'on' bits is equal. Otherwise uniform on all combinations (default true)", true);
 
-    public Input<BooleanParameter> parameterInput = new Input<BooleanParameter>("parameter", "the parameter to operate a flip on.", Validate.REQUIRED);
+    final public Input<BooleanParameter> parameterInput = new Input<>("parameter", "the parameter to operate a flip on.", Validate.REQUIRED);
 
     private boolean usesPriorOnSum = true;
 
-    public void initAndValidate() {
+    @Override
+	public void initAndValidate() {
         final Boolean b = uniformInput.get();
         if (b != null) {
             usesPriorOnSum = b;
diff --git a/src/beast/evolution/operators/CompoundParameterHelper.java b/src/beast/evolution/operators/CompoundParameterHelper.java
index c7d8505..0ad67de 100644
--- a/src/beast/evolution/operators/CompoundParameterHelper.java
+++ b/src/beast/evolution/operators/CompoundParameterHelper.java
@@ -40,42 +40,42 @@ public class CompoundParameterHelper<T> {
         return parameterIndex.length;
     }
 
-    public void setValue(final int iParam, final T fValue) {
-        final Parameter<T> para = parameterList.get(getY(iParam));
-        para.setValue(getX(iParam), fValue);
+    public void setValue(final int param, final T value) {
+        final Parameter<T> para = parameterList.get(getY(param));
+        para.setValue(getX(param), value);
     }
 
-    public T getValue(final int iParam) {
-        return parameterList.get(getY(iParam)).getValue(getX(iParam));
+    public T getValue(final int param) {
+        return parameterList.get(getY(param)).getValue(getX(param));
     }
 
-    public T getLower(final int iParam) {
-        return parameterList.get(getY(iParam)).getLower();
+    public T getLower(final int param) {
+        return parameterList.get(getY(param)).getLower();
     }
 
-    public T getUpper(final int iParam) {
-        return parameterList.get(getY(iParam)).getUpper();
+    public T getUpper(final int param) {
+        return parameterList.get(getY(param)).getUpper();
     }
 
-    // given {{?,?,?,?}{?,?}{?,?,?}}, parameterIndex[] is 0 0 0 0 1 1 2 2 2, iParam starts from 0;
-    // if iParam < 4, then getX(iParam) = iParam;
-    // if iParam >= 4, then getX(iParam) = iParam - the sum of previous dimensions
-    // for example, iParam = 7, then getX = 7 - (4 + 2) = 1
-    protected int getX(final int iParam) {
+    // given {{?,?,?,?}{?,?}{?,?,?}}, parameterIndex[] is 0 0 0 0 1 1 2 2 2, param starts from 0;
+    // if param < 4, then getX(param) = param;
+    // if param >= 4, then getX(param) = param - the sum of previous dimensions
+    // for example, param = 7, then getX = 7 - (4 + 2) = 1
+    protected int getX(final int param) {
         int sumPrevDim = parameterList.get(0).getDimension();
-        if (iParam < sumPrevDim) {
-            return iParam;
+        if (param < sumPrevDim) {
+            return param;
         }
-        for (int y = 1; y < getY(iParam); y++) {
+        for (int y = 1; y < getY(param); y++) {
             sumPrevDim += parameterList.get(y).getDimension();
         }
 
-        return iParam - sumPrevDim;
+        return param - sumPrevDim;
     }
 
     // the index of parameter list
-    protected int getY(final int iParam) {
-        return parameterIndex[iParam];
+    protected int getY(final int param) {
+        return parameterIndex[param];
     }
 
 }
diff --git a/src/beast/evolution/operators/DeltaExchangeOperator.java b/src/beast/evolution/operators/DeltaExchangeOperator.java
index eb0f412..df55d25 100644
--- a/src/beast/evolution/operators/DeltaExchangeOperator.java
+++ b/src/beast/evolution/operators/DeltaExchangeOperator.java
@@ -25,31 +25,68 @@ import beast.util.Randomizer;
  */
 @Description("A generic operator for use with a sum-constrained (possibly weighted) vector parameter.")
 public class DeltaExchangeOperator extends Operator {
-    //public Input<Tree> m_pTree = new Input<Tree>("tree", "if specified, all beast.tree branch length are scaled");
+    //public Input<Tree> m_pTree = new Input<>("tree", "if specified, all beast.tree branch length are scaled");
 
-    public final Input<List<RealParameter>> parameterInput = new Input<List<RealParameter>>("parameter",
-            "if specified, this parameter is operated on", new ArrayList<RealParameter>());
-    public final Input<List<IntegerParameter>> intparameterInput = new Input<List<IntegerParameter>>("intparameter",
-            "if specified, this parameter is operated on", new ArrayList<IntegerParameter>());
+    public final Input<List<RealParameter>> parameterInput = new Input<>("parameter",
+            "if specified, this parameter is operated on", new ArrayList<>());
+    public final Input<List<IntegerParameter>> intparameterInput = new Input<>("intparameter",
+            "if specified, this parameter is operated on", new ArrayList<>());
 
-    public final Input<Double> deltaInput = new Input<Double>("delta", "Magnitude of change for two randomly picked values.", 1.0);
+    public final Input<Double> deltaInput = new Input<>("delta", "Magnitude of change for two randomly picked values.", 1.0);
     public final Input<Boolean> autoOptimizeiInput =
-            new Input<Boolean>("autoOptimize", "if true, window size will be adjusted during the MCMC run to improve mixing.", true);
-    public final Input<Boolean> sIntegerOperatorInput = new Input<Boolean>("integer", "if true, changes are all integers.", false);
-    public final Input<IntegerParameter> parameterWeightsInput = new Input<IntegerParameter>("weightvector", "weights on a vector parameter");
+            new Input<>("autoOptimize", "if true, window size will be adjusted during the MCMC run to improve mixing.", true);
+    public final Input<Boolean> integerOperatorInput = new Input<>("integer", "if true, changes are all integers.", false);
+    public final Input<IntegerParameter> parameterWeightsInput = new Input<>("weightvector", "weights on a vector parameter");
 
     private boolean autoOptimize;
     private double delta;
     private boolean isIntegerOperator;
-    private int[] parameterWeights;
     private CompoundParameterHelper compoundParameter = null;
     // because CompoundParameter cannot derive from parameter due to framework, the code complexity is doubled
 
-    public void initAndValidate() {
+	private int[] weights() {
+		int[] weights;
+		if (compoundParameter == null) { // one parameter case
+			if (parameterInput.get().isEmpty()) {
+				if (intparameterInput.get().size() > 0) {
+					weights = new int[intparameterInput.get().get(0)
+							.getDimension()];
+				} else {
+					// happens when BEAUti is setting things up
+					weights = new int[0];
+				}
+			} else {
+				weights = new int[parameterInput.get().get(0).getDimension()];
+			}
+		} else {
+			if (compoundParameter.getDimension() < 1)
+				throw new IllegalArgumentException(
+						"Compound parameter is not created properly, dimension = "
+								+ compoundParameter.getDimension());
+
+			weights = new int[compoundParameter.getDimension()];
+		}
+
+		if (parameterWeightsInput.get() != null) {
+			if (weights.length != parameterWeightsInput.get().getDimension())
+				throw new IllegalArgumentException(
+						"Weights vector should have the same length as parameter dimension");
+
+			for (int i = 0; i < weights.length; i++) {
+				weights[i] = parameterWeightsInput.get().getValue(i);
+			}
+		} else {
+			for (int i = 0; i < weights.length; i++) {
+				weights[i] = 1;
+			}
+		}
+		return weights;
+	}
 
+    public void initAndValidate() {
         autoOptimize = autoOptimizeiInput.get();
         delta = deltaInput.get();
-        isIntegerOperator = sIntegerOperatorInput.get();
+        isIntegerOperator = integerOperatorInput.get();
 
         if (parameterInput.get().isEmpty()) {
             if (intparameterInput.get().size() > 1) {
@@ -57,7 +94,7 @@ public class DeltaExchangeOperator extends Operator {
             	for (int i = 0; i < intparameterInput.get().size(); i++) {
             		for (int j = i + 1; j < intparameterInput.get().size(); j++) {
             			if (intparameterInput.get().get(i) == intparameterInput.get().get(j)) {
-            				throw new RuntimeException("Dublicate intparameter (" + intparameterInput.get().get(j).getID() + ") found in operator " + getID());
+            				throw new RuntimeException("Duplicate intparameter (" + intparameterInput.get().get(j).getID() + ") found in operator " + getID());
             			}
             		}
             	}
@@ -70,7 +107,7 @@ public class DeltaExchangeOperator extends Operator {
             	for (int i = 0; i < parameterInput.get().size(); i++) {
             		for (int j = i + 1; j < parameterInput.get().size(); j++) {
             			if (parameterInput.get().get(i) == parameterInput.get().get(j)) {
-            				throw new RuntimeException("Dublicate intparameter (" + parameterInput.get().get(j).getID() + ") found in operator " + getID());
+            				throw new RuntimeException("Duplicate intparameter (" + parameterInput.get().get(j).getID() + ") found in operator " + getID());
             			}
             		}
             	}
@@ -79,37 +116,6 @@ public class DeltaExchangeOperator extends Operator {
             }
         }
 
-        if (compoundParameter == null) { // one parameter case
-            if (parameterInput.get().isEmpty()) {
-            	if (intparameterInput.get().size() > 0) {
-            		parameterWeights = new int[intparameterInput.get().get(0).getDimension()];
-            	} else {
-            		// happens when BEAUti is setting things up
-            		parameterWeights = new int[0];
-            	}
-            } else {
-                parameterWeights = new int[parameterInput.get().get(0).getDimension()];
-            }
-        } else {
-            if (compoundParameter.getDimension() < 1)
-                throw new IllegalArgumentException("Compound parameter is not created properly, dimension = " + compoundParameter.getDimension());
-
-            parameterWeights = new int[compoundParameter.getDimension()];
-        }
-
-        if (parameterWeightsInput.get() != null) {
-            if (parameterWeights.length != parameterWeightsInput.get().getDimension())
-                throw new IllegalArgumentException("Weights vector should have the same length as parameter dimension");
-
-            for (int i = 0; i < parameterWeights.length; i++) {
-                parameterWeights[i] = parameterWeightsInput.get().getValue(i);
-            }
-        } else {
-            for (int i = 0; i < parameterWeights.length; i++) {
-                parameterWeights[i] = 1;
-            }
-        }
-
         if (isIntegerOperator && delta != Math.round(delta)) {
             throw new IllegalArgumentException("Can't be an integer operator if delta is not integer");
         }
@@ -130,6 +136,7 @@ public class DeltaExchangeOperator extends Operator {
 
     @Override
     public final double proposal() {
+    	int[] parameterWeights = weights();
         double logq = 0.0;
 
         if (compoundParameter == null) { // one parameter case
@@ -172,7 +179,7 @@ public class DeltaExchangeOperator extends Operator {
                     final double d = Randomizer.nextDouble() * delta;
                     scalar1 -= d;
                     if (parameterWeights[dim1] != parameterWeights[dim2]) {
-                        scalar2 += d * (double) parameterWeights[dim1] / (double) parameterWeights[dim2];
+                        scalar2 += d * parameterWeights[dim1] / parameterWeights[dim2];
                     } else {
                         scalar2 += d;
                     }
@@ -240,7 +247,7 @@ public class DeltaExchangeOperator extends Operator {
                     final double d = Randomizer.nextDouble() * delta;
                     scalar1 -= d;
                     if (parameterWeights[dim1] != parameterWeights[dim2]) {
-                        scalar2 += d * (double) parameterWeights[dim1] / (double) parameterWeights[dim2];
+                        scalar2 += d * parameterWeights[dim1] / parameterWeights[dim2];
                     } else {
                         scalar2 += d;
                     }
@@ -293,8 +300,8 @@ public class DeltaExchangeOperator extends Operator {
     }
 
     @Override
-    public void setCoercableParameterValue(final double fValue) {
-        delta = fValue;
+    public void setCoercableParameterValue(final double value) {
+        delta = value;
     }
 
     /**
@@ -308,9 +315,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 fDelta = calcDelta(logAlpha);
-            fDelta += Math.log(delta);
-            delta = Math.exp(fDelta);
+            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/Exchange.java b/src/beast/evolution/operators/Exchange.java
index a2cad80..738dd8d 100644
--- a/src/beast/evolution/operators/Exchange.java
+++ b/src/beast/evolution/operators/Exchange.java
@@ -64,7 +64,7 @@ import beast.util.Randomizer;
         "The narrow exchange is very similar to a rooted-beast.tree nearest-neighbour " +
         "interchange but with the restriction that node height must remain consistent.")
 public class Exchange extends TreeOperator {
-    public Input<Boolean> isNarrowInput = new Input<Boolean>("isNarrow", "if true (default) a narrow exchange is performed, otherwise a wide exchange", true);
+    final public Input<Boolean> isNarrowInput = new Input<>("isNarrow", "if true (default) a narrow exchange is performed, otherwise a wide exchange", true);
 
     @Override
     public void initAndValidate() {
@@ -79,15 +79,15 @@ public class Exchange extends TreeOperator {
     public double proposal() {
         final Tree tree = treeInput.get(this);
 
-        double fLogHastingsRatio = 0;
+        double logHastingsRatio = 0;
 
         if (isNarrowInput.get()) {
-            fLogHastingsRatio = narrow(tree);
+            logHastingsRatio = narrow(tree);
         } else {
-            fLogHastingsRatio = wide(tree);
+            logHastingsRatio = wide(tree);
         }
 
-        return fLogHastingsRatio;
+        return logHastingsRatio;
     }
 
     private int isg(final Node n) {
@@ -107,67 +107,67 @@ public class Exchange extends TreeOperator {
             //        Alternative implementation that has less risk of rejection due to
             //    	  selecting an invalid initial node
             //
-            final int nInternalNodes = tree.getInternalNodeCount();
-            if (nInternalNodes <= 1) {
+            final int internalNodes = tree.getInternalNodeCount();
+            if (internalNodes <= 1) {
                 return Double.NEGATIVE_INFINITY;
             }
 
-            Node iGrandParent = tree.getNode(nInternalNodes + 1 + Randomizer.nextInt(nInternalNodes));
-            while (iGrandParent.getLeft().isLeaf() && iGrandParent.getRight().isLeaf()) {
-                iGrandParent = tree.getNode(nInternalNodes + 1 + Randomizer.nextInt(nInternalNodes));
+            Node grandParent = tree.getNode(internalNodes + 1 + Randomizer.nextInt(internalNodes));
+            while (grandParent.getLeft().isLeaf() && grandParent.getRight().isLeaf()) {
+                grandParent = tree.getNode(internalNodes + 1 + Randomizer.nextInt(internalNodes));
             }
 
-            Node iParent = iGrandParent.getLeft();
-            Node iUncle = iGrandParent.getRight();
-            if (iParent.getHeight() < iUncle.getHeight()) {
-                iParent = iGrandParent.getRight();
-                iUncle = iGrandParent.getLeft();
+            Node parentIndex = grandParent.getLeft();
+            Node uncle = grandParent.getRight();
+            if (parentIndex.getHeight() < uncle.getHeight()) {
+                parentIndex = grandParent.getRight();
+                uncle = grandParent.getLeft();
             }
 
-            if( iParent.isLeaf() ) {
+            if( parentIndex.isLeaf() ) {
                 // tree with dated tips
                 return Double.NEGATIVE_INFINITY;
             }
 
             int validGP = 0;
             {
-                for(int i = nInternalNodes + 1; i < 1 + 2*nInternalNodes; ++i) {
+                for(int i = internalNodes + 1; i < 1 + 2*internalNodes; ++i) {
                     validGP += isg(tree.getNode(i));
                 }
             }
 
-            final int c2 = sisg(iParent) + sisg(iUncle);
+            final int c2 = sisg(parentIndex) + sisg(uncle);
 
-            final Node i = (Randomizer.nextBoolean() ? iParent.getLeft() : iParent.getRight());
-            exchangeNodes(i, iUncle, iParent, iGrandParent);
+            final Node i = (Randomizer.nextBoolean() ? parentIndex.getLeft() : parentIndex.getRight());
+            exchangeNodes(i, uncle, parentIndex, grandParent);
 
-            final int validGPafter = validGP - c2 + sisg(iParent) + sisg(iUncle);
+            final int validGPafter = validGP - c2 + sisg(parentIndex) + sisg(uncle);
 
             return Math.log((float)validGP/validGPafter);
         } else {
 
-            final int nNodes = tree.getNodeCount();
+            final int nodeCount = tree.getNodeCount();
 
             Node i = tree.getRoot();
 
             while (i.isRoot() || i.getParent().isRoot()) {
-                i = tree.getNode(Randomizer.nextInt(nNodes));
+                i = tree.getNode(Randomizer.nextInt(nodeCount));
             }
 
-            final Node iParent = i.getParent();
-            final Node iGrandParent = iParent.getParent();
-            Node iUncle = iGrandParent.getLeft();
-            if (iUncle.getNr() == iParent.getNr()) {
-                iUncle = iGrandParent.getRight();
-                assert (iUncle.getNr() != iParent.getNr());
+            final Node parentIndex = i.getParent();
+            final Node grandParent = parentIndex.getParent();
+            Node uncle = grandParent.getLeft();
+            if (uncle.getNr() == parentIndex.getNr()) {
+                uncle = grandParent.getRight();
+                assert (uncle.getNr() != parentIndex.getNr());
             }
-            assert iUncle == getOtherChild(iGrandParent, iParent);
+            assert uncle == getOtherChild(grandParent, parentIndex);
 
-            assert i.getHeight() <= iGrandParent.getHeight();
+            assert i.getHeight() <= grandParent.getHeight();
 
-            if (//i.getHeight() < iUncle.getHeight() &&
-                    iUncle.getHeight() < iParent.getHeight()) {
-                exchangeNodes(i, iUncle, iParent, iGrandParent);
+            if (//i.getHeight() < uncle.getHeight() &&
+                    uncle.getHeight() < parentIndex.getHeight()) {
+                exchangeNodes(i, uncle, parentIndex, grandParent);
                 return 0;
             } else {
                 // Couldn't find valid narrow move on this beast.tree!!
@@ -195,21 +195,21 @@ public class Exchange extends TreeOperator {
             j = tree.getNode(Randomizer.nextInt(nodeCount));
         }
 
-        final Node iP = i.getParent();
+        final Node p = i.getParent();
         final Node jP = j.getParent();
 
-        if ((iP != jP) && (i != jP) && (j != iP)
-                && (j.getHeight() < iP.getHeight())
+        if ((p != jP) && (i != jP) && (j != p)
+                && (j.getHeight() < p.getHeight())
                 && (i.getHeight() < jP.getHeight())
-//                && ((iP.getHeight() < jP.getHeight() && i.getHeight() < j.getHeight()) ||
-//                (iP.getHeight() > jP.getHeight() && i.getHeight() > j.getHeight()))
+//                && ((p.getHeight() < jP.getHeight() && i.getHeight() < j.getHeight()) ||
+//                (p.getHeight() > jP.getHeight() && i.getHeight() > j.getHeight()))
                 ) {
-            exchangeNodes(i, j, iP, jP);
+            exchangeNodes(i, j, p, jP);
 
             // All the nodes on the path from i/j to the common ancestor of i/j parents had a topology change,
             // so they need to be marked FILTHY.
             if( markCladesInput.get() ) {
-                Node iup = iP;
+                Node iup = p;
                 Node jup = jP;
                 while (iup != jup) {
                     if( iup.getHeight() < jup.getHeight() ) {
@@ -235,10 +235,10 @@ public class Exchange extends TreeOperator {
     /* exchange sub-trees whose root are i and j */
 
     protected void exchangeNodes(Node i, Node j,
-                                 Node iP, Node jP) {
-        // precondition iP -> i & jP -> j
-        replace(iP, i, j);
+                                 Node p, Node jP) {
+        // precondition p -> i & jP -> j
+        replace(p, i, j);
         replace(jP, j, i);
-        // postcondition iP -> j & iP -> i
+        // postcondition p -> j & p -> i
     }
 }
diff --git a/src/beast/evolution/operators/IntRandomWalkOperator.java b/src/beast/evolution/operators/IntRandomWalkOperator.java
index 3f51d38..216cec1 100644
--- a/src/beast/evolution/operators/IntRandomWalkOperator.java
+++ b/src/beast/evolution/operators/IntRandomWalkOperator.java
@@ -2,8 +2,8 @@ package beast.evolution.operators;
 
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.Operator;
 import beast.core.Input.Validate;
+import beast.core.Operator;
 import beast.core.parameter.IntegerParameter;
 import beast.util.Randomizer;
 
@@ -11,14 +11,15 @@ import beast.util.Randomizer;
 @Description("A random walk operator that selects a random dimension of the integer parameter and perturbs the value a " +
         "random amount within +/- windowSize.")
 public class IntRandomWalkOperator extends Operator {
-    public Input<Integer> windowSizeInput =
-            new Input<Integer>("windowSize", "the size of the window both up and down", Validate.REQUIRED);
-    public Input<IntegerParameter> parameterInput =
-            new Input<IntegerParameter>("parameter", "the parameter to operate a random walk on.", Validate.REQUIRED);
+    final public Input<Integer> windowSizeInput =
+            new Input<>("windowSize", "the size of the window both up and down", Validate.REQUIRED);
+    final public Input<IntegerParameter> parameterInput =
+            new Input<>("parameter", "the parameter to operate a random walk on.", Validate.REQUIRED);
 
     int windowSize = 1;
 
-    public void initAndValidate() {
+    @Override
+	public void initAndValidate() {
         windowSize = windowSizeInput.get();
     }
 
diff --git a/src/beast/evolution/operators/IntUniformOperator.java b/src/beast/evolution/operators/IntUniformOperator.java
index e3aefdf..77ed34d 100644
--- a/src/beast/evolution/operators/IntUniformOperator.java
+++ b/src/beast/evolution/operators/IntUniformOperator.java
@@ -2,20 +2,22 @@ package beast.evolution.operators;
 
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.Operator;
 import beast.core.Input.Validate;
+import beast.core.Operator;
 import beast.core.parameter.IntegerParameter;
+import beast.core.util.Log;
 import beast.util.Randomizer;
 
 
 @Description("A uniform random operator that selects a random dimension of the integer parameter and picks a new random value within the bounds.")
 @Deprecated
 public class IntUniformOperator extends Operator {
-    public Input<IntegerParameter> parameterInput = new Input<IntegerParameter>("parameter", "the parameter to operate a random walk on.", Validate.REQUIRED);
+    final public Input<IntegerParameter> parameterInput = new Input<>("parameter", "the parameter to operate a random walk on.", Validate.REQUIRED);
 
 
-    public void initAndValidate() {
-        System.err.println("\n\nIntUniformOperator is depracated. Use UniformOperator instead.\n\n");
+    @Override
+	public void initAndValidate() {
+    	Log.warning.println("\n\nIntUniformOperator is depracated. Use UniformOperator instead.\n\n");
     }
 
     /**
diff --git a/src/beast/evolution/operators/JointOperator.java b/src/beast/evolution/operators/JointOperator.java
index 1f033ed..41e2be8 100644
--- a/src/beast/evolution/operators/JointOperator.java
+++ b/src/beast/evolution/operators/JointOperator.java
@@ -16,14 +16,14 @@
  */
 package beast.evolution.operators;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.Operator;
 import beast.core.StateNode;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import beast.core.util.Log;
 
 /**
  * @author Tim Vaughan <tgvaughan at gmail.com>
@@ -33,10 +33,10 @@ import java.util.logging.Logger;
         + " of the state.")
 public class JointOperator extends Operator {
     
-    public Input<List<Operator>> operatorsInput = new Input<List<Operator>>(
+    final public Input<List<Operator>> operatorsInput = new Input<>(
             "operator",
             "List of operators to combine into one operation.",
-            new ArrayList<Operator>());
+            new ArrayList<>());
 
     @Override
     public void initAndValidate() { }
@@ -59,7 +59,7 @@ public class JointOperator extends Operator {
                 if (!op.listStateNodes().isEmpty())
                     op.listStateNodes().get(0).getState().checkCalculationNodesDirtiness();
             } catch (Exception ex) {
-                Logger.getLogger(JointOperator.class.getName()).log(Level.SEVERE, null, ex);
+                Log.err(ex.getMessage());
             }
         }
         
@@ -67,8 +67,8 @@ public class JointOperator extends Operator {
     }
     
     @Override
-    public List<StateNode> listStateNodes() throws Exception {
-        List<StateNode> stateNodeList = new ArrayList<StateNode>();
+    public List<StateNode> listStateNodes() {
+        List<StateNode> stateNodeList = new ArrayList<>();
         
         for (Operator op : operatorsInput.get())
             stateNodeList.addAll(op.listStateNodes());
diff --git a/src/beast/evolution/operators/NodeReheight.java b/src/beast/evolution/operators/NodeReheight.java
index 4336762..88b429b 100644
--- a/src/beast/evolution/operators/NodeReheight.java
+++ b/src/beast/evolution/operators/NodeReheight.java
@@ -21,8 +21,8 @@ import beast.util.Randomizer;
 @Description("Tree operator which randomly changes the height of a node, " +
         "then reconstructs the tree from node heights.")
 public class NodeReheight extends TreeOperator {
-    public final Input<TaxonSet> taxonSetInput = new Input<TaxonSet>("taxonset", "taxon set describing species tree taxa and their gene trees", Validate.REQUIRED);
-    public final Input<List<Tree>> geneTreesInput = new Input<List<Tree>>("genetree", "list of gene trees that constrain species tree movement", new ArrayList<Tree>());
+    public final Input<TaxonSet> taxonSetInput = new Input<>("taxonset", "taxon set describing species tree taxa and their gene trees", Validate.REQUIRED);
+    public final Input<List<Tree>> geneTreesInput = new Input<>("genetree", "list of gene trees that constrain species tree movement", new ArrayList<>());
     Node[] m_nodes;
 
 
@@ -34,9 +34,9 @@ public class NodeReheight extends TreeOperator {
     int nrOfSpecies;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         /** maps gene taxa names to species number **/
-        final Map<String, Integer> taxonMap = new HashMap<String, Integer>();
+        final Map<String, Integer> taxonMap = new HashMap<>();
         final List<Taxon> list = taxonSetInput.get().taxonsetInput.get();
         
         if (list.size() <= 1) {
@@ -56,9 +56,9 @@ public class NodeReheight extends TreeOperator {
         }
 
         /** build the taxon map for each gene tree **/
-        m_taxonMap = new ArrayList<Map<Integer, Integer>>();
+        m_taxonMap = new ArrayList<>();
         for (final Tree tree : geneTreesInput.get()) {
-            final Map<Integer, Integer> map = new HashMap<Integer, Integer>();
+            final Map<Integer, Integer> map = new HashMap<>();
             setupTaxaMap(tree.getRoot(), map, taxonMap);
             m_taxonMap.add(map);
         }
@@ -81,26 +81,26 @@ public class NodeReheight extends TreeOperator {
     public double proposal() {
         final Tree tree = treeInput.get();
         m_nodes = tree.getNodesAsArray();
-        final int nNodes = tree.getNodeCount();
+        final int nodeCount = tree.getNodeCount();
         // randomly change left/right order
         tree.startEditing(this);  // we change the tree
         reorder(tree.getRoot());
         // collect heights
-        final double[] fHeights = new double[nNodes];
-        final int[] iReverseOrder = new int[nNodes];
-        collectHeights(tree.getRoot(), fHeights, iReverseOrder, 0);
+        final double[] heights = new double[nodeCount];
+        final int[] reverseOrder = new int[nodeCount];
+        collectHeights(tree.getRoot(), heights, reverseOrder, 0);
         // change height of an internal node
-        int iNode = Randomizer.nextInt(fHeights.length);
-        while (m_nodes[iReverseOrder[iNode]].isLeaf()) {
-            iNode = Randomizer.nextInt(fHeights.length);
+        int nodeIndex = Randomizer.nextInt(heights.length);
+        while (m_nodes[reverseOrder[nodeIndex]].isLeaf()) {
+            nodeIndex = Randomizer.nextInt(heights.length);
         }
-        final double fMaxHeight = calcMaxHeight(iReverseOrder, iNode);
-        fHeights[iNode] = Randomizer.nextDouble() * fMaxHeight;
-        m_nodes[iReverseOrder[iNode]].setHeight(fHeights[iNode]);
+        final double maxHeight = calcMaxHeight(reverseOrder, nodeIndex);
+        heights[nodeIndex] = Randomizer.nextDouble() * maxHeight;
+        m_nodes[reverseOrder[nodeIndex]].setHeight(heights[nodeIndex]);
         // reconstruct tree from heights
-        final Node root = reconstructTree(fHeights, iReverseOrder, 0, fHeights.length, new boolean[fHeights.length]);
+        final Node root = reconstructTree(heights, reverseOrder, 0, heights.length, new boolean[heights.length]);
 
-        assert checkConsistency(root, new boolean[fHeights.length]) ;
+        assert checkConsistency(root, new boolean[heights.length]) ;
 //            System.err.println("Inconsisten tree");
 //        }
         root.setParent(null);
@@ -108,67 +108,67 @@ public class NodeReheight extends TreeOperator {
         return 0;
     }
 
-    private boolean checkConsistency(final Node node, final boolean[] bUsed) {
-        if (bUsed[node.getNr()]) {
+    private boolean checkConsistency(final Node node, final boolean[] used) {
+        if (used[node.getNr()]) {
             // used twice? tha's bad
             return false;
         }
-        bUsed[node.getNr()] = true;
+        used[node.getNr()] = true;
         if ( node.isLeaf() ) {
             return true;
         }
-        return checkConsistency(node.getLeft(), bUsed) && checkConsistency(node.getRight(), bUsed);
+        return checkConsistency(node.getLeft(), used) && checkConsistency(node.getRight(), used);
     }
 
     /**
-     * calculate maximum height that node iNode can become restricted
+     * calculate maximum height that node nodeIndex can become restricted
      * by nodes on the left and right
      */
-    private double calcMaxHeight(final int[] iReverseOrder, final int iNode) {
+    private double calcMaxHeight(final int[] reverseOrder, final int nodeIndex) {
         // find maximum height between two species. Only upper right part is populated
-        final double[][] fMaxHeight = new double[nrOfSpecies][nrOfSpecies];
+        final double[][] maxHeight = new double[nrOfSpecies][nrOfSpecies];
         for (int i = 0; i < nrOfSpecies; i++) {
-            Arrays.fill(fMaxHeight[i], Double.POSITIVE_INFINITY);
+            Arrays.fill(maxHeight[i], Double.POSITIVE_INFINITY);
         }
 
         // calculate for every species tree the maximum allowable merge point
         for (int i = 0; i < nrOfGeneTrees; i++) {
             final Tree tree = geneTreesInput.get().get(i);
-            findMaximaInGeneTree(tree.getRoot(), new boolean[nrOfSpecies], m_taxonMap.get(i), fMaxHeight);
+            findMaximaInGeneTree(tree.getRoot(), new boolean[nrOfSpecies], m_taxonMap.get(i), maxHeight);
         }
 
         // find species on the left of selected node
-        final boolean[] bLowerSpecies = new boolean[nrOfSpecies];
+        final boolean[] isLowerSpecies = new boolean[nrOfSpecies];
         final Node[] nodes = treeInput.get().getNodesAsArray();
-        for (int i = 0; i < iNode; i++) {
-            final Node node = nodes[iReverseOrder[i]];
+        for (int i = 0; i < nodeIndex; i++) {
+            final Node node = nodes[reverseOrder[i]];
             if (node.isLeaf()) {
-                bLowerSpecies[node.getNr()] = true;
+                isLowerSpecies[node.getNr()] = true;
             }
         }
         // find species on the right of selected node
-        final boolean[] bUpperSpecies = new boolean[nrOfSpecies];
-        for (int i = iNode + 1; i < nodes.length; i++) {
-            final Node node = nodes[iReverseOrder[i]];
+        final boolean[] isUpperSpecies = new boolean[nrOfSpecies];
+        for (int i = nodeIndex + 1; i < nodes.length; i++) {
+            final Node node = nodes[reverseOrder[i]];
             if (node.isLeaf()) {
-                bUpperSpecies[node.getNr()] = true;
+                isUpperSpecies[node.getNr()] = true;
             }
         }
 
         // find max
-        double fMax = Double.POSITIVE_INFINITY;
+        double max = Double.POSITIVE_INFINITY;
         for (int i = 0; i < nrOfSpecies; i++) {
-            if (bLowerSpecies[i]) {
+            if (isLowerSpecies[i]) {
                 for (int j = 0; j < nrOfSpecies; j++) {
-                    if (j != i && bUpperSpecies[j]) {
+                    if (j != i && isUpperSpecies[j]) {
                         final int x = Math.min(i, j);
                         final int y = Math.max(i, j);
-                        fMax = Math.min(fMax, fMaxHeight[x][y]);
+                        max = Math.min(max, maxHeight[x][y]);
                     }
                 }
             }
         }
-        return fMax;
+        return max;
     } // calcMaxHeight
 
 
@@ -176,28 +176,28 @@ public class NodeReheight extends TreeOperator {
      * for every species in the left on the gene tree and for every species in the right
      * cap the maximum join height by the lowest place the two join in the gene tree
      */
-    private void findMaximaInGeneTree(final Node node, final boolean[] taxonSet, final Map<Integer, Integer> taxonMap, final double[][] fMaxHeight) {
+    private void findMaximaInGeneTree(final Node node, final boolean[] taxonSet, final Map<Integer, Integer> taxonMap, final double[][] maxHeight) {
         if (node.isLeaf()) {
-            final int iSpecies = taxonMap.get(node.getNr());
-            taxonSet[iSpecies] = true;
+            final int species = taxonMap.get(node.getNr());
+            taxonSet[species] = true;
         } else {
-            final boolean[] bLeftTaxonSet = new boolean[nrOfSpecies];
-            findMaximaInGeneTree(node.getLeft(), bLeftTaxonSet, taxonMap, fMaxHeight);
-            final boolean[] bRightTaxonSet = new boolean[nrOfSpecies];
-            findMaximaInGeneTree(node.getRight(), bRightTaxonSet, taxonMap, fMaxHeight);
+            final boolean[] isLeftTaxonSet = new boolean[nrOfSpecies];
+            findMaximaInGeneTree(node.getLeft(), isLeftTaxonSet, taxonMap, maxHeight);
+            final boolean[] isRightTaxonSet = new boolean[nrOfSpecies];
+            findMaximaInGeneTree(node.getRight(), isRightTaxonSet, taxonMap, maxHeight);
             for (int i = 0; i < nrOfSpecies; i++) {
-                if (bLeftTaxonSet[i]) {
+                if (isLeftTaxonSet[i]) {
                     for (int j = 0; j < nrOfSpecies; j++) {
-                        if (j != i && bRightTaxonSet[j]) {
+                        if (j != i && isRightTaxonSet[j]) {
                             final int x = Math.min(i, j);
                             final int y = Math.max(i, j);
-                            fMaxHeight[x][y] = Math.min(fMaxHeight[x][y], node.getHeight());
+                            maxHeight[x][y] = Math.min(maxHeight[x][y], node.getHeight());
                         }
                     }
                 }
             }
             for (int i = 0; i < nrOfSpecies; i++) {
-                taxonSet[i] = bLeftTaxonSet[i] | bRightTaxonSet[i];
+                taxonSet[i] = isLeftTaxonSet[i] | isRightTaxonSet[i];
             }
         }
     }
@@ -207,90 +207,90 @@ public class NodeReheight extends TreeOperator {
      */
 
 
-    private Node reconstructTree(final double[] fHeights, final int[] iReverseOrder, final int iFrom, final int iTo, final boolean[] bHasParent) {
-        //iNode = maxIndex(fHeights, 0, fHeights.length);
-        int iNode = -1;
-        double fMax = Double.NEGATIVE_INFINITY;
-        for (int j = iFrom; j < iTo; j++) {
-            if (fMax < fHeights[j] && !m_nodes[iReverseOrder[j]].isLeaf()) {
-                fMax = fHeights[j];
-                iNode = j;
+    private Node reconstructTree(final double[] heights, final int[] reverseOrder, final int from, final int to, final boolean[] hasParent) {
+        //nodeIndex = maxIndex(heights, 0, heights.length);
+        int nodeIndex = -1;
+        double max = Double.NEGATIVE_INFINITY;
+        for (int j = from; j < to; j++) {
+            if (max < heights[j] && !m_nodes[reverseOrder[j]].isLeaf()) {
+                max = heights[j];
+                nodeIndex = j;
             }
         }
-        if (iNode < 0) {
+        if (nodeIndex < 0) {
             return null;
         }
-        final Node node = m_nodes[iReverseOrder[iNode]];
+        final Node node = m_nodes[reverseOrder[nodeIndex]];
 
-        //int iLeft = maxIndex(fHeights, 0, iNode);
-        int iLeft = -1;
-        fMax = Double.NEGATIVE_INFINITY;
-        for (int j = iFrom; j < iNode; j++) {
-            if (fMax < fHeights[j] && !bHasParent[j]) {
-                fMax = fHeights[j];
-                iLeft = j;
+        //int left = maxIndex(heights, 0, nodeIndex);
+        int left = -1;
+        max = Double.NEGATIVE_INFINITY;
+        for (int j = from; j < nodeIndex; j++) {
+            if (max < heights[j] && !hasParent[j]) {
+                max = heights[j];
+                left = j;
             }
         }
 
-        //int iRight = maxIndex(fHeights, iNode+1, fHeights.length);
-        int iRight = -1;
-        fMax = Double.NEGATIVE_INFINITY;
-        for (int j = iNode + 1; j < iTo; j++) {
-            if (fMax < fHeights[j] && !bHasParent[j]) {
-                fMax = fHeights[j];
-                iRight = j;
+        //int right = maxIndex(heights, nodeIndex+1, heights.length);
+        int right = -1;
+        max = Double.NEGATIVE_INFINITY;
+        for (int j = nodeIndex + 1; j < to; j++) {
+            if (max < heights[j] && !hasParent[j]) {
+                max = heights[j];
+                right = j;
             }
         }
 
-        node.setLeft(m_nodes[iReverseOrder[iLeft]]);
+        node.setLeft(m_nodes[reverseOrder[left]]);
         node.getLeft().setParent(node);
-        node.setRight(m_nodes[iReverseOrder[iRight]]);
+        node.setRight(m_nodes[reverseOrder[right]]);
         node.getRight().setParent(node);
         if (node.getLeft().isLeaf()) {
-            fHeights[iLeft] = Double.NEGATIVE_INFINITY;
+            heights[left] = Double.NEGATIVE_INFINITY;
         }
         if (node.getRight().isLeaf()) {
-            fHeights[iRight] = Double.NEGATIVE_INFINITY;
+            heights[right] = Double.NEGATIVE_INFINITY;
         }
-        bHasParent[iLeft] = true;
-        bHasParent[iRight] = true;
-        fHeights[iNode] = Double.NEGATIVE_INFINITY;
+        hasParent[left] = true;
+        hasParent[right] = true;
+        heights[nodeIndex] = Double.NEGATIVE_INFINITY;
 
 
-        reconstructTree(fHeights, iReverseOrder, iFrom, iNode, bHasParent);
-        reconstructTree(fHeights, iReverseOrder, iNode, iTo, bHasParent);
+        reconstructTree(heights, reverseOrder, from, nodeIndex, hasParent);
+        reconstructTree(heights, reverseOrder, nodeIndex, to, hasParent);
         return node;
     }
 
     // helper for reconstructTree, to find maximum in range
-//    private int maxIndex(final double[] fHeights, final int iFrom, final int iTo) {
-//        int iMax = -1;
-//        double fMax = Double.NEGATIVE_INFINITY;
-//        for (int i = iFrom; i < iTo; i++) {
-//            if (fMax < fHeights[i]) {
-//                fMax = fHeights[i];
-//                iMax = i;
+//    private int maxIndex(final double[] heights, final int from, final int to) {
+//        int maxIndex = -1;
+//        double max = Double.NEGATIVE_INFINITY;
+//        for (int i = from; i < to; i++) {
+//            if (max < heights[i]) {
+//                max = heights[i];
+//                maxIndex = i;
 //            }
 //        }
-//        return iMax;
+//        return maxIndex;
 //    }
 
    /**
       ** gather height of each node, and the node index associated with the height.*
       **/
-    private int collectHeights(final Node node, final double[] fHeights, final int[] iReverseOrder, int iCurrent) {
+    private int collectHeights(final Node node, final double[] heights, final int[] reverseOrder, int current) {
         if (node.isLeaf()) {
-            fHeights[iCurrent] = node.getHeight();
-            iReverseOrder[iCurrent] = node.getNr();
-            iCurrent++;
+            heights[current] = node.getHeight();
+            reverseOrder[current] = node.getNr();
+            current++;
         } else {
-            iCurrent = collectHeights(node.getLeft(), fHeights, iReverseOrder, iCurrent);
-            fHeights[iCurrent] = node.getHeight();
-            iReverseOrder[iCurrent] = node.getNr();
-            iCurrent++;
-            iCurrent = collectHeights(node.getRight(), fHeights, iReverseOrder, iCurrent);
+            current = collectHeights(node.getLeft(), heights, reverseOrder, current);
+            heights[current] = node.getHeight();
+            reverseOrder[current] = node.getNr();
+            current++;
+            current = collectHeights(node.getRight(), heights, reverseOrder, current);
         }
-        return iCurrent;
+        return current;
     }
 
     /**
diff --git a/src/beast/evolution/operators/RealRandomWalkOperator.java b/src/beast/evolution/operators/RealRandomWalkOperator.java
index 803d2fd..263229a 100644
--- a/src/beast/evolution/operators/RealRandomWalkOperator.java
+++ b/src/beast/evolution/operators/RealRandomWalkOperator.java
@@ -4,8 +4,8 @@ import java.text.DecimalFormat;
 
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.Operator;
 import beast.core.Input.Validate;
+import beast.core.Operator;
 import beast.core.parameter.RealParameter;
 import beast.util.Randomizer;
 
@@ -15,17 +15,18 @@ import beast.util.Randomizer;
 @Description("A random walk operator that selects a random dimension of the real parameter and perturbs the value a " +
         "random amount within +/- windowSize.")
 public class RealRandomWalkOperator extends Operator {
-    public Input<Double> windowSizeInput =
-            new Input<Double>("windowSize", "the size of the window both up and down when using uniform interval OR standard deviation when using Gaussian", Input.Validate.REQUIRED);
-    public Input<RealParameter> parameterInput =
-            new Input<RealParameter>("parameter", "the parameter to operate a random walk on.", Validate.REQUIRED);
-    public Input<Boolean> useGaussianInput =
-            new Input<Boolean>("useGaussian", "Use Gaussian to move instead of uniform interval. Default false.", false);
+    final public Input<Double> windowSizeInput =
+            new Input<>("windowSize", "the size of the window both up and down when using uniform interval OR standard deviation when using Gaussian", Input.Validate.REQUIRED);
+    final public Input<RealParameter> parameterInput =
+            new Input<>("parameter", "the parameter to operate a random walk on.", Validate.REQUIRED);
+    final public Input<Boolean> useGaussianInput =
+            new Input<>("useGaussian", "Use Gaussian to move instead of uniform interval. Default false.", false);
 
     double windowSize = 1;
     boolean useGaussian;
 
-    public void initAndValidate() {
+    @Override
+	public void initAndValidate() {
         windowSize = windowSizeInput.get();
         useGaussian = useGaussianInput.get();
     }
@@ -68,8 +69,8 @@ public class RealRandomWalkOperator extends Operator {
     }
 
     @Override
-    public void setCoercableParameterValue(double fValue) {
-        windowSize = fValue;
+    public void setCoercableParameterValue(double value) {
+        windowSize = value;
     }
 
     /**
@@ -82,10 +83,10 @@ public class RealRandomWalkOperator extends Operator {
     @Override
     public void optimize(double logAlpha) {
         // must be overridden by operator implementation to have an effect
-        double fDelta = calcDelta(logAlpha);
+        double delta = calcDelta(logAlpha);
 
-        fDelta += Math.log(windowSize);
-        windowSize = Math.exp(fDelta);
+        delta += Math.log(windowSize);
+        windowSize = Math.exp(delta);
     }
 
     @Override
diff --git a/src/beast/evolution/operators/ScaleOperator.java b/src/beast/evolution/operators/ScaleOperator.java
index 8af180a..7fbe151 100644
--- a/src/beast/evolution/operators/ScaleOperator.java
+++ b/src/beast/evolution/operators/ScaleOperator.java
@@ -25,6 +25,8 @@
 package beast.evolution.operators;
 
 
+import java.text.DecimalFormat;
+
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.Operator;
@@ -34,36 +36,34 @@ import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
 import beast.util.Randomizer;
 
-import java.text.DecimalFormat;
-
 
 @Description("Scales a parameter or a complete beast.tree (depending on which of the two is specified.")
 public class ScaleOperator extends Operator {
 
-    public final Input<Tree> treeInput = new Input<Tree>("tree", "if specified, all beast.tree divergence times are scaled");
+    public final Input<Tree> treeInput = new Input<>("tree", "if specified, all beast.tree divergence times are scaled");
 
-    public final Input<RealParameter> parameterInput = new Input<RealParameter>("parameter", "if specified, this parameter is scaled",
+    public final Input<RealParameter> parameterInput = new Input<>("parameter", "if specified, this parameter is scaled",
             Input.Validate.XOR, treeInput);
 
-    public final Input<Double> scaleFactorInput = new Input<Double>("scaleFactor", "scaling factor: larger means more bold proposals", 1.0);
+    public final Input<Double> scaleFactorInput = new Input<>("scaleFactor", "scaling factor: larger means more bold proposals", 1.0);
     public final Input<Boolean> scaleAllInput =
-            new Input<Boolean>("scaleAll", "if true, all elements of a parameter (not beast.tree) are scaled, otherwise one is randomly selected",
+            new Input<>("scaleAll", "if true, all elements of a parameter (not beast.tree) are scaled, otherwise one is randomly selected",
                     false);
     public final Input<Boolean> scaleAllIndependentlyInput =
-            new Input<Boolean>("scaleAllIndependently", "if true, all elements of a parameter (not beast.tree) are scaled with " +
+            new Input<>("scaleAllIndependently", "if true, all elements of a parameter (not beast.tree) are scaled with " +
                     "a different factor, otherwise a single factor is used", false);
 
-    public Input<Integer> degreesOfFreedomInput = new Input<Integer>("degreesOfFreedom", "Degrees of freedom used when " +
+    final public Input<Integer> degreesOfFreedomInput = new Input<>("degreesOfFreedom", "Degrees of freedom used when " +
             "scaleAllIndependently=false and scaleAll=true to override default in calculation of Hasting ratio. " +
             "Ignored when less than 1, default 0.", 0);
-    public Input<BooleanParameter> indicatorInput = new Input<BooleanParameter>("indicator", "indicates which of the dimension " +
+    final public Input<BooleanParameter> indicatorInput = new Input<>("indicator", "indicates which of the dimension " +
             "of the parameters can be scaled. Only used when scaleAllIndependently=false and scaleAll=false. If not specified " +
             "it is assumed all dimensions are allowed to be scaled.");
-    public Input<Boolean> rootOnlyInput = new Input<Boolean>("rootOnly", "scale root of a tree only, ignored if tree is not specified (default false)", false);
-    public Input<Boolean> optimiseInput = new Input<Boolean>("optimise", "flag to indicate that the scale factor is automatically changed in order to achieve a good acceptance rate (default true)", true);
+    final public Input<Boolean> rootOnlyInput = new Input<>("rootOnly", "scale root of a tree only, ignored if tree is not specified (default false)", false);
+    final public Input<Boolean> optimiseInput = new Input<>("optimise", "flag to indicate that the scale factor is automatically changed in order to achieve a good acceptance rate (default true)", true);
 
-    public Input<Double> scaleUpperLimit = new Input<Double>("upper", "Upper Limit of scale factor", 1.0 - 1e-8);
-    public Input<Double> scaleLowerLimit = new Input<Double>("lower", "Lower limit of scale factor", 1e-8);
+    final public Input<Double> scaleUpperLimit = new Input<>("upper", "Upper Limit of scale factor", 1.0 - 1e-8);
+    final public Input<Double> scaleLowerLimit = new Input<>("lower", "Lower limit of scale factor", 1e-8);
 
     /**
      * shadows input *
@@ -77,7 +77,7 @@ public class ScaleOperator extends Operator {
     boolean m_bIsTreeScaler = true;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         m_fScaleFactor = scaleFactorInput.get();
         m_bIsTreeScaler = (treeInput.get() != null);
         upper = scaleUpperLimit.get();
@@ -86,12 +86,12 @@ public class ScaleOperator extends Operator {
         final BooleanParameter indicators = indicatorInput.get();
         if (indicators != null) {
             if (m_bIsTreeScaler) {
-                throw new Exception("indicator is specified which has no effect for scaling a tree");
+                throw new IllegalArgumentException("indicator is specified which has no effect for scaling a tree");
             }
             final int dataDim = parameterInput.get().getDimension();
             final int indsDim = indicators.getDimension();
             if (!(indsDim == dataDim || indsDim + 1 == dataDim)) {
-                throw new Exception("indicator dimension not compatible from parameter dimension");
+                throw new IllegalArgumentException("indicator dimension not compatible from parameter dimension");
             }
         }
     }
@@ -127,24 +127,24 @@ public class ScaleOperator extends Operator {
                 final Tree tree = treeInput.get(this);
                 if (rootOnlyInput.get()) {
                     final Node root = tree.getRoot();
-                    final double fNewHeight = root.getHeight() * scale;
+                    final double newHeight = root.getHeight() * scale;
 
-                    if (fNewHeight < Math.max(root.getLeft().getHeight(), root.getRight().getHeight())) {
+                    if (newHeight < Math.max(root.getLeft().getHeight(), root.getRight().getHeight())) {
                         return Double.NEGATIVE_INFINITY;
                     }
-                    root.setHeight(fNewHeight);
+                    root.setHeight(newHeight);
                     return -Math.log(scale);
                 } else {
                     // scale the beast.tree
-                    final int nInternalNodes = tree.scale(scale);
-                    return Math.log(scale) * (nInternalNodes - 2);
+                    final int internalNodes = tree.scale(scale);
+                    return Math.log(scale) * (internalNodes - 2);
                 }
             }
 
             // not a tree scaler, so scale a parameter
-            final boolean bScaleAll = scaleAllInput.get();
-            final int nDegreesOfFreedom = degreesOfFreedomInput.get();
-            final boolean bScaleAllIndependently = scaleAllIndependentlyInput.get();
+            final boolean scaleAll = scaleAllInput.get();
+            final int degreesOfFreedom = degreesOfFreedomInput.get();
+            final boolean scaleAllIndependently = scaleAllIndependentlyInput.get();
 
             final RealParameter param = parameterInput.get(this);
 
@@ -152,14 +152,14 @@ public class ScaleOperator extends Operator {
 
             final int dim = param.getDimension();
 
-            if (bScaleAllIndependently) {
+            if (scaleAllIndependently) {
                 // update all dimensions independently.
                 hastingsRatio = 0;
                 final BooleanParameter indicators = indicatorInput.get();
                 if (indicators != null) {
-                    final int nDim = indicators.getDimension();
+                    final int dimCount = indicators.getDimension();
                     final Boolean[] indicator = indicators.getValues();
-                    final boolean impliedOne = nDim == (dim - 1);
+                    final boolean impliedOne = dimCount == (dim - 1);
                     for (int i = 0; i < dim; i++) {
                         if( (impliedOne && (i == 0 || indicator[i-1])) || (!impliedOne && indicator[i]) )  {
                             final double scaleOne = getScaler();
@@ -190,11 +190,11 @@ public class ScaleOperator extends Operator {
                         param.setValue(i, newValue);
                     }
                 }
-            } else if (bScaleAll) {
+            } else if (scaleAll) {
                 // update all dimensions
                 // hasting ratio is dim-2 times of 1dim case. would be nice to have a reference here
                 // for the proof. It is supposed to be somewhere in an Alexei/Nicholes article.
-                final int df = (nDegreesOfFreedom > 0) ? nDegreesOfFreedom - 2 : dim - 2;
+                final int df = (degreesOfFreedom > 0) ? degreesOfFreedom - 2 : dim - 2;
                 hastingsRatio = df * Math.log(scale);
 
                 // all Values assumed independent!
@@ -213,27 +213,27 @@ public class ScaleOperator extends Operator {
                 final int index;
                 final BooleanParameter indicators = indicatorInput.get();
                 if (indicators != null) {
-                    final int nDim = indicators.getDimension();
+                    final int dimCount = indicators.getDimension();
                     final Boolean[] indicator = indicators.getValues();
-                    final boolean impliedOne = nDim == (dim - 1);
+                    final boolean impliedOne = dimCount == (dim - 1);
 
                     // available bit locations. there can be hundreds of them. scan list only once.
-                    final int[] loc = new int[nDim + 1];
-                    int nLoc = 0;
+                    final int[] loc = new int[dimCount + 1];
+                    int locIndex = 0;
 
                     if (impliedOne) {
-                        loc[nLoc] = 0;
-                        ++nLoc;
+                        loc[locIndex] = 0;
+                        ++locIndex;
                     }
-                    for (int i = 0; i < nDim; i++) {
+                    for (int i = 0; i < dimCount; i++) {
                         if (indicator[i]) {
-                            loc[nLoc] = i + (impliedOne ? 1 : 0);
-                            ++nLoc;
+                            loc[locIndex] = i + (impliedOne ? 1 : 0);
+                            ++locIndex;
                         }
                     }
 
-                    if (nLoc > 0) {
-                        final int rand = Randomizer.nextInt(nLoc);
+                    if (locIndex > 0) {
+                        final int rand = Randomizer.nextInt(locIndex);
                         index = loc[rand];
                     } else {
                         return Double.NEGATIVE_INFINITY; // no active indicators
@@ -278,9 +278,9 @@ public class ScaleOperator extends Operator {
     @Override
     public void optimize(final double logAlpha) {
         if (optimiseInput.get()) {
-            double fDelta = calcDelta(logAlpha);
-            fDelta += Math.log(1.0 / m_fScaleFactor - 1.0);
-            setCoercableParameterValue(1.0 / (Math.exp(fDelta) + 1.0));
+            double delta = calcDelta(logAlpha);
+            delta += Math.log(1.0 / m_fScaleFactor - 1.0);
+            setCoercableParameterValue(1.0 / (Math.exp(delta) + 1.0));
         }
     }
 
@@ -290,8 +290,8 @@ public class ScaleOperator extends Operator {
     }
 
     @Override
-    public void setCoercableParameterValue(final double fValue) {
-        m_fScaleFactor = Math.max(Math.min(fValue, upper), lower);
+    public void setCoercableParameterValue(final double value) {
+        m_fScaleFactor = Math.max(Math.min(value, upper), lower);
     }
 
     @Override
diff --git a/src/beast/evolution/operators/SliceOperator.java b/src/beast/evolution/operators/SliceOperator.java
index 47d3c38..1b2b3b7 100644
--- a/src/beast/evolution/operators/SliceOperator.java
+++ b/src/beast/evolution/operators/SliceOperator.java
@@ -5,10 +5,11 @@ import java.text.DecimalFormat;
 import beast.core.Description;
 import beast.core.Distribution;
 import beast.core.Input;
-import beast.core.Operator;
 import beast.core.Input.Validate;
+import beast.core.Operator;
 import beast.core.parameter.RealParameter;
 import beast.core.util.Evaluator;
+import beast.core.util.Log;
 import beast.util.Randomizer;
 
 
@@ -17,12 +18,12 @@ import beast.util.Randomizer;
 @Description("A random walk operator that selects a random dimension of the real parameter and perturbs the value a " +
         "random amount within +/- windowSize.")
 public class SliceOperator extends Operator {
-    public Input<RealParameter> parameterInput =
-            new Input<RealParameter>("parameter", "the parameter to operate a random walk on.", Validate.REQUIRED);
-    public Input<Double> windowSizeInput =
-            new Input<Double>("windowSize", "the size of the step for finding the slice boundaries", Input.Validate.REQUIRED);
-    public Input<Distribution> sliceDensityInput =
-            new Input<Distribution>("sliceDensity", "The density to sample from using slice sampling.", Input.Validate.REQUIRED);
+    final public Input<RealParameter> parameterInput =
+            new Input<>("parameter", "the parameter to operate a random walk on.", Validate.REQUIRED);
+    final public Input<Double> windowSizeInput =
+            new Input<>("windowSize", "the size of the step for finding the slice boundaries", Input.Validate.REQUIRED);
+    final public Input<Distribution> sliceDensityInput =
+            new Input<>("sliceDensity", "The density to sample from using slice sampling.", Input.Validate.REQUIRED);
 
     Double totalDelta;
     int totalNumber;
@@ -32,7 +33,8 @@ public class SliceOperator extends Operator {
     double windowSize = 1;
     Distribution sliceDensity;
 
-    public void initAndValidate() {
+    @Override
+	public void initAndValidate() {
         totalDelta = 0.0;
         totalNumber = 0;
         n_learning_iterations = 100;
@@ -53,7 +55,8 @@ public class SliceOperator extends Operator {
         return (x > X.getUpper());
     }
 
-    public Distribution getEvaluatorDistribution() {
+    @Override
+	public Distribution getEvaluatorDistribution() {
         return sliceDensity;
     }
 
@@ -143,10 +146,10 @@ public class SliceOperator extends Operator {
             else
                 L = x1;
         }
-        System.err.println("Warning!  Is size of the interval really ZERO?");
+        Log.warning.println("Warning!  Is size of the interval really ZERO?");
         //	double logy_x0 = evaluate(E,X,x0);
-        System.err.println("    L0 = " + L0 + "   x0 = " + x0 + "   R0 = " + R0 + "   gx0 = " + gx0);
-        System.err.println("    L  = " + L + "   x1 = " + x1 + "   R  = " + R0 + "   gx1 = " + evaluate(E));
+        Log.warning.println("    L0 = " + L0 + "   x0 = " + x0 + "   R0 = " + R0 + "   gx0 = " + gx0);
+        Log.warning.println("    L  = " + L + "   x1 = " + x1 + "   R  = " + R0 + "   gx1 = " + evaluate(E));
 
         return x0;
     }
@@ -212,8 +215,8 @@ public class SliceOperator extends Operator {
     }
 
     @Override
-    public void setCoercableParameterValue(double fValue) {
-        windowSize = fValue;
+    public void setCoercableParameterValue(double value) {
+        windowSize = value;
     }
 
     /**
@@ -226,10 +229,10 @@ public class SliceOperator extends Operator {
     @Override
     public void optimize(double logAlpha) {
         // must be overridden by operator implementation to have an effect
-        double fDelta = calcDelta(logAlpha);
+        double delta = calcDelta(logAlpha);
 
-        fDelta += Math.log(windowSize);
-        windowSize = Math.exp(fDelta);
+        delta += Math.log(windowSize);
+        windowSize = Math.exp(delta);
     }
 
     @Override
diff --git a/src/beast/evolution/operators/SubtreeSlide.java b/src/beast/evolution/operators/SubtreeSlide.java
index 2190b18..2bb72bc 100644
--- a/src/beast/evolution/operators/SubtreeSlide.java
+++ b/src/beast/evolution/operators/SubtreeSlide.java
@@ -50,16 +50,16 @@
 package beast.evolution.operators;
 
 
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.List;
+
 import beast.core.Description;
 import beast.core.Input;
 import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
 import beast.util.Randomizer;
 
-import java.text.DecimalFormat;
-import java.util.ArrayList;
-import java.util.List;
-
 
 /**
  * Implements the subtree slide move.
@@ -70,18 +70,18 @@ import java.util.List;
         "slide down into.")
 public class SubtreeSlide extends TreeOperator {
 
-    public Input<Double> sizeInput = new Input<Double>("size", "size of the slide, default 1.0", 1.0);
-    public Input<Boolean> gaussianInput = new Input<Boolean>("gaussian", "Gaussian (=true=default) or uniform delta", true);
-    public Input<Boolean> optimiseInput = new Input<Boolean>("optimise", "flag to indicate that the scale factor is automatically changed in order to achieve a good acceptance rate (default true)", true);
-    public Input<Double> limitInput = new Input<Double>("limit", "limit on step size, default disable, " +
+    final public Input<Double> sizeInput = new Input<>("size", "size of the slide, default 1.0", 1.0);
+    final public Input<Boolean> gaussianInput = new Input<>("gaussian", "Gaussian (=true=default) or uniform delta", true);
+    final public Input<Boolean> optimiseInput = new Input<>("optimise", "flag to indicate that the scale factor is automatically changed in order to achieve a good acceptance rate (default true)", true);
+    final public Input<Double> limitInput = new Input<>("limit", "limit on step size, default disable, " +
             "i.e. -1. (when positive, gets multiplied by tree-height/log2(n-taxa).", -1.0);
     // shadows size
-    double fSize;
+    double size;
     private double limit;
 
     @Override
     public void initAndValidate() {
-        fSize = sizeInput.get();
+        size = sizeInput.get();
         limit = limitInput.get();
     }
 
@@ -99,18 +99,18 @@ public class SubtreeSlide extends TreeOperator {
         Node i;
         final boolean markClades = markCladesInput.get();
         // 1. choose a random node avoiding root
-        final int nNodes = tree.getNodeCount();
+        final int nodeCount = tree.getNodeCount();
         do {
-            i = tree.getNode(Randomizer.nextInt(nNodes));
+            i = tree.getNode(Randomizer.nextInt(nodeCount));
         } while (i.isRoot());
 
-        final Node iP = i.getParent();
-        final Node CiP = getOtherChild(iP, i);
-        final Node PiP = iP.getParent();
+        final Node p = i.getParent();
+        final Node CiP = getOtherChild(p, i);
+        final Node PiP = p.getParent();
 
         // 2. choose a delta to move
         final double delta = getDelta();
-        final double oldHeight = iP.getHeight();
+        final double oldHeight = p.getHeight();
         final double newHeight = oldHeight + delta;
 
         // 3. if the move is up
@@ -120,32 +120,32 @@ public class SubtreeSlide extends TreeOperator {
             if (PiP != null && PiP.getHeight() < newHeight) {
                 // find new parent
                 Node newParent = PiP;
-                Node newChild = iP;
+                Node newChild = p;
                 while (newParent.getHeight() < newHeight) {
                     newChild = newParent;
                     if( markClades ) newParent.makeDirty(Tree.IS_FILTHY); // JH
                     newParent = newParent.getParent();
                     if (newParent == null) break;
                 }
-                // the moved node 'iP' would become a child of 'newParent'
+                // the moved node 'p' would become a child of 'newParent'
                 //
 
                 // 3.1.1 if creating a new root
                 if (newChild.isRoot()) {
-                    replace(iP, CiP, newChild);
-                    replace(PiP, iP, CiP);
+                    replace(p, CiP, newChild);
+                    replace(PiP, p, CiP);
 
-                    iP.setParent(null);
-                    tree.setRoot(iP);
+                    p.setParent(null);
+                    tree.setRoot(p);
                 }
                 // 3.1.2 no new root
                 else {
-                    replace(iP, CiP, newChild);
-                    replace(PiP, iP, CiP);
-                    replace(newParent, newChild, iP);
+                    replace(p, CiP, newChild);
+                    replace(PiP, p, CiP);
+                    replace(newParent, newChild, p);
                 }
 
-                iP.setHeight(newHeight);
+                p.setHeight(newHeight);
 
                 // 3.1.3 count the hypothetical sources of this destination.
                 final int possibleSources = intersectingEdges(newChild, oldHeight, null);
@@ -155,7 +155,7 @@ public class SubtreeSlide extends TreeOperator {
 
             } else {
                 // just change the node height
-                iP.setHeight(newHeight);
+                p.setHeight(newHeight);
                 logq = 0.0;
             }
         }
@@ -170,7 +170,7 @@ public class SubtreeSlide extends TreeOperator {
             // 4.1 will the move change the topology
             if (CiP.getHeight() > newHeight) {
 
-                final List<Node> newChildren = new ArrayList<Node>();
+                final List<Node> newChildren = new ArrayList<>();
                 final int possibleDestinations = intersectingEdges(CiP, newHeight, newChildren);
 
                 // if no valid destinations then return a failure
@@ -183,25 +183,25 @@ public class SubtreeSlide extends TreeOperator {
                 final Node newChild = newChildren.get(childIndex);
                 final Node newParent = newChild.getParent();
 
-                // 4.1.1 if iP was root
-                if (iP.isRoot()) {
+                // 4.1.1 if p was root
+                if (p.isRoot()) {
                     // new root is CiP
-                    replace(iP, CiP, newChild);
-                    replace(newParent, newChild, iP);
+                    replace(p, CiP, newChild);
+                    replace(newParent, newChild, p);
 
                     CiP.setParent(null);
                     tree.setRoot(CiP);
 
                 } else {
-                    replace(iP, CiP, newChild);
-                    replace(PiP, iP, CiP);
-                    replace(newParent, newChild, iP);
+                    replace(p, CiP, newChild);
+                    replace(PiP, p, CiP);
+                    replace(newParent, newChild, p);
                 }
 
-                iP.setHeight(newHeight);
+                p.setHeight(newHeight);
                 if( markClades ) {
                     // make dirty the path from the (down) moved node back up to former parent.
-                    Node n = iP;
+                    Node n = p;
                     while( n != CiP ) {
                         n.makeDirty(Tree.IS_FILTHY); // JH
                         n = n.getParent();
@@ -210,7 +210,7 @@ public class SubtreeSlide extends TreeOperator {
 
                 logq = Math.log(possibleDestinations);
             } else {
-                iP.setHeight(newHeight);
+                p.setHeight(newHeight);
                 logq = 0.0;
             }
         }
@@ -219,9 +219,9 @@ public class SubtreeSlide extends TreeOperator {
 
     private double getDelta() {
         if (!gaussianInput.get()) {
-            return (Randomizer.nextDouble() * fSize) - (fSize / 2.0);
+            return (Randomizer.nextDouble() * size) - (size / 2.0);
         } else {
-            return Randomizer.nextGaussian() * fSize;
+            return Randomizer.nextGaussian() * size;
         }
     }
 
@@ -251,32 +251,32 @@ public class SubtreeSlide extends TreeOperator {
     @Override
     public void optimize(final double logAlpha) {
         if (optimiseInput.get() && ! Double.isInfinite(logAlpha) ) {
-            double fDelta = calcDelta(logAlpha);
-            fDelta += Math.log(fSize);
-            final double f = Math.exp(fDelta);
-//            double f = Math.exp(fDelta);
+            double delta = calcDelta(logAlpha);
+            delta += Math.log(size);
+            final double f = Math.exp(delta);
+//            double f = Math.exp(delta);
             if( limit > 0 ) {
                 final Tree tree = treeInput.get();
                 final double h = tree.getRoot().getHeight();
                 final double k = Math.log(tree.getLeafNodeCount()) / Math.log(2);
                 final double lim = (h / k) * limit;
                 if( f <= lim ) {
-                    fSize = f;
+                    size = f;
                 }
             } else {
-               fSize = f;
+               size = f;
             }
         }
     }
 
     @Override
     public double getCoercableParameterValue() {
-        return fSize;
+        return size;
     }
 
     @Override
-    public void setCoercableParameterValue(final double fValue) {
-        fSize = fValue;
+    public void setCoercableParameterValue(final double value) {
+        size = value;
     }
 
     @Override
@@ -289,7 +289,7 @@ public class SubtreeSlide extends TreeOperator {
         if (ratio > 2.0) ratio = 2.0;
         if (ratio < 0.5) ratio = 0.5;
 
-        final double newDelta = fSize * ratio;
+        final double newDelta = size * ratio;
 
         final DecimalFormat formatter = new DecimalFormat("#.###");
         if (prob < 0.10) {
diff --git a/src/beast/evolution/operators/SwapOperator.java b/src/beast/evolution/operators/SwapOperator.java
index 4d05009..f5da861 100644
--- a/src/beast/evolution/operators/SwapOperator.java
+++ b/src/beast/evolution/operators/SwapOperator.java
@@ -6,8 +6,8 @@ import java.util.List;
 
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.Operator;
 import beast.core.Input.Validate;
+import beast.core.Operator;
 import beast.core.parameter.IntegerParameter;
 import beast.core.parameter.Parameter;
 import beast.core.parameter.RealParameter;
@@ -17,9 +17,9 @@ import beast.util.Randomizer;
 
 @Description("A generic operator swapping a one or more pairs in a multi-dimensional parameter")
 public class SwapOperator extends Operator {
-    public Input<RealParameter> parameterInput = new Input<RealParameter>("parameter", "a real parameter to swap individual values for");
-    public Input<IntegerParameter> intparameterInput = new Input<IntegerParameter>("intparameter", "an integer parameter to swap individual values for", Validate.XOR, parameterInput);
-    public Input<Integer> howManyInput = new Input<Integer>("howMany", "number of items to swap, default 1, must be less than half the dimension of the parameter", 1);
+    final public Input<RealParameter> parameterInput = new Input<>("parameter", "a real parameter to swap individual values for");
+    final public Input<IntegerParameter> intparameterInput = new Input<>("intparameter", "an integer parameter to swap individual values for", Validate.XOR, parameterInput);
+    final public Input<Integer> howManyInput = new Input<>("howMany", "number of items to swap, default 1, must be less than half the dimension of the parameter", 1);
 
 
     int howMany;
@@ -27,7 +27,7 @@ public class SwapOperator extends Operator {
     private List<Integer> masterList = null;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         if (parameterInput.get() != null) {
             parameter = parameterInput.get();
         } else {
@@ -36,10 +36,10 @@ public class SwapOperator extends Operator {
 
         howMany = howManyInput.get();
         if (howMany * 2 > parameter.getDimension()) {
-            throw new Exception("howMany it too large: must be less than half the dimension of the parameter");
+            throw new IllegalArgumentException("howMany it too large: must be less than half the dimension of the parameter");
         }
 
-        List<Integer> list = new ArrayList<Integer>();
+        List<Integer> list = new ArrayList<>();
         for (int i = 0; i < parameter.getDimension(); i++) {
             list.add(i);
         }
@@ -48,7 +48,7 @@ public class SwapOperator extends Operator {
 
     @Override
     public double proposal() {
-        List<Integer> allIndices = new ArrayList<Integer>(masterList);
+        List<Integer> allIndices = new ArrayList<>(masterList);
         int left, right;
 
         for (int i = 0; i < howMany; i++) {
diff --git a/src/beast/evolution/operators/TipDatesRandomWalker.java b/src/beast/evolution/operators/TipDatesRandomWalker.java
index 4cfbc02..9268b9f 100644
--- a/src/beast/evolution/operators/TipDatesRandomWalker.java
+++ b/src/beast/evolution/operators/TipDatesRandomWalker.java
@@ -15,13 +15,13 @@ import beast.util.Randomizer;
 @Description("Randomly moves tip dates on a tree by randomly selecting one from (a subset of) taxa")
 public class TipDatesRandomWalker extends TreeOperator {
     // perhaps multiple trees may be necessary if they share the same taxon?
-    // public Input<List<Tree>> m_treesInput = new Input<List<Tree>>("tree" ,"tree to operate on", new ArrayList<Tree>(), Validate.REQUIRED);
+    // public Input<List<Tree>> m_treesInput = new Input<>("tree" ,"tree to operate on", new ArrayList<>(), Validate.REQUIRED);
 
-    public Input<Double> windowSizeInput =
-            new Input<Double>("windowSize", "the size of the window both up and down when using uniform interval OR standard deviation when using Gaussian", Input.Validate.REQUIRED);
-    public Input<TaxonSet> m_taxonsetInput = new Input<TaxonSet>("taxonset", "limit scaling to a subset of taxa. By default all tips are scaled.");
-    public Input<Boolean> useGaussianInput =
-            new Input<Boolean>("useGaussian", "Use Gaussian to move instead of uniform interval. Default false.", false);
+    final public Input<Double> windowSizeInput =
+            new Input<>("windowSize", "the size of the window both up and down when using uniform interval OR standard deviation when using Gaussian", Input.Validate.REQUIRED);
+    final public Input<TaxonSet> m_taxonsetInput = new Input<>("taxonset", "limit scaling to a subset of taxa. By default all tips are scaled.");
+    final public Input<Boolean> useGaussianInput =
+            new Input<>("useGaussian", "Use Gaussian to move instead of uniform interval. Default false.", false);
 
     /**
      * node indices of taxa to choose from *
@@ -37,27 +37,27 @@ public class TipDatesRandomWalker extends TreeOperator {
     boolean reflectValue = true;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         windowSize = windowSizeInput.get();
         useGaussian = useGaussianInput.get();
 
         // determine taxon set to choose from
         if (m_taxonsetInput.get() != null) {
-            List<String> sTaxaNames = new ArrayList<String>();
-            for (String sTaxon : treeInput.get().getTaxaNames()) {
-                sTaxaNames.add(sTaxon);
+            List<String> taxaNames = new ArrayList<>();
+            for (String taxon : treeInput.get().getTaxaNames()) {
+                taxaNames.add(taxon);
             }
 
             List<String> set = m_taxonsetInput.get().asStringList();
-            int nNrOfTaxa = set.size();
-            taxonIndices = new int[nNrOfTaxa];
+            int nrOfTaxa = set.size();
+            taxonIndices = new int[nrOfTaxa];
             int k = 0;
-            for (String sTaxon : set) {
-                int iTaxon = sTaxaNames.indexOf(sTaxon);
-                if (iTaxon < 0) {
-                    throw new Exception("Cannot find taxon " + sTaxon + " in tree");
+            for (String taxon : set) {
+                int taxonIndex = taxaNames.indexOf(taxon);
+                if (taxonIndex < 0) {
+                    throw new IllegalArgumentException("Cannot find taxon " + taxon + " in tree");
                 }
-                taxonIndices[k++] = iTaxon;
+                taxonIndices[k++] = taxonIndex;
             }
         } else {
             taxonIndices = new int[treeInput.get().getTaxaNames().length];
@@ -152,16 +152,16 @@ public class TipDatesRandomWalker extends TreeOperator {
     }
 
     @Override
-    public void setCoercableParameterValue(double fValue) {
-        windowSize = fValue;
+    public void setCoercableParameterValue(double value) {
+        windowSize = value;
     }
 
     @Override
     public void optimize(double logAlpha) {
         // must be overridden by operator implementation to have an effect
-        double fDelta = calcDelta(logAlpha);
-        fDelta += Math.log(windowSize);
-        windowSize = Math.exp(fDelta);
+        double delta = calcDelta(logAlpha);
+        delta += Math.log(windowSize);
+        windowSize = Math.exp(delta);
     }
 
     @Override
diff --git a/src/beast/evolution/operators/TipDatesScaler.java b/src/beast/evolution/operators/TipDatesScaler.java
index f3b1d5c..fbf51fa 100644
--- a/src/beast/evolution/operators/TipDatesScaler.java
+++ b/src/beast/evolution/operators/TipDatesScaler.java
@@ -16,10 +16,10 @@ import beast.util.Randomizer;
 @Description("Scales tip dates on a tree by randomly selecting one from (a subset of) taxa")
 public class TipDatesScaler extends TreeOperator {
     // perhaps multiple trees may be necessary if they share the same taxon?
-    // public Input<List<Tree>> m_treesInput = new Input<List<Tree>>("tree" ,"tree to operate on", new ArrayList<Tree>(), Validate.REQUIRED);
+    // public Input<List<Tree>> m_treesInput = new Input<>("tree" ,"tree to operate on", new ArrayList<>(), Validate.REQUIRED);
 
-    public Input<Double> scaleFactorInput = new Input<Double>("scaleFactor", "scaling factor: larger means more bold proposals", 1.0);
-    public Input<TaxonSet> taxonsetInput = new Input<TaxonSet>("taxonset", "limit scaling to a subset of taxa. By default all tips are scaled.");
+    final public Input<Double> scaleFactorInput = new Input<>("scaleFactor", "scaling factor: larger means more bold proposals", 1.0);
+    final public Input<TaxonSet> taxonsetInput = new Input<>("taxonset", "limit scaling to a subset of taxa. By default all tips are scaled.");
 
     /**
      * shadows input *
@@ -31,26 +31,26 @@ public class TipDatesScaler extends TreeOperator {
     int[] taxonIndices;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         scaleFactor = scaleFactorInput.get();
 
         // determine taxon set to choose from
         if (taxonsetInput.get() != null) {
-            List<String> sTaxaNames = new ArrayList<String>();
-            for (String sTaxon : treeInput.get().getTaxaNames()) {
-                sTaxaNames.add(sTaxon);
+            List<String> taxaNames = new ArrayList<>();
+            for (String taxon : treeInput.get().getTaxaNames()) {
+                taxaNames.add(taxon);
             }
 
             List<String> set = taxonsetInput.get().asStringList();
-            int nNrOfTaxa = set.size();
-            taxonIndices = new int[nNrOfTaxa];
+            int nrOfTaxa = set.size();
+            taxonIndices = new int[nrOfTaxa];
             int k = 0;
-            for (String sTaxon : set) {
-                int iTaxon = sTaxaNames.indexOf(sTaxon);
-                if (iTaxon < 0) {
-                    throw new Exception("Cannot find taxon " + sTaxon + " in tree");
+            for (String taxon : set) {
+                int taxonIndex = taxaNames.indexOf(taxon);
+                if (taxonIndex < 0) {
+                    throw new IllegalArgumentException("Cannot find taxon " + taxon + " in tree");
                 }
-                taxonIndices[k++] = iTaxon;
+                taxonIndices[k++] = taxonIndex;
             }
         } else {
             taxonIndices = new int[treeInput.get().getTaxaNames().length];
@@ -67,21 +67,21 @@ public class TipDatesScaler extends TreeOperator {
         // randomly select leaf node
         int i = Randomizer.nextInt(taxonIndices.length);
         Node node = tree.getNode(taxonIndices[i]);
-        double fUpper = node.getParent().getHeight();
-        //double fLower = 0.0;
-        //final double newValue = (Randomizer.nextDouble() * (fUpper -fLower)) + fLower;
+        double upper = node.getParent().getHeight();
+        //double lower = 0.0;
+        //final double newValue = (Randomizer.nextDouble() * (upper -lower)) + lower;
 
         // scale node
-        double fScale = (scaleFactor + (Randomizer.nextDouble() * ((1.0 / scaleFactor) - scaleFactor)));
-        final double newValue = node.getHeight() * fScale;
+        double scale = (scaleFactor + (Randomizer.nextDouble() * ((1.0 / scaleFactor) - scaleFactor)));
+        final double newValue = node.getHeight() * scale;
 
         // check the tree does not get negative branch lengths
-        if (newValue > fUpper) {
+        if (newValue > upper) {
             return Double.NEGATIVE_INFINITY;
         }
         node.setHeight(newValue);
 
-        return -Math.log(fScale);
+        return -Math.log(scale);
     }
 
     @Override
@@ -90,16 +90,16 @@ public class TipDatesScaler extends TreeOperator {
     }
 
     @Override
-    public void setCoercableParameterValue(double fValue) {
-        scaleFactor = fValue;
+    public void setCoercableParameterValue(double value) {
+        scaleFactor = value;
     }
 
 
     @Override
     public void optimize(double logAlpha) {
-        double fDelta = calcDelta(logAlpha);
-        fDelta += Math.log(1.0 / scaleFactor - 1.0);
-        scaleFactor = 1.0 / (Math.exp(fDelta) + 1.0);
+        double delta = calcDelta(logAlpha);
+        delta += Math.log(1.0 / scaleFactor - 1.0);
+        scaleFactor = 1.0 / (Math.exp(delta) + 1.0);
     }
 
     @Override
diff --git a/src/beast/evolution/operators/TreeOperator.java b/src/beast/evolution/operators/TreeOperator.java
index b187bf9..a734e09 100644
--- a/src/beast/evolution/operators/TreeOperator.java
+++ b/src/beast/evolution/operators/TreeOperator.java
@@ -27,16 +27,16 @@ package beast.evolution.operators;
 
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.Operator;
 import beast.core.Input.Validate;
+import beast.core.Operator;
 import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
 
 
 @Description("This operator changes a beast.tree.")
 abstract public class TreeOperator extends Operator {
-    public Input<Tree> treeInput = new Input<Tree>("tree", "beast.tree on which this operation is performed", Validate.REQUIRED);
-    public Input<Boolean> markCladesInput = new Input<>("markclades", "Mark all ancestors of nodes changed by the operator as changed," +
+    final public Input<Tree> treeInput = new Input<>("tree", "beast.tree on which this operation is performed", Validate.REQUIRED);
+    final public Input<Boolean> markCladesInput = new Input<>("markclades", "Mark all ancestors of nodes changed by the operator as changed," +
             " up to the MRCA of all nodes changed by the operator.", false);
 
     /**
diff --git a/src/beast/evolution/operators/Uniform.java b/src/beast/evolution/operators/Uniform.java
index 6042fa1..9f32ece 100644
--- a/src/beast/evolution/operators/Uniform.java
+++ b/src/beast/evolution/operators/Uniform.java
@@ -86,7 +86,7 @@ public class Uniform extends TreeOperator {
         final Tree tree = treeInput.get(this);
 
         // randomly select internal node
-        final int nNodeCount = tree.getNodeCount();
+        final int nodeCount = tree.getNodeCount();
         
         // Abort if no non-root internal nodes
         if (tree.getInternalNodeCount()==1)
@@ -94,12 +94,12 @@ public class Uniform extends TreeOperator {
         
         Node node;
         do {
-            final int iNodeNr = nNodeCount / 2 + 1 + Randomizer.nextInt(nNodeCount / 2);
-            node = tree.getNode(iNodeNr);
+            final int nodeNr = nodeCount / 2 + 1 + Randomizer.nextInt(nodeCount / 2);
+            node = tree.getNode(nodeNr);
         } while (node.isRoot() || node.isLeaf());
-        final double fUpper = node.getParent().getHeight();
-        final double fLower = Math.max(node.getLeft().getHeight(), node.getRight().getHeight());
-        final double newValue = (Randomizer.nextDouble() * (fUpper - fLower)) + fLower;
+        final double upper = node.getParent().getHeight();
+        final double lower = Math.max(node.getLeft().getHeight(), node.getRight().getHeight());
+        final double newValue = (Randomizer.nextDouble() * (upper - lower)) + lower;
         node.setHeight(newValue);
 
         return 0.0;
diff --git a/src/beast/evolution/operators/UniformOperator.java b/src/beast/evolution/operators/UniformOperator.java
index 6aa7923..c1440bd 100644
--- a/src/beast/evolution/operators/UniformOperator.java
+++ b/src/beast/evolution/operators/UniformOperator.java
@@ -2,8 +2,8 @@ package beast.evolution.operators;
 
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.Operator;
 import beast.core.Input.Validate;
+import beast.core.Operator;
 import beast.core.parameter.IntegerParameter;
 import beast.core.parameter.Parameter;
 import beast.core.parameter.RealParameter;
@@ -11,30 +11,30 @@ import beast.util.Randomizer;
 
 @Description("Assign one or more parameter values to a uniformly selected value in its range.")
 public class UniformOperator extends Operator {
-    public Input<Parameter<?>> parameterInput = new Input<Parameter<?>>("parameter", "a real or integer parameter to sample individual values for", Validate.REQUIRED, Parameter.class);
-    public Input<Integer> howManyInput = new Input<Integer>("howMany", "number of items to sample, default 1, must be less than the dimension of the parameter", 1);
+    final public Input<Parameter<?>> parameterInput = new Input<>("parameter", "a real or integer parameter to sample individual values for", Validate.REQUIRED, Parameter.class);
+    final public Input<Integer> howManyInput = new Input<>("howMany", "number of items to sample, default 1, must be less than the dimension of the parameter", 1);
 
     int howMany;
     Parameter<?> parameter;
-    double fLower, fUpper;
-    int iLower, iUpper;
+    double lower, upper;
+    int lowerIndex, upperIndex;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         parameter = parameterInput.get();
         if (parameter instanceof RealParameter) {
-            fLower = (Double) parameter.getLower();
-            fUpper = (Double) parameter.getUpper();
+            lower = (Double) parameter.getLower();
+            upper = (Double) parameter.getUpper();
         } else if (parameter instanceof IntegerParameter) {
-            iLower = (Integer) parameter.getLower();
-            iUpper = (Integer) parameter.getUpper();
+            lowerIndex = (Integer) parameter.getLower();
+            upperIndex = (Integer) parameter.getUpper();
         } else {
-            throw new Exception("parameter should be a RealParameter or IntergerParameter, not " + parameter.getClass().getName());
+            throw new IllegalArgumentException("parameter should be a RealParameter or IntergerParameter, not " + parameter.getClass().getName());
         }
 
         howMany = howManyInput.get();
         if (howMany > parameter.getDimension()) {
-            throw new Exception("howMany it too large: must be less than the dimension of the parameter");
+            throw new IllegalArgumentException("howMany it too large: must be less than the dimension of the parameter");
         }
     }
 
@@ -45,10 +45,10 @@ public class UniformOperator extends Operator {
             int index = Randomizer.nextInt(parameter.getDimension());
 
             if (parameter instanceof IntegerParameter) {
-                int newValue = Randomizer.nextInt(iUpper - iLower + 1) + iLower; // from 0 to n-1, n must > 0,
+                int newValue = Randomizer.nextInt(upperIndex - lowerIndex + 1) + lowerIndex; // from 0 to n-1, n must > 0,
                 ((IntegerParameter) parameter).setValue(index, newValue);
             } else {
-                double newValue = Randomizer.nextDouble() * (fUpper - fLower) + fLower;
+                double newValue = Randomizer.nextDouble() * (upper - lower) + lower;
                 ((RealParameter) parameter).setValue(index, newValue);
             }
 
diff --git a/src/beast/evolution/operators/UpDownOperator.java b/src/beast/evolution/operators/UpDownOperator.java
index 58e0133..c56e76e 100644
--- a/src/beast/evolution/operators/UpDownOperator.java
+++ b/src/beast/evolution/operators/UpDownOperator.java
@@ -7,11 +7,12 @@ import java.util.List;
 
 import beast.core.Description;
 import beast.core.Input;
+import beast.core.Input.Validate;
 import beast.core.Operator;
 import beast.core.StateNode;
-import beast.core.Input.Validate;
 import beast.core.parameter.Parameter;
 import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
 import beast.util.Randomizer;
 
 
@@ -20,30 +21,30 @@ import beast.util.Randomizer;
         "The up parameter is multiplied by this scale and the down parameter is divided by this scale.")
 public class UpDownOperator extends Operator {
 
-    public Input<Double> scaleFactorInput = new Input<Double>("scaleFactor",
+    final public Input<Double> scaleFactorInput = new Input<>("scaleFactor",
             "magnitude factor used for scaling", Validate.REQUIRED);
-    public Input<List<StateNode>> upInput = new Input<List<StateNode>>("up",
-            "zero or more items to scale upwards", new ArrayList<StateNode>());
-    public Input<List<StateNode>> downInput = new Input<List<StateNode>>("down",
-            "zero or more items to scale downwards", new ArrayList<StateNode>());
-    public Input<Boolean> optimiseInput = new Input<Boolean>("optimise", "flag to indicate that the scale factor is automatically changed in order to acheive a good acceptance rate (default true)", true);
-    public Input<Boolean> elementWiseInput = new Input<Boolean>("elementWise", "flag to indicate that the scaling is applied to a random index in multivariate parameters (default false)", false);
+    final public Input<List<StateNode>> upInput = new Input<>("up",
+            "zero or more items to scale upwards", new ArrayList<>());
+    final public Input<List<StateNode>> downInput = new Input<>("down",
+            "zero or more items to scale downwards", new ArrayList<>());
+    final public Input<Boolean> optimiseInput = new Input<>("optimise", "flag to indicate that the scale factor is automatically changed in order to acheive a good acceptance rate (default true)", true);
+    final public Input<Boolean> elementWiseInput = new Input<>("elementWise", "flag to indicate that the scaling is applied to a random index in multivariate parameters (default false)", false);
 
-    public Input<Double> scaleUpperLimit = new Input<Double>("upper", "Upper Limit of scale factor", 1.0);
-    public Input<Double> scaleLowerLimit = new Input<Double>("lower", "Lower limit of scale factor", 0.0);
+    final public Input<Double> scaleUpperLimit = new Input<>("upper", "Upper Limit of scale factor", 1.0);
+    final public Input<Double> scaleLowerLimit = new Input<>("lower", "Lower limit of scale factor", 0.0);
 
     double scaleFactor;
     private double upper,lower;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         scaleFactor = scaleFactorInput.get();
         // sanity checks
         if (upInput.get().size() + downInput.get().size() == 0) {
-            System.err.println("WARNING: At least one up or down item must be specified");
+        	Log.warning.println("WARNING: At least one up or down item must be specified");
         }
         if (upInput.get().size() == 0 || downInput.get().size() == 0) {
-            System.err.println("WARNING: no " + (upInput.get().size() == 0 ? "up" : "down") + " item specified in UpDownOperator");
+        	Log.warning.println("WARNING: no " + (upInput.get().size() == 0 ? "up" : "down") + " item specified in UpDownOperator");
         }
         upper = scaleUpperLimit.get();
         lower = scaleLowerLimit.get();
@@ -137,7 +138,7 @@ public class UpDownOperator extends Operator {
 
     private boolean outsideBounds(final StateNode node) {
         if (node instanceof Parameter<?>) {
-            final Parameter<?> p = (Parameter) node;
+            final Parameter<?> p = (Parameter<?>) node;
             final Double lower = (Double) p.getLower();
             final Double upper = (Double) p.getUpper();
             final Double value = (Double) p.getValue();
@@ -154,9 +155,9 @@ public class UpDownOperator extends Operator {
     @Override
     public void optimize(final double logAlpha) {
         if (optimiseInput.get()) {
-            double fDelta = calcDelta(logAlpha);
-            fDelta += Math.log(1.0 / scaleFactor - 1.0);
-            setCoercableParameterValue(1.0 / (Math.exp(fDelta) + 1.0) );
+            double delta = calcDelta(logAlpha);
+            delta += Math.log(1.0 / scaleFactor - 1.0);
+            setCoercableParameterValue(1.0 / (Math.exp(delta) + 1.0) );
         }
     }
 
@@ -166,8 +167,8 @@ public class UpDownOperator extends Operator {
     }
 
     @Override
-    public void setCoercableParameterValue(final double fValue) {
-        scaleFactor = Math.max(Math.min(fValue,upper),lower);
+    public void setCoercableParameterValue(final double value) {
+        scaleFactor = Math.max(Math.min(value,upper),lower);
     }
 
     @Override
diff --git a/src/beast/evolution/operators/WilsonBalding.java b/src/beast/evolution/operators/WilsonBalding.java
index a5a057b..c2cd7bd 100644
--- a/src/beast/evolution/operators/WilsonBalding.java
+++ b/src/beast/evolution/operators/WilsonBalding.java
@@ -81,7 +81,7 @@ public class WilsonBalding extends TreeOperator {
     public double proposal() {
         Tree tree = treeInput.get(this);
 
-        double oldMinAge, newMinAge, newRange, oldRange, newAge, fHastingsRatio;
+        double oldMinAge, newMinAge, newRange, oldRange, newAge, hastingsRatio;
 
         // choose a random node avoiding root
         final int nodeCount = tree.getNodeCount();
@@ -89,7 +89,7 @@ public class WilsonBalding extends TreeOperator {
         do {
             i = tree.getNode(Randomizer.nextInt(nodeCount));
         } while (i.isRoot());
-        final Node iP = i.getParent();
+        final Node p = i.getParent();
 
         // choose another random node to insert i above
         Node j;
@@ -102,30 +102,30 @@ public class WilsonBalding extends TreeOperator {
         } while ((jP != null && jP.getHeight() <= i.getHeight()) || (i.getNr() == j.getNr()));
 
         // disallow moves that change the root.
-        if (j.isRoot() || iP.isRoot()) {
+        if (j.isRoot() || p.isRoot()) {
             return Double.NEGATIVE_INFINITY;
         }
 
         assert jP != null;  // j != root tested above
-        final int iPnr = iP.getNr();
+        final int pnr = p.getNr();
         final int jPnr = jP.getNr();
-        if ( jPnr == iPnr || j.getNr() == iPnr || jPnr == i.getNr())
+        if ( jPnr == pnr || j.getNr() == pnr || jPnr == i.getNr())
             return Double.NEGATIVE_INFINITY;
 
-        final Node CiP = getOtherChild(iP, i);
+        final Node CiP = getOtherChild(p, i);
 
-        final Node PiP = iP.getParent();
+        final Node PiP = p.getParent();
 
         newMinAge = Math.max(i.getHeight(), j.getHeight());
         newRange = jP.getHeight() - newMinAge;
         newAge = newMinAge + (Randomizer.nextDouble() * newRange);
         oldMinAge = Math.max(i.getHeight(), CiP.getHeight());
         oldRange = PiP.getHeight() - oldMinAge;
-        fHastingsRatio = newRange / Math.abs(oldRange);
+        hastingsRatio = newRange / Math.abs(oldRange);
 
         if (oldRange == 0 || newRange == 0) {
             // This happens when some branch lengths are zero.
-            // If oldRange = 0, fHastingsRatio == Double.POSITIVE_INFINITY and
+            // If oldRange = 0, hastingsRatio == Double.POSITIVE_INFINITY and
             // node i can be catapulted anywhere in the tree, resulting in
             // very bad trees that are always accepted.
             // For symmetry, newRange = 0 should therefore be ruled out as well
@@ -136,44 +136,44 @@ public class WilsonBalding extends TreeOperator {
 
         //update
 //        if (j.isRoot()) {
-//            // 1. remove edges <iP, CiP>
-//            // 2. add edges <k, iP>, <iP, j>, <PiP, CiP>
+//            // 1. remove edges <p, CiP>
+//            // 2. add edges <k, p>, <p, j>, <PiP, CiP>
 //
-//            replace(iP, CiP, j);
-//            replace(PiP, iP, CiP);
+//            replace(p, CiP, j);
+//            replace(PiP, p, CiP);
 //
-//            // iP is the new root
-//            iP.setParent(null);
-//            tree.setRoot(iP);
+//            // p is the new root
+//            p.setParent(null);
+//            tree.setRoot(p);
 //
-//        } else if (iP.isRoot()) {
-//            // 1. remove edges <k, j>, <iP, CiP>, <PiP, iP>
-//            // 2. add edges <k, iP>, <iP, j>, <PiP, CiP>
+//        } else if (p.isRoot()) {
+//            // 1. remove edges <k, j>, <p, CiP>, <PiP, p>
+//            // 2. add edges <k, p>, <p, j>, <PiP, CiP>
 //
-//            replace(jP, j, iP);
-//            //replace(iP, CiP, iP);
-//            replace(iP, CiP, j);
+//            replace(jP, j, p);
+//            //replace(p, CiP, p);
+//            replace(p, CiP, j);
 //
 //            // CiP is the new root
 //            CiP.setParent(null);
 //            tree.setRoot(CiP);
 //
 //        } else {
-//            // 1. remove edges <k, j>, <iP, CiP>, <PiP, iP>
-            // 2. add edges <k, iP>, <iP, j>, <PiP, CiP>
+//            // 1. remove edges <k, j>, <p, CiP>, <PiP, p>
+            // 2. add edges <k, p>, <p, j>, <PiP, CiP>
 
-            // disconnect iP
-            final Node iPP = iP.getParent();
-            replace(iPP, iP, CiP);
-            // re-attach, first child node to iP
-            replace(iP, CiP, j);
-            // then parent node of j to iP
-            replace(jP, j, iP);
+            // disconnect p
+            final Node pP = p.getParent();
+            replace(pP, p, CiP);
+            // re-attach, first child node to p
+            replace(p, CiP, j);
+            // then parent node of j to p
+            replace(jP, j, p);
 
         // mark paths to common ancestor as changed
             if( markCladesInput.get() ) {
-                Node iup = iPP;
-                Node jup = iP;
+                Node iup = pP;
+                Node jup = p;
                 while (iup != jup) {
                     if( iup.getHeight() < jup.getHeight() ) {
                         assert !iup.isRoot();
@@ -189,9 +189,9 @@ public class WilsonBalding extends TreeOperator {
 
 //        }
 
-        iP.setHeight(newAge);
+        p.setHeight(newAge);
 
-        return Math.log(fHastingsRatio);
+        return Math.log(hastingsRatio);
     }
 
 
diff --git a/src/beast/evolution/sitemodel/SiteModel.java b/src/beast/evolution/sitemodel/SiteModel.java
index 730de94..293a070 100644
--- a/src/beast/evolution/sitemodel/SiteModel.java
+++ b/src/beast/evolution/sitemodel/SiteModel.java
@@ -33,6 +33,7 @@ import org.apache.commons.math.distribution.GammaDistributionImpl;
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
 import beast.evolution.substitutionmodel.SubstitutionModel;
 import beast.evolution.tree.Node;
 
@@ -50,14 +51,14 @@ import beast.evolution.tree.Node;
 public class SiteModel extends SiteModelInterface.Base {
 
 
-    public Input<RealParameter> muParameterInput = new Input<RealParameter>("mutationRate", "mutation rate (defaults to 1.0)");
-    public Input<Integer> gammaCategoryCount =
-            new Input<Integer>("gammaCategoryCount", "gamma category count (default=zero for no gamma)", 0);
-    public Input<RealParameter> shapeParameterInput =
-            new Input<RealParameter>("shape", "shape parameter of gamma distribution. Ignored if gammaCategoryCount 1 or less");
-    public Input<RealParameter> invarParameterInput =
-            new Input<RealParameter>("proportionInvariant", "proportion of sites that is invariant: should be between 0 (default) and 1");
-    //public Input<Boolean> useBeast1StyleGammaInput = new Input<Boolean>("useBeast1Gamma", "use BEAST1 style gamma categories -- for backward compatibility testing", false);
+    final public Input<RealParameter> muParameterInput = new Input<>("mutationRate", "mutation rate (defaults to 1.0)");
+    final public Input<Integer> gammaCategoryCount =
+            new Input<>("gammaCategoryCount", "gamma category count (default=zero for no gamma)", 0);
+    final public Input<RealParameter> shapeParameterInput =
+            new Input<>("shape", "shape parameter of gamma distribution. Ignored if gammaCategoryCount 1 or less");
+    final public Input<RealParameter> invarParameterInput =
+            new Input<>("proportionInvariant", "proportion of sites that is invariant: should be between 0 (default) and 1");
+    //public Input<Boolean> useBeast1StyleGammaInput = new Input<>("useBeast1Gamma", "use BEAST1 style gamma categories -- for backward compatibility testing", false);
 
     RealParameter muParameter;
     RealParameter shapeParameter;
@@ -65,7 +66,7 @@ public class SiteModel extends SiteModelInterface.Base {
     boolean useBeast1StyleGamma;
     
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
     	useBeast1StyleGamma = true; //useBeast1StyleGammaInput.get();
         muParameter = muParameterInput.get();
         if (muParameter == null) {
@@ -92,7 +93,7 @@ public class SiteModel extends SiteModelInterface.Base {
 
 
         if (/*invarParameter != null && */(invarParameter.getValue() < 0 || invarParameter.getValue() > 1)) {
-            throw new Exception("proportion invariant should be between 0 and 1");
+            throw new IllegalArgumentException("proportion invariant should be between 0 and 1");
         }
         refresh();
 
@@ -107,7 +108,7 @@ public class SiteModel extends SiteModelInterface.Base {
             categoryCount = gammaCategoryCount.get();
             if (categoryCount < 1) {
             	if (categoryCount < 0) {
-            		System.out.println("SiteModel: Invalid category count (" + categoryCount + ") Setting category count to 1");
+            		Log.warning.println("SiteModel: Invalid category count (" + categoryCount + ") Setting category count to 1");
             	}
                 categoryCount = 1;
             }
@@ -271,7 +272,7 @@ public class SiteModel extends SiteModelInterface.Base {
 
                 } catch (Exception e) {
                     e.printStackTrace();
-                    System.err.println("Something went wrong with the gamma distribution calculation");
+                    Log.err.println("Something went wrong with the gamma distribution calculation");
                     System.exit(-1);
                 }
                 mean += categoryRates[i + cat];
@@ -344,13 +345,12 @@ public class SiteModel extends SiteModelInterface.Base {
      * @param shape shape parameter
      * @param scale scale parameter
      * @return icdf value
-     * @throws Exception if arguments out of range
      */
-    protected double GammaDistributionQuantile(double y, double shape, double scale) throws Exception {
+    protected double GammaDistributionQuantile(double y, double shape, double scale) {
         return 0.5 * scale * pointChi2(y, 2.0 * shape);
     }
 
-    double pointChi2(double prob, double v) throws Exception {
+    double pointChi2(double prob, double v) {
         // Returns z so that Prob{x<z}=prob where x is Chi2 distributed with df
         // = v
         // RATNEST FORTRAN by
@@ -361,7 +361,7 @@ public class SiteModel extends SiteModelInterface.Base {
         double xx, c, ch, a, q, p1, p2, t, x, b, s1, s2, s3, s4, s5, s6;
 
         if (prob < 0.000002 || prob > 0.999998 || v <= 0) {
-            throw new Exception("Error SiteModel 102: Arguments out of range");
+            throw new IllegalArgumentException("Error SiteModel 102: Arguments out of range");
         }
         g = GammaFunctionlnGamma(v / 2);
         xx = v / 2;
@@ -399,7 +399,7 @@ public class SiteModel extends SiteModelInterface.Base {
             q = ch;
             p1 = 0.5 * ch;
             if ((t = GammaFunctionincompleteGammaP(xx, p1, g)) < 0) {
-                throw new Exception("Error SiteModel 101: Arguments out of range: t < 0");
+                throw new IllegalArgumentException("Error SiteModel 101: Arguments out of range: t < 0");
             }
             p2 = prob - t;
             t = p2 * Math.exp(xx * aa + g + p1 - c * Math.log(ch));
@@ -462,9 +462,8 @@ public class SiteModel extends SiteModelInterface.Base {
      * @param x        argument
      * @param lnGammaA precomputed lnGamma(a)
      * @return function value
-     * @throws Exception if illegal arguments given
      */
-    double GammaFunctionincompleteGammaP(double a, double x, double lnGammaA) throws Exception {
+    double GammaFunctionincompleteGammaP(double a, double x, double lnGammaA) {
         return incompleteGamma(x, a, lnGammaA);
     }
 
@@ -477,9 +476,8 @@ public class SiteModel extends SiteModelInterface.Base {
      * @param alpha          shape parameter
      * @param ln_gamma_alpha the log gamma function for alpha
      * @return the incomplete gamma ratio
-     * @throws Exception if illegal arguments given
      */
-    double incompleteGamma(double x, double alpha, double ln_gamma_alpha) throws Exception {
+    double incompleteGamma(double x, double alpha, double ln_gamma_alpha) {
         // (1) series expansion     if (alpha>x || x<=1)
         // (2) continued fraction   otherwise
         // RATNEST FORTRAN by
@@ -494,7 +492,7 @@ public class SiteModel extends SiteModelInterface.Base {
             return 0.0;
         }
         if (x < 0.0 || alpha <= 0.0) {
-            throw new Exception("Error SiteModel 103: Arguments out of bounds");
+            throw new IllegalArgumentException("Error SiteModel 103: Arguments out of bounds");
         }
 
         factor = Math.exp(alpha * Math.log(x) - x - ln_gamma_alpha);
@@ -557,7 +555,7 @@ public class SiteModel extends SiteModelInterface.Base {
         return gin;
     }
 
-    double NormalDistributionQuantile(double z, double m, double sd) throws Exception {
+    double NormalDistributionQuantile(double z, double m, double sd) {
         return m + Math.sqrt(2.0) * sd * ErrorFunctionInverseErf(2.0 * z - 1.0);
     }
 
@@ -566,9 +564,8 @@ public class SiteModel extends SiteModelInterface.Base {
      *
      * @param z argument
      * @return function value
-     * @throws Exception argument out of range
      */
-    double ErrorFunctionInverseErf(double z) throws Exception {
+    double ErrorFunctionInverseErf(double z) {
         return ErrorFunctionPointNormal(0.5 * z + 0.5) / Math.sqrt(2.0);
     }
 
@@ -577,7 +574,7 @@ public class SiteModel extends SiteModelInterface.Base {
 
     // Returns z so that Prob{x<z}=prob where x ~ N(0,1) and (1e-12) < prob<1-(1e-12)
 
-    double ErrorFunctionPointNormal(double prob) throws Exception {
+    double ErrorFunctionPointNormal(double prob) {
         // Odeh RE & Evans JO (1974) The percentage points of the normal distribution.
         // Applied Statistics 22: 96-97 (AS70)
 
@@ -594,7 +591,7 @@ public class SiteModel extends SiteModelInterface.Base {
 
         p1 = (prob < 0.5 ? prob : 1 - prob);
         if (p1 < 1e-20) {
-            throw new Exception("Error SiteModel 104: Argument prob out of range");
+            throw new IllegalArgumentException("Error SiteModel 104: Argument prob out of range");
         }
 
         y = Math.sqrt(Math.log(1 / (p1 * p1)));
@@ -602,7 +599,8 @@ public class SiteModel extends SiteModelInterface.Base {
         return (prob < 0.5 ? -z : z);
     }
 
-    public double getProportionInvariant() {
+    @Override
+	public double getProportionInvariant() {
         //if (invarParameter == null) {
         //	return 0;
         //}
diff --git a/src/beast/evolution/sitemodel/SiteModelInterface.java b/src/beast/evolution/sitemodel/SiteModelInterface.java
index a364038..a7877c6 100644
--- a/src/beast/evolution/sitemodel/SiteModelInterface.java
+++ b/src/beast/evolution/sitemodel/SiteModelInterface.java
@@ -1,5 +1,8 @@
 package beast.evolution.sitemodel;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import beast.core.CalculationNode;
 import beast.core.Description;
 import beast.core.Input;
@@ -10,9 +13,6 @@ import beast.evolution.likelihood.TreeLikelihood;
 import beast.evolution.substitutionmodel.SubstitutionModel;
 import beast.evolution.tree.Node;
 
-import java.util.ArrayList;
-import java.util.List;
-
 
 
 
@@ -35,8 +35,8 @@ 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 {
-    	public Input<SubstitutionModel.Base> substModelInput =
-                new Input<SubstitutionModel.Base>("substModel", "substitution model along branches in the beast.tree", null, Validate.REQUIRED);
+    	final public Input<SubstitutionModel.Base> substModelInput =
+                new Input<>("substModel", "substitution model along branches in the beast.tree", null, Validate.REQUIRED);
 
     	/**
          * Specifies whether SiteModel should integrate over the different categories at
@@ -102,9 +102,9 @@ public interface SiteModelInterface {
             final SubstitutionModel substModel = (SubstitutionModel) o;
             if (m_dataType == null) {
             	// try to find out the data type from the data in a treelikelihood in an output
-            	for (Object plugin : getOutputs()) {
-            		if (plugin instanceof TreeLikelihood) {
-            			TreeLikelihood likelihood = (TreeLikelihood) plugin;
+            	for (Object beastObject : getOutputs()) {
+            		if (beastObject instanceof TreeLikelihood) {
+            			TreeLikelihood likelihood = (TreeLikelihood) beastObject;
             			m_dataType = likelihood.dataInput.get().getDataType();
             			break;
             		}
@@ -128,8 +128,8 @@ public interface SiteModelInterface {
          */
         public boolean hasPropInvariantCategory = true;
 
-        public void setPropInvariantIsCategory(final boolean bPropInvariantIsCategory) {
-            hasPropInvariantCategory = bPropInvariantIsCategory;
+        public void setPropInvariantIsCategory(final boolean propInvariantIsCategory) {
+            hasPropInvariantCategory = propInvariantIsCategory;
             refresh();
         }
 
@@ -169,7 +169,7 @@ public interface SiteModelInterface {
         public void addCondition(final Input<? extends StateNode> stateNode) {
             if (stateNode.get() == null) return;
 
-            if (conditions == null) conditions = new ArrayList<String>();
+            if (conditions == null) conditions = new ArrayList<>();
 
             conditions.add(stateNode.get().getID());
         }
diff --git a/src/beast/evolution/speciation/BirthDeathGernhard08Model.java b/src/beast/evolution/speciation/BirthDeathGernhard08Model.java
index 5902562..31f2208 100644
--- a/src/beast/evolution/speciation/BirthDeathGernhard08Model.java
+++ b/src/beast/evolution/speciation/BirthDeathGernhard08Model.java
@@ -26,6 +26,10 @@
 package beast.evolution.speciation;
 
 
+import static org.apache.commons.math.special.Gamma.logGamma;
+
+import java.util.Arrays;
+
 import beast.core.Citation;
 import beast.core.Description;
 import beast.core.Input;
@@ -33,10 +37,6 @@ import beast.core.Input.Validate;
 import beast.core.parameter.RealParameter;
 import beast.evolution.tree.TreeInterface;
 
-import java.util.Arrays;
-
-import static org.apache.commons.math.special.Gamma.logGamma;
-
 /* Ported from Beast 1.6
  * @author Joseph Heled
  *         Date: 24/02/2008
@@ -58,28 +58,28 @@ public class BirthDeathGernhard08Model extends YuleModel {
 
     final static String[] TYPES = {"unscaled", "timesonly", "oriented", "labeled"};
 
-    public Input<String> typeInput =
-            new Input<String>("type", "tree type, should be one of " + Arrays.toString(TYPES) + " (default unscaled)",
+    final public Input<String> typeInput =
+            new Input<>("type", "tree type, should be one of " + Arrays.toString(TYPES) + " (default unscaled)",
                     "unscaled", TYPES);
-    public Input<RealParameter> relativeDeathRateParameterInput =
-            new Input<RealParameter>("relativeDeathRate", "relative death rate parameter, mu/lambda in birth death model", Validate.REQUIRED);
-    public Input<RealParameter> sampleProbabilityInput =
-            new Input<RealParameter>("sampleProbability", "sample probability, rho in birth/death model");
+    final public Input<RealParameter> relativeDeathRateParameterInput =
+            new Input<>("relativeDeathRate", "relative death rate parameter, mu/lambda in birth death model", Validate.REQUIRED);
+    final public Input<RealParameter> sampleProbabilityInput =
+            new Input<>("sampleProbability", "sample probability, rho in birth/death model");
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
-        final String sType = typeInput.get().toLowerCase();
-        if (sType.equals("unscaled")) {
+        final String typeName = typeInput.get().toLowerCase();
+        if (typeName.equals("unscaled")) {
             type = TreeType.UNSCALED;
-        } else if (sType.equals("timesonly")) {
+        } else if (typeName.equals("timesonly")) {
             type = TreeType.TIMESONLY;
-        } else if (sType.equals("oriented")) {
+        } else if (typeName.equals("oriented")) {
             type = TreeType.ORIENTED;
-        } else if (sType.equals("labeled")) {
+        } else if (typeName.equals("labeled")) {
             type = TreeType.LABELED;
         } else {
-            throw new Exception("type '" + sType + "' is not recognized. Should be one of unscaled, timesonly, oriented and labeled.");
+            throw new IllegalArgumentException("type '" + typeName + "' is not recognized. Should be one of unscaled, timesonly, oriented and labeled.");
         }
     }
 
@@ -104,7 +104,8 @@ public class BirthDeathGernhard08Model extends YuleModel {
     /**
      * scaling coefficient of tree *
      */
-    protected double logCoeff(final int taxonCount) {
+    @Override
+	protected double logCoeff(final int taxonCount) {
         switch (type) {
             case UNSCALED:
                 break;
diff --git a/src/beast/evolution/speciation/CalibratedBirthDeathModel.java b/src/beast/evolution/speciation/CalibratedBirthDeathModel.java
index b14835d..af82441 100644
--- a/src/beast/evolution/speciation/CalibratedBirthDeathModel.java
+++ b/src/beast/evolution/speciation/CalibratedBirthDeathModel.java
@@ -1,10 +1,20 @@
 package beast.evolution.speciation;
 
 
-import beast.core.*;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.math.MathException;
+
+import beast.core.Description;
+import beast.core.Distribution;
+import beast.core.Input;
 import beast.core.Input.Validate;
 import beast.core.parameter.RealParameter;
 import beast.core.util.CompoundDistribution;
+import beast.core.util.Log;
 import beast.evolution.alignment.TaxonSet;
 import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
@@ -12,11 +22,6 @@ import beast.evolution.tree.TreeInterface;
 import beast.math.distributions.MRCAPrior;
 import beast.math.statistic.RPNcalculator;
 
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 /**
 * @author Joseph Heled
  */
@@ -41,7 +46,8 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
             this.ename = name;
         }
 
-        public String toString() {
+        @Override
+		public String toString() {
             return ename;
         }
 
@@ -49,28 +55,28 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
     }
 
     // Q2R does this makes sense, or it has to be a realParameter??
-    public Input<RealParameter> birthRateInput =
-            new Input<RealParameter>("birthRate", "birth rate - the rate at which new lineages are created as a result of an " +
+    final public Input<RealParameter> birthRateInput =
+            new Input<>("birthRate", "birth rate - the rate at which new lineages are created as a result of an " +
                     "existing lineage splitting into two.", Validate.REQUIRED);
 
-    public Input<RealParameter> deathToBirthRatioInput =
-            new Input<RealParameter>("relativeDeathRate", "relative death rate parameter, mu/lambda in birth death model",
+    final public Input<RealParameter> deathToBirthRatioInput =
+            new Input<>("relativeDeathRate", "relative death rate parameter, mu/lambda in birth death model",
                     Validate.OPTIONAL);
 
-    public Input<RealParameter> sampleProbabilityInput =
-            new Input<RealParameter>("sampleProbability", "sample probability, rho in birth/death model",
+    final public Input<RealParameter> sampleProbabilityInput =
+            new Input<>("sampleProbability", "sample probability, rho in birth/death model",
                     Validate.OPTIONAL);
 
-    public Input<List<CalibrationPoint>> calibrationsInput =
-            new Input<List<CalibrationPoint>>("calibrations", "Set of calibrated nodes", new ArrayList<CalibrationPoint>());
+    final public Input<List<CalibrationPoint>> calibrationsInput =
+            new Input<>("calibrations", "Set of calibrated nodes", new ArrayList<>());
 
-    public Input<Type> correctionTypeInput = new Input<Type>("type", "Type of correction: none for no correction " +
+    final public Input<Type> correctionTypeInput = new Input<>("type", "Type of correction: none for no correction " +
             "(same as BEAST1), full for Yule-like over calibrated times, and restricted for Yule-like over calibrated" +
             " times and ranked topology (default 'full'). However, 'full'" +
             " is generally slow except for a few special cases, such as a single clade or two nested clades.",
             Type.OVER_ALL_TOPOS, Type.values());
 
-    public Input<RPNcalculator> userMarInput = new Input<RPNcalculator>("logMarginal",
+    final public Input<RPNcalculator> userMarInput = new Input<>("logMarginal",
             "Use provided formula to compute the (log of) the marginal for special cases.",
             (RPNcalculator) null);
 
@@ -100,7 +106,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
 
         type = correctionTypeInput.get();
@@ -108,11 +114,11 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
         final TreeInterface tree = treeInput.get();
 
         // shallow copy. we shall change cals later
-        final List<CalibrationPoint> cals = new ArrayList<CalibrationPoint>(calibrationsInput.get());
-        int nCals = cals.size();
-        final List<TaxonSet> taxaSets = new ArrayList<TaxonSet>(nCals);
+        final List<CalibrationPoint> cals = new ArrayList<>(calibrationsInput.get());
+        int calCount = cals.size();
+        final List<TaxonSet> taxaSets = new ArrayList<>(calCount);
         if (cals.size() > 0) {
-            xclades = new int[nCals][];
+            xclades = new int[calCount][];
 
             // convenience
             for (final CalibrationPoint cal : cals) {
@@ -121,9 +127,9 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
 
         } else {
             // find calibration points from prior
-            for (final Object plugin : getOutputs()) {
-                if (plugin instanceof CompoundDistribution) {
-                    final CompoundDistribution prior = (CompoundDistribution) plugin;
+            for (final Object beastObject : getOutputs()) {
+                if (beastObject instanceof CompoundDistribution) {
+                    final CompoundDistribution prior = (CompoundDistribution) beastObject;
                     for (final Distribution distr : prior.pDistributions.get()) {
                         if (distr instanceof MRCAPrior) {
                             final MRCAPrior _MRCAPrior = (MRCAPrior) distr;
@@ -131,7 +137,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
                             if (_MRCAPrior.distInput.get() != null) {
                                 // make sure MRCAPrior is monophyletic
                                 if (!_MRCAPrior.isMonophyleticInput.get()) {
-                                    throw new Exception("MRCAPriors must be monophyletic for Calibrated Yule prior");
+                                    throw new IllegalArgumentException("MRCAPriors must be monophyletic for Calibrated Yule prior");
                                 }
                                 // create CalibrationPoint from MRCAPrior
                                 final CalibrationPoint cal = new CalibrationPoint();
@@ -141,37 +147,37 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
                                 cals.add(cal);
                                 taxaSets.add(cal.taxa());
                                 cal.taxa().initAndValidate();
-                                nCals++;
+                                calCount++;
                                 calcCalibrations = false;
                             } else {
                                 if (_MRCAPrior.isMonophyleticInput.get()) {
-                                    System.err.println("WARNING: MRCAPriors must have a distribution when monophyletic for Calibrated Yule prior");
+                                    Log.warning.println("WARNING: MRCAPriors must have a distribution when monophyletic for Calibrated Yule prior");
                                 }
                             }
                         }
                     }
                 }
             }
-            xclades = new int[nCals][];
+            xclades = new int[calCount][];
         }
-        if (nCals == 0) {
+        if (calCount == 0) {
             // assume we are in beauti, back off for now
             return;
         }
 
-        for (int k = 0; k < nCals; ++k) {
+        for (int k = 0; k < calCount; ++k) {
             final TaxonSet tk = taxaSets.get(k);
-            for (int i = k + 1; i < nCals; ++i) {
+            for (int i = k + 1; i < calCount; ++i) {
                 final TaxonSet ti = taxaSets.get(i);
                 if (ti.containsAny(tk)) {
                     if (!(ti.containsAll(tk) || tk.containsAll(ti))) {
-                        throw new Exception("Overlapping taxaSets??");
+                        throw new IllegalArgumentException("Overlapping taxaSets??");
                     }
                 }
             }
         }
 
-        orderedCalibrations = new CalibrationPoint[nCals];
+        orderedCalibrations = new CalibrationPoint[calCount];
 
         {
             int loc = taxaSets.size() - 1;
@@ -192,7 +198,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
                     final int taxonIndex = getTaxonIndex(tree, tk.get(nt));
                     this.xclades[loc][nt] = taxonIndex;
                     if (taxonIndex < 0) {
-                        throw new Exception("Taxon not found in tree: " + tk.get(nt));
+                        throw new IllegalArgumentException("Taxon not found in tree: " + tk.get(nt));
                     }
                 }
 
@@ -204,9 +210,10 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
         }
 
         // tio[i] will contain all taxaSets contained in the i'th clade, in the form of thier index into orderedCalibrations
-        final List<Integer>[] tio = new List[orderedCalibrations.length];
+        @SuppressWarnings("unchecked")
+		final List<Integer>[] tio = new List[orderedCalibrations.length];
         for (int k = 0; k < orderedCalibrations.length; ++k) {
-            tio[k] = new ArrayList<Integer>();
+            tio[k] = new ArrayList<>();
         }
 
         for (int k = 0; k < orderedCalibrations.length; ++k) {
@@ -230,12 +237,12 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
         }
 
         // true if clade is not contained in any other clade
-        final boolean[] maximal = new boolean[nCals];
-        for (int k = 0; k < nCals; ++k) {
+        final boolean[] maximal = new boolean[calCount];
+        for (int k = 0; k < calCount; ++k) {
             maximal[k] = true;
         }
 
-        for (int k = 0; k < nCals; ++k) {
+        for (int k = 0; k < calCount; ++k) {
             for (final int i : this.taxaPartialOrder[k]) {
                 maximal[i] = false;
             }
@@ -248,7 +255,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
             boolean needTables = false;
 
             if (type == Type.OVER_ALL_TOPOS) {
-                if (nCals == 1 && isYule ) {
+                if (calCount == 1 && isYule ) {
                     // closed form formula
                 } else {
                     boolean anyParent = false;
@@ -258,14 +265,14 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
                         }
                     }
                     if( anyParent ) {
-                        throw new Exception("Sorry, not implemented: calibration on parent for more than one clade.");
+                        throw new IllegalArgumentException("Sorry, not implemented: calibration on parent for more than one clade.");
                     }
                     if( isYule &&
-                            nCals == 2 && orderedCalibrations[1].taxa().containsAll(orderedCalibrations[0].taxa())) {
+                            calCount == 2 && orderedCalibrations[1].taxa().containsAll(orderedCalibrations[0].taxa())) {
                         // closed form formulas
                     } else {
                         needTables = true;
-                        lastHeights = new double[nCals];
+                        lastHeights = new double[calCount];
                     }
                 }
             } else if (type == Type.OVER_RANKED_COUNTS) {
@@ -284,20 +291,20 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
         final double height = leafs.get(0).getHeight();
         for (final Node leaf : leafs) {
         	if (Math.abs(leaf.getHeight() - height) > 1e-8) {
-        		System.err.println("WARNING: Calibrated Birth-Death Model does not handle dated tips correctly. " +
+        		Log.warning.println("WARNING: Calibrated Birth-Death Model does not handle dated tips correctly. " +
                         "Consider using a coalescent prior instead.");
         		break;
         	}
         }
     }
 
-    Tree compatibleInitialTree() throws Exception {
-        final int nCals = orderedCalibrations.length;
-        final double[] lowBound = new double[nCals];
-        final double[] cladeHeight = new double[nCals];
+    Tree compatibleInitialTree() throws MathException {
+        final int calCount = orderedCalibrations.length;
+        final double[] lowBound = new double[calCount];
+        final double[] cladeHeight = new double[calCount];
 
         // get lower  bound: max(lower bound of dist , bounds of nested clades)
-        for (int k = 0; k < nCals; ++k) {
+        for (int k = 0; k < calCount; ++k) {
             final CalibrationPoint cal = orderedCalibrations[k];
             lowBound[k] = cal.dist().inverseCumulativeProbability(0);
             // those are node heights
@@ -310,7 +317,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
             cladeHeight[k] = cal.dist().inverseCumulativeProbability(1);
         }
 
-        for (int k = nCals - 1; k >= 0; --k) {
+        for (int k = calCount - 1; k >= 0; --k) {
             //  cladeHeight[k] should be the upper bound of k
             double upper = cladeHeight[k];
             if (Double.isInfinite(upper)) {
@@ -324,15 +331,15 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
         }
 
         final TreeInterface tree = treeInput.get();
-        final int nNodes = tree.getLeafNodeCount();
-        final boolean[] used = new boolean[nNodes];
+        final int nodeCount = tree.getLeafNodeCount();
+        final boolean[] used = new boolean[nodeCount];
 
         int curLeaf = -1;
-        int curInternal = nNodes - 1;
+        int curInternal = nodeCount - 1;
 
-        final Node[] subTree = new Node[nCals];
-        for (int k = 0; k < nCals; ++k) {
-            final List<Integer> freeTaxa = new ArrayList<Integer>();
+        final Node[] subTree = new Node[calCount];
+        for (int k = 0; k < calCount; ++k) {
+            final List<Integer> freeTaxa = new ArrayList<>();
             for (final int ti : xclades[k]) {
                 freeTaxa.add(ti);
             }
@@ -342,7 +349,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
                 }
             }
 
-            final List<Node> sbs = new ArrayList<Node>();
+            final List<Node> sbs = new ArrayList<>();
             for (final int i : freeTaxa) {
                 final Node n = new Node(tree.getNode(i).getID());
                 n.setNr(++curLeaf);
@@ -365,10 +372,10 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
             subTree[k] = tr;
         }
 
-        Node finalTree = subTree[nCals - 1];
-        double h = cladeHeight[nCals - 1];
+        Node finalTree = subTree[calCount - 1];
+        double h = cladeHeight[calCount - 1];
 
-        for(int k = 0; k < nCals-1; ++k) {
+        for(int k = 0; k < calCount-1; ++k) {
           final Node s = subTree[k];
           h = Math.max(h, cladeHeight[k]) + 1;
           finalTree = Node.connect(finalTree, s, h);
@@ -461,10 +468,10 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
     public double getCorrection(final TreeInterface tree, final double lam, final double a, final double rho) {
         double logL = 0.0;
 
-        final int nCals = orderedCalibrations.length;
-        final double[] hs = new double[nCals];
+        final int calCount = orderedCalibrations.length;
+        final double[] hs = new double[calCount];
 
-        for (int k = 0; k < nCals; ++k) {
+        for (int k = 0; k < calCount; ++k) {
             final CalibrationPoint cal = orderedCalibrations[k];
             Node c;
             final int[] taxk = xclades[k];
@@ -504,15 +511,15 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
         }
 
         if (userPDF == null) {
-            final int nTaxa = tree.getLeafNodeCount();
+            final int taxonCount = tree.getLeafNodeCount();
             switch (type) {
                 case OVER_ALL_TOPOS: {
-                    if (nCals == 1 && isYule ) {
-                        logL -= logMarginalDensity(lam, nTaxa, hs[0], xclades[0].length,
+                    if (calCount == 1 && isYule ) {
+                        logL -= logMarginalDensity(lam, taxonCount, hs[0], xclades[0].length,
                                 orderedCalibrations[0].forParent());
-                    } else if (nCals == 2 && taxaPartialOrder[1].length == 1 && isYule) {
+                    } else if (calCount == 2 && taxaPartialOrder[1].length == 1 && isYule) {
                         //assert !forParent[0] && !forParent[1];
-                        logL -= logMarginalDensity(lam, nTaxa, hs[0], xclades[0].length,
+                        logL -= logMarginalDensity(lam, taxonCount, hs[0], xclades[0].length,
                                 hs[1], xclades[1].length);
                     } else {
 
@@ -570,7 +577,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
                     logL -= nt;
 
                     Arrays.sort(hs);
-                    final int[] cs = new int[nCals + 1];
+                    final int[] cs = new int[calCount + 1];
                     for (final Node n : tree.getInternalNodes()) {
                         final double nhk = n.getHeight();
                         int i = 0;
@@ -597,8 +604,8 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
                             ll += c * (Math.log1p(-Math.exp(-lam * (hs[i] - hs[i - 1]))) - lam * hs[i - 1]);
                             ll += -lam * hs[i] - lfactorials[c];
                         }
-                        ll += -lam * (cs[nCals] + 1) * hs[nCals - 1] - lfactorials[cs[nCals] + 1];
-                        ll += Math.log(lam) * nCals;
+                        ll += -lam * (cs[calCount] + 1) * hs[calCount - 1] - lfactorials[cs[calCount] + 1];
+                        ll += Math.log(lam) * calCount;
 
                         logL -= ll;
                     } else {
@@ -635,18 +642,20 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
                         }
 
                         // from last calibration to oo contribution
-                        final double xu = ia/(rho + ira * Math.exp(-r*hs[nCals - 1]));
-                        final int n2 = cs[nCals];                 assert n2 > 0;  // fixme
+                        final double xu = ia/(rho + ira * Math.exp(-r*hs[calCount - 1]));
+                        final int n2 = cs[calCount];                 assert n2 > 0;  // fixme
 
                         final double rhoia = rho / ia;
                         ll += -lfactorials[n2 + 1] - (n2) * Math.log(r * rhoia)
-                                - (n2+1) * r * hs[nCals - 1] + (n2+1) * Math.log(xu);
+                                - (n2+1) * r * hs[calCount - 1] + (n2+1) * Math.log(xu);
                         // non-node terms
-                        ll += lfactorials[nTaxa] + (nTaxa - 1) * Math.log(r*rhoia);
+                        ll += lfactorials[taxonCount] + (taxonCount - 1) * Math.log(r*rhoia);
                         logL -= ll;
                     }
                     break;
                 }
+			default:
+				break;
             }
         } else {
             final double value = userPDF.getArrayValue();
@@ -659,7 +668,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
         return logL;
     }
 
-    private static double logMarginalDensity(final double lam, final int nTaxa, final double h, final int nClade,
+    private static double logMarginalDensity(final double lam, final int taxonCount, final double h, final int clade,
                                              final boolean forParent) {
         double lgp;
 
@@ -669,16 +678,16 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
             // n(n+1) factor left out
 
             lgp = -2 * lh + Math.log(lam);
-            if (nClade > 1) {
-                lgp += (nClade - 1) * Math.log(1 - Math.exp(-lh));
+            if (clade > 1) {
+                lgp += (clade - 1) * Math.log(1 - Math.exp(-lh));
             }
         } else {
-            assert nClade > 1;
+            assert clade > 1;
 
-            lgp = -3 * lh + (nClade - 2) * Math.log(1 - Math.exp(-lh)) + Math.log(lam);
+            lgp = -3 * lh + (clade - 2) * Math.log(1 - Math.exp(-lh)) + Math.log(lam);
 
             // root is a special case
-            if (nTaxa == nClade) {
+            if (taxonCount == clade) {
                 // n(n-1) factor left out
                 lgp += lh;
             } else {
@@ -689,7 +698,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
         return lgp;
     }
 
-    private static double logMarginalDensity(final double lam, final int nTaxa, final double h2, final int n,
+    private static double logMarginalDensity(final double lam, final int taxonCount, final double h2, final int n,
                                              final double h1, final int nm) {
 
         assert h2 <= h1 && n < nm;
@@ -708,7 +717,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
                 - m * (m - 1) * elh1 * elh2 + (m * (m + 1) / 2.) * elh1 * elh1
                 + ((m - 1) * (m - 2) / 2.) * elh2 * elh2);
 
-        if (nm < nTaxa) {
+        if (nm < taxonCount) {
             /* lgl += Math.log(0.5*(n*(n*n-1))*(n+1+m)) */
             lgl -= lam * (h2 + 3 * h1);
         } else {
@@ -724,9 +733,9 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
 
         final int ni = cli.setup(ranks);
 
-        final int nHeights = hs.length;
+        final int heights = hs.length;
 
-        final double[] lehs = new double[nHeights + 1];
+        final double[] lehs = new double[heights + 1];
         lehs[0] = 0.0;
         for (int i = 1; i < lehs.length; ++i) {
             lehs[i] = -lam * hs[i - 1];
@@ -736,20 +745,20 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
         //final boolean noRoot = ni == lehs.length;
         final boolean noRoot = ! cli.isRootCalibrated();
 
-        final int nLevels = nHeights + (noRoot ? 1 : 0);
+        final int levels = heights + (noRoot ? 1 : 0);
 
-        final double[] lebase = new double[nLevels];
+        final double[] lebase = new double[levels];
 
-        for (int i = 0; i < nHeights; ++i) {
+        for (int i = 0; i < heights; ++i) {
             final double d = lehs[i + 1] - lehs[i];
             lebase[i] = d != 0 ? lehs[i] + Math.log1p(-Math.exp(d)) : -50;
         }
 
         if (noRoot) {
-            lebase[nHeights] = lehs[nHeights];
+            lebase[heights] = lehs[heights];
         }
 
-        final int[] linsAtLevel = new int[nLevels];
+        final int[] linsAtLevel = new int[levels];
 
         final int[][] joiners = cli.allJoiners();
 
@@ -760,16 +769,16 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
         //int ccc = 0;
         while ((linsInLevels = cli.next()) != null) {
             //ccc++;
-            double v = countRankedTrees(nLevels, linsInLevels, joiners, linsAtLevel);
+            double v = countRankedTrees(levels, linsInLevels, joiners, linsAtLevel);
             // 1 for root formula, 1 for kludge in iterator which sets root as 2 lineages
             if (noRoot) {
-                final int ll = linsAtLevel[nLevels - 1] + 2;
-                linsAtLevel[nLevels - 1] = ll;
+                final int ll = linsAtLevel[levels - 1] + 2;
+                linsAtLevel[levels - 1] = ll;
 
                 v -= lc2[ll] + lg2;
             }
 
-            for (int i = 0; i < nLevels; ++i) {
+            for (int i = 0; i < levels; ++i) {
                 v += linsAtLevel[i] * lebase[i];
             }
 
@@ -788,7 +797,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
         double logc0 = 0.0;
         int totLin = 0;
         for (int i = 0; i < ni; ++i) {
-            final int l = cli.nStart(i);
+            final int l = cli.start(i);
             if (l > 0) {
                 logc0 += lNR[l];
                 totLin += l;
@@ -797,15 +806,15 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
 
         final double logc1 = lfactorials[totLin];
 
-        double logc2 = nHeights * Math.log(lam);
+        double logc2 = heights * Math.log(lam);
 
-        for (int i = 1; i < nHeights + 1; ++i) {
+        for (int i = 1; i < heights + 1; ++i) {
             logc2 += lehs[i];
         }
 
         if (!noRoot) {
             // we don't have an iterator for 0 free lineages
-            logc2 += 1 * lehs[nHeights];
+            logc2 += 1 * lehs[heights];
         }
 
         // Missing scale by total of all possible trees over all ranking orders.
@@ -852,12 +861,12 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
     }
 
     private double
-    countRankedTrees(final int nLevels, final int[][] linsAtCrossings, final int[][] joiners, final int[] linsAtLevel) {
+    countRankedTrees(final int levels, final int[][] linsAtCrossings, final int[][] joiners, final int[] linsAtLevel) {
         double logCount = 0;
 
-        for (int i = 0; i < nLevels; ++i) {
+        for (int i = 0; i < levels; ++i) {
             int sumLins = 0;
-            for (int k = i; k < nLevels; ++k) {
+            for (int k = i; k < levels; ++k) {
                 final int[] lack = linsAtCrossings[k];
                 int cki = lack[i];
                 if (joiners[k][i] > 0) {
@@ -986,7 +995,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
     // log likelihood and clades heights
 
     @Override
-    public void init(final PrintStream out) throws Exception {
+    public void init(final PrintStream out) {
         out.print(getID() + "\t");
         if (calcCalibrations) {
             for (final CalibrationPoint cp : orderedCalibrations) {
@@ -996,7 +1005,7 @@ public class CalibratedBirthDeathModel extends SpeciesTreeDistribution {
     }
 
     @Override
-    public void log(final int nSample, final PrintStream out) {
+    public void log(final int sample, final PrintStream out) {
         out.print(getCurrentLogP() + "\t");
         if (calcCalibrations) {
             final TreeInterface tree = treeInput.get();
diff --git a/src/beast/evolution/speciation/CalibratedYuleInitialTree.java b/src/beast/evolution/speciation/CalibratedYuleInitialTree.java
index 09425f6..57d98f7 100644
--- a/src/beast/evolution/speciation/CalibratedYuleInitialTree.java
+++ b/src/beast/evolution/speciation/CalibratedYuleInitialTree.java
@@ -26,15 +26,17 @@
 package beast.evolution.speciation;
 
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.math.MathException;
+
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.StateNode;
 import beast.core.StateNodeInitialiser;
 import beast.evolution.tree.Tree;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /**
 * @author Joseph Heled
  */
@@ -42,19 +44,19 @@ import java.util.List;
 @Description("A tree compatible with a set of monophyletic clades and hard limits on the clade root.")
 public class CalibratedYuleInitialTree extends Tree implements StateNodeInitialiser {
 
-    public Input<List<CalibrationPoint>> calibrationsInput =
-            new Input<List<CalibrationPoint>>("calibrations", "Set of calibrated nodes", new ArrayList<CalibrationPoint>(),
+    final public Input<List<CalibrationPoint>> calibrationsInput =
+            new Input<>("calibrations", "Set of calibrated nodes", new ArrayList<>(),
                     Input.Validate.REQUIRED);
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
         initStateNodes();
     }
 
     @Override
-    public void initStateNodes() throws Exception {
-        // Would have been nice to use the MCMC CalibratedYuleModel plugin directly, but at this point
+    public void initStateNodes() {
+        // Would have been nice to use the MCMC CalibratedYuleModel beastObject directly, but at this point
         // it does not exist since the tree being initialized is one of its arguments. So, build a temporary
         // one using the initializer tree.
 
@@ -68,7 +70,12 @@ public class CalibratedYuleInitialTree extends Tree implements StateNodeInitiali
         cym.setInputValue("type", CalibratedYuleModel.Type.NONE);
         cym.initAndValidate();
 
-        final Tree t = cym.compatibleInitialTree();
+        Tree t;
+		try {
+			t = cym.compatibleInitialTree();
+		} catch (MathException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
         m_initial.get().assignFromWithoutID(t);
     }
 
diff --git a/src/beast/evolution/speciation/CalibratedYuleModel.java b/src/beast/evolution/speciation/CalibratedYuleModel.java
index cbcd1f3..f672d91 100644
--- a/src/beast/evolution/speciation/CalibratedYuleModel.java
+++ b/src/beast/evolution/speciation/CalibratedYuleModel.java
@@ -1,7 +1,17 @@
 package beast.evolution.speciation;
 
 
-import beast.core.*;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.math.MathException;
+
+import beast.core.Citation;
+import beast.core.Description;
+import beast.core.Distribution;
+import beast.core.Input;
 import beast.core.Input.Validate;
 import beast.core.parameter.RealParameter;
 import beast.core.util.CompoundDistribution;
@@ -14,11 +24,6 @@ import beast.math.distributions.MRCAPrior;
 import beast.math.distributions.ParametricDistribution;
 import beast.math.statistic.RPNcalculator;
 
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
 /**
  * @author Joseph Heled
  */
@@ -42,7 +47,8 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
             this.ename = name;
         }
 
-        public String toString() {
+        @Override
+		public String toString() {
             return ename;
         }
 
@@ -50,19 +56,19 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
     }
 
     // Q2R does this makes sense, or it has to be a realParameter??
-    public Input<RealParameter> birthRateInput =
-            new Input<RealParameter>("birthRate", "birth rate of splitting a linage into two", Validate.REQUIRED);
+    final public Input<RealParameter> birthRateInput =
+            new Input<>("birthRate", "birth rate of splitting a linage into two", Validate.REQUIRED);
 
-    public Input<List<CalibrationPoint>> calibrationsInput =
-            new Input<List<CalibrationPoint>>("calibrations", "Set of calibrated nodes", new ArrayList<CalibrationPoint>());
+    final public Input<List<CalibrationPoint>> calibrationsInput =
+            new Input<>("calibrations", "Set of calibrated nodes", new ArrayList<>());
 
-    public Input<Type> correctionTypeInput = new Input<Type>("type", "Type of correction: none for no correction " +
+    final public Input<Type> correctionTypeInput = new Input<>("type", "Type of correction: none for no correction " +
             "(same as BEAST1), full for Yule-like over calibrated times, and restricted for Yule-like over calibrated" +
             " times and ranked topology (default 'full'). However, 'full'" +
             " is generally slow except for in a few special cases, such as a single clade or two nested clades.",
             Type.OVER_ALL_TOPOS, Type.values());
 
-    public Input<RPNcalculator> userMarInput = new Input<RPNcalculator>("logMarginal",
+    final public Input<RPNcalculator> userMarInput = new Input<>("logMarginal",
             "Used provided correction (log of marginal) for special cases.", (RPNcalculator) null);
 
     // Which correction to apply
@@ -89,7 +95,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
 
         type = correctionTypeInput.get();
@@ -97,11 +103,11 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         final TreeInterface tree = treeInput.get();
 
         // shallow copy. we shall change cals later
-        final List<CalibrationPoint> cals = new ArrayList<CalibrationPoint>(calibrationsInput.get());
-        int nCals = cals.size();
-        final List<TaxonSet> taxaSets = new ArrayList<TaxonSet>(nCals);
+        final List<CalibrationPoint> cals = new ArrayList<>(calibrationsInput.get());
+        int calCount = cals.size();
+        final List<TaxonSet> taxaSets = new ArrayList<>(calCount);
         if (cals.size() > 0) {
-            xclades = new int[nCals][];
+            xclades = new int[calCount][];
 
             // convenience
             for (final CalibrationPoint cal : cals) {
@@ -110,9 +116,9 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
 
         } else {
             // find calibration points from prior
-            for (final Object plugin : getOutputs()) {
-                if (plugin instanceof CompoundDistribution) {
-                    final CompoundDistribution prior = (CompoundDistribution) plugin;
+            for (final Object beastObject : getOutputs()) {
+                if (beastObject instanceof CompoundDistribution) {
+                    final CompoundDistribution prior = (CompoundDistribution) beastObject;
                     for (final Distribution distr : prior.pDistributions.get()) {
                         if (distr instanceof MRCAPrior) {
                             final MRCAPrior _MRCAPrior = (MRCAPrior) distr;
@@ -120,7 +126,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
                             if (_MRCAPrior.distInput.get() != null) {
                                 // make sure MRCAPrior is monophyletic
                                 if (!_MRCAPrior.isMonophyleticInput.get()) {
-                                    throw new Exception("MRCAPriors must be monophyletic for Calibrated Yule prior");
+                                    throw new IllegalArgumentException("MRCAPriors must be monophyletic for Calibrated Yule prior");
                                 }
                                 // create CalibrationPoint from MRCAPrior
                                 final CalibrationPoint cal = new CalibrationPoint();
@@ -130,7 +136,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
                                 cals.add(cal);
                                 taxaSets.add(cal.taxa());
                                 cal.taxa().initAndValidate();
-                                nCals++;
+                                calCount++;
                                 calcCalibrations = false;
                             } else {
                                 if (_MRCAPrior.isMonophyleticInput.get()) {
@@ -143,27 +149,27 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
                     }
                 }
             }
-            xclades = new int[nCals][];
+            xclades = new int[calCount][];
         }
-        if (nCals == 0) {
+        if (calCount == 0) {
         	Log.warning.println("WARNING: Calibrated Yule prior could not find any properly configured calibrations. Expect this to crash in a BEAST run.");                                	
             // assume we are in beauti, back off for now
             return;
         }
 
-        for (int k = 0; k < nCals; ++k) {
+        for (int k = 0; k < calCount; ++k) {
             final TaxonSet tk = taxaSets.get(k);
-            for (int i = k + 1; i < nCals; ++i) {
+            for (int i = k + 1; i < calCount; ++i) {
                 final TaxonSet ti = taxaSets.get(i);
                 if (ti.containsAny(tk)) {
                     if (!(ti.containsAll(tk) || tk.containsAll(ti))) {
-                        throw new Exception("Overlapping taxaSets??");
+                        throw new IllegalArgumentException("Overlapping taxaSets??");
                     }
                 }
             }
         }
 
-        orderedCalibrations = new CalibrationPoint[nCals];
+        orderedCalibrations = new CalibrationPoint[calCount];
 
         {
             int loc = taxaSets.size() - 1;
@@ -184,7 +190,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
                     final int taxonIndex = getTaxonIndex(tree, tk.get(nt));
                     this.xclades[loc][nt] = taxonIndex;
                     if (taxonIndex < 0) {
-                        throw new Exception("Taxon not found in tree: " + tk.get(nt));
+                        throw new IllegalArgumentException("Taxon not found in tree: " + tk.get(nt));
                     }
                 }
 
@@ -196,9 +202,10 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         }
 
         // tio[i] will contain all taxaSets contained in the i'th clade, in the form of thier index into orderedCalibrations
-        final List<Integer>[] tio = new List[orderedCalibrations.length];
+        @SuppressWarnings("unchecked")
+		final List<Integer>[] tio = new List[orderedCalibrations.length];
         for (int k = 0; k < orderedCalibrations.length; ++k) {
-            tio[k] = new ArrayList<Integer>();
+            tio[k] = new ArrayList<>();
         }
 
         for (int k = 0; k < orderedCalibrations.length; ++k) {
@@ -222,12 +229,12 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         }
 
         // true if clade is not contained in any other clade
-        final boolean[] maximal = new boolean[nCals];
-        for (int k = 0; k < nCals; ++k) {
+        final boolean[] maximal = new boolean[calCount];
+        for (int k = 0; k < calCount; ++k) {
             maximal[k] = true;
         }
 
-        for (int k = 0; k < nCals; ++k) {
+        for (int k = 0; k < calCount; ++k) {
             for (final int i : this.taxaPartialOrder[k]) {
                 maximal[i] = false;
             }
@@ -237,7 +244,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         if (userPDF == null) {
 
             if (type == Type.OVER_ALL_TOPOS) {
-                if (nCals == 1) {
+                if (calCount == 1) {
                     // closed form formula
                 } else {
                     boolean anyParent = false;
@@ -247,15 +254,15 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
                         }
                     }
                     if (anyParent) {
-                        throw new Exception("Sorry, not implemented: calibration on parent for more than one clade.");
+                        throw new IllegalArgumentException("Sorry, not implemented: calibration on parent for more than one clade.");
                     }
-                    if (nCals == 2 && orderedCalibrations[1].taxa().containsAll(orderedCalibrations[0].taxa())) {
+                    if (calCount == 2 && orderedCalibrations[1].taxa().containsAll(orderedCalibrations[0].taxa())) {
                         // closed form formulas
                     } else {
                         setUpTables(tree.getLeafNodeCount() + 1);
                         linsIter = new CalibrationLineagesIterator(this.xclades, this.taxaPartialOrder, maximal,
                                 tree.getLeafNodeCount());
-                        lastHeights = new double[nCals];
+                        lastHeights = new double[calCount];
                     }
                 }
             } else if (type == Type.OVER_RANKED_COUNTS) {
@@ -267,19 +274,19 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         final double height = leafs.get(0).getHeight();
         for (final Node leaf : leafs) {
             if (Math.abs(leaf.getHeight() - height) > 1e-8) {
-                System.err.println("WARNING: Calibrated Yule Model cannot handle dated tips. Use for example a coalescent prior instead.");
+            	Log.warning.println("WARNING: Calibrated Yule Model cannot handle dated tips. Use for example a coalescent prior instead.");
                 break;
             }
         }
     }
 
-    public Tree compatibleInitialTree() throws Exception {
-        final int nCals = orderedCalibrations.length;
-        final double[] lowBound = new double[nCals];
-        final double[] cladeHeight = new double[nCals];
+    public Tree compatibleInitialTree() throws MathException {
+        final int calCount = orderedCalibrations.length;
+        final double[] lowBound = new double[calCount];
+        final double[] cladeHeight = new double[calCount];
 
         // get lower  bound: max(lower bound of dist , bounds of nested clades)
-        for (int k = 0; k < nCals; ++k) {
+        for (int k = 0; k < calCount; ++k) {
             final CalibrationPoint cal = orderedCalibrations[k];
             final ParametricDistribution dist = cal.dist();
             //final double offset = dist.getOffset();
@@ -297,7 +304,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
 //            }
         }
 
-        for (int k = nCals - 1; k >= 0; --k) {
+        for (int k = calCount - 1; k >= 0; --k) {
             //  cladeHeight[k] should be the upper bound of k
             double upper = cladeHeight[k];
             if (Double.isInfinite(upper)) {
@@ -311,15 +318,15 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         }
 
         final TreeInterface tree = treeInput.get();
-        final int nNodes = tree.getLeafNodeCount();
-        final boolean[] used = new boolean[nNodes];
+        final int nodeCount = tree.getLeafNodeCount();
+        final boolean[] used = new boolean[nodeCount];
 
         int curLeaf = -1;
-        int curInternal = nNodes - 1;
+        int curInternal = nodeCount - 1;
 
-        final Node[] subTree = new Node[nCals];
-        for (int k = 0; k < nCals; ++k) {
-            final List<Integer> freeTaxa = new ArrayList<Integer>();
+        final Node[] subTree = new Node[calCount];
+        for (int k = 0; k < calCount; ++k) {
+            final List<Integer> freeTaxa = new ArrayList<>();
             for (final int ti : xclades[k]) {
                 freeTaxa.add(ti);
             }
@@ -329,7 +336,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
                 }
             }
 
-            final List<Node> sbs = new ArrayList<Node>();
+            final List<Node> sbs = new ArrayList<>();
             for (final int i : freeTaxa) {
                 final Node n = new Node(tree.getNode(i).getID());
                 n.setNr(++curLeaf);
@@ -353,10 +360,10 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
             subTree[k] = tr;
         }
 
-        Node finalTree = subTree[nCals - 1];
-        double h = cladeHeight[nCals - 1];
+        Node finalTree = subTree[calCount - 1];
+        double h = cladeHeight[calCount - 1];
 
-        for (int k = 0; k < nCals - 1; ++k) {
+        for (int k = 0; k < calCount - 1; ++k) {
             final Node s = subTree[k];
             if( s != null ) {
                 h = Math.max(h, cladeHeight[k]) + 1;
@@ -414,10 +421,10 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
     public double getCorrection(final TreeInterface tree, final double lam) {
         double logL = 0.0;
 
-        final int nCals = orderedCalibrations.length;
-        final double[] hs = new double[nCals];
+        final int calCount = orderedCalibrations.length;
+        final double[] hs = new double[calCount];
 
-        for (int k = 0; k < nCals; ++k) {
+        for (int k = 0; k < calCount; ++k) {
             final CalibrationPoint cal = orderedCalibrations[k];
             Node c;
             final int[] taxk = xclades[k];
@@ -459,10 +466,10 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         if (userPDF == null) {
             switch (type) {
                 case OVER_ALL_TOPOS: {
-                    if (nCals == 1) {
+                    if (calCount == 1) {
                         logL -= logMarginalDensity(lam, tree.getLeafNodeCount(), hs[0], xclades[0].length,
                                 orderedCalibrations[0].forParent());
-                    } else if (nCals == 2 && taxaPartialOrder[1].length == 1) {
+                    } else if (calCount == 2 && taxaPartialOrder[1].length == 1) {
                         //assert !forParent[0] && !forParent[1];
                         logL -= logMarginalDensity(lam, tree.getLeafNodeCount(), hs[0], xclades[0].length,
                                 hs[1], xclades[1].length);
@@ -508,7 +515,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
 
                 case OVER_RANKED_COUNTS: {
                     Arrays.sort(hs);
-                    final int[] cs = new int[nCals + 1];
+                    final int[] cs = new int[calCount + 1];
                     for (final Node n : tree.getInternalNodes()) {
                         final double nhk = n.getHeight();
                         int i = 0;
@@ -534,12 +541,14 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
                         ll += c * (Math.log1p(-Math.exp(-lam * (hs[i] - hs[i - 1]))) - lam * hs[i - 1]);
                         ll += -lam * hs[i] - lfactorials[c];
                     }
-                    ll += -lam * (cs[nCals] + 1) * hs[nCals - 1] - lfactorials[cs[nCals] + 1];
-                    ll += Math.log(lam) * nCals;
+                    ll += -lam * (cs[calCount] + 1) * hs[calCount - 1] - lfactorials[cs[calCount] + 1];
+                    ll += Math.log(lam) * calCount;
 
                     logL -= ll;
                     break;
                 }
+			default:
+				break;
             }
         } else {
             final double value = userPDF.getArrayValue();
@@ -552,7 +561,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         return logL;
     }
 
-    private static double logMarginalDensity(final double lam, final int nTaxa, final double h, final int nClade,
+    private static double logMarginalDensity(final double lam, final int taxonCount, final double h, final int clade,
                                              final boolean forParent) {
         double lgp;
 
@@ -562,16 +571,16 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
             // n(n+1) factor left out
 
             lgp = -2 * lh + Math.log(lam);
-            if (nClade > 1) {
-                lgp += (nClade - 1) * Math.log(1 - Math.exp(-lh));
+            if (clade > 1) {
+                lgp += (clade - 1) * Math.log(1 - Math.exp(-lh));
             }
         } else {
-            assert nClade > 1;
+            assert clade > 1;
 
-            lgp = -3 * lh + (nClade - 2) * Math.log(1 - Math.exp(-lh)) + Math.log(lam);
+            lgp = -3 * lh + (clade - 2) * Math.log(1 - Math.exp(-lh)) + Math.log(lam);
 
             // root is a special case
-            if (nTaxa == nClade) {
+            if (taxonCount == clade) {
                 // n(n-1) factor left out
                 lgp += lh;
             } else {
@@ -582,7 +591,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         return lgp;
     }
 
-    private static double logMarginalDensity(final double lam, final int nTaxa, final double h2, final int n,
+    private static double logMarginalDensity(final double lam, final int taxonCount, final double h2, final int n,
                                              final double h1, final int nm) {
 
         assert h2 <= h1 && n < nm;
@@ -601,7 +610,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
                 - m * (m - 1) * elh1 * elh2 + (m * (m + 1) / 2.) * elh1 * elh1
                 + ((m - 1) * (m - 2) / 2.) * elh2 * elh2);
 
-        if (nm < nTaxa) {
+        if (nm < taxonCount) {
             /* lgl += Math.log(0.5*(n*(n*n-1))*(n+1+m)) */
             lgl -= lam * (h2 + 3 * h1);
         } else {
@@ -617,9 +626,9 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
 
         final int ni = cli.setup(ranks);
 
-        final int nHeights = hs.length;
+        final int heights = hs.length;
 
-        final double[] lehs = new double[nHeights + 1];
+        final double[] lehs = new double[heights + 1];
         lehs[0] = 0.0;
         for (int i = 1; i < lehs.length; ++i) {
             lehs[i] = -lam * hs[i - 1];
@@ -628,20 +637,20 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         // assert maxRank == len(sit)
         final boolean noRoot = ni == lehs.length;
 
-        final int nLevels = nHeights + (noRoot ? 1 : 0);
+        final int levels = heights + (noRoot ? 1 : 0);
 
-        final double[] lebase = new double[nLevels];
+        final double[] lebase = new double[levels];
 
-        for (int i = 0; i < nHeights; ++i) {
+        for (int i = 0; i < heights; ++i) {
             final double d = lehs[i + 1] - lehs[i];
             lebase[i] = d != 0 ? lehs[i] + Math.log1p(-Math.exp(d)) : -50;
         }
 
         if (noRoot) {
-            lebase[nHeights] = lehs[nHeights];
+            lebase[heights] = lehs[heights];
         }
 
-        final int[] linsAtLevel = new int[nLevels];
+        final int[] linsAtLevel = new int[levels];
 
         final int[][] joiners = cli.allJoiners();
 
@@ -652,16 +661,16 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         //int ccc = 0;
         while ((linsInLevels = cli.next()) != null) {
             //ccc++;
-            double v = countRankedTrees(nLevels, linsInLevels, joiners, linsAtLevel);
+            double v = countRankedTrees(levels, linsInLevels, joiners, linsAtLevel);
             // 1 for root formula, 1 for kludge in iterator which sets root as 2 lineages
             if (noRoot) {
-                final int ll = linsAtLevel[nLevels - 1] + 2;
-                linsAtLevel[nLevels - 1] = ll;
+                final int ll = linsAtLevel[levels - 1] + 2;
+                linsAtLevel[levels - 1] = ll;
 
                 v -= lc2[ll] + lg2;
             }
 
-            for (int i = 0; i < nLevels; ++i) {
+            for (int i = 0; i < levels; ++i) {
                 v += linsAtLevel[i] * lebase[i];
             }
 
@@ -680,7 +689,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
         double logc0 = 0.0;
         int totLin = 0;
         for (int i = 0; i < ni; ++i) {
-            final int l = cli.nStart(i);
+            final int l = cli.start(i);
             if (l > 0) {
                 logc0 += lNR[l];
                 totLin += l;
@@ -689,15 +698,15 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
 
         final double logc1 = lfactorials[totLin];
 
-        double logc2 = nHeights * Math.log(lam);
+        double logc2 = heights * Math.log(lam);
 
-        for (int i = 1; i < nHeights + 1; ++i) {
+        for (int i = 1; i < heights + 1; ++i) {
             logc2 += lehs[i];
         }
 
         if (!noRoot) {
             // we dont have an iterator for 0 free lineages
-            logc2 += 1 * lehs[nHeights];
+            logc2 += 1 * lehs[heights];
         }
 
         // Missing scale by total of all possible trees over all ranking orders.
@@ -709,12 +718,12 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
     }
 
     private double
-    countRankedTrees(final int nLevels, final int[][] linsAtCrossings, final int[][] joiners, final int[] linsAtLevel) {
+    countRankedTrees(final int levels, final int[][] linsAtCrossings, final int[][] joiners, final int[] linsAtLevel) {
         double logCount = 0;
 
-        for (int i = 0; i < nLevels; ++i) {
+        for (int i = 0; i < levels; ++i) {
             int sumLins = 0;
-            for (int k = i; k < nLevels; ++k) {
+            for (int k = i; k < levels; ++k) {
                 final int[] lack = linsAtCrossings[k];
                 int cki = lack[i];
                 if (joiners[k][i] > 0) {
@@ -843,7 +852,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
     // log likelihood and clades heights
 
     @Override
-    public void init(final PrintStream out) throws Exception {
+    public void init(final PrintStream out) {
         out.print(getID() + "\t");
         if (calcCalibrations) {
             for (final CalibrationPoint cp : orderedCalibrations) {
@@ -853,7 +862,7 @@ public class CalibratedYuleModel extends SpeciesTreeDistribution {
     }
 
     @Override
-    public void log(final int nSample, final PrintStream out) {
+    public void log(final int sample, final PrintStream out) {
         out.print(getCurrentLogP() + "\t");
         if (calcCalibrations) {
             final TreeInterface tree = treeInput.get();
diff --git a/src/beast/evolution/speciation/CalibrationLineagesIterator.java b/src/beast/evolution/speciation/CalibrationLineagesIterator.java
index f5db7b0..2b2e7c1 100644
--- a/src/beast/evolution/speciation/CalibrationLineagesIterator.java
+++ b/src/beast/evolution/speciation/CalibrationLineagesIterator.java
@@ -15,8 +15,8 @@ public class CalibrationLineagesIterator {
 
     private final boolean rootCalibrated;
 
-    // Use iterators 0 to nCurIters-1 (i.e. iters[0:nCurIters])
-    private int nCurIters;
+    // Use iterators 0 to curIters-1 (i.e. iters[0:curIters])
+    private int curIters;
 
     // per clade Iterator
     private final LinsIterator[] iters;
@@ -25,7 +25,7 @@ public class CalibrationLineagesIterator {
     private int[][] vals;
 
     // Number of taxa not below any calibration point
-    private int nFreeLineages;
+    private int freeLineages;
 
     // indices of maximal clades
     private final int[] maximalClades;
@@ -46,28 +46,28 @@ public class CalibrationLineagesIterator {
         vals = new int[iters.length][];
 
         // number of maximal clades
-        int nMax = 0;
+        int max = 0;
         for(final boolean b : maximal) {
-           nMax += b ? 1 : 0;
+           max += b ? 1 : 0;
         }
 
         // indices of maximal clades in a list
-        maximalClades = new int[nMax];
-        nFreeLineages = leafCount;
+        maximalClades = new int[max];
+        freeLineages = leafCount;
 
-        nMax = 0;
+        max = 0;
         for(int m = 0; m < maximal.length; ++m) {
             if( maximal[m] ) {
-              maximalClades[nMax] = m;
-              ++nMax;
-              nFreeLineages -= clades[m].length;
+              maximalClades[max] = m;
+              ++max;
+              freeLineages -= clades[m].length;
             }
         }
 
-        rootCalibrated = ( nMax == 1 && clades[maximalClades[0]].length == leafCount );
+        rootCalibrated = ( max == 1 && clades[maximalClades[0]].length == leafCount );
 
-        assert ! (rootCalibrated &&  nFreeLineages > 0);
-        assert nFreeLineages >= 0;
+        assert ! (rootCalibrated &&  freeLineages > 0);
+        assert freeLineages >= 0;
     }
 
     boolean isRootCalibrated() {
@@ -79,32 +79,32 @@ public class CalibrationLineagesIterator {
         final int n = cladesFreeLins.length;
 
         // reset iterators used. each call to setOneIterator will increment it by one.
-        nCurIters = 0;
+        curIters = 0;
 
         for(int k = 0; k < n; ++k) {
             setOneIterator(ranks, taxaPartialOrder[k], cladesFreeLins[k], ranks[k]);
         }
 
         if( ! rootCalibrated ) {
-          setOneIterator(ranks, maximalClades, nFreeLineages, n+1);
+          setOneIterator(ranks, maximalClades, freeLineages, n+1);
         }
         
-        for(int k = 0; k < nCurIters-1; ++k) {
+        for(int k = 0; k < curIters-1; ++k) {
             vals[k] = iters[k].next();
         }
 
-        return nCurIters;
+        return curIters;
     }
 
     private void setOneIterator(final int[] ranks, final int[] joinerClades, final int nl, final int rank) {
-        final int nSubs = joinerClades.length;
+        final int subs = joinerClades.length;
 
         LinsIterator itr/* = null*/;
-        if( nSubs == 0 ) {
+        if( subs == 0 ) {
             itr = new LinsIterator(nl, rank, null);
-        } else /*if( nl > 0 || nSubs > 2 ) */ {
-            final int[] s = new int[nSubs];
-            for(int i = 0; i < nSubs; ++i) {
+        } else /*if( nl > 0 || subs > 2 ) */ {
+            final int[] s = new int[subs];
+            for(int i = 0; i < subs; ++i) {
                 s[i] = ranks[joinerClades[i]];
             }
             itr = new LinsIterator(nl, rank, s);
@@ -115,20 +115,20 @@ public class CalibrationLineagesIterator {
             // sorted according to rank
             iters[itr.rank-1] = itr;
             itr.startIter();
-            ++nCurIters;
+            ++curIters;
         //}
     }
 
     int[][] next()
     {
-        final int[] l = iters[nCurIters-1].next();
+        final int[] l = iters[curIters-1].next();
 
         if( l != null ) {
-            vals[nCurIters-1] = l;
+            vals[curIters-1] = l;
             return vals;
         }
 
-        int i = nCurIters-2;
+        int i = curIters-2;
         for( ; i >= 0; --i) {
             if( (vals[i] = iters[i].next()) != null) {
                 break;
@@ -141,7 +141,7 @@ public class CalibrationLineagesIterator {
 
         ++i;
 
-        for( ; i < nCurIters; ++i) {
+        for( ; i < curIters; ++i) {
             iters[i].startIter();
             vals[i] = iters[i].next();
         }
@@ -150,22 +150,22 @@ public class CalibrationLineagesIterator {
     }
 
     public int[][] allJoiners() {
-        final int[][] joiners = new int[nCurIters][];
+        final int[][] joiners = new int[curIters][];
 
-        for(int i = 0; i < nCurIters; ++i) {
+        for(int i = 0; i < curIters; ++i) {
             joiners[i] = iters[i].ljoins();
         }
         return joiners;
     }
 
-    public int nStart(final int i) {
-        return iters[i].nStart;
+    public int start(final int i) {
+        return iters[i].start;
     }
 
     class LinsIterator {
 
         private final int rank;
-        private final int nStart;
+        private final int start;
         private final int[] joiners;
         private final int[] aStart;
         // Current count of lineages at all relevant time points, from 0 (start) to clade top.
@@ -175,7 +175,7 @@ public class CalibrationLineagesIterator {
 
         LinsIterator(final int ns, final int r, final int[] jnr) {
             rank = r;
-            nStart = ns;
+            start = ns;
             joiners = new int [r];
 
             lastJoinger = -1;
@@ -209,7 +209,7 @@ public class CalibrationLineagesIterator {
             } else {
                 //assert(rank > 1);
 
-                if( nStart > 0 ) {
+                if( start > 0 ) {
                     int i = 1;
                     for(; i < lastJoinger+1; ++i) {
                         aStart[i] = 1;
diff --git a/src/beast/evolution/speciation/CalibrationPoint.java b/src/beast/evolution/speciation/CalibrationPoint.java
index 8094473..9cb5c2e 100644
--- a/src/beast/evolution/speciation/CalibrationPoint.java
+++ b/src/beast/evolution/speciation/CalibrationPoint.java
@@ -1,8 +1,8 @@
 package beast.evolution.speciation;
 
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.BEASTObject;
 import beast.evolution.alignment.TaxonSet;
 import beast.math.distributions.ParametricDistribution;
 
@@ -12,16 +12,16 @@ import beast.math.distributions.ParametricDistribution;
 
 @Description("Specification of a single calibration point of the calibrated Yule.")
 public class CalibrationPoint extends BEASTObject {
-    public Input<TaxonSet> taxonsetInput = new Input<TaxonSet>("taxonset",
+    final public Input<TaxonSet> taxonsetInput = new Input<>("taxonset",
             "Set of taxa. The prior distribution is applied to their TMRCA.", Input.Validate.REQUIRED);
 
-    public Input<ParametricDistribution> distInput = new Input<ParametricDistribution>("distr",
+    final public Input<ParametricDistribution> distInput = new Input<>("distr",
             "Prior distribution applied to time of clade MRCA", Input.Validate.REQUIRED);
 
-//    public Input<Boolean> m_bIsMonophyleticInput = new Input<Boolean>("monophyletic",
+//    public Input<Boolean> m_bIsMonophyleticInput = new Input<>("monophyletic",
 //            "whether the taxon set is monophyletic (forms a clade without other taxa) or nor. Default is false.", false);
 
-    public Input<Boolean> forParentInput = new Input<Boolean>("parentOf",
+    final public Input<Boolean> forParentInput = new Input<>("parentOf",
             "Use time of clade parent. Default is false.", false);
 
 
@@ -31,7 +31,8 @@ public class CalibrationPoint extends BEASTObject {
 
     public CalibrationPoint() {}
 
-    public void initAndValidate() throws Exception {
+    @Override
+	public void initAndValidate() {
         t = taxonsetInput.get();
         forPar = forParentInput.get();
         pd = distInput.get();
diff --git a/src/beast/evolution/speciation/GeneTreeForSpeciesTreeDistribution.java b/src/beast/evolution/speciation/GeneTreeForSpeciesTreeDistribution.java
index 810860d..21a2af7 100644
--- a/src/beast/evolution/speciation/GeneTreeForSpeciesTreeDistribution.java
+++ b/src/beast/evolution/speciation/GeneTreeForSpeciesTreeDistribution.java
@@ -9,14 +9,14 @@ import java.util.Random;
 
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.State;
 import beast.core.Input.Validate;
+import beast.core.State;
 import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
 import beast.evolution.alignment.Taxon;
 import beast.evolution.alignment.TaxonSet;
 import beast.evolution.speciation.SpeciesTreePrior.TreePopSizeFunction;
 import beast.evolution.tree.Node;
-import beast.evolution.tree.Tree;
 import beast.evolution.tree.TreeDistribution;
 import beast.evolution.tree.TreeInterface;
 
@@ -24,22 +24,22 @@ import beast.evolution.tree.TreeInterface;
 
 @Description("Calculates probability of gene tree conditioned on a species tree (multi-species coalescent)")
 public class GeneTreeForSpeciesTreeDistribution extends TreeDistribution {
-    public Input<TreeInterface> speciesTreeInput =
-            new Input<TreeInterface>("speciesTree", "species tree containing the associated gene tree", Validate.REQUIRED);
+    final public Input<TreeInterface> speciesTreeInput =
+            new Input<>("speciesTree", "species tree containing the associated gene tree", Validate.REQUIRED);
 
 //    public enum PLOIDY {autosomal_nuclear, X, Y, mitrochondrial};
     
-    public Input<Double> ploidyInput =
-            new Input<Double>("ploidy", "ploidy (copy number) for this gene, typically a whole number or half (default 2 for autosomal_nuclear)", 2.0);
+    final public Input<Double> ploidyInput =
+            new Input<>("ploidy", "ploidy (copy number) for this gene, typically a whole number or half (default 2 for autosomal_nuclear)", 2.0);
 //    public Input<PLOIDY> m_ploidy =
-//        new Input<PLOIDY>("ploidy", "ploidy for this gene (default X, Possible values: " + PLOIDY.values(), PLOIDY.X, PLOIDY.values());
+//        new Input<>("ploidy", "ploidy for this gene (default X, Possible values: " + PLOIDY.values(), PLOIDY.X, PLOIDY.values());
 
     
-    public Input<SpeciesTreePrior> speciesTreePriorInput =
-            new Input<SpeciesTreePrior>("speciesTreePrior", "defines population function and its parameters", Validate.REQUIRED);
+    final public Input<SpeciesTreePrior> speciesTreePriorInput =
+            new Input<>("speciesTreePrior", "defines population function and its parameters", Validate.REQUIRED);
 
-    public Input<TreeTopFinder> treeTopFinderInput =
-            new Input<TreeTopFinder>("treetop", "calculates height of species tree, required only for linear *beast analysis");
+    final public Input<TreeTopFinder> treeTopFinderInput =
+            new Input<>("treetop", "calculates height of species tree, required only for linear *beast analysis");
 
     // intervals for each of the species tree branches
     private PriorityQueue<Double>[] intervalsInput;
@@ -60,8 +60,9 @@ public class GeneTreeForSpeciesTreeDistribution extends TreeDistribution {
         treeInput.setRule(Validate.REQUIRED);
     }
 
-    @Override
-    public void initAndValidate() throws Exception {
+    @SuppressWarnings("unchecked")
+	@Override
+    public void initAndValidate() {
     	ploidy = ploidyInput.get();
 //    	switch (m_ploidy.get()) {
 //			case autosomal_nuclear: m_fPloidy = 2.0; break;
@@ -71,57 +72,57 @@ public class GeneTreeForSpeciesTreeDistribution extends TreeDistribution {
 //			default: throw new Exception("Unknown value for ploidy");
 //		}
         final Node[] gtNodes = treeInput.get().getNodesAsArray();
-        final int nGtLineages = treeInput.get().getLeafNodeCount();
+        final int gtLineages = treeInput.get().getLeafNodeCount();
         final Node[] sptNodes = speciesTreeInput.get().getNodesAsArray();
-        final int nSpecies = speciesTreeInput.get().getNodeCount();
+        final int speciesCount = speciesTreeInput.get().getNodeCount();
 
 
-        if (nSpecies <= 1 && sptNodes[0].getID().equals("Beauti2DummyTaxonSet")) {
+        if (speciesCount <= 1 && sptNodes[0].getID().equals("Beauti2DummyTaxonSet")) {
             // we are in Beauti, don't initialise
             return;
         }
 
 
         // reserve memory for priority queues
-        intervalsInput = new PriorityQueue[nSpecies];
-        for (int i = 0; i < nSpecies; i++) {
-            intervalsInput[i] = new PriorityQueue<Double>();
+        intervalsInput = new PriorityQueue[speciesCount];
+        for (int i = 0; i < speciesCount; i++) {
+            intervalsInput[i] = new PriorityQueue<>();
         }
 
         // sanity check lineage nodes are all at height=0
-        for (int i = 0; i < nGtLineages; i++) {
+        for (int i = 0; i < gtLineages; i++) {
             if (gtNodes[i].getHeight() != 0) {
-                throw new Exception("Cannot deal with taxon " + gtNodes[i].getID() +
+                throw new IllegalArgumentException("Cannot deal with taxon " + gtNodes[i].getID() +
                         ", which has non-zero height + " + gtNodes[i].getHeight());
             }
         }
         // set up m_nLineageToSpeciesMap
-        nrOfLineageToSpeciesMap = new int[nGtLineages];
+        nrOfLineageToSpeciesMap = new int[gtLineages];
 
         Arrays.fill(nrOfLineageToSpeciesMap, -1);
-        for (int i = 0; i < nGtLineages; i++) {
-            final String sSpeciesID = getSetID(gtNodes[i].getID());
+        for (int i = 0; i < gtLineages; i++) {
+            final String speciesID = getSetID(gtNodes[i].getID());
             // ??? can this be a startup check? can this happen during run due to tree change?
-            if (sSpeciesID == null) {
-                throw new Exception("Cannot find species for lineage " + gtNodes[i].getID());
+            if (speciesID == null) {
+                throw new IllegalArgumentException("Cannot find species for lineage " + gtNodes[i].getID());
             }
-            for (int iSpecies = 0; iSpecies < nSpecies; iSpecies++) {
-                if (sSpeciesID.equals(sptNodes[iSpecies].getID())) {
-                    nrOfLineageToSpeciesMap[i] = iSpecies;
+            for (int species = 0; species < speciesCount; species++) {
+                if (speciesID.equals(sptNodes[species].getID())) {
+                    nrOfLineageToSpeciesMap[i] = species;
                     break;
                 }
             }
             if (nrOfLineageToSpeciesMap[i] < 0) {
-                throw new Exception("Cannot find species with name " + sSpeciesID + " in species tree");
+                throw new IllegalArgumentException("Cannot find species with name " + speciesID + " in species tree");
             }
         }
 
         // calculate nr of lineages per species
-        nrOfLineages = new int[nSpecies];
+        nrOfLineages = new int[speciesCount];
 //        for (final Node node : gtNodes) {
 //            if (node.isLeaf()) {
-//                final int iSpecies = m_nLineageToSpeciesMap[node.getNr()];
-//                m_nLineages[iSpecies]++;
+//                final int species = m_nLineageToSpeciesMap[node.getNr()];
+//                m_nLineages[species]++;
 //            }
 //        }
 
@@ -134,16 +135,16 @@ public class GeneTreeForSpeciesTreeDistribution extends TreeDistribution {
     }
 
     /**
-     * @param sLineageID
+     * @param lineageID
      * @return species ID to which the lineage ID belongs according to the TaxonSets
      */
-    String getSetID(final String sLineageID) {
+    String getSetID(final String lineageID) {
         final TaxonSet taxonSuperset = speciesTreePriorInput.get().taxonSetInput.get();
         final List<Taxon> taxonSets = taxonSuperset.taxonsetInput.get();
         for (final Taxon taxonSet : taxonSets) {
             final List<Taxon> taxa = ((TaxonSet) taxonSet).taxonsetInput.get();
             for (final Taxon aTaxa : taxa) {
-                if (aTaxa.getID().equals(sLineageID)) {
+                if (aTaxa.getID().equals(lineageID)) {
                     return taxonSet.getID();
                 }
             }
@@ -187,48 +188,48 @@ public class GeneTreeForSpeciesTreeDistribution extends TreeDistribution {
             traverseSpeciesTree(node.getRight());
         }
         // calculate contribution of a branch in the species tree to the log probability
-        final int iNode = node.getNr();
+        final int nodeIndex = node.getNr();
 
         // k, as defined in the paper
         //System.err.println(Arrays.toString(m_nLineages));
-        final int k = intervalsInput[iNode].size();
-        final double[] fTimes = new double[k + 2];
-        fTimes[0] = node.getHeight();
+        final int k = intervalsInput[nodeIndex].size();
+        final double[] times = new double[k + 2];
+        times[0] = node.getHeight();
         for (int i = 1; i <= k; i++) {
-            fTimes[i] = intervalsInput[iNode].poll();
+            times[i] = intervalsInput[nodeIndex].poll();
         }
         if (!node.isRoot()) {
-            fTimes[k + 1] = node.getParent().getHeight();
+            times[k + 1] = node.getParent().getHeight();
         } else {
             if (isConstantPopFunction == TreePopSizeFunction.linear) {
-                fTimes[k + 1] = treeTopFinderInput.get().getHighestTreeHeight();
+                times[k + 1] = treeTopFinderInput.get().getHighestTreeHeight();
             } else {
-                fTimes[k + 1] = Math.max(node.getHeight(), treeInput.get().getRoot().getHeight());
+                times[k + 1] = Math.max(node.getHeight(), treeInput.get().getRoot().getHeight());
             }
         }
         // sanity check
         for (int i = 0; i <= k; i++) {
-            if (fTimes[i] > fTimes[i + 1]) {
-                System.err.println("invalid times");
+            if (times[i] > times[i + 1]) {
+            	Log.warning.println("invalid times");
                 calculateLogP();
             }
         }
 
-        final int nLineagesBottom = nrOfLineages[iNode];
+        final int lineagesBottom = nrOfLineages[nodeIndex];
 
         switch (isConstantPopFunction) {
             case constant:
-                calcConstantPopSizeContribution(nLineagesBottom, popSizesBottom.getValue(iNode), fTimes, k);
+                calcConstantPopSizeContribution(lineagesBottom, popSizesBottom.getValue(nodeIndex), times, k);
                 break;
             case linear:
-                logP += calcLinearPopSizeContributionJH(nLineagesBottom, iNode, fTimes, k, node);
+                logP += calcLinearPopSizeContributionJH(lineagesBottom, nodeIndex, times, k, node);
                 break;
             case linear_with_constant_root:
                 if (node.isRoot()) {
-                    final double fPopSize = getTopPopSize(node.getLeft().getNr()) + getTopPopSize(node.getRight().getNr());
-                    calcConstantPopSizeContribution(nLineagesBottom, fPopSize, fTimes, k);
+                    final double popSize = getTopPopSize(node.getLeft().getNr()) + getTopPopSize(node.getRight().getNr());
+                    calcConstantPopSizeContribution(lineagesBottom, popSize, times, k);
                 } else {
-                    logP += calcLinearPopSizeContribution(nLineagesBottom, iNode, fTimes, k, node);
+                    logP += calcLinearPopSizeContribution(lineagesBottom, nodeIndex, times, k, node);
                 }
                 break;
         }
@@ -237,92 +238,92 @@ public class GeneTreeForSpeciesTreeDistribution extends TreeDistribution {
     /* the contribution of a branch in the species tree to
       * the log probability, for constant population function.
       */
-    private void calcConstantPopSizeContribution(final int nLineagesBottom, final double fPopSize2,
-                                                 final double[] fTimes, final int k) {
-        final double fPopSize = fPopSize2 * ploidy;
-        logP += -k * Math.log(fPopSize);
+    private void calcConstantPopSizeContribution(final int lineagesBottom, final double popSize2,
+                                                 final double[] times, final int k) {
+        final double popSize = popSize2 * ploidy;
+        logP += -k * Math.log(popSize);
 //		System.err.print(logP);
         for (int i = 0; i <= k; i++) {
-            logP += -((nLineagesBottom - i) * (nLineagesBottom - i - 1.0) / 2.0) * (fTimes[i + 1] - fTimes[i]) / fPopSize;
+            logP += -((lineagesBottom - i) * (lineagesBottom - i - 1.0) / 2.0) * (times[i + 1] - times[i]) / popSize;
         }
-//		System.err.println(" " + logP + " " + Arrays.toString(fTimes) + " " + iNode + " " + k);
+//		System.err.println(" " + logP + " " + Arrays.toString(times) + " " + nodeIndex + " " + k);
     }
 
     /* the contribution of a branch in the species tree to
       * the log probability, for linear population function.
       */
-    private double calcLinearPopSizeContribution(final int nLineagesBottom, final int iNode, final double[] fTimes,
+    private double calcLinearPopSizeContribution(final int lineagesBottom, final int nodeIndex, final double[] times,
                                                  final int k, final Node node) {
         double lp = 0.0;
-        final double fPopSizeBottom;
+        final double popSizeBottom;
         if (node.isLeaf()) {
-            fPopSizeBottom = popSizesBottom.getValue(iNode) * ploidy;
+            popSizeBottom = popSizesBottom.getValue(nodeIndex) * ploidy;
         } else {
             // use sum of left and right child branches for internal nodes
-            fPopSizeBottom = (getTopPopSize(node.getLeft().getNr()) + getTopPopSize(node.getRight().getNr())) * ploidy;
+            popSizeBottom = (getTopPopSize(node.getLeft().getNr()) + getTopPopSize(node.getRight().getNr())) * ploidy;
         }
-        final double fPopSizeTop = getTopPopSize(iNode) * ploidy;
-        final double a = (fPopSizeTop - fPopSizeBottom) / (fTimes[k + 1] - fTimes[0]);
-        final double b = fPopSizeBottom;
+        final double popSizeTop = getTopPopSize(nodeIndex) * ploidy;
+        final double a = (popSizeTop - popSizeBottom) / (times[k + 1] - times[0]);
+        final double b = popSizeBottom;
         for (int i = 0; i < k; i++) {
-            //double fPopSize = fPopSizeBottom + (fPopSizeTop-fPopSizeBottom) * fTimes[i+1]/(fTimes[k]-fTimes[0]);
-            final double fPopSize = a * (fTimes[i + 1] - fTimes[0]) + b;
-            lp += -Math.log(fPopSize);
+            //double popSize = popSizeBottom + (popSizeTop-popSizeBottom) * times[i+1]/(times[k]-times[0]);
+            final double popSize = a * (times[i + 1] - times[0]) + b;
+            lp += -Math.log(popSize);
         }
         for (int i = 0; i <= k; i++) {
-            if (Math.abs(fPopSizeTop - fPopSizeBottom) < 1e-10) {
+            if (Math.abs(popSizeTop - popSizeBottom) < 1e-10) {
                 // slope = 0, so population function is constant
-                final double fPopSize = a * (fTimes[i + 1] - fTimes[0]) + b;
-                lp += -((nLineagesBottom - i) * (nLineagesBottom - i - 1.0) / 2.0) * (fTimes[i + 1] - fTimes[i]) / fPopSize;
+                final double popSize = a * (times[i + 1] - times[0]) + b;
+                lp += -((lineagesBottom - i) * (lineagesBottom - i - 1.0) / 2.0) * (times[i + 1] - times[i]) / popSize;
             } else {
-                final double f = (a * (fTimes[i + 1] - fTimes[0]) + b) / (a * (fTimes[i] - fTimes[0]) + b);
-                lp += -((nLineagesBottom - i) * (nLineagesBottom - i - 1.0) / 2.0) * Math.log(f) / a;
+                final double f = (a * (times[i + 1] - times[0]) + b) / (a * (times[i] - times[0]) + b);
+                lp += -((lineagesBottom - i) * (lineagesBottom - i - 1.0) / 2.0) * Math.log(f) / a;
             }
         }
         return lp;
     }
 
-    private double calcLinearPopSizeContributionJH(final int nLineagesBottom, final int iNode, final double[] fTimes,
+    private double calcLinearPopSizeContributionJH(final int lineagesBottom, final int nodeIndex, final double[] times,
                                                    final int k, final Node node) {
         double lp = 0.0;
-        double fPopSizeBottom;
+        double popSizeBottom;
         if (node.isLeaf()) {
-            fPopSizeBottom = popSizesBottom.getValue(iNode);
+            popSizeBottom = popSizesBottom.getValue(nodeIndex);
         } else {
             // use sum of left and right child branches for internal nodes
-            fPopSizeBottom = (getTopPopSize(node.getLeft().getNr()) + getTopPopSize(node.getRight().getNr()));
+            popSizeBottom = (getTopPopSize(node.getLeft().getNr()) + getTopPopSize(node.getRight().getNr()));
         }
-        fPopSizeBottom *= ploidy;
+        popSizeBottom *= ploidy;
 
-        final double fPopSizeTop = getTopPopSize(iNode) * ploidy;
-        final double d5 = fPopSizeTop - fPopSizeBottom;
-        final double fTime0 = fTimes[0];
-        final double a = d5 / (fTimes[k + 1] - fTime0);
-        final double b = fPopSizeBottom;
+        final double popSizeTop = getTopPopSize(nodeIndex) * ploidy;
+        final double d5 = popSizeTop - popSizeBottom;
+        final double time0 = times[0];
+        final double a = d5 / (times[k + 1] - time0);
+        final double b = popSizeBottom;
 
         if (Math.abs(d5) < 1e-10) {
             // use approximation for small values to bypass numerical instability
             for (int i = 0; i <= k; i++) {
-                final double fTimeip1 = fTimes[i + 1];
-                final double fPopSize = a * (fTimeip1 - fTime0) + b;
+                final double timeip1 = times[i + 1];
+                final double popSize = a * (timeip1 - time0) + b;
                 if( i < k ) {
-                  lp += -Math.log(fPopSize);
+                  lp += -Math.log(popSize);
                 }
                 // slope = 0, so population function is constant
 
-                final int i1 = nLineagesBottom - i;
-                lp -= (i1 * (i1 - 1.0) / 2.0) * (fTimeip1 - fTimes[i]) / fPopSize;
+                final int i1 = lineagesBottom - i;
+                lp -= (i1 * (i1 - 1.0) / 2.0) * (timeip1 - times[i]) / popSize;
             }
         } else {
-            final double vv = b - a * fTime0;
+            final double vv = b - a * time0;
             for (int i = 0; i <= k; i++) {
-                final double fPopSize = a * fTimes[i + 1] + vv;
+                final double popSize = a * times[i + 1] + vv;
                 if( i < k ) {
-                  lp += -Math.log(fPopSize);
+                  lp += -Math.log(popSize);
                 }
-                final double f = fPopSize / (a * fTimes[i] + vv);
+                final double f = popSize / (a * times[i] + vv);
 
-                final int i1 = nLineagesBottom - i;
+                final int i1 = lineagesBottom - i;
                 lp += -(i1 * (i1 - 1.0) / 2.0) * Math.log(f) / a;
             }
         }
@@ -339,30 +340,30 @@ public class GeneTreeForSpeciesTreeDistribution extends TreeDistribution {
      */
     private int traverseLineageTree(final Node[] speciesNodes, final Node node) {
         if (node.isLeaf()) {
-            final int iSpecies = nrOfLineageToSpeciesMap[node.getNr()];
-            nrOfLineages[iSpecies]++;
-            return iSpecies;
+            final int species = nrOfLineageToSpeciesMap[node.getNr()];
+            nrOfLineages[species]++;
+            return species;
         } else {
-            int nSpeciesLeft = traverseLineageTree(speciesNodes, node.getLeft());
-            int nSpeciesRight = traverseLineageTree(speciesNodes, node.getRight());
-            final double fHeight = node.getHeight();
+            int speciesLeft = traverseLineageTree(speciesNodes, node.getLeft());
+            int speciesRight = traverseLineageTree(speciesNodes, node.getRight());
+            final double height = node.getHeight();
 
-            while (!speciesNodes[nSpeciesLeft].isRoot() && fHeight > speciesNodes[nSpeciesLeft].getParent().getHeight()) {
-                nSpeciesLeft = speciesNodes[nSpeciesLeft].getParent().getNr();
-                nrOfLineages[nSpeciesLeft]++;
+            while (!speciesNodes[speciesLeft].isRoot() && height > speciesNodes[speciesLeft].getParent().getHeight()) {
+                speciesLeft = speciesNodes[speciesLeft].getParent().getNr();
+                nrOfLineages[speciesLeft]++;
             }
-            while (!speciesNodes[nSpeciesRight].isRoot() && fHeight > speciesNodes[nSpeciesRight].getParent().getHeight()) {
-                nSpeciesRight = speciesNodes[nSpeciesRight].getParent().getNr();
-                nrOfLineages[nSpeciesRight]++;
+            while (!speciesNodes[speciesRight].isRoot() && height > speciesNodes[speciesRight].getParent().getHeight()) {
+                speciesRight = speciesNodes[speciesRight].getParent().getNr();
+                nrOfLineages[speciesRight]++;
             }
             // validity check
-            if (nSpeciesLeft != nSpeciesRight) {
+            if (speciesLeft != speciesRight) {
                 // if we got here, it means the gene tree does
                 // not fit in the species tree
                 logP = Double.NEGATIVE_INFINITY;
             }
-            intervalsInput[nSpeciesRight].add(fHeight);
-            return nSpeciesRight;
+            intervalsInput[speciesRight].add(height);
+            return speciesRight;
         }
     }
 
@@ -371,9 +372,9 @@ public class GeneTreeForSpeciesTreeDistribution extends TreeDistribution {
       * of m_fPopSizesTop, then the root node can be numbered with a lower number
       * and we can use that entry in m_fPopSizesTop for the rogue internal node.
       */
-    private double getTopPopSize(final int iNode) {
-        if (iNode < popSizesTop.getDimension()) {
-            return popSizesTop.getArrayValue(iNode);
+    private double getTopPopSize(final int nodeIndex) {
+        if (nodeIndex < popSizesTop.getDimension()) {
+            return popSizesTop.getArrayValue(nodeIndex);
         }
         return popSizesTop.getArrayValue(speciesTreeInput.get().getRoot().getNr());
     }
diff --git a/src/beast/evolution/speciation/RandomGeneTree.java b/src/beast/evolution/speciation/RandomGeneTree.java
index 2d02194..149c1c8 100644
--- a/src/beast/evolution/speciation/RandomGeneTree.java
+++ b/src/beast/evolution/speciation/RandomGeneTree.java
@@ -16,10 +16,10 @@ import beast.evolution.tree.coalescent.PopulationFunction;
         "that the root of the species tree is lower than any coalescent events in " +
         "the gene tree")
 public class RandomGeneTree extends RandomTree {
-    public Input<Tree> speciesTreeInput = new Input<Tree>("speciesTree", "The species tree in which this random gene tree needs to fit", Validate.REQUIRED);
+    final public Input<Tree> speciesTreeInput = new Input<>("speciesTree", "The species tree in which this random gene tree needs to fit", Validate.REQUIRED);
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
     }
 
@@ -35,11 +35,11 @@ public class RandomGeneTree extends RandomTree {
             throw new IllegalArgumentException("empty nodes set");
         }
 
-        final double fLowestHeight = speciesTreeInput.get().getRoot().getHeight();
+        final double lowestHeight = speciesTreeInput.get().getRoot().getHeight();
 
         for (int attempts = 0; attempts < 1000; ++attempts) {
             try {
-                final List<Node> rootNode = simulateCoalescent(nodes, demographic, fLowestHeight, maxHeight);
+                final List<Node> rootNode = simulateCoalescent(nodes, demographic, lowestHeight, maxHeight);
                 if (rootNode.size() == 1) {
                     return rootNode.get(0);
                 }
diff --git a/src/beast/evolution/speciation/SpeciesTreeDistribution.java b/src/beast/evolution/speciation/SpeciesTreeDistribution.java
index 327ba6d..1f16b8a 100644
--- a/src/beast/evolution/speciation/SpeciesTreeDistribution.java
+++ b/src/beast/evolution/speciation/SpeciesTreeDistribution.java
@@ -32,7 +32,6 @@ import java.util.Random;
 
 import beast.core.Description;
 import beast.core.State;
-import beast.evolution.tree.Tree;
 import beast.evolution.tree.TreeDistribution;
 import beast.evolution.tree.TreeInterface;
 
diff --git a/src/beast/evolution/speciation/SpeciesTreeLogger.java b/src/beast/evolution/speciation/SpeciesTreeLogger.java
index 4c42364..9baad2c 100644
--- a/src/beast/evolution/speciation/SpeciesTreeLogger.java
+++ b/src/beast/evolution/speciation/SpeciesTreeLogger.java
@@ -4,13 +4,13 @@ import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.List;
 
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Function;
 import beast.core.Input;
+import beast.core.Input.Validate;
 import beast.core.Loggable;
 import beast.core.StateNode;
-import beast.core.BEASTObject;
-import beast.core.Input.Validate;
 import beast.core.parameter.Parameter;
 import beast.evolution.speciation.SpeciesTreePrior.TreePopSizeFunction;
 import beast.evolution.tree.Node;
@@ -20,12 +20,12 @@ import beast.evolution.tree.Tree;
 
 @Description("Logs tree annotated with metadata in StarBeast format")
 public class SpeciesTreeLogger extends BEASTObject implements Loggable {
-    public Input<Tree> treeInput = new Input<Tree>("tree", "tree to be logged", Validate.REQUIRED);
-    public Input<Function> parameterInput = new Input<Function>("popSize", "population size parameter associated with tree nodes", Validate.REQUIRED);
-    public Input<Function> parameterTopInput = new Input<Function>("popSizeTop", "population size parameter associated with top of tree branches, only used for non-constant *beast analysis");
-    public Input<SpeciesTreePrior> speciesTreePriorInput = new Input<SpeciesTreePrior>("speciesTreePrior", "species tree prior, used to find which Population Size Function is used. If not specified, assumes 'constant'");
-    public Input<TreeTopFinder> treeTopFinderInput = new Input<TreeTopFinder>("treetop", "calculates height of species tree", Validate.REQUIRED);
-    public Input<List<Function>> metadataInput = new Input<List<Function>>("metadata", "meta data to be logged with the tree nodes",new ArrayList<>());
+    final public Input<Tree> treeInput = new Input<>("tree", "tree to be logged", Validate.REQUIRED);
+    final public Input<Function> parameterInput = new Input<>("popSize", "population size parameter associated with tree nodes", Validate.REQUIRED);
+    final public Input<Function> parameterTopInput = new Input<>("popSizeTop", "population size parameter associated with top of tree branches, only used for non-constant *beast analysis");
+    final public Input<SpeciesTreePrior> speciesTreePriorInput = new Input<>("speciesTreePrior", "species tree prior, used to find which Population Size Function is used. If not specified, assumes 'constant'");
+    final public Input<TreeTopFinder> treeTopFinderInput = new Input<>("treetop", "calculates height of species tree", Validate.REQUIRED);
+    final public Input<List<Function>> metadataInput = new Input<>("metadata", "meta data to be logged with the tree nodes",new ArrayList<>());
 
     TreePopSizeFunction popSizeFunction;
     String metaDataLabel;
@@ -44,12 +44,12 @@ public class SpeciesTreeLogger extends BEASTObject implements Loggable {
     }
 
     @Override
-    public void init(final PrintStream out) throws Exception {
+    public void init(final PrintStream out) {
         treeInput.get().init(out);
     }
 
     @Override
-    public void log(final int nSample, final PrintStream out) {
+    public void log(final int sample, final PrintStream out) {
         // make sure we get the current version of the inputs
         final Tree tree = (Tree) treeInput.get().getCurrent();
         Function metadata = parameterInput.get();
@@ -69,7 +69,7 @@ public class SpeciesTreeLogger extends BEASTObject implements Loggable {
         }
 
         // write out the log tree with meta data
-        out.print("tree STATE_" + nSample + " = ");
+        out.print("tree STATE_" + sample + " = ");
         tree.getRoot().sort();
         out.print(toNewick(tree.getRoot(), metadata, metadataTop, metadataList));
         //out.print(tree.getRoot().toShortNewick(false));
@@ -135,7 +135,7 @@ public class SpeciesTreeLogger extends BEASTObject implements Loggable {
 	            buf.append(((BEASTObject)metadata2).getID());
 	            buf.append('=');
 	            if (metadata2 instanceof Parameter<?>) {
-	            	Parameter p = (Parameter) metadata2;
+	            	Parameter<?> p = (Parameter<?>) metadata2;
 	            	int dim = p.getMinorDimension1();
 	            	if (dim > 1) {
 		            	buf.append('{');
diff --git a/src/beast/evolution/speciation/SpeciesTreePrior.java b/src/beast/evolution/speciation/SpeciesTreePrior.java
index cd16c16..80c37c6 100644
--- a/src/beast/evolution/speciation/SpeciesTreePrior.java
+++ b/src/beast/evolution/speciation/SpeciesTreePrior.java
@@ -7,8 +7,8 @@ import java.util.Random;
 
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.State;
 import beast.core.Input.Validate;
+import beast.core.State;
 import beast.core.parameter.RealParameter;
 import beast.evolution.alignment.TaxonSet;
 import beast.evolution.tree.Node;
@@ -19,25 +19,25 @@ import beast.math.distributions.Gamma;
 
 @Description("Species tree prior for *BEAST analysis")
 public class SpeciesTreePrior extends TreeDistribution {
-    //public Input<Tree> m_speciesTree = new Input<Tree>("speciesTree", "species tree containing the associated gene tree", Validate.REQUIRED);
+    //public Input<Tree> m_speciesTree = new Input<>("speciesTree", "species tree containing the associated gene tree", Validate.REQUIRED);
 
     protected enum TreePopSizeFunction {constant, linear, linear_with_constant_root}
 
-    public final Input<TreePopSizeFunction> popFunctionInput = new Input<TreePopSizeFunction>("popFunction", "Population function. " +
+    public final Input<TreePopSizeFunction> popFunctionInput = new Input<>("popFunction", "Population function. " +
             "This can be " + Arrays.toString(TreePopSizeFunction.values()) + " (default 'constant')", TreePopSizeFunction.constant, TreePopSizeFunction.values());
 
-    public final Input<RealParameter> popSizesBottomInput = new Input<RealParameter>("bottomPopSize", "population size parameter for populations at the bottom of a branch. " +
+    public final Input<RealParameter> popSizesBottomInput = new Input<>("bottomPopSize", "population size parameter for populations at the bottom of a branch. " +
             "For linear population function, this is the same at the top of the branch.", Validate.REQUIRED);
-    public final Input<RealParameter> popSizesTopInput = new Input<RealParameter>("topPopSize", "population size parameter at the top of a branch. " +
+    public final Input<RealParameter> popSizesTopInput = new Input<>("topPopSize", "population size parameter at the top of a branch. " +
             "Ignored for constant population function, but required for linear population function.");
 
-    public final Input<RealParameter> gammaParameterInput = new Input<RealParameter>("gammaParameter", "shape parameter of the gamma distribution", Validate.REQUIRED);
+    public final Input<RealParameter> gammaParameterInput = new Input<>("gammaParameter", "shape parameter of the gamma distribution", Validate.REQUIRED);
 
-//	public Input<RealParameter> m_rootHeightParameter = new Input<RealParameter>("rootBranchHeight","height of the node above the root, representing the root branch", Validate.REQUIRED);
+//	public Input<RealParameter> m_rootHeightParameter = new Input<>("rootBranchHeight","height of the node above the root, representing the root branch", Validate.REQUIRED);
     /**
      * m_taxonSet is used by GeneTreeForSpeciesTreeDistribution *
      */
-    public Input<TaxonSet> taxonSetInput = new Input<TaxonSet>("taxonset", "set of taxa mapping lineages to species", Validate.REQUIRED);
+    final public Input<TaxonSet> taxonSetInput = new Input<>("taxonset", "set of taxa mapping lineages to species", Validate.REQUIRED);
 
 
     private TreePopSizeFunction popFunction;
@@ -48,31 +48,31 @@ public class SpeciesTreePrior extends TreeDistribution {
     private Gamma gamma4Prior;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         popFunction = popFunctionInput.get();
         popSizesBottom = popSizesBottomInput.get();
         popSizesTop = popSizesTopInput.get();
 
         // set up sizes of population functions
-        final int nSpecies = treeInput.get().getLeafNodeCount();
-        final int nNodes = treeInput.get().getNodeCount();
+        final int speciesCount = treeInput.get().getLeafNodeCount();
+        final int nodeCount = treeInput.get().getNodeCount();
         switch (popFunction) {
             case constant:
-                popSizesBottom.setDimension(nNodes);
+                popSizesBottom.setDimension(nodeCount);
                 break;
             case linear:
                 if (popSizesTop == null) {
-                    throw new Exception("topPopSize must be specified");
+                    throw new IllegalArgumentException("topPopSize must be specified");
                 }
-                popSizesBottom.setDimension(nSpecies);
-                popSizesTop.setDimension(nNodes);
+                popSizesBottom.setDimension(speciesCount);
+                popSizesTop.setDimension(nodeCount);
                 break;
             case linear_with_constant_root:
                 if (popSizesTop == null) {
-                    throw new Exception("topPopSize must be specified");
+                    throw new IllegalArgumentException("topPopSize must be specified");
                 }
-                popSizesBottom.setDimension(nSpecies);
-                popSizesTop.setDimension(nNodes - 1);
+                popSizesBottom.setDimension(speciesCount);
+                popSizesTop.setDimension(nodeCount - 1);
                 break;
         }
 
@@ -87,13 +87,13 @@ public class SpeciesTreePrior extends TreeDistribution {
         gamma4Prior.betaInput.setValue(gammaParameterInput.get(), gamma4Prior);
 
         if (popFunction != TreePopSizeFunction.constant && gamma4Prior == null) {
-            throw new Exception("Top prior must be specified when population function is not constant");
+            throw new IllegalArgumentException("Top prior must be specified when population function is not constant");
         }
         // make sure the m_taxonSet is a set of taxonsets
 // HACK to make Beauti initialise: skip the check here
 //		for (Taxon taxon : m_taxonSet.get().m_taxonset.get()) {
 //			if (!(taxon instanceof TaxonSet)) {
-//				throw new Exception("taxonset should be sets of taxa only, not individual taxons");
+//				throw new IllegalArgumentException("taxonset should be sets of taxa only, not individual taxons");
 //			}
 //		}
     }
@@ -114,52 +114,52 @@ public class SpeciesTreePrior extends TreeDistribution {
                     // constant pop size function
                     logP += gamma2Prior.calcLogP(popSizesBottom);
 //			for (int i = 0; i < speciesNodes.length; i++) {
-//				double fPopSize = m_fPopSizesBottom.getValue(i);
-//				logP += m_bottomPrior.logDensity(fPopSize); 
+//				double popSize = m_fPopSizesBottom.getValue(i);
+//				logP += m_bottomPrior.logDensity(popSize); 
 //			}
                     break;
                 case linear:
                     // linear pop size function
-//			int nSpecies = m_tree.get().getLeafNodeCount();
-//			m_fPopSizesBottom.setDimension(nSpecies);
+//			int speciesCount = m_tree.get().getLeafNodeCount();
+//			m_fPopSizesBottom.setDimension(speciesCount);
 //			logP += m_gamma4Prior.calcLogP(m_fPopSizesBottom);
-//			int nNodes = m_tree.get().getNodeCount();
-//			m_fPopSizesTop.setDimension(nNodes-1);
+//			int nodeCount = m_tree.get().getNodeCount();
+//			m_fPopSizesTop.setDimension(nodeCount-1);
 //			logP += m_gamma2Prior.calcLogP(m_fPopSizesTop);
 
                     for (int i = 0; i < speciesNodes.length; i++) {
                         final Node node = speciesNodes[i];
-                        final double fPopSizeBottom;
+                        final double popSizeBottom;
                         if (node.isLeaf()) {
-                            // Gamma(4, fPsi) prior
-                            fPopSizeBottom = popSizesBottom.getValue(i);
-                            logP += gamma4Prior.logDensity(fPopSizeBottom);
+                            // Gamma(4, psi) prior
+                            popSizeBottom = popSizesBottom.getValue(i);
+                            logP += gamma4Prior.logDensity(popSizeBottom);
                         }
-                        final double fPopSizeTop = popSizesTop.getValue(i);
-                        logP += gamma2Prior.logDensity(fPopSizeTop);
+                        final double popSizeTop = popSizesTop.getValue(i);
+                        logP += gamma2Prior.logDensity(popSizeTop);
                     }
                     break;
                 case linear_with_constant_root:
 //			logP += m_gamma4Prior.calcLogP(m_fPopSizesBottom);
 //			logP += m_gamma2Prior.calcLogP(m_fPopSizesTop);
-//			int iRoot = m_tree.get().getRoot().getNr();
-//			double fPopSize = m_fPopSizesTop.getValue(iRoot);
-//			logP -= m_gamma2Prior.logDensity(fPopSize); 
+//			int rootNr = m_tree.get().getRoot().getNr();
+//			double popSize = m_fPopSizesTop.getValue(rootNr);
+//			logP -= m_gamma2Prior.logDensity(popSize); 
 
                     for (int i = 0; i < speciesNodes.length; i++) {
                         final Node node = speciesNodes[i];
                         if (node.isLeaf()) {
-                            final double fPopSizeBottom = popSizesBottom.getValue(i);
-                            logP += gamma4Prior.logDensity(fPopSizeBottom);
+                            final double popSizeBottom = popSizesBottom.getValue(i);
+                            logP += gamma4Prior.logDensity(popSizeBottom);
                         }
                         if (!node.isRoot()) {
                             if (i < speciesNodes.length - 1) {
-                                final double fPopSizeTop = popSizesTop.getArrayValue(i);
-                                logP += gamma2Prior.logDensity(fPopSizeTop);
+                                final double popSizeTop = popSizesTop.getArrayValue(i);
+                                logP += gamma2Prior.logDensity(popSizeTop);
                             } else {
-                                final int iNode = treeInput.get().getRoot().getNr();
-                                final double fPopSizeTop = popSizesTop.getArrayValue(iNode);
-                                logP += gamma2Prior.logDensity(fPopSizeTop);
+                                final int nodeIndex = treeInput.get().getRoot().getNr();
+                                final double popSizeTop = popSizesTop.getArrayValue(nodeIndex);
+                                logP += gamma2Prior.logDensity(popSizeTop);
                             }
                         }
                     }
diff --git a/src/beast/evolution/speciation/StarBeastStartState.java b/src/beast/evolution/speciation/StarBeastStartState.java
index 7c7ea61..0e65ad7 100644
--- a/src/beast/evolution/speciation/StarBeastStartState.java
+++ b/src/beast/evolution/speciation/StarBeastStartState.java
@@ -1,5 +1,19 @@
 package beast.evolution.speciation;
 
+import static java.lang.Math.abs;
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.commons.math.MathException;
+
 import beast.core.*;
 import beast.core.Input.Validate;
 import beast.core.parameter.RealParameter;
@@ -9,14 +23,12 @@ import beast.evolution.alignment.TaxonSet;
 import beast.evolution.alignment.distance.Distance;
 import beast.evolution.alignment.distance.JukesCantorDistance;
 import beast.evolution.tree.Node;
+import beast.evolution.tree.RandomTree;
 import beast.evolution.tree.Tree;
-import beast.evolution.tree.TreeInterface;
+import beast.evolution.tree.coalescent.ConstantPopulation;
+import beast.math.distributions.MRCAPrior;
 import beast.util.ClusterTree;
 
-import java.util.*;
-
-import static java.lang.Math.*;
-
 /**
 * @author Joseph Heled
  */
@@ -32,53 +44,75 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
             this.ename = name;
         }
 
-        public String toString() {
+        @Override
+		public String toString() {
             return ename;
         }
 
         private final String ename;
     }
-    public Input<Method> initMethod = new Input<Method>("method", "Initialise either with a totally random " +
+    final public Input<Method> initMethod = new Input<>("method", "Initialise either with a totally random " +
             "state or a point estimate based on alignments data (default point-estimate)",
             Method.POINT, Method.values());
 
-    public Input<Tree> speciesTreeInput = new Input<Tree>("speciesTree", "The species tree to initialize");
+    final public Input<Tree> speciesTreeInput = new Input<>("speciesTree", "The species tree to initialize");
 
-    public Input<List<Tree>> genes = new Input<List<Tree>>("gene", "Gene trees to initialize", new ArrayList<Tree>());
+    final public Input<List<Tree>> genes = new Input<>("gene", "Gene trees to initialize", new ArrayList<>());
     //,
     //        Validate.REQUIRED);
 
-    public Input<CalibratedYuleModel> calibratedYule = new Input<CalibratedYuleModel>("calibratedYule",
+    final public Input<CalibratedYuleModel> calibratedYule = new Input<>("calibratedYule",
             "The species tree (with calibrations) to initialize", Validate.XOR, speciesTreeInput);
 
-    public Input<RealParameter> popMean = new Input<RealParameter>("popMean",
+    final public Input<RealParameter> popMean = new Input<>("popMean",
             "Population mean hyper prior to initialse");
 
-    public Input<RealParameter> birthRate = new Input<RealParameter>("birthRate",
+    final public Input<RealParameter> birthRate = new Input<>("birthRate",
             "Tree prior birth rate to initialize");
 
-    public Input<SpeciesTreePrior> speciesTreePriorInput =
-            new Input<SpeciesTreePrior>("speciesTreePrior", "Population size parameters to initialise");
+    final public Input<SpeciesTreePrior> speciesTreePriorInput =
+            new Input<>("speciesTreePrior", "Population size parameters to initialise");
 
-    public Input<Function> muInput = new Input<Function>("baseRate",
+    final public Input<Function> muInput = new Input<>("baseRate",
             "Main clock rate used to scale trees (default 1).");
 
 
     private boolean hasCalibrations;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         // what does this do and is it dangerous to call it or not to call it at the start or at the end??????
         super.initAndValidate();
         hasCalibrations = calibratedYule.get() != null;
     }
 
     @Override
-    public void initStateNodes() throws Exception {
+    public void initStateNodes() {
+
+        final Set<BEASTInterface> treeOutputs = speciesTreeInput.get().getOutputs();
+        List<MRCAPrior> calibrations = new ArrayList<>();
+        for (final Object plugin : treeOutputs ) {
+            if( plugin instanceof MRCAPrior ) {
+                calibrations.add((MRCAPrior) plugin);
+            }
+        }
 
         if( hasCalibrations ) {
-            initWithCalibrations();
+            if( calibrations.size() > 0 ) {
+                throw new IllegalArgumentException("Not implemented: mix of calibrated yule and MRCA priors: " +
+                        "place all priors in the calibrated Yule");
+            }
+            try {
+				initWithCalibrations();
+			} catch (MathException e) {
+				throw new IllegalArgumentException(e);
+			}
         } else {
+            if( calibrations.size() > 0 )  {
+                initWithMRCACalibrations(calibrations);
+                return;
+            }
+
             final Method method = initMethod.get();
 
             switch( method ) {
@@ -92,15 +126,16 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
         }
     }
 
-    private double[] firstMeetings(final Tree gtree, final Map<String, Integer> tipName2Species, final int nSpecies) {
+    private double[] firstMeetings(final Tree gtree, final Map<String, Integer> tipName2Species, final int speciesCount) {
         final Node[] nodes = gtree.listNodesPostOrder(null, null);
-        final Set<Integer>[] tipsSpecies = new Set[nodes.length];
+        @SuppressWarnings("unchecked")
+		final Set<Integer>[] tipsSpecies = new Set[nodes.length];
         for(int k = 0; k < tipsSpecies.length; ++k) {
-            tipsSpecies[k] = new HashSet<Integer>();
+            tipsSpecies[k] = new HashSet<>();
         }
         // d[i,j] = minimum height of node which has tips belonging to species i and j
         // d is is upper triangular
-        final double[] dmin = new double[(nSpecies*(nSpecies-1))/2];
+        final double[] dmin = new double[(speciesCount*(speciesCount-1))/2];
         Arrays.fill(dmin, Double.MAX_VALUE);
 
         for (final Node n : nodes) {
@@ -108,17 +143,18 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
                 tipsSpecies[n.getNr()].add(tipName2Species.get(n.getID()));
             } else {
                 assert n.getChildCount() == 2;
-                final Set<Integer>[] sps = new Set[2];
+                @SuppressWarnings("unchecked")
+				final Set<Integer>[] sps = new Set[2];
                 sps[0] = tipsSpecies[n.getChild(0).getNr()];
                 sps[1] = tipsSpecies[n.getChild(1).getNr()];
-                final Set<Integer> u = new HashSet<Integer>(sps[0]);
+                final Set<Integer> u = new HashSet<>(sps[0]);
                 u.retainAll(sps[1]);
                 sps[0].removeAll(u);
                 sps[1].removeAll(u);
 
                 for (final Integer s1 : sps[0]) {
                     for (final Integer s2 : sps[1]) {
-                        final int i = getDMindex(nSpecies, s1, s2);
+                        final int i = getDMindex(speciesCount, s1, s2);
                         dmin[i] = min(dmin[i], n.getHeight());
                     }
                 }
@@ -130,13 +166,13 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
         return dmin;
     }
 
-    private int getDMindex(final int nSpecies, final int s1, final int s2) {
+    private int getDMindex(final int speciesCount, final int s1, final int s2) {
         final int mij = min(s1,s2);
-        return (mij*(2*nSpecies-1 - mij))/2 + (abs(s1-s2)-1);
+        return (mij*(2*speciesCount-1 - mij))/2 + (abs(s1-s2)-1);
     }
 
 
-    private void fullInit() throws Exception {
+    private void fullInit() {
         // Build gene trees from  alignments
 
         final Function muInput = this.muInput.get();
@@ -145,12 +181,12 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
         final Tree stree = speciesTreeInput.get();
         final TaxonSet species = stree.m_taxonset.get();
         final List<String> speciesNames = species.asStringList();
-        final int nSpecies = speciesNames.size();
+        final int speciesCount = speciesNames.size();
 
         final List<Tree> geneTrees = genes.get();
 
         //final List<Alignment> alignments = genes.get();
-        //final List<Tree> geneTrees = new ArrayList<Tree>(alignments.size());
+        //final List<Tree> geneTrees = new ArrayList<>(alignments.size());
         double maxNsites = 0;
         //for( final Alignment alignment : alignments)  {
         for (final Tree gtree : geneTrees) {
@@ -163,7 +199,7 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
 
             maxNsites = max(maxNsites, alignment.getSiteCount());
         }
-        final Map<String, Integer> geneTips2Species = new HashMap<String, Integer>();
+        final Map<String, Integer> geneTips2Species = new HashMap<>();
         final List<Taxon> taxonSets = species.taxonsetInput.get();
 
         for(int k = 0; k < speciesNames.size(); ++k) {
@@ -173,13 +209,13 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
               geneTips2Species.put(n.getID(), k);
             }
         }
-        final double[] dg = new double[(nSpecies*(nSpecies-1))/2];
+        final double[] dg = new double[(speciesCount*(speciesCount-1))/2];
 
         final double[][] genesDmins = new double[geneTrees.size()][];
 
         for( int ng = 0; ng < geneTrees.size(); ++ng ) {
             final Tree g = geneTrees.get(ng);
-            final double[] dmin = firstMeetings(g, geneTips2Species, nSpecies);
+            final double[] dmin = firstMeetings(g, geneTips2Species, speciesCount);
             genesDmins[ng] = dmin;
 
             for(int i = 0; i < dmin.length; ++i) {
@@ -188,13 +224,13 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
                 	// this happens when a gene tree has no taxa for some species-tree taxon.
                 	// TODO: ensure that if this happens, there will always be an "infinite"
                 	// distance between species-taxon 0 and the species-taxon with missing lineages,
-                	// so i < nSpecies - 1.
+                	// so i < speciesCount - 1.
                 	// What if lineages for species-taxon 0 are missing? Then all entries will be 'infinite'.
-                	String id = (i < nSpecies - 1? stree.getExternalNodes().get(i+1).getID() : "unknown taxon");
+                	String id = (i < speciesCount - 1? stree.getExternalNodes().get(i+1).getID() : "unknown taxon");
                 	if (i == 0) {
                 		// test that all entries are 'infinite', which implies taxon 0 has lineages missing 
                 		boolean b = true;
-                		for (int k = 1; b && k < nSpecies - 1; k++) {
+                		for (int k = 1; b && k < speciesCount - 1; k++) {
                 			b = (dmin[k] == Double.MAX_VALUE);
                 		}
                 		if (b) {
@@ -222,17 +258,17 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
         final Distance distance = new Distance() {
             @Override
             public double pairwiseDistance(final int s1, final int s2) {
-                final int i = getDMindex(nSpecies, s1,s2);
+                final int i = getDMindex(speciesCount, s1,s2);
                 return dg[i];
             }
         };
         ctree.initByName("initial", stree, "taxonset", species,"clusterType", "upgma", "distance", distance);
 
-        final Map<String, Integer> sptips2SpeciesIndex = new HashMap<String, Integer>();
+        final Map<String, Integer> sptips2SpeciesIndex = new HashMap<>();
         for(int i = 0; i < speciesNames.size(); ++i) {
             sptips2SpeciesIndex.put(speciesNames.get(i), i);
         }
-        final double[] spmin = firstMeetings(stree, sptips2SpeciesIndex, nSpecies);
+        final double[] spmin = firstMeetings(stree, sptips2SpeciesIndex, speciesCount);
 
         for( int ng = 0; ng < geneTrees.size(); ++ng ) {
             final double[] dmin = genesDmins[ng];
@@ -248,10 +284,10 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
                 final TaxonSet gtreeTaxa = gtree.m_taxonset.get();
                 final Alignment alignment = gtreeTaxa.alignmentInput.get();
                 final List<String> taxaNames = alignment.getTaxaNames();
-                final int nTaxa =  taxaNames.size();
+                final int taxonCount =  taxaNames.size();
                 // speedup
-                final Map<Integer,Integer> g2s = new HashMap<Integer, Integer>();
-                for(int i = 0; i < nTaxa; ++i) {
+                final Map<Integer,Integer> g2s = new HashMap<>();
+                for(int i = 0; i < taxonCount; ++i) {
                     g2s.put(i, geneTips2Species.get(taxaNames.get(i)));
                 }
 
@@ -264,7 +300,7 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
                         final int s2 = g2s.get(t2);
                         double d = jc.pairwiseDistance(t1,t2)/mu;
                         if( s1 != s2 ) {
-                            final int i = getDMindex(nSpecies, s1,s2);
+                            final int i = getDMindex(speciesCount, s1,s2);
                             final double minDist = 2 * spmin[i];
                             if( d <= minDist ) {
                                 d = minDist * 1.001;
@@ -284,7 +320,7 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
             if( lambda != null ) {
                 final double rh = stree.getRoot().getHeight();
                 double l = 0;
-                for(int i = 2; i < nSpecies+1; ++i) {
+                for(int i = 2; i < speciesCount+1; ++i) {
                     l += 1./i;
                 }
                 lambda.setValue((1 / rh) * l);
@@ -327,7 +363,7 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
         }
     }
 
-    private void randomInit() throws Exception {
+    private void randomInit() {
         double lam = 1;
         final RealParameter lambda = birthRate.get();
         if( lambda != null ) {
@@ -335,9 +371,9 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
         }
         final Tree stree = speciesTreeInput.get();
         final TaxonSet species = stree.m_taxonset.get();
-        final int nSpecies = species.asStringList().size();
+        final int speciesCount = species.asStringList().size();
         double s = 0;
-        for(int k = 2; k <= nSpecies; ++k) {
+        for(int k = 2; k <= speciesCount; ++k) {
             s += 1.0/k;
         }
         final double rootHeight = (1/lam) * s;
@@ -349,7 +385,7 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
 //        }
     }
 
-    private void initWithCalibrations() throws Exception {
+    private void initWithCalibrations() throws MathException {
         final CalibratedYuleModel cYule = calibratedYule.get();
         final Tree spTree = (Tree) cYule.treeInput.get();
 
@@ -380,6 +416,25 @@ public class StarBeastStartState extends Tree implements StateNodeInitialiser {
         cYule.initAndValidate();
     }
 
+    private void initWithMRCACalibrations(List<MRCAPrior> calibrations) {
+        final Tree spTree = speciesTreeInput.get();
+        final RandomTree rnd = new RandomTree();
+        rnd.setInputValue("taxonset", spTree.getTaxonset());
+
+        for( final MRCAPrior cal : calibrations ) {
+          rnd.setInputValue("constraint", cal);
+        }
+        ConstantPopulation pf = new ConstantPopulation();
+        pf.setInputValue("popSize", new RealParameter("1.0"));
+
+        rnd.setInputValue("populationModel", pf);
+        rnd.initAndValidate();
+        spTree.assignFromWithoutID((Tree)rnd);
+
+        final double rootHeight = spTree.getRoot().getHeight();
+        randomInitGeneTrees(rootHeight);
+    }
+
     @Override
     public void getInitialisedStateNodes(final List<StateNode> stateNodes) {
         if( hasCalibrations ) {
diff --git a/src/beast/evolution/speciation/TreeTopFinder.java b/src/beast/evolution/speciation/TreeTopFinder.java
index cdf3dc5..3aeabc6 100644
--- a/src/beast/evolution/speciation/TreeTopFinder.java
+++ b/src/beast/evolution/speciation/TreeTopFinder.java
@@ -12,14 +12,15 @@ import beast.evolution.tree.Tree;
 
 @Description("Finds height of highest tree among a set of trees")
 public class TreeTopFinder extends CalculationNode {
-    public Input<List<Tree>> treeInputs = new Input<List<Tree>>("tree", "set of trees to search among", new ArrayList<Tree>());
+    final public Input<List<Tree>> treeInputs = new Input<>("tree", "set of trees to search among", new ArrayList<>());
 
     List<Tree> trees;
 
     double oldHeight;
     double height;
 
-    public void initAndValidate() throws Exception {
+    @Override
+	public void initAndValidate() {
         oldHeight = Double.NaN;
         trees = treeInputs.get();
         height = calcHighestTreeHeight();
@@ -30,18 +31,18 @@ public class TreeTopFinder extends CalculationNode {
     }
 
     private double calcHighestTreeHeight() {
-        double fTop = 0;
+        double top = 0;
         for (Tree tree : trees) {
-            fTop = Math.max(tree.getRoot().getHeight(), fTop);
+            top = Math.max(tree.getRoot().getHeight(), top);
         }
-        return fTop;
+        return top;
     }
 
     @Override
     protected boolean requiresRecalculation() {
-        double fTop = calcHighestTreeHeight();
-        if (fTop != height) {
-            height = fTop;
+        double top = calcHighestTreeHeight();
+        if (top != height) {
+            height = top;
             return true;
         }
         return false;
diff --git a/src/beast/evolution/speciation/YuleModel.java b/src/beast/evolution/speciation/YuleModel.java
index 79a64c2..e978f5b 100644
--- a/src/beast/evolution/speciation/YuleModel.java
+++ b/src/beast/evolution/speciation/YuleModel.java
@@ -6,8 +6,8 @@ import beast.core.Description;
 import beast.core.Input;
 import beast.core.Input.Validate;
 import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
 import beast.evolution.tree.Node;
-import beast.evolution.tree.Tree;
 import beast.evolution.tree.TreeInterface;
 
 
@@ -21,18 +21,18 @@ import beast.evolution.tree.TreeInterface;
 
 @Description("Pure birth model (i.e. no deaths)")
 public class YuleModel extends SpeciesTreeDistribution {
-    public Input<RealParameter> birthDiffRateParameterInput =
-            new Input<RealParameter>("birthDiffRate", "birth difference rate parameter, lambda - mu in birth/death model", Validate.REQUIRED);
-    public Input<RealParameter> originHeightParameterInput =
-            new Input<RealParameter>("originHeight", "the height of the point of origin of the process");
-    public Input<Boolean> conditionalOnRootInput =
-            new Input<Boolean>("conditionalOnRoot", "Whether to condition on the root (default false)", false);
+    final public Input<RealParameter> birthDiffRateParameterInput =
+            new Input<>("birthDiffRate", "birth difference rate parameter, lambda - mu in birth/death model", Validate.REQUIRED);
+    final public Input<RealParameter> originHeightParameterInput =
+            new Input<>("originHeight", "the height of the point of origin of the process");
+    final public Input<Boolean> conditionalOnRootInput =
+            new Input<>("conditionalOnRoot", "Whether to condition on the root (default false)", false);
 
     protected boolean conditionalOnRoot;
     protected boolean conditionalOnOrigin;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
         conditionalOnRoot = conditionalOnRootInput.get();
         conditionalOnOrigin = originHeightParameterInput.get() != null;
@@ -51,7 +51,7 @@ public class YuleModel extends SpeciesTreeDistribution {
         double height = leafs.get(0).getHeight();
         for (Node leaf : leafs) {
             if (Math.abs(leaf.getHeight() - height) > 1e-8) {
-                System.err.println("WARNING: Yule Model cannot handle dated tips. Use for example a coalescent prior instead.");
+            	Log.warning.println("WARNING: Yule Model cannot handle dated tips. Use for example a coalescent prior instead.");
                 break;
             }
         }
diff --git a/src/beast/evolution/substitutionmodel/BinaryCovarion.java b/src/beast/evolution/substitutionmodel/BinaryCovarion.java
index bd2bc46..9abf7fa 100644
--- a/src/beast/evolution/substitutionmodel/BinaryCovarion.java
+++ b/src/beast/evolution/substitutionmodel/BinaryCovarion.java
@@ -1,5 +1,7 @@
 package beast.evolution.substitutionmodel;
 
+import java.lang.reflect.InvocationTargetException;
+
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.Input.Validate;
@@ -64,13 +66,13 @@ import beast.evolution.datatype.TwoStateCovarion;
  */
 @Description("Covarion model for Binary data")
 public class BinaryCovarion extends GeneralSubstitutionModel {
-    public Input<RealParameter> alphaInput = new Input<RealParameter>("alpha", "the rate of evolution in slow mode", Validate.REQUIRED);
-    public Input<RealParameter> switchRateInput = new Input<RealParameter>("switchRate", "the rate of flipping between slow and fast modes", Validate.REQUIRED);
-    public Input<RealParameter> frequenciesInput = new Input<RealParameter>("vfrequencies", "the frequencies of the visible states", Validate.REQUIRED);
-    public Input<RealParameter> hfrequenciesInput = new Input<RealParameter>("hfrequencies", "the frequencies of the hidden rates");
+    final public Input<RealParameter> alphaInput = new Input<>("alpha", "the rate of evolution in slow mode", Validate.REQUIRED);
+    final public Input<RealParameter> switchRateInput = new Input<>("switchRate", "the rate of flipping between slow and fast modes", Validate.REQUIRED);
+    final public Input<RealParameter> frequenciesInput = new Input<>("vfrequencies", "the frequencies of the visible states", Validate.REQUIRED);
+    final public Input<RealParameter> hfrequenciesInput = new Input<>("hfrequencies", "the frequencies of the hidden rates");
 
     public enum MODE {BEAST, REVERSIBLE, TUFFLEYSTEEL};
-	public Input<MODE> modeInput = new Input<>("mode","one of BEAST, REVERSIBLE, TUFFLESTEEL "
+	final public Input<MODE> modeInput = new Input<>("mode","one of BEAST, REVERSIBLE, TUFFLESTEEL "
 			+ "BEAST = implementation as in BEAST 1 "
 			+ "REVERSIBLE = like BEAST 1 implementation, but using frequencies to make it reversible "
 			+ "TUFFLEYSTEEL = Tuffley & Steel (1996) impementation (no rates for ", MODE.BEAST,MODE.values());
@@ -91,7 +93,7 @@ public class BinaryCovarion extends GeneralSubstitutionModel {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         alpha = alphaInput.get();
         switchRate = switchRateInput.get();
         frequencies = frequenciesInput.get();
@@ -100,25 +102,25 @@ public class BinaryCovarion extends GeneralSubstitutionModel {
         
         if (mode.equals(MODE.BEAST) || mode.equals(MODE.REVERSIBLE)) {
         	if (switchRate.getDimension() != 1) {
-        		throw new Exception("switchRate should have dimension 1");
+        		throw new IllegalArgumentException("switchRate should have dimension 1");
         	}
         } else {
         	if (switchRate.getDimension() != 2) {
-        		throw new Exception("switchRate should have dimension 2");
+        		throw new IllegalArgumentException("switchRate should have dimension 2");
         	}
         }
         if (alpha.getDimension() != 1) {
-            throw new Exception("alpha should have dimension 1");
+            throw new IllegalArgumentException("alpha should have dimension 1");
         }
         if (frequencies.getDimension() != 2) {
-            throw new Exception("frequencies should have dimension 2");
+            throw new IllegalArgumentException("frequencies should have dimension 2");
         }
         if (mode.equals(MODE.BEAST) || mode.equals(MODE.REVERSIBLE)) {
         	if (hfrequenciesInput.get() == null) {
-        		throw new Exception("hiddenFrequenciesshould should be specified");
+        		throw new IllegalArgumentException("hiddenFrequenciesshould should be specified");
         	}
             if (hiddenFrequencies.getDimension() != 2) {
-                throw new Exception("hiddenFrequenciesshould have dimension 2");
+                throw new IllegalArgumentException("hiddenFrequenciesshould have dimension 2");
             }
         } else {
         	if (hfrequenciesInput.get() != null) {
@@ -133,7 +135,12 @@ public class BinaryCovarion extends GeneralSubstitutionModel {
         storedUnnormalizedQ = new double[4][4];
 
         updateMatrix = true;
-        eigenSystem = createEigenSystem();
+        try {
+			eigenSystem = createEigenSystem();
+		} catch (SecurityException | ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
+				| InvocationTargetException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
         rateMatrix = new double[nrOfStates][nrOfStates];
         relativeRates = new double[4 * 3];
         storedRelativeRates = new double[4 * 3];
@@ -163,18 +170,18 @@ public class BinaryCovarion extends GeneralSubstitutionModel {
         // bring in frequencies
 //        for (int i = 0; i < m_nStates; i++) {
 //            for (int j = i + 1; j < m_nStates; j++) {
-//            	m_rateMatrix[i][j] *= fFreqs[j];
-//            	m_rateMatrix[j][i] *= fFreqs[i];
+//            	m_rateMatrix[i][j] *= freqs[j];
+//            	m_rateMatrix[j][i] *= freqs[i];
 //            }
 //        }
         // set up diagonal
         for (int i = 0; i < nrOfStates; i++) {
-            double fSum = 0.0;
+            double sum = 0.0;
             for (int j = 0; j < nrOfStates; j++) {
                 if (i != j)
-                    fSum += rateMatrix[i][j];
+                    sum += rateMatrix[i][j];
             }
-            rateMatrix[i][i] = -fSum;
+            rateMatrix[i][i] = -sum;
         }
         // normalise rate matrix to one expected substitution per unit time
         normalize(rateMatrix, getFrequencies());
@@ -182,21 +189,21 @@ public class BinaryCovarion extends GeneralSubstitutionModel {
 
     @Override
     public double[] getFrequencies() {
-        double[] fFreqs = new double[4];
+        double[] freqs = new double[4];
         if (mode.equals(MODE.BEAST) || mode.equals(MODE.REVERSIBLE)) {
-	        fFreqs[0] = frequencies.getValue(0) * hiddenFrequencies.getValue(0);
-	        fFreqs[1] = frequencies.getValue(1) * hiddenFrequencies.getValue(0);
-	        fFreqs[2] = frequencies.getValue(0) * hiddenFrequencies.getValue(1);
-	        fFreqs[3] = frequencies.getValue(1) * hiddenFrequencies.getValue(1);
+	        freqs[0] = frequencies.getValue(0) * hiddenFrequencies.getValue(0);
+	        freqs[1] = frequencies.getValue(1) * hiddenFrequencies.getValue(0);
+	        freqs[2] = frequencies.getValue(0) * hiddenFrequencies.getValue(1);
+	        freqs[3] = frequencies.getValue(1) * hiddenFrequencies.getValue(1);
         } else {
         	double h0 = alpha.getValue(1) * (alpha.getValue(0) + alpha.getValue(1));
         	double h1 = alpha.getValue(0) * (alpha.getValue(0) + alpha.getValue(1));
-	        fFreqs[0] = frequencies.getValue(0) * h0;
-	        fFreqs[1] = frequencies.getValue(1) * h0;
-	        fFreqs[2] = frequencies.getValue(0) * h1;
-	        fFreqs[3] = frequencies.getValue(1) * h1;        	
+	        freqs[0] = frequencies.getValue(0) * h0;
+	        freqs[1] = frequencies.getValue(1) * h0;
+	        freqs[2] = frequencies.getValue(0) * h1;
+	        freqs[3] = frequencies.getValue(1) * h1;        	
         }
-        return fFreqs;
+        return freqs;
     }
 
 
diff --git a/src/beast/evolution/substitutionmodel/Blosum62.java b/src/beast/evolution/substitutionmodel/Blosum62.java
index 8be9a8f..75030a5 100644
--- a/src/beast/evolution/substitutionmodel/Blosum62.java
+++ b/src/beast/evolution/substitutionmodel/Blosum62.java
@@ -256,13 +256,13 @@ public class Blosum62 extends EmpiricalSubstitutionModel {
     @Override
     public int[] getEncodingOrder() {
         Aminoacid dataType = new Aminoacid();
-        String sCodeMap = dataType.getCodeMap();
-        int[] nCodeMap = new int[dataType.getStateCount()];
-        String sEncoding = "ARNDCQEGHILKMFPSTWYV";
+        String codeMap = dataType.getCodeMap();
+        int[] codeMapNrs = new int[dataType.getStateCount()];
+        String encoding = "ARNDCQEGHILKMFPSTWYV";
         for (int i = 0; i < dataType.getStateCount(); i++) {
-            nCodeMap[i] = sEncoding.indexOf(sCodeMap.charAt(i));
+            codeMapNrs[i] = encoding.indexOf(codeMap.charAt(i));
         }
-        return nCodeMap;
+        return codeMapNrs;
     }
 
     @Override
diff --git a/src/beast/evolution/substitutionmodel/CPREV.java b/src/beast/evolution/substitutionmodel/CPREV.java
index c65e586..93f59b1 100644
--- a/src/beast/evolution/substitutionmodel/CPREV.java
+++ b/src/beast/evolution/substitutionmodel/CPREV.java
@@ -255,13 +255,13 @@ public class CPREV extends EmpiricalSubstitutionModel {
     @Override
     public int[] getEncodingOrder() {
         Aminoacid dataType = new Aminoacid();
-        String sCodeMap = dataType.getCodeMap();
-        int[] nCodeMap = new int[dataType.getStateCount()];
-        String sEncoding = "ARNDCQEGHILKMFPSTWYV";
+        String codeMap = dataType.getCodeMap();
+        int[] codeMapNrs = new int[dataType.getStateCount()];
+        String encoding = "ARNDCQEGHILKMFPSTWYV";
         for (int i = 0; i < dataType.getStateCount(); i++) {
-            nCodeMap[i] = sEncoding.indexOf(sCodeMap.charAt(i));
+            codeMapNrs[i] = encoding.indexOf(codeMap.charAt(i));
         }
-        return nCodeMap;
+        return codeMapNrs;
     }
 
     @Override
diff --git a/src/beast/evolution/substitutionmodel/Dayhoff.java b/src/beast/evolution/substitutionmodel/Dayhoff.java
index 33b7b0b..f1cf9ff 100644
--- a/src/beast/evolution/substitutionmodel/Dayhoff.java
+++ b/src/beast/evolution/substitutionmodel/Dayhoff.java
@@ -258,13 +258,13 @@ public class Dayhoff extends EmpiricalSubstitutionModel {
     @Override
     public int[] getEncodingOrder() {
         Aminoacid dataType = new Aminoacid();
-        String sCodeMap = dataType.getCodeMap();
-        int[] nCodeMap = new int[dataType.getStateCount()];
-        String sEncoding = "ARNDCQEGHILKMFPSTWYV";
+        String codeMap = dataType.getCodeMap();
+        int[] codeMapNrs = new int[dataType.getStateCount()];
+        String encoding = "ARNDCQEGHILKMFPSTWYV";
         for (int i = 0; i < dataType.getStateCount(); i++) {
-            nCodeMap[i] = sEncoding.indexOf(sCodeMap.charAt(i));
+            codeMapNrs[i] = encoding.indexOf(codeMap.charAt(i));
         }
-        return nCodeMap;
+        return codeMapNrs;
     }
 
     @Override
diff --git a/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java b/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java
index ca2eca2..142405f 100644
--- a/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java
+++ b/src/beast/evolution/substitutionmodel/DefaultEigenSystem.java
@@ -1,5 +1,6 @@
 package beast.evolution.substitutionmodel;
 
+import beast.core.util.Log;
 import beast.math.MachineAccuracy;
 
 /**
@@ -26,7 +27,8 @@ public class DefaultEigenSystem implements EigenSystem {
      * set instantaneous rate matrix
      * This changes the values in qMatrix as side effect
      */
-    public EigenDecomposition decomposeMatrix(double[][] qMatrix) {
+    @Override
+	public EigenDecomposition decomposeMatrix(double[][] qMatrix) {
 
         Eval = new double[stateCount];
         Evec = new double[stateCount][stateCount];
@@ -176,7 +178,7 @@ public class DefaultEigenSystem implements EigenSystem {
                 }
                 if (itn == 0) {
                     /* eigenvalues have not converged */
-                    System.out.println("Eigenvalues not converged");
+                    Log.warning.println("Eigenvalues not converged");
                     throw new ArithmeticException();
                 }
                 y = h[na - 1][na - 1];
@@ -576,7 +578,7 @@ public class DefaultEigenSystem implements EigenSystem {
             }
             if (maxb == 0.0) {
                 /* Singular matrix */
-                System.out.println("Singular matrix encountered");
+                Log.err.println("Singular matrix encountered");
                 throw new IllegalArgumentException("Singular matrix");
             }
             wk[i] = 1.0 / maxb;
diff --git a/src/beast/evolution/substitutionmodel/EmpiricalSubstitutionModel.java b/src/beast/evolution/substitutionmodel/EmpiricalSubstitutionModel.java
index 8505559..066db05 100644
--- a/src/beast/evolution/substitutionmodel/EmpiricalSubstitutionModel.java
+++ b/src/beast/evolution/substitutionmodel/EmpiricalSubstitutionModel.java
@@ -1,5 +1,7 @@
 package beast.evolution.substitutionmodel;
 
+import java.lang.reflect.InvocationTargetException;
+
 import beast.core.Description;
 import beast.core.Input.Validate;
 import beast.core.parameter.RealParameter;
@@ -17,18 +19,23 @@ public abstract class EmpiricalSubstitutionModel extends GeneralSubstitutionMode
     double[] m_empiricalRates;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         frequencies = getEmpericalFrequencieValues();
         m_empiricalRates = getEmpericalRateValues();
-        int nFreqs = frequencies.getFreqs().length;
-        if (m_empiricalRates.length != nFreqs * (nFreqs - 1)) {
-            throw new Exception("The number of empirical rates (" + m_empiricalRates.length + ") should be " +
-                    "equal to #frequencies * (#frequencies-1) = (" + nFreqs + "*" + (nFreqs - 1) + ").");
+        int freqs = frequencies.getFreqs().length;
+        if (m_empiricalRates.length != freqs * (freqs - 1)) {
+            throw new IllegalArgumentException("The number of empirical rates (" + m_empiricalRates.length + ") should be " +
+                    "equal to #frequencies * (#frequencies-1) = (" + freqs + "*" + (freqs - 1) + ").");
         }
 
         updateMatrix = true;
         nrOfStates = frequencies.getFreqs().length;
-        eigenSystem = createEigenSystem();
+        try {
+			eigenSystem = createEigenSystem();
+		} catch (SecurityException | ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
+				| InvocationTargetException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
         rateMatrix = new double[nrOfStates][nrOfStates];
         relativeRates = new double[m_empiricalRates.length];
         storedRelativeRates = new double[m_empiricalRates.length];
@@ -43,17 +50,17 @@ public abstract class EmpiricalSubstitutionModel extends GeneralSubstitutionMode
     /**
      * convert empirical rates into a RealParameter, only off diagonal entries are recorded *
      */
-    double[] getEmpericalRateValues() throws Exception {
+    double[] getEmpericalRateValues() {
         double[][] matrix = getEmpiricalRates();
-        int[] nOrder = getEncodingOrder();
-        int nStates = matrix.length;
+        int[] order = getEncodingOrder();
+        int states = matrix.length;
 
-        double[] rates = new double[nStates * (nStates - 1)];
+        double[] rates = new double[states * (states - 1)];
         int k = 0;
-        for (int i = 0; i < nStates; i++) {
-            int u = nOrder[i];
-            for (int j = 0; j < nStates; j++) {
-                int v = nOrder[j];
+        for (int i = 0; i < states; i++) {
+            int u = order[i];
+            for (int j = 0; j < states; j++) {
+                int v = order[j];
                 if (i != j) {
                     rates[k++] = matrix[Math.min(u, v)][Math.max(u, v)];
                 }
@@ -65,22 +72,22 @@ public abstract class EmpiricalSubstitutionModel extends GeneralSubstitutionMode
     /**
      * convert empirical frequencies into a RealParameter *
      */
-    Frequencies getEmpericalFrequencieValues() throws Exception {
+    Frequencies getEmpericalFrequencieValues() {
         double[] freqs = getEmpiricalFrequencies();
-        int[] nOrder = getEncodingOrder();
-        int nStates = freqs.length;
+        int[] order = getEncodingOrder();
+        int states = freqs.length;
         Frequencies freqsParam = new Frequencies();
-        String sValues = "";
+        String valuesString = "";
 
-        for (int i = 0; i < nStates; i++) {
-            sValues += freqs[nOrder[i]] + " ";
+        for (int i = 0; i < states; i++) {
+            valuesString += freqs[order[i]] + " ";
         }
         RealParameter freqsRParam = new RealParameter();
         freqsRParam.initByName(
-                "value", sValues,
+                "value", valuesString,
                 "lower", 0.0,
                 "upper", 1.0,
-                "dimension", nStates
+                "dimension", states
         );
         freqsParam.frequenciesInput.setValue(freqsRParam, freqsParam);
         freqsParam.initAndValidate();
@@ -111,21 +118,21 @@ public abstract class EmpiricalSubstitutionModel extends GeneralSubstitutionMode
     @Override
     public double[] getRateMatrix(Node node) {
         double[][] matrix = getEmpiricalRates();
-        int nStates = matrix.length;
-        double[] rates = new double[nStates * nStates];
-        for (int i = 0; i < nStates; i++) {
-            for (int j = i + 1; j < nStates; j++) {
-                rates[i * nStates + j] = matrix[i][j];
-                rates[j * nStates + i] = matrix[i][j];
+        int states = matrix.length;
+        double[] rates = new double[states * states];
+        for (int i = 0; i < states; i++) {
+            for (int j = i + 1; j < states; j++) {
+                rates[i * states + j] = matrix[i][j];
+                rates[j * states + i] = matrix[i][j];
             }
         }
         // determine diagonal
-        for (int i = 0; i < nStates; i++) {
-            double fSum = 0;
-            for (int j = i + 1; j < nStates; j++) {
-                fSum += rates[i * nStates + j];
+        for (int i = 0; i < states; i++) {
+            double sum = 0;
+            for (int j = i + 1; j < states; j++) {
+                sum += rates[i * states + j];
             }
-            rates[i * nStates + i] = -fSum;
+            rates[i * states + i] = -sum;
         }
         return rates;
     }
diff --git a/src/beast/evolution/substitutionmodel/Frequencies.java b/src/beast/evolution/substitutionmodel/Frequencies.java
index 06ffe5b..4f06b46 100644
--- a/src/beast/evolution/substitutionmodel/Frequencies.java
+++ b/src/beast/evolution/substitutionmodel/Frequencies.java
@@ -43,9 +43,9 @@ import beast.evolution.datatype.DataType;
         "Calculates empirical frequencies of characters in sequence data, or simply assumes a uniform " +
         "distribution if the estimate flag is set to false.")
 public class Frequencies extends CalculationNode {
-    public Input<Alignment> dataInput = new Input<Alignment>("data", "Sequence data for which frequencies are calculated");
-    public Input<Boolean> estimateInput = new Input<Boolean>("estimate", "Whether to estimate the frequencies from data (true=default) or assume a uniform distribution over characters (false)", true);
-    public Input<RealParameter> frequenciesInput = new Input<RealParameter>("frequencies", "A set of frequencies specified as space separated values summing to 1", Validate.XOR, dataInput);
+    final public Input<Alignment> dataInput = new Input<>("data", "Sequence data for which frequencies are calculated");
+    final public Input<Boolean> estimateInput = new Input<>("estimate", "Whether to estimate the frequencies from data (true=default) or assume a uniform distribution over characters (false)", true);
+    final public Input<RealParameter> frequenciesInput = new Input<>("frequencies", "A set of frequencies specified as space separated values summing to 1", Validate.XOR, dataInput);
 
     /**
      * contains frequency distribution *
@@ -59,12 +59,12 @@ public class Frequencies extends CalculationNode {
 
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         update();
-        double fSum = getSumOfFrequencies(getFreqs());
+        double sum = getSumOfFrequencies(getFreqs());
         // sanity check
-        if (Math.abs(fSum - 1.0) > 1e-6) {
-            throw new Exception("Frequencies do not add up to 1");
+        if (Math.abs(sum - 1.0) > 1e-6) {
+            throw new IllegalArgumentException("Frequencies do not add up to 1");
         }
 
     }
@@ -101,10 +101,10 @@ public class Frequencies extends CalculationNode {
             checkFrequencies();
         } else {
             // uniformly distributed
-            int nStates = dataInput.get().getMaxStateCount();
-            freqs = new double[nStates];
-            for (int i = 0; i < nStates; i++) {
-                freqs[i] = 1.0 / nStates;
+            int states = dataInput.get().getMaxStateCount();
+            freqs = new double[states];
+            for (int i = 0; i < states; i++) {
+                freqs[i] = 1.0 / states;
             }
         }
         needsUpdate = false;
@@ -123,65 +123,65 @@ public class Frequencies extends CalculationNode {
         freqs = new double[stateCount];
         Arrays.fill(freqs, 1.0 / stateCount);
 
-        int nAttempts = 0;
-        double fDifference;
+        int attempts = 0;
+        double difference;
         do {
-            double[] fTmpFreq = new double[stateCount];
+            double[] tmpFreq = new double[stateCount];
 
-            double fTotal = 0.0;
+            double total = 0.0;
             for (int i = 0; i < alignment.getPatternCount(); i++) {
-                int[] nPattern = alignment.getPattern(i);
-                double fWeight = alignment.getPatternWeight(i);
+                int[] pattern = alignment.getPattern(i);
+                double weight = alignment.getPatternWeight(i);
 
-                for (int iValue : nPattern) {
-                    int[] codes = dataType.getStatesForCode(iValue);
+                for (int value : pattern) {
+                    int[] codes = dataType.getStatesForCode(value);
 
                     double sum = 0.0;
-                    for (int iCode : codes) {
-                        sum += freqs[iCode];
+                    for (int codeIndex : codes) {
+                        sum += freqs[codeIndex];
                     }
 
-                    for (int iCode : codes) {
-                        double fTmp = (freqs[iCode] * fWeight) / sum;
-                        fTmpFreq[iCode] += fTmp;
-                        fTotal += fTmp;
+                    for (int codeIndex : codes) {
+                        double tmp = (freqs[codeIndex] * weight) / sum;
+                        tmpFreq[codeIndex] += tmp;
+                        total += tmp;
                     }
                 }
             }
 
-            fDifference = 0.0;
+            difference = 0.0;
             for (int i = 0; i < stateCount; i++) {
-                fDifference += Math.abs((fTmpFreq[i] / fTotal) - freqs[i]);
-                freqs[i] = fTmpFreq[i] / fTotal;
+                difference += Math.abs((tmpFreq[i] / total) - freqs[i]);
+                freqs[i] = tmpFreq[i] / total;
             }
-            nAttempts++;
-        } while (fDifference > 1E-8 && nAttempts < 1000);
+            attempts++;
+        } while (difference > 1E-8 && attempts < 1000);
 
 //    	Alignment alignment = m_data.get();
 //        m_fFreqs = new double[alignment.getMaxStateCount()];
 //        for (int i = 0; i < alignment.getPatternCount(); i++) {
-//            int[] nPattern = alignment.getPattern(i);
-//            double fWeight = alignment.getPatternWeight(i);
+//            int[] pattern = alignment.getPattern(i);
+//            double weight = alignment.getPatternWeight(i);
 //            DataType dataType = alignment.getDataType();
-//            for (int iValue : nPattern) {
-//            	if (iValue < 4) {
-//            	int [] codes = dataType.getStatesForCode(iValue);
-//            	for (int iCode : codes) {
-//                    m_fFreqs[iCode] += fWeight / codes.length;
+//            for (int value : pattern) {
+//            	if (value < 4) {
+//            	int [] codes = dataType.getStatesForCode(value);
+//            	for (int codeIndex : codes) {
+//                    m_fFreqs[codeIndex] += weight / codes.length;
 //            	}
 //            	}
-////                if (iValue < m_fFreqs.length) { // ignore unknowns
-////                    m_fFreqs[iValue] += nWeight;
+////                if (value < m_fFreqs.length) { // ignore unknowns
+////                    m_fFreqs[value] += weight;
 ////                }
 //            }
 //        }
 //        // normalize
-//        double fSum = 0;
+//        double sum = 0;
 //        for (double f : m_fFreqs) {
-//            fSum += f;
+//            sum += f;
 //        }
 //        for (int i = 0; i < m_fFreqs.length; i++) {
-//            m_fFreqs[i] /= fSum;
+//            m_fFreqs[i] /= sum;
 //        }
         Log.info.println("Starting frequencies: " + Arrays.toString(freqs));
     } // calcFrequencies
@@ -251,7 +251,8 @@ public class Frequencies extends CalculationNode {
         return total;
     }
 
-    public void restore() {
+    @Override
+	public void restore() {
         needsUpdate = true;
         super.restore();
     }
diff --git a/src/beast/evolution/substitutionmodel/GTR.java b/src/beast/evolution/substitutionmodel/GTR.java
index 1c23cac..69398d1 100644
--- a/src/beast/evolution/substitutionmodel/GTR.java
+++ b/src/beast/evolution/substitutionmodel/GTR.java
@@ -1,5 +1,7 @@
 package beast.evolution.substitutionmodel;
 
+import java.lang.reflect.InvocationTargetException;
+
 import beast.core.Description;
 import beast.core.Function;
 import beast.core.Input;
@@ -11,12 +13,12 @@ import beast.evolution.datatype.Nucleotide;
 @Description("General Time Reversible model of nucleotide evolution. " +
         "Rates that are not specified are assumed to be 1. ")
 public class GTR extends GeneralSubstitutionModel {
-    public Input<Function> rateACInput = new Input<>("rateAC", "substitution rate for A to C (default 1)");
-    public Input<Function> rateAGInput = new Input<>("rateAG", "substitution rate for A to G (default 1)");
-    public Input<Function> rateATInput = new Input<>("rateAT", "substitution rate for A to T (default 1)");
-    public Input<Function> rateCGInput = new Input<>("rateCG", "substitution rate for C to G (default 1)");
-    public Input<Function> rateCTInput = new Input<>("rateCT", "substitution rate for C to T (default 1)");
-    public Input<Function> rateGTInput = new Input<>("rateGT", "substitution rate for G to T (default 1)");
+    final public Input<Function> rateACInput = new Input<>("rateAC", "substitution rate for A to C (default 1)");
+    final public Input<Function> rateAGInput = new Input<>("rateAG", "substitution rate for A to G (default 1)");
+    final public Input<Function> rateATInput = new Input<>("rateAT", "substitution rate for A to T (default 1)");
+    final public Input<Function> rateCGInput = new Input<>("rateCG", "substitution rate for C to G (default 1)");
+    final public Input<Function> rateCTInput = new Input<>("rateCT", "substitution rate for C to T (default 1)");
+    final public Input<Function> rateGTInput = new Input<>("rateGT", "substitution rate for G to T (default 1)");
 
     Function rateAC;
     Function rateAG;
@@ -36,19 +38,24 @@ public class GTR extends GeneralSubstitutionModel {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         if (ratesInput.get() != null) {
-            throw new Exception("the rates attribute should not be used. Use the individual rates rateAC, rateCG, etc, instead.");
+            throw new IllegalArgumentException("the rates attribute should not be used. Use the individual rates rateAC, rateCG, etc, instead.");
         }
 
         frequencies = frequenciesInput.get();
         updateMatrix = true;
         nrOfStates = frequencies.getFreqs().length;
         if (nrOfStates != 4) {
-            throw new Exception("Frequencies has wrong size. Expected 4, but got " + nrOfStates);
+            throw new IllegalArgumentException("Frequencies has wrong size. Expected 4, but got " + nrOfStates);
         }
 
-        eigenSystem = createEigenSystem();
+        try {
+			eigenSystem = createEigenSystem();
+		} catch (SecurityException | ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
+				| InvocationTargetException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
         rateMatrix = new double[nrOfStates][nrOfStates];
         relativeRates = new double[nrOfStates * (nrOfStates - 1)];
         storedRelativeRates = new double[nrOfStates * (nrOfStates - 1)];
@@ -61,7 +68,7 @@ public class GTR extends GeneralSubstitutionModel {
         rateGT = getParameter(rateGTInput);
     }
 
-    private Function getParameter(Input<Function> parameterInput) throws Exception {
+    private Function getParameter(Input<Function> parameterInput) {
         if (parameterInput.get() != null) {
             return parameterInput.get();
         }
diff --git a/src/beast/evolution/substitutionmodel/GeneralSubstitutionModel.java b/src/beast/evolution/substitutionmodel/GeneralSubstitutionModel.java
index 2d6e9b7..ccc7d56 100644
--- a/src/beast/evolution/substitutionmodel/GeneralSubstitutionModel.java
+++ b/src/beast/evolution/substitutionmodel/GeneralSubstitutionModel.java
@@ -28,6 +28,7 @@ package beast.evolution.substitutionmodel;
 
 
 import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
 
 import beast.core.Description;
 import beast.core.Function;
@@ -42,13 +43,13 @@ import beast.evolution.tree.Node;
         "than that one of the is equal to one and the others are specified relative to " +
         "this unit rate. Works for any number of states.")
 public class GeneralSubstitutionModel extends SubstitutionModel.Base {
-    public Input<Function> ratesInput =
-            new Input<Function>("rates", "Rate parameter which defines the transition rate matrix. " +
+    final public Input<Function> ratesInput =
+            new Input<>("rates", "Rate parameter which defines the transition rate matrix. " +
                     "Only the off-diagonal entries need to be specified (diagonal makes row sum to zero in a " +
                     "rate matrix). Entry i specifies the rate from floor(i/(n-1)) to i%(n-1)+delta where " +
                     "n is the number of states and delta=1 if floor(i/(n-1)) >= i%(n-1) and 0 otherwise.", Validate.REQUIRED);
 
-    public Input<String> eigenSystemClass = new Input<String>("eigenSystem", "Name of the class used for creating an EigenSystem", DefaultEigenSystem.class.getName());
+    final public Input<String> eigenSystemClass = new Input<>("eigenSystem", "Name of the class used for creating an EigenSystem", DefaultEigenSystem.class.getName());
     /**
      * a square m_nStates x m_nStates matrix containing current rates  *
      */
@@ -56,17 +57,22 @@ public class GeneralSubstitutionModel extends SubstitutionModel.Base {
 
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
         updateMatrix = true;
         nrOfStates = frequencies.getFreqs().length;
         if (ratesInput.get().getDimension() != nrOfStates * (nrOfStates - 1)) {
-            throw new Exception("Dimension of input 'rates' is " + ratesInput.get().getDimension() + " but a " +
+            throw new IllegalArgumentException("Dimension of input 'rates' is " + ratesInput.get().getDimension() + " but a " +
                     "rate matrix of dimension " + nrOfStates + "x" + (nrOfStates - 1) + "=" + nrOfStates * (nrOfStates - 1) + " was " +
                     "expected");
         }
 
-        eigenSystem = createEigenSystem();
+        try {
+			eigenSystem = createEigenSystem();
+		} catch (SecurityException | ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
+				| InvocationTargetException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
         //eigenSystem = new DefaultEigenSystem(m_nStates);
 
         rateMatrix = new double[nrOfStates][nrOfStates];
@@ -75,9 +81,15 @@ public class GeneralSubstitutionModel extends SubstitutionModel.Base {
     } // initAndValidate
 
     /**
-     * create an EigenSystem of the class indicated by the eigenSystemClass input *
+     * create an EigenSystem of the class indicated by the eigenSystemClass input 
+     * @throws ClassNotFoundException 
+     * @throws SecurityException 
+     * @throws InvocationTargetException 
+     * @throws IllegalArgumentException 
+     * @throws IllegalAccessException 
+     * @throws InstantiationException *
      */
-    protected EigenSystem createEigenSystem() throws Exception {
+    protected EigenSystem createEigenSystem() throws SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
         Constructor<?>[] ctors = Class.forName(eigenSystemClass.get()).getDeclaredConstructors();
         Constructor<?> ctor = null;
         for (int i = 0; i < ctors.length; i++) {
@@ -101,8 +113,8 @@ public class GeneralSubstitutionModel extends SubstitutionModel.Base {
     private boolean storedUpdateMatrix = true;
 
     @Override
-    public void getTransitionProbabilities(Node node, double fStartTime, double fEndTime, double fRate, double[] matrix) {
-        double distance = (fStartTime - fEndTime) * fRate;
+    public void getTransitionProbabilities(Node node, double startTime, double endTime, double rate, double[] matrix) {
+        double distance = (startTime - endTime) * rate;
 
         int i, j, k;
         double temp;
@@ -168,7 +180,7 @@ public class GeneralSubstitutionModel extends SubstitutionModel.Base {
      * sets up rate matrix *
      */
     protected void setupRateMatrix() {
-        double[] fFreqs = frequencies.getFreqs();
+        double[] freqs = frequencies.getFreqs();
         for (int i = 0; i < nrOfStates; i++) {
             rateMatrix[i][i] = 0;
             for (int j = 0; j < i; j++) {
@@ -181,27 +193,27 @@ public class GeneralSubstitutionModel extends SubstitutionModel.Base {
         // bring in frequencies
         for (int i = 0; i < nrOfStates; i++) {
             for (int j = i + 1; j < nrOfStates; j++) {
-                rateMatrix[i][j] *= fFreqs[j];
-                rateMatrix[j][i] *= fFreqs[i];
+                rateMatrix[i][j] *= freqs[j];
+                rateMatrix[j][i] *= freqs[i];
             }
         }
         // set up diagonal
         for (int i = 0; i < nrOfStates; i++) {
-            double fSum = 0.0;
+            double sum = 0.0;
             for (int j = 0; j < nrOfStates; j++) {
                 if (i != j)
-                    fSum += rateMatrix[i][j];
+                    sum += rateMatrix[i][j];
             }
-            rateMatrix[i][i] = -fSum;
+            rateMatrix[i][i] = -sum;
         }
         // normalise rate matrix to one expected substitution per unit time
-        double fSubst = 0.0;
+        double subst = 0.0;
         for (int i = 0; i < nrOfStates; i++)
-            fSubst += -rateMatrix[i][i] * fFreqs[i];
+            subst += -rateMatrix[i][i] * freqs[i];
 
         for (int i = 0; i < nrOfStates; i++) {
             for (int j = 0; j < nrOfStates; j++) {
-                rateMatrix[i][j] = rateMatrix[i][j] / fSubst;
+                rateMatrix[i][j] = rateMatrix[i][j] / subst;
             }
         }
     } // setupRateMatrix
diff --git a/src/beast/evolution/substitutionmodel/HKY.java b/src/beast/evolution/substitutionmodel/HKY.java
index 185f928..b7aee97 100644
--- a/src/beast/evolution/substitutionmodel/HKY.java
+++ b/src/beast/evolution/substitutionmodel/HKY.java
@@ -39,7 +39,7 @@ import beast.evolution.tree.Node;
                 "  molecular clock of mitochondrial DNA. Journal of Molecular Evolution\n" +
                 "  22:160-174.", DOI = "10.1007/BF02101694", year = 1985, firstAuthorSurname = "hasegawa")
 public class HKY extends SubstitutionModel.NucleotideBase {
-    public Input<RealParameter> kappaInput = new Input<RealParameter>("kappa", "kappa parameter in HKY model", Validate.REQUIRED);
+    final public Input<RealParameter> kappaInput = new Input<>("kappa", "kappa parameter in HKY model", Validate.REQUIRED);
 
     /**
      * applies to nucleotides only *
@@ -62,7 +62,7 @@ public class HKY extends SubstitutionModel.NucleotideBase {
     protected boolean updateMatrix = true;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
         kappaInput.get().setBounds(Math.max(0.0, kappaInput.get().getLower()), kappaInput.get().getUpper());
 
@@ -70,11 +70,13 @@ public class HKY extends SubstitutionModel.NucleotideBase {
     }
 
     @Override
-    public void getTransitionProbabilities(Node node, double fStartTime, double fEndTime, double fRate, double[] matrix) {
-        double distance = (fStartTime - fEndTime) * fRate;
+    public void getTransitionProbabilities(Node node, double startTime, double endTime, double rate, double[] matrix) {
+        double distance = (startTime - endTime) * rate;
 
-        if (updateMatrix) {
-            setupMatrix();
+        synchronized(this) {
+        	if (updateMatrix) {
+        		setupMatrix();
+        	}
         }
 
         final double xx = beta * distance;
diff --git a/src/beast/evolution/substitutionmodel/JTT.java b/src/beast/evolution/substitutionmodel/JTT.java
index beb5edb..adb86c2 100644
--- a/src/beast/evolution/substitutionmodel/JTT.java
+++ b/src/beast/evolution/substitutionmodel/JTT.java
@@ -257,13 +257,13 @@ public class JTT extends EmpiricalSubstitutionModel {
     @Override
     public int[] getEncodingOrder() {
         Aminoacid dataType = new Aminoacid();
-        String sCodeMap = dataType.getCodeMap();
-        int[] nCodeMap = new int[dataType.getStateCount()];
-        String sEncoding = "ARNDCQEGHILKMFPSTWYV";
+        String codeMap = dataType.getCodeMap();
+        int[] codeMapNrs = new int[dataType.getStateCount()];
+        String encoding = "ARNDCQEGHILKMFPSTWYV";
         for (int i = 0; i < dataType.getStateCount(); i++) {
-            nCodeMap[i] = sEncoding.indexOf(sCodeMap.charAt(i));
+            codeMapNrs[i] = encoding.indexOf(codeMap.charAt(i));
         }
-        return nCodeMap;
+        return codeMapNrs;
     }
 
     @Override
diff --git a/src/beast/evolution/substitutionmodel/JukesCantor.java b/src/beast/evolution/substitutionmodel/JukesCantor.java
index f289c8b..0cc8ffa 100644
--- a/src/beast/evolution/substitutionmodel/JukesCantor.java
+++ b/src/beast/evolution/substitutionmodel/JukesCantor.java
@@ -1,13 +1,13 @@
 package beast.evolution.substitutionmodel;
 
+import java.util.Arrays;
+
 import beast.core.Description;
 import beast.core.Input.Validate;
 import beast.evolution.datatype.DataType;
 import beast.evolution.datatype.Nucleotide;
 import beast.evolution.tree.Node;
 
-import java.util.Arrays;
-
 @Description("Jukes Cantor substitution model: all rates equal and " + "uniformly distributed frequencies")
 public class JukesCantor extends SubstitutionModel.Base {
 
@@ -28,7 +28,7 @@ public class JukesCantor extends SubstitutionModel.Base {
     EigenDecomposition eigenDecomposition;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         double[] eval = new double[]{0.0, -1.3333333333333333, -1.3333333333333333, -1.3333333333333333};
         double[] evec = new double[]{1.0, 2.0, 0.0, 0.5, 1.0, -2.0, 0.5, 0.0, 1.0, 2.0, 0.0, -0.5, 1.0, -2.0, -0.5, 0.0};
         double[] ivec = new double[]{0.25, 0.25, 0.25, 0.25, 0.125, -0.125, 0.125, -0.125, 0.0, 1.0, 0.0, -1.0, 1.0, 0.0, -1.0, 0.0};
@@ -48,15 +48,15 @@ public class JukesCantor extends SubstitutionModel.Base {
     }
 
     @Override
-    public void getTransitionProbabilities(Node node, double fStartTime, double fEndTime, double fRate, double[] matrix) {
-        double fDelta = 4.0 / 3.0 * (fStartTime - fEndTime);
-        double fPStay = (1.0 + 3.0 * Math.exp(-fDelta * fRate)) / 4.0;
-        double fPMove = (1.0 - Math.exp(-fDelta * fRate)) / 4.0;
+    public void getTransitionProbabilities(Node node, double startTime, double endTime, double rate, double[] matrix) {
+        double delta = 4.0 / 3.0 * (startTime - endTime);
+        double pStay = (1.0 + 3.0 * Math.exp(-delta * rate)) / 4.0;
+        double pMove = (1.0 - Math.exp(-delta * rate)) / 4.0;
         // fill the matrix with move probabilities
-        Arrays.fill(matrix, fPMove);
+        Arrays.fill(matrix, pMove);
         // fill the diagonal
         for (int i = 0; i < 4; i++) {
-            matrix[i * 5] = fPStay;
+            matrix[i * 5] = pStay;
         }
     }
 
diff --git a/src/beast/evolution/substitutionmodel/MTREV.java b/src/beast/evolution/substitutionmodel/MTREV.java
index f3b0884..dcca804 100644
--- a/src/beast/evolution/substitutionmodel/MTREV.java
+++ b/src/beast/evolution/substitutionmodel/MTREV.java
@@ -263,13 +263,13 @@ public class MTREV extends EmpiricalSubstitutionModel {
     @Override
     public int[] getEncodingOrder() {
         Aminoacid dataType = new Aminoacid();
-        String sCodeMap = dataType.getCodeMap();
-        int[] nCodeMap = new int[dataType.getStateCount()];
-        String sEncoding = "ARNDCQEGHILKMFPSTWYV";
+        String codeMap = dataType.getCodeMap();
+        int[] codeMapNrs = new int[dataType.getStateCount()];
+        String encoding = "ARNDCQEGHILKMFPSTWYV";
         for (int i = 0; i < dataType.getStateCount(); i++) {
-            nCodeMap[i] = sEncoding.indexOf(sCodeMap.charAt(i));
+            codeMapNrs[i] = encoding.indexOf(codeMap.charAt(i));
         }
-        return nCodeMap;
+        return codeMapNrs;
     }
 
     @Override
diff --git a/src/beast/evolution/substitutionmodel/MutationDeathModel.java b/src/beast/evolution/substitutionmodel/MutationDeathModel.java
index 75b50de..2306afa 100644
--- a/src/beast/evolution/substitutionmodel/MutationDeathModel.java
+++ b/src/beast/evolution/substitutionmodel/MutationDeathModel.java
@@ -10,10 +10,10 @@ import beast.evolution.tree.Node;
 @Description("Mutation Death substitution model, can be used as Stochastic Dollo model.")
 public class MutationDeathModel extends SubstitutionModel.Base {
 
-    public Input<RealParameter> delParameter = new Input<RealParameter>("deathprob", "rate of death, used to calculate death probability", Validate.REQUIRED);
+    final public Input<RealParameter> delParameter = new Input<>("deathprob", "rate of death, used to calculate death probability", Validate.REQUIRED);
     // mutation rate is already provided in SiteModel, so no need to duplicate it here
-    //public Input<RealParameter> mutationRate = new Input<RealParameter>("mu", "mutation rate, default 1");
-    public Input<SubstitutionModel.Base> CTMCModelInput = new Input<SubstitutionModel.Base>("substmodel", "CTMC Model for the life states, so should have " +
+    //public Input<RealParameter> mutationRate = new Input<>("mu", "mutation rate, default 1");
+    final public Input<SubstitutionModel.Base> CTMCModelInput = new Input<>("substmodel", "CTMC Model for the life states, so should have " +
             "a state-space one less than this model. If not specified, ...");
     // TODO: figure out the end of the last sentence
 
@@ -27,14 +27,14 @@ public class MutationDeathModel extends SubstitutionModel.Base {
     int nrOfStates;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
         double[] freqs = getFrequencies();
         nrOfStates = freqs.length;
         trMatrix = new double[(nrOfStates - 1) * (nrOfStates - 1)];
         if (CTMCModelInput.get() != null) {
             if (CTMCModelInput.get().frequenciesInput.get().freqs.length != nrOfStates - 1) {
-                throw new Exception("substmodel does not have the correct state space: should be " + (nrOfStates - 1));
+                throw new IllegalArgumentException("substmodel does not have the correct state space: should be " + (nrOfStates - 1));
             }
         }
     }
@@ -45,8 +45,8 @@ public class MutationDeathModel extends SubstitutionModel.Base {
     }
 
     @Override
-    public void getTransitionProbabilities(Node node, double fStartTime, double fEndTime, double fRate, double[] matrix) {
-        double distance = (fStartTime - fEndTime) * fRate;
+    public void getTransitionProbabilities(Node node, double startTime, double endTime, double rate, double[] matrix) {
+        double distance = (startTime - endTime) * rate;
         int i, j;
         // assuming that expected number of changes in CTMCModel is 1 per unit time
         // we are contributing s*deathRate number of changes per unit of time
@@ -62,7 +62,7 @@ public class MutationDeathModel extends SubstitutionModel.Base {
         }
         SubstitutionModel.Base CTMCModel = CTMCModelInput.get();
         if (CTMCModel != null) {
-            CTMCModel.getTransitionProbabilities(node, fStartTime, fEndTime, mutationR * fRate, trMatrix);
+            CTMCModel.getTransitionProbabilities(node, startTime, endTime, mutationR * rate, trMatrix);
         } else {
             trMatrix[0] = 1.0;
         }
diff --git a/src/beast/evolution/substitutionmodel/SYM.java b/src/beast/evolution/substitutionmodel/SYM.java
index 4ac1fff..a9d18f6 100644
--- a/src/beast/evolution/substitutionmodel/SYM.java
+++ b/src/beast/evolution/substitutionmodel/SYM.java
@@ -1,5 +1,7 @@
 package beast.evolution.substitutionmodel;
 
+import java.lang.reflect.InvocationTargetException;
+
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.Input.Validate;
@@ -10,12 +12,12 @@ import beast.evolution.datatype.Nucleotide;
 @Description("Symmetrical model of nucleotide evolution with equal base frequencies." +
         "Rates that are not specified are assumed to be 1.")
 public class SYM extends GeneralSubstitutionModel {
-    public Input<RealParameter> rateACInput = new Input<RealParameter>("rateAC", "substitution rate for A to C (default 1)");
-    public Input<RealParameter> rateAGInput = new Input<RealParameter>("rateAG", "substitution rate for A to G (default 1)");
-    public Input<RealParameter> rateATInput = new Input<RealParameter>("rateAT", "substitution rate for A to T (default 1)");
-    public Input<RealParameter> rateCGInput = new Input<RealParameter>("rateCG", "substitution rate for C to G (default 1)");
-    public Input<RealParameter> rateCTInput = new Input<RealParameter>("rateCT", "substitution rate for C to T (default 1)");
-    public Input<RealParameter> rateGTInput = new Input<RealParameter>("rateGT", "substitution rate for G to T (default 1)");
+    final public Input<RealParameter> rateACInput = new Input<>("rateAC", "substitution rate for A to C (default 1)");
+    final public Input<RealParameter> rateAGInput = new Input<>("rateAG", "substitution rate for A to G (default 1)");
+    final public Input<RealParameter> rateATInput = new Input<>("rateAT", "substitution rate for A to T (default 1)");
+    final public Input<RealParameter> rateCGInput = new Input<>("rateCG", "substitution rate for C to G (default 1)");
+    final public Input<RealParameter> rateCTInput = new Input<>("rateCT", "substitution rate for C to T (default 1)");
+    final public Input<RealParameter> rateGTInput = new Input<>("rateGT", "substitution rate for G to T (default 1)");
 
     RealParameter rateAC;
     RealParameter rateAG;
@@ -47,9 +49,9 @@ public class SYM extends GeneralSubstitutionModel {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         if (ratesInput.get() != null) {
-            throw new Exception("the rates attribute should not be used. Use the individual rates rateAC, rateCG, etc, instead.");
+            throw new IllegalArgumentException("the rates attribute should not be used. Use the individual rates rateAC, rateCG, etc, instead.");
         }
 
         //if (frequenciesInput.get() != null) {
@@ -62,7 +64,12 @@ public class SYM extends GeneralSubstitutionModel {
         updateMatrix = true;
         nrOfStates = frequencies.getFreqs().length;
 
-        eigenSystem = createEigenSystem();
+        try {
+			eigenSystem = createEigenSystem();
+		} catch (SecurityException | ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
+				| InvocationTargetException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
         rateMatrix = new double[nrOfStates][nrOfStates];
         relativeRates = new double[nrOfStates * (nrOfStates - 1)];
         storedRelativeRates = new double[nrOfStates * (nrOfStates - 1)];
@@ -75,7 +82,7 @@ public class SYM extends GeneralSubstitutionModel {
         rateGT = getParameter(rateGTInput);
     }
 
-    private RealParameter getParameter(Input<RealParameter> parameterInput) throws Exception {
+    private RealParameter getParameter(Input<RealParameter> parameterInput) {
         if (parameterInput.get() != null) {
             return parameterInput.get();
         }
diff --git a/src/beast/evolution/substitutionmodel/SubstitutionModel.java b/src/beast/evolution/substitutionmodel/SubstitutionModel.java
index bdef250..82823b6 100644
--- a/src/beast/evolution/substitutionmodel/SubstitutionModel.java
+++ b/src/beast/evolution/substitutionmodel/SubstitutionModel.java
@@ -39,16 +39,16 @@ public interface SubstitutionModel {
 
     /**
      * get the complete transition probability matrix for the given distance
-     * determined as (fStartTime-fEndTime)*fRate
+     * determined as (startTime-endTime)*rate
      *
      * @param node       tree node for which to calculate the probabilities
-     * @param fStartTime
-     * @param fEndTime   we assume start time is larger than end time
-     * @param fRate      rate, includes gamma rates and branch rates
+     * @param startTime
+     * @param endTime   we assume start time is larger than end time
+     * @param rate      rate, includes gamma rates and branch rates
      * @param matrix     an array to store the matrix which represents the transition probability
      *                   matrix in the form of an array. So, matrix must be of size n*n where n is number of states.
      */
-    void getTransitionProbabilities(Node node, double fStartTime, double fEndTime, double fRate, double[] matrix);
+    void getTransitionProbabilities(Node node, double startTime, double endTime, double rate, double[] matrix);
 
     /**
      * @param node In most cases, the rate matrix is independent of the tree, but if it changes
@@ -95,8 +95,8 @@ public interface SubstitutionModel {
      */
     @Description(value = "Base implementation of a substitution model.", isInheritable = false)
     public abstract class Base extends CalculationNode implements SubstitutionModel {
-        public Input<Frequencies> frequenciesInput =
-                new Input<Frequencies>("frequencies", "substitution model equilibrium state frequencies", Validate.REQUIRED);
+        final public Input<Frequencies> frequenciesInput =
+                new Input<>("frequencies", "substitution model equilibrium state frequencies", Validate.REQUIRED);
 
         /**
          * shadows frequencies, or can be set by subst model *
@@ -109,7 +109,7 @@ public interface SubstitutionModel {
         protected int nrOfStates;
 
         @Override
-        public void initAndValidate() throws Exception {
+        public void initAndValidate() {
             frequencies = frequenciesInput.get();
         }
 
diff --git a/src/beast/evolution/substitutionmodel/TIM.java b/src/beast/evolution/substitutionmodel/TIM.java
index c131b73..e878c61 100644
--- a/src/beast/evolution/substitutionmodel/TIM.java
+++ b/src/beast/evolution/substitutionmodel/TIM.java
@@ -1,5 +1,7 @@
 package beast.evolution.substitutionmodel;
 
+import java.lang.reflect.InvocationTargetException;
+
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.Input.Validate;
@@ -12,12 +14,12 @@ import beast.evolution.datatype.Nucleotide;
 public class TIM extends GeneralSubstitutionModel {
 
     // Transition rates
-    public Input<RealParameter> rateAGInput = new Input<RealParameter>("rateAG", "substitution rate for A to G (default 1)");
-    public Input<RealParameter> rateCTInput = new Input<RealParameter>("rateCT", "substitution rate for C to T (default 1)");
+    final public Input<RealParameter> rateAGInput = new Input<>("rateAG", "substitution rate for A to G (default 1)");
+    final public Input<RealParameter> rateCTInput = new Input<>("rateCT", "substitution rate for C to T (default 1)");
 
     // Transversion rates
-    public Input<RealParameter> rateTransversions1Input = new Input<RealParameter>("rateTransversions1", "substitution rate for A<->C and G<->T");
-    public Input<RealParameter> rateTransversions2Input = new Input<RealParameter>("rateTransversions2", "substitution rate for C<->G and A<->T");
+    final public Input<RealParameter> rateTransversions1Input = new Input<>("rateTransversions1", "substitution rate for A<->C and G<->T");
+    final public Input<RealParameter> rateTransversions2Input = new Input<>("rateTransversions2", "substitution rate for C<->G and A<->T");
 
     RealParameter rateAG;
     RealParameter rateCT;
@@ -35,19 +37,24 @@ public class TIM extends GeneralSubstitutionModel {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         if (ratesInput.get() != null) {
-            throw new Exception("the rates attribute should not be used. Use the individual rates rateAG, rateCT, etc, instead.");
+            throw new IllegalArgumentException("the rates attribute should not be used. Use the individual rates rateAG, rateCT, etc, instead.");
         }
 
         frequencies = frequenciesInput.get();
         updateMatrix = true;
         nrOfStates = frequencies.getFreqs().length;
         if (nrOfStates != 4) {
-            throw new Exception("Frequencies has wrong size. Expected 4, but got " + nrOfStates);
+            throw new IllegalArgumentException("Frequencies has wrong size. Expected 4, but got " + nrOfStates);
         }
 
-        eigenSystem = createEigenSystem();
+        try {
+			eigenSystem = createEigenSystem();
+		} catch (SecurityException | ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
+				| InvocationTargetException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
         rateMatrix = new double[nrOfStates][nrOfStates];
         relativeRates = new double[nrOfStates * (nrOfStates - 1)];
         storedRelativeRates = new double[nrOfStates * (nrOfStates - 1)];
@@ -58,7 +65,7 @@ public class TIM extends GeneralSubstitutionModel {
         rateTransversions2 = getParameter(rateTransversions2Input);
     }
 
-    private RealParameter getParameter(Input<RealParameter> parameterInput) throws Exception {
+    private RealParameter getParameter(Input<RealParameter> parameterInput) {
         if (parameterInput.get() != null) {
             return parameterInput.get();
         }
diff --git a/src/beast/evolution/substitutionmodel/TN93.java b/src/beast/evolution/substitutionmodel/TN93.java
index 150f6c3..eea7263 100644
--- a/src/beast/evolution/substitutionmodel/TN93.java
+++ b/src/beast/evolution/substitutionmodel/TN93.java
@@ -61,8 +61,8 @@ import beast.evolution.tree.Node;
 @Citation(value = "Tamura, K., & Nei, M. (1993). Estimation of the number of nucleotide substitutions in the control region " +
         "of mitochondrial DNA in humans and chimpanzees. Molecular Biology and Evolution, 10(3), 512-526.", DOI = "", year = 1994, firstAuthorSurname = "tamura")
 public class TN93 extends SubstitutionModel.NucleotideBase {
-    public Input<RealParameter> kappa1Variable = new Input<RealParameter>("kappa1", "rate of A<->G transitions", Validate.REQUIRED);
-    public Input<RealParameter> kappa2Variable = new Input<RealParameter>("kappa2", "rate of C<->T transitions", Validate.REQUIRED);
+    final public Input<RealParameter> kappa1Variable = new Input<>("kappa1", "rate of A<->G transitions", Validate.REQUIRED);
+    final public Input<RealParameter> kappa2Variable = new Input<>("kappa2", "rate of C<->T transitions", Validate.REQUIRED);
 
     private boolean updateIntermediates = true;
 
@@ -107,7 +107,7 @@ public class TN93 extends SubstitutionModel.NucleotideBase {
 
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         super.initAndValidate();
 
         kappa1Variable.get().setBounds(Math.max(0.0, kappa1Variable.get().getLower()), kappa1Variable.get().getUpper());
@@ -139,9 +139,10 @@ public class TN93 extends SubstitutionModel.NucleotideBase {
      *
      * @param matrix an array to store the matrix
      */
-    public void getTransitionProbabilities(Node node, double fStartTime, double fEndTime, double fRate, double[] matrix) {
+    @Override
+	public void getTransitionProbabilities(Node node, double startTime, double endTime, double rate, double[] matrix) {
 
-        double distance = (fStartTime - fEndTime) * fRate;
+        double distance = (startTime - endTime) * rate;
 
         synchronized (this) {
             if (updateIntermediates) {
@@ -224,7 +225,8 @@ public class TN93 extends SubstitutionModel.NucleotideBase {
         //System.arraycopy(fa1, 0, matrix, 0, 16);
     }
 
-    public EigenDecomposition getEigenDecomposition(Node node) {
+    @Override
+	public EigenDecomposition getEigenDecomposition(Node node) {
 
         if (eigenDecomposition == null) {
             double[] evec = new double[STATE_COUNT * STATE_COUNT];
diff --git a/src/beast/evolution/substitutionmodel/TVM.java b/src/beast/evolution/substitutionmodel/TVM.java
index b69616b..b2d3b3d 100644
--- a/src/beast/evolution/substitutionmodel/TVM.java
+++ b/src/beast/evolution/substitutionmodel/TVM.java
@@ -1,5 +1,7 @@
 package beast.evolution.substitutionmodel;
 
+import java.lang.reflect.InvocationTargetException;
+
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.Input.Validate;
@@ -12,13 +14,13 @@ import beast.evolution.datatype.Nucleotide;
 public class TVM extends GeneralSubstitutionModel {
 
     // Transversion rates
-    public Input<RealParameter> rateACInput = new Input<RealParameter>("rateAC", "substitution rate for A to C (default 1)");
-    public Input<RealParameter> rateATInput = new Input<RealParameter>("rateAT", "substitution rate for A to T (default 1)");
-    public Input<RealParameter> rateCGInput = new Input<RealParameter>("rateCG", "substitution rate for C to G (default 1)");
-    public Input<RealParameter> rateGTInput = new Input<RealParameter>("rateGT", "substitution rate for G to T (default 1)");
+    final public Input<RealParameter> rateACInput = new Input<>("rateAC", "substitution rate for A to C (default 1)");
+    final public Input<RealParameter> rateATInput = new Input<>("rateAT", "substitution rate for A to T (default 1)");
+    final public Input<RealParameter> rateCGInput = new Input<>("rateCG", "substitution rate for C to G (default 1)");
+    final public Input<RealParameter> rateGTInput = new Input<>("rateGT", "substitution rate for G to T (default 1)");
 
     // Transition rates
-    public Input<RealParameter> rateTransitionsInput = new Input<RealParameter>("rateTransitions", "substitution rate for A<->G and C<->T");
+    final public Input<RealParameter> rateTransitionsInput = new Input<>("rateTransitions", "substitution rate for A<->G and C<->T");
 
     RealParameter rateAC;
     RealParameter rateGT;
@@ -37,19 +39,24 @@ public class TVM extends GeneralSubstitutionModel {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         if (ratesInput.get() != null) {
-            throw new Exception("the rates attribute should not be used. Use the individual rates rateAC, rateCG, etc, instead.");
+            throw new IllegalArgumentException("the rates attribute should not be used. Use the individual rates rateAC, rateCG, etc, instead.");
         }
 
         frequencies = frequenciesInput.get();
         updateMatrix = true;
         nrOfStates = frequencies.getFreqs().length;
         if (nrOfStates != 4) {
-            throw new Exception("Frequencies has wrong size. Expected 4, but got " + nrOfStates);
+            throw new IllegalArgumentException("Frequencies has wrong size. Expected 4, but got " + nrOfStates);
         }
 
-        eigenSystem = createEigenSystem();
+        try {
+			eigenSystem = createEigenSystem();
+		} catch (SecurityException | ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
+				| InvocationTargetException e) {
+			throw new IllegalArgumentException(e.getMessage());
+		}
         rateMatrix = new double[nrOfStates][nrOfStates];
         relativeRates = new double[nrOfStates * (nrOfStates - 1)];
         storedRelativeRates = new double[nrOfStates * (nrOfStates - 1)];
@@ -62,7 +69,7 @@ public class TVM extends GeneralSubstitutionModel {
         rateTransitions = getParameter(rateTransitionsInput);
     }
 
-    private RealParameter getParameter(Input<RealParameter> parameterInput) throws Exception {
+    private RealParameter getParameter(Input<RealParameter> parameterInput) {
         if (parameterInput.get() != null) {
             return parameterInput.get();
         }
diff --git a/src/beast/evolution/substitutionmodel/WAG.java b/src/beast/evolution/substitutionmodel/WAG.java
index 6c1d795..e635ca2 100644
--- a/src/beast/evolution/substitutionmodel/WAG.java
+++ b/src/beast/evolution/substitutionmodel/WAG.java
@@ -642,13 +642,13 @@ public class WAG extends EmpiricalSubstitutionModel {
     @Override
     public int[] getEncodingOrder() {
         Aminoacid dataType = new Aminoacid();
-        String sCodeMap = dataType.getCodeMap();
-        int[] nCodeMap = new int[dataType.getStateCount()];
-        String sEncoding = "ARNDCQEGHILKMFPSTWYV";
+        String codeMap = dataType.getCodeMap();
+        int[] codeMapNrs = new int[dataType.getStateCount()];
+        String encoding = "ARNDCQEGHILKMFPSTWYV";
         for (int i = 0; i < dataType.getStateCount(); i++) {
-            nCodeMap[i] = sEncoding.indexOf(sCodeMap.charAt(i));
+            codeMapNrs[i] = encoding.indexOf(codeMap.charAt(i));
         }
-        return nCodeMap;
+        return codeMapNrs;
     }
 
     @Override
@@ -660,7 +660,7 @@ public class WAG extends EmpiricalSubstitutionModel {
 
         WAG wag = new WAG();
 
-        String aminoAcids = "ARNDCQEGHILKMFPSTWYV";
+        //String aminoAcids = "ARNDCQEGHILKMFPSTWYV";
         boolean[] class1 = {false,true,false,false,true,true,true,false,false,true,true,
                 false,true,false,false,false,false,true,true,true};
 
diff --git a/src/beast/evolution/tree/CladeSet.java b/src/beast/evolution/tree/CladeSet.java
index b8cb0e1..1cb28be 100644
--- a/src/beast/evolution/tree/CladeSet.java
+++ b/src/beast/evolution/tree/CladeSet.java
@@ -26,11 +26,15 @@
 package beast.evolution.tree;
 
 
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
 import beast.evolution.alignment.TaxonSet;
 import beast.util.FrequencySet;
 
-import java.util.*;
-
 /**
  * Stores a set of unique clades (and their node heights) for a tree.
  * Import from BEAST 1.
@@ -88,7 +92,7 @@ public class CladeSet extends FrequencySet<BitSet> {
 
     private SortedSet<String> getTaxaSet(BitSet bits) {
 
-        SortedSet<String> taxaSet = new TreeSet<String>();
+        SortedSet<String> taxaSet = new TreeSet<>();
 
         for (int i = 0; i < bits.length(); i++) {
             if (bits.get(i)) {
@@ -256,6 +260,6 @@ public class CladeSet extends FrequencySet<BitSet> {
     // Private stuff
     //
     private TaxonSet taxonSet = null;
-    private final Map<BitSet, Double> totalNodeHeight = new HashMap<BitSet, Double>();
+    private final Map<BitSet, Double> totalNodeHeight = new HashMap<>();
     private int totalTrees = 0;
 }
diff --git a/src/beast/evolution/tree/Node.java b/src/beast/evolution/tree/Node.java
index 7078aeb..5bf959a 100644
--- a/src/beast/evolution/tree/Node.java
+++ b/src/beast/evolution/tree/Node.java
@@ -25,12 +25,17 @@
 package beast.evolution.tree;
 
 
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
 import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.util.HeapSort;
 
-import java.util.*;
-
 
 @Description("Nodes in building beast.tree data structure.")
 public class Node extends BEASTObject {
@@ -48,14 +53,14 @@ public class Node extends BEASTObject {
     /**
      * Arbitrarily labeled metadata on this node. Not currently implemented as part of state!
      */
-    protected Map<String, Object> metaData = new TreeMap<String, Object>();
+    protected Map<String, Object> metaData = new TreeMap<>();
 
     /**
      * list of children of this node *
      * Don't use m_left and m_right directly
      * Use getChildCount() and getChild(x) or getChildren() instead
      */
-    List<Node> children = new ArrayList<Node>();
+    List<Node> children = new ArrayList<>();
 
 //    @Deprecated
 //	private Node m_left;
@@ -86,7 +91,7 @@ public class Node extends BEASTObject {
     public Node() {
     }
 
-    public Node(final String id) throws Exception {
+    public Node(final String id) {
         setID(id);
         initAndValidate();
     }
@@ -96,7 +101,7 @@ public class Node extends BEASTObject {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         // do nothing
     }
 
@@ -111,8 +116,8 @@ public class Node extends BEASTObject {
         return labelNr;
     }
 
-    public void setNr(final int iLabel) {
-        labelNr = iLabel;
+    public void setNr(final int labelIndex) {
+        labelNr = labelIndex;
     }
 
     public double getHeight() {
@@ -123,9 +128,9 @@ public class Node extends BEASTObject {
         return m_tree.getDate(height);
     }
 
-    public void setHeight(final double fHeight) {
+    public void setHeight(final double height) {
         startEditing();
-        height = fHeight;
+        this.height = height;
         isDirty |= Tree.IS_DIRTY;
         if (!isLeaf()) {
             getLeft().isDirty |= Tree.IS_DIRTY;
@@ -156,16 +161,16 @@ public class Node extends BEASTObject {
         return isDirty;
     }
 
-    public void makeDirty(final int nDirty) {
-        isDirty |= nDirty;
+    public void makeDirty(final int dirty) {
+        isDirty |= dirty;
     }
 
-    public void makeAllDirty(final int nDirty) {
-        isDirty = nDirty;
+    public void makeAllDirty(final int dirty) {
+        isDirty = dirty;
         if (!isLeaf()) {
-            getLeft().makeAllDirty(nDirty);
+            getLeft().makeAllDirty(dirty);
             if (getRight() != null) {
-                getRight().makeAllDirty(nDirty);
+                getRight().makeAllDirty(dirty);
             }
         }
     }
@@ -223,7 +228,7 @@ public class Node extends BEASTObject {
      * @return
      */
     public List<Node> getAllChildNodes() {
-        final List<Node> childNodes = new ArrayList<Node>();
+        final List<Node> childNodes = new ArrayList<>();
         if (!this.isLeaf()) getAllChildNodes(childNodes);
         return childNodes;
     }
@@ -241,7 +246,7 @@ public class Node extends BEASTObject {
      * @return
      */
     public List<Node> getAllLeafNodes() {
-        final List<Node> leafNodes = new ArrayList<Node>();
+        final List<Node> leafNodes = new ArrayList<>();
         if (!this.isLeaf()) getAllLeafNodes(leafNodes);
         return leafNodes;
     }
@@ -330,23 +335,23 @@ public class Node extends BEASTObject {
      *         information. Unlike toNewick(), here Nodes are numbered, instead of
      *         using the node labels.
      *         If there are internal nodes with non-null IDs then their numbers are also printed.
-     *         Also, all internal nodes are labelled if bPrintInternalNodeNumbers
+     *         Also, all internal nodes are labelled if printInternalNodeNumbers
      *         is set true. This is useful for example when storing a State to file
      *         so that it can be restored.
      */
-    public String toShortNewick(final boolean bPrintInternalNodeNumbers) {
+    public String toShortNewick(final boolean printInternalNodeNumbers) {
         final StringBuilder buf = new StringBuilder();
         if (getLeft() != null) {
             buf.append("(");
-            buf.append(getLeft().toShortNewick(bPrintInternalNodeNumbers));
+            buf.append(getLeft().toShortNewick(printInternalNodeNumbers));
             if (getRight() != null) {
                 buf.append(',');
-                buf.append(getRight().toShortNewick(bPrintInternalNodeNumbers));
+                buf.append(getRight().toShortNewick(printInternalNodeNumbers));
             }
             buf.append(")");
             if (getID() != null) {
                 buf.append(getNr());
-            } else if (bPrintInternalNodeNumbers) {
+            } else if (printInternalNodeNumbers) {
                 buf.append(getNr());
             }
 
@@ -363,38 +368,38 @@ public class Node extends BEASTObject {
      * in a clade. Print node numbers (m_iLabel) incremented by 1
      * for leaves and internal nodes with non-null IDs.
      */
-    String toSortedNewick(final int[] iMaxNodeInClade) {
-        return toSortedNewick(iMaxNodeInClade, false);
+    String toSortedNewick(final int[] maxNodeInClade) {
+        return toSortedNewick(maxNodeInClade, false);
     }
 
-    public String toSortedNewick(int[] iMaxNodeInClade, boolean printMetaData) {
+    public String toSortedNewick(int[] maxNodeInClade, boolean printMetaData) {
         StringBuilder buf = new StringBuilder();
         if (getLeft() != null) {
             buf.append("(");
-            String sChild1 = getLeft().toSortedNewick(iMaxNodeInClade, printMetaData);
-            int iChild1 = iMaxNodeInClade[0];
+            String child1 = getLeft().toSortedNewick(maxNodeInClade, printMetaData);
+            int child1Index = maxNodeInClade[0];
             if (getRight() != null) {
-                String sChild2 = getRight().toSortedNewick(iMaxNodeInClade, printMetaData);
-                int iChild2 = iMaxNodeInClade[0];
-                if (iChild1 > iChild2) {
-                    buf.append(sChild2);
+                String child2 = getRight().toSortedNewick(maxNodeInClade, printMetaData);
+                int child2Index = maxNodeInClade[0];
+                if (child1Index > child2Index) {
+                    buf.append(child2);
                     buf.append(",");
-                    buf.append(sChild1);
+                    buf.append(child1);
                 } else {
-                    buf.append(sChild1);
+                    buf.append(child1);
                     buf.append(",");
-                    buf.append(sChild2);
-                    iMaxNodeInClade[0] = iChild1;
+                    buf.append(child2);
+                    maxNodeInClade[0] = child1Index;
                 }
             } else {
-                buf.append(sChild1);
+                buf.append(child1);
             }
             buf.append(")");
             if (getID() != null) {
                 buf.append(labelNr+1);
             }
         } else {
-            iMaxNodeInClade[0] = labelNr;
+            maxNodeInClade[0] = labelNr;
             buf.append(labelNr + 1);
         }
 
@@ -460,22 +465,22 @@ public class Node extends BEASTObject {
     }
 
     /**
-     * @param sLabels
+     * @param labels
      * @return beast.tree in long Newick format, with all length and meta data
      *         information, but with leafs labelled with their names
      */
-    public String toString(final List<String> sLabels) {
+    public String toString(final List<String> labels) {
         final StringBuilder buf = new StringBuilder();
         if (getLeft() != null) {
             buf.append("(");
-            buf.append(getLeft().toString(sLabels));
+            buf.append(getLeft().toString(labels));
             if (getRight() != null) {
                 buf.append(',');
-                buf.append(getRight().toString(sLabels));
+                buf.append(getRight().toString(labels));
             }
             buf.append(")");
         } else {
-            buf.append(sLabels.get(labelNr));
+            buf.append(labels.get(labelNr));
         }
         if (metaDataString != null) {
             buf.append('[');
@@ -486,7 +491,8 @@ public class Node extends BEASTObject {
         return buf.toString();
     }
 
-    public String toString() {
+    @Override
+	public String toString() {
         return toShortNewick(true);
     }
 
@@ -505,7 +511,7 @@ public class Node extends BEASTObject {
 
         if (childCount == 1) return getChild(0).sort();
 
-        final List<Integer> lowest = new ArrayList<Integer>();
+        final List<Integer> lowest = new ArrayList<>();
         final int[] indices = new int[childCount];
 
         // relies on this being a copy of children list
@@ -526,20 +532,20 @@ public class Node extends BEASTObject {
      * but internal nodes are left to zero. After labeling internal
      * nodes, m_iLabel uniquely identifies a node in a beast.tree.
      *
-     * @param iLabel
+     * @param labelIndex
      * @return
      */
-    public int labelInternalNodes(int iLabel) {
+    public int labelInternalNodes(int labelIndex) {
         if (isLeaf()) {
-            return iLabel;
+            return labelIndex;
         } else {
-            iLabel = getLeft().labelInternalNodes(iLabel);
+            labelIndex = getLeft().labelInternalNodes(labelIndex);
             if (getRight() != null) {
-                iLabel = getRight().labelInternalNodes(iLabel);
+                labelIndex = getRight().labelInternalNodes(labelIndex);
             }
-            labelNr = iLabel++;
+            labelNr = labelIndex++;
         }
-        return iLabel;
+        return labelIndex;
     } // labelInternalNodes
 
     /**
@@ -550,7 +556,7 @@ public class Node extends BEASTObject {
         node.height = height;
         node.labelNr = labelNr;
         node.metaDataString = metaDataString;
-        node.metaData = new TreeMap<String, Object>(metaData);
+        node.metaData = new TreeMap<>(metaData);
         node.parent = null;
         node.setID(getID());
 
@@ -568,7 +574,7 @@ public class Node extends BEASTObject {
         node.height = height;
         node.labelNr = labelNr;
         node.metaDataString = metaDataString;
-        node.metaData = new TreeMap<String, Object>(metaData);
+        node.metaData = new TreeMap<>(metaData);
         node.parent = null;
         node.setID(getID());
         if (getLeft() != null) {
@@ -590,7 +596,7 @@ public class Node extends BEASTObject {
         height = node.height;
         labelNr = node.labelNr;
         metaDataString = node.metaDataString;
-        metaData = new TreeMap<String, Object>(node.metaData);
+        metaData = new TreeMap<>(node.metaData);
         parent = null;
         setID(node.getID());
         if (node.getLeft() != null) {
@@ -610,26 +616,26 @@ public class Node extends BEASTObject {
      * Only heights are recognised, but derived classes could deal with
      * richer meta data pattersn.
      */
-    public void setMetaData(final String sPattern, final Object fValue) {
+    public void setMetaData(final String pattern, final Object value) {
         startEditing();
-        if (sPattern.equals(TraitSet.DATE_TRAIT) ||
-                sPattern.equals(TraitSet.DATE_FORWARD_TRAIT) ||
-                sPattern.equals(TraitSet.DATE_BACKWARD_TRAIT)) {
-            height = (Double) fValue;
+        if (pattern.equals(TraitSet.DATE_TRAIT) ||
+                pattern.equals(TraitSet.DATE_FORWARD_TRAIT) ||
+                pattern.equals(TraitSet.DATE_BACKWARD_TRAIT)) {
+            height = (Double) value;
             isDirty |= Tree.IS_DIRTY;
         } else {
-            metaData.put(sPattern, fValue);
+            metaData.put(pattern, value);
         }
 
     }
 
-    public Object getMetaData(final String sPattern) {
-        if (sPattern.equals(TraitSet.DATE_TRAIT) ||
-                sPattern.equals(TraitSet.DATE_FORWARD_TRAIT) ||
-                sPattern.equals(TraitSet.DATE_BACKWARD_TRAIT)) {
+    public Object getMetaData(final String pattern) {
+        if (pattern.equals(TraitSet.DATE_TRAIT) ||
+                pattern.equals(TraitSet.DATE_FORWARD_TRAIT) ||
+                pattern.equals(TraitSet.DATE_BACKWARD_TRAIT)) {
             return height;
         } else {
-            final Object d = metaData.get(sPattern);
+            final Object d = metaData.get(pattern);
             if (d != null) return d;
         }
         return 0;
@@ -643,21 +649,21 @@ public class Node extends BEASTObject {
     /**
      * scale height of this node and all its descendants
      *
-     * @param fScale scale factor
+     * @param scale scale factor
      */
-    public void scale(final double fScale) throws Exception {
+    public void scale(final double scale) {
         startEditing();
         isDirty |= Tree.IS_DIRTY;
         if (!isLeaf() && !isFake()) {
-            height *= fScale;
+            height *= scale;
         }
         if (!isLeaf()) {
-            getLeft().scale(fScale);
+            getLeft().scale(scale);
             if (getRight() != null) {
-                getRight().scale(fScale);
+                getRight().scale(scale);
             }
             if (height < getLeft().height || height < getRight().height) {
-                throw new Exception("Scale gives negative branch length");
+                throw new IllegalArgumentException("Scale gives negative branch length");
             }
         }
     }
@@ -666,24 +672,23 @@ public class Node extends BEASTObject {
 //     * Used for sampled ancestor trees
 //     * Scales this node and all its descendants (either all descendants, or only non-sampled descendants)
 //     *
-//     * @param fScale    the scalar to multiply each scaled node age by
+//     * @param scale    the scalar to multiply each scaled node age by
 //     * @param scaleSNodes true if sampled nodes should be scaled as well as internal nodes, false if only non-sampled
 //     *                  internal nodes should be scaled.
-//     * @throws Exception throws exception if resulting tree would have negative branch lengths.
 //     */
-//    public void scale(double fScale, boolean scaleSNodes) throws Exception {
+//    public void scale(double scale, boolean scaleSNodes) {
 //        startEditing();
 //        isDirty |= Tree.IS_DIRTY;
 //        if (scaleSNodes || (!isLeaf() && !isFake())) {
-//            height *= fScale;
+//            height *= scale;
 //        }
 //        if (!isLeaf()) {
-//            (getLeft()).scale(fScale, scaleSNodes);
+//            (getLeft()).scale(scale, scaleSNodes);
 //            if (getRight() != null) {
-//                (getRight()).scale(fScale, scaleSNodes);
+//                (getRight()).scale(scale, scaleSNodes);
 //            }
 //            if (height < getLeft().height || height < getRight().height) {
-//                throw new Exception("Scale gives negative branch length");
+//                throw new IllegalArgumentException("Scale gives negative branch length");
 //            }
 //        }
 //    }
@@ -701,15 +706,15 @@ public class Node extends BEASTObject {
         return children.size();
     }
 
-    public Node getChild(final int iChild) {
-        return children.get(iChild);
+    public Node getChild(final int childIndex) {
+        return children.get(childIndex);
     }
 
-    public void setChild(final int iChild, final Node node) {
-        while (children.size() < iChild) {
+    public void setChild(final int childIndex, final Node node) {
+        while (children.size() < childIndex) {
             children.add(null);
         }
-        children.set(iChild, node);
+        children.set(childIndex, node);
     }
 
 
diff --git a/src/beast/evolution/tree/RandomTree.java b/src/beast/evolution/tree/RandomTree.java
index 285abcd..c5158c1 100644
--- a/src/beast/evolution/tree/RandomTree.java
+++ b/src/beast/evolution/tree/RandomTree.java
@@ -26,15 +26,25 @@
 package beast.evolution.tree;
 
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.commons.math.MathException;
 
+import beast.core.BEASTInterface;
 import beast.core.Description;
 import beast.core.Input;
+import beast.core.Input.Validate;
 import beast.core.StateNode;
 import beast.core.StateNodeInitialiser;
 import beast.core.util.Log;
-import beast.core.BEASTInterface;
-import beast.core.Input.Validate;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.alignment.TaxonSet;
 import beast.evolution.tree.coalescent.PopulationFunction;
@@ -48,11 +58,11 @@ import beast.util.Randomizer;
 
 @Description("This class provides the basic engine for coalescent simulation of a given demographic model over a given time period. ")
 public class RandomTree extends Tree implements StateNodeInitialiser {
-    public Input<Alignment> taxaInput = new Input<>("taxa", "set of taxa to initialise tree specified by alignment");
+    final public Input<Alignment> taxaInput = new Input<>("taxa", "set of taxa to initialise tree specified by alignment");
 
-    public Input<PopulationFunction> populationFunctionInput = new Input<PopulationFunction>("populationModel", "population function for generating coalescent???", Validate.REQUIRED);
-    public Input<List<MRCAPrior>> calibrationsInput = new Input<List<MRCAPrior>>("constraint", "specifies (monophyletic or height distribution) constraints on internal nodes", new ArrayList<MRCAPrior>());
-    public Input<Double> rootHeightInput = new Input<Double>("rootHeight", "If specified the tree will be scaled to match the root height, if constraints allow this");
+    final public Input<PopulationFunction> populationFunctionInput = new Input<>("populationModel", "population function for generating coalescent???", Validate.REQUIRED);
+    final public Input<List<MRCAPrior>> calibrationsInput = new Input<>("constraint", "specifies (monophyletic or height distribution) constraints on internal nodes", new ArrayList<>());
+    final public Input<Double> rootHeightInput = new Input<>("rootHeight", "If specified the tree will be scaled to match the root height, if constraints allow this");
 
     // total nr of taxa
     int nrOfTaxa;
@@ -61,7 +71,8 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
         Double upper = Double.POSITIVE_INFINITY;
         Double lower = Double.NEGATIVE_INFINITY;
 
-        public String toString() {
+        @Override
+		public String toString() {
             return "[" + lower + "," + upper + "]";
         }
     }
@@ -87,7 +98,7 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
 
     List<Integer>[] children;
 
-    Set<String> sTaxa;
+    Set<String> taxa;
 
     // number of the next internal node, used when creating new internal nodes
     int nextNodeNr;
@@ -98,16 +109,16 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
 
-        sTaxa = new LinkedHashSet<>();
+        taxa = new LinkedHashSet<>();
         if (taxaInput.get() != null) {
-            sTaxa.addAll(taxaInput.get().getTaxaNames());
+            taxa.addAll(taxaInput.get().getTaxaNames());
         } else {
-            sTaxa.addAll(m_taxonset.get().asStringList());
+            taxa.addAll(m_taxonset.get().asStringList());
         }
 
-        nrOfTaxa = sTaxa.size();
+        nrOfTaxa = taxa.size();
 
         initStateNodes();
         super.initAndValidate();
@@ -132,15 +143,16 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
 
     // returns true if bitSet is a subset of bitSet2
 //    private boolean isSubset(final BitSet bitSet, final BitSet bitSet2) {
-//        boolean bIsSubset = true;
-//        for (int k = bitSet.nextSetBit(0); bIsSubset && k >= 0; k = bitSet.nextSetBit(k + 1)) {
-//            bIsSubset = bitSet2.get(k);
+//        boolean isSubset = true;
+//        for (int k = bitSet.nextSetBit(0); isSubset && k >= 0; k = bitSet.nextSetBit(k + 1)) {
+//            isSubset = bitSet2.get(k);
 //        }
-//        return bIsSubset;
+//        return isSubset;
 //    }
 
-    @Override
-    public void initStateNodes() throws Exception {
+    @SuppressWarnings("unchecked")
+	@Override
+    public void initStateNodes() {
         // find taxon sets we are dealing with
         taxonSets = new ArrayList<>();
         m_bounds = new ArrayList<>();
@@ -149,25 +161,25 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
         lastMonophyletic = 0;
 
         if (taxaInput.get() != null) {
-            sTaxa.addAll(taxaInput.get().getTaxaNames());
+            taxa.addAll(taxaInput.get().getTaxaNames());
         } else {
-            sTaxa.addAll(m_taxonset.get().asStringList());
+            taxa.addAll(m_taxonset.get().asStringList());
         }
 
         // pick up constraints from outputs, m_inititial input tree and output tree, if any
-        List<MRCAPrior> calibrations = new ArrayList<MRCAPrior>();
+        List<MRCAPrior> calibrations = new ArrayList<>();
         calibrations.addAll(calibrationsInput.get());
-//    	for (Plugin plugin : outputs) {
+//    	for (BEASTObject beastObject : outputs) {
 //    	// pick up constraints in outputs
-//		if (plugin instanceof MRCAPrior && !calibrations.contains(plugin)) {
-//			calibrations.add((MRCAPrior) plugin);
-//		} else  if (plugin instanceof Tree) {
+//		if (beastObject instanceof MRCAPrior && !calibrations.contains(beastObject)) {
+//			calibrations.add((MRCAPrior) beastObject);
+//		} else  if (beastObject instanceof Tree) {
 //        	// pick up constraints in outputs if output tree
-//			Tree tree = (Tree) plugin;
+//			Tree tree = (Tree) beastObject;
 //			if (tree.m_initial.get() == this) {
-//            	for (Plugin plugin2 : tree.outputs) {
-//            		if (plugin2 instanceof MRCAPrior && !calibrations.contains(plugin2)) {
-//            			calibrations.add((MRCAPrior) plugin2);
+//            	for (BEASTObject beastObject2 : tree.outputs) {
+//            		if (beastObject2 instanceof MRCAPrior && !calibrations.contains(beastObject2)) {
+//            			calibrations.add((MRCAPrior) beastObject2);
 //            		}                		
 //            	}
 //			}
@@ -175,15 +187,15 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
 //		
 //	}
         // pick up constraints in m_initial tree
-        for (final Object plugin : getOutputs()) {
-            if (plugin instanceof MRCAPrior && !calibrations.contains(plugin) ) {
-                calibrations.add((MRCAPrior) plugin);
+        for (final Object beastObject : getOutputs()) {
+            if (beastObject instanceof MRCAPrior && !calibrations.contains(beastObject) ) {
+                calibrations.add((MRCAPrior) beastObject);
             }
         }
         if (m_initial.get() != null) {
-            for (final Object plugin : m_initial.get().getOutputs()) {
-                if (plugin instanceof MRCAPrior && !calibrations.contains(plugin)) {
-                    calibrations.add((MRCAPrior) plugin);
+            for (final Object beastObject : m_initial.get().getOutputs()) {
+                if (beastObject instanceof MRCAPrior && !calibrations.contains(beastObject)) {
+                    calibrations.add((MRCAPrior) beastObject);
                 }
             }
         }
@@ -191,32 +203,35 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
         for (final MRCAPrior prior : calibrations) {
             final TaxonSet taxonSet = prior.taxonsetInput.get();
             if (taxonSet != null && !prior.onlyUseTipsInput.get()) {
-	            final Set<String> bTaxa = new HashSet<>();
+	            final Set<String> usedTaxa = new HashSet<>();
 	        	if (taxonSet.asStringList() == null) {
 	        		taxonSet.initAndValidate();
 	        	}
-	            for (final String sTaxonID : taxonSet.asStringList()) {
-
-	                if (!sTaxa.contains(sTaxonID)) {
-	                    throw new Exception("Taxon <" + sTaxonID + "> could not be found in list of taxa. Choose one of " + sTaxa.toArray(new String[0]));
+	            for (final String taxonID : taxonSet.asStringList()) {
+	                if (!taxa.contains(taxonID)) {
+	                    throw new IllegalArgumentException("Taxon <" + taxonID + "> could not be found in list of taxa. Choose one of " + taxa);
 	                }
-	                bTaxa.add(sTaxonID);
+	                usedTaxa.add(taxonID);
 	            }
 	            final ParametricDistribution distr = prior.distInput.get();
 	            final Bound bounds = new Bound();
 	            if (distr != null) {
-	        		List<BEASTInterface> plugins = new ArrayList<BEASTInterface>();
-	        		distr.getPredecessors(plugins);
-	        		for (int i = plugins.size() - 1; i >= 0 ; i--) {
-	        			plugins.get(i).initAndValidate();
+	        		List<BEASTInterface> beastObjects = new ArrayList<>();
+	        		distr.getPredecessors(beastObjects);
+	        		for (int i = beastObjects.size() - 1; i >= 0 ; i--) {
+	        			beastObjects.get(i).initAndValidate();
 	        		}
-	                bounds.lower = distr.inverseCumulativeProbability(0.0) + distr.offsetInput.get();
-	                bounds.upper = distr.inverseCumulativeProbability(1.0) + distr.offsetInput.get();
+	                try {
+						bounds.lower = distr.inverseCumulativeProbability(0.0) + distr.offsetInput.get();
+		                bounds.upper = distr.inverseCumulativeProbability(1.0) + distr.offsetInput.get();
+					} catch (MathException e) {
+						Log.warning.println("At RandomTree::initStateNodes, bound on MRCAPrior could not be set " + e.getMessage());
+					}
 	            }
 	
 	            if (prior.isMonophyleticInput.get()) {
 	                // add any monophyletic constraint
-	                taxonSets.add(lastMonophyletic, bTaxa);
+	                taxonSets.add(lastMonophyletic, usedTaxa);
 	                distributions.add(lastMonophyletic, distr);
 	                m_bounds.add(lastMonophyletic, bounds);
 	                taxonSetIDs.add(prior.getID());
@@ -224,7 +239,7 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
 	            } else {
 	                // only calibrations with finite bounds are added
 	                if (!Double.isInfinite(bounds.lower) || !Double.isInfinite(bounds.upper)) {
-	                    taxonSets.add(bTaxa);
+	                    taxonSets.add(usedTaxa);
 	                    distributions.add(distr);
 	                    m_bounds.add(bounds);
 	                    taxonSetIDs.add(prior.getID());
@@ -246,18 +261,18 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
                 intersection.retainAll(taxonSets.get(j));
 
                 if (intersection.size() > 0) {
-                    final boolean bIsSubset = taxonSets.get(i).containsAll(taxonSets.get(j));
-                    final boolean bIsSubset2 = taxonSets.get(j).containsAll(taxonSets.get(i));
+                    final boolean isSubset = taxonSets.get(i).containsAll(taxonSets.get(j));
+                    final boolean isSubset2 = taxonSets.get(j).containsAll(taxonSets.get(i));
                     // sanity check: make sure either
                     // o taxonset1 is subset of taxonset2 OR
                     // o taxonset1 is superset of taxonset2 OR
                     // o taxonset1 does not intersect taxonset2
-                    if (!(bIsSubset || bIsSubset2)) {
-                        throw new Exception("333: Don't know how to generate a Random Tree for taxon sets that intersect, " +
+                    if (!(isSubset || isSubset2)) {
+                        throw new IllegalArgumentException("333: Don't know how to generate a Random Tree for taxon sets that intersect, " +
                                 "but are not inclusive. Taxonset " + taxonSetIDs.get(i) + " and " + taxonSetIDs.get(j));
                     }
                     // swap i & j if b1 subset of b2
-                    if (bIsSubset) {
+                    if (isSubset) {
                         swap(taxonSets, i, j);
                         swap(distributions, i, j);
                         swap(m_bounds, i, j);
@@ -269,25 +284,25 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
 
         // build tree of mono constraints such that j is parent of i if i is a subset of j but i+1,i+2,...,j-1 are not.
         // The last one, standing for the virtual "root" of all monophyletic clades is not associated with an actual clade
-        final int[] nParent = new int[lastMonophyletic];
+        final int[] parent = new int[lastMonophyletic];
         children = new List[lastMonophyletic + 1];
         for (int i = 0; i < lastMonophyletic + 1; i++) {
-            children[i] = new ArrayList<Integer>();
+            children[i] = new ArrayList<>();
         }
         for (int i = 0; i < lastMonophyletic; i++) {
             int j = i + 1;
             while (j < lastMonophyletic && !taxonSets.get(j).containsAll(taxonSets.get(i))) {
                 j++;
             }
-            nParent[i] = j;
+            parent[i] = j;
             children[j].add(i);
         }
 
         // make sure upper bounds of a child does not exceed the upper bound of its parent
         for (int i = lastMonophyletic-1; i >= 0 ;--i) {
-            if (nParent[i] < lastMonophyletic ) {
-                if (m_bounds.get(i).upper > m_bounds.get(nParent[i]).upper) {
-                    m_bounds.get(i).upper = m_bounds.get(nParent[i]).upper - 1e-100;
+            if (parent[i] < lastMonophyletic ) {
+                if (m_bounds.get(i).upper > m_bounds.get(parent[i]).upper) {
+                    m_bounds.get(i).upper = m_bounds.get(parent[i]).upper - 1e-100;
                 }
             }
         }
@@ -295,14 +310,14 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
 
         final PopulationFunction popFunction = populationFunctionInput.get();
 
-        simulateTree(sTaxa, popFunction);
+        simulateTree(taxa, popFunction);
         if (rootHeightInput.get() != null) {
         	scaleToFit(rootHeightInput.get() / root.getHeight(), root);
         }
 
-        nodeCount = 2 * sTaxa.size() - 1;
-        internalNodeCount = sTaxa.size() - 1;
-        leafNodeCount = sTaxa.size();
+        nodeCount = 2 * taxa.size() - 1;
+        internalNodeCount = taxa.size() - 1;
+        leafNodeCount = taxa.size();
 
         HashMap<String,Integer> taxonToNR = null;
         // preserve node numbers where possible
@@ -333,10 +348,13 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
             final MRCAPrior p = calibrations.get(k);
             if( p.isMonophyleticInput.get() ) {
                 final TaxonSet taxonSet = p.taxonsetInput.get();
-                final Set<String> bTaxa = new HashSet<>();
-                bTaxa.addAll(taxonSet.asStringList());
-                int c = traverse(root, bTaxa, taxonSet.getTaxonCount(), new int[1]);
-                boolean b = c == nrOfTaxa + 127;
+                if (taxonSet == null) {
+                	throw new IllegalArgumentException("Something is wrong with constraint " + p.getID() + " -- a taxonset must be specified if a monophyletic constraint is enforced.");
+                }
+                final Set<String> usedTaxa = new HashSet<>();
+                usedTaxa.addAll(taxonSet.asStringList());
+                /* int c = */ traverse(root, usedTaxa, taxonSet.getTaxonCount(), new int[1]);
+                // boolean b = c == nrOfTaxa + 127;
             }
         }
     }
@@ -363,9 +381,9 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
         if (!node.isLeaf()) {
 	    	double oldHeight = node.getHeight();
 	    	node.height *= scale;
-	        final Integer iConstraint = getDistrConstraint(node);
-	        if (iConstraint != null) {
-	            if (node.height < m_bounds.get(iConstraint).lower || node.height > m_bounds.get(iConstraint).upper) {
+	        final Integer constraint = getDistrConstraint(node);
+	        if (constraint != null) {
+	            if (node.height < m_bounds.get(constraint).lower || node.height > m_bounds.get(constraint).upper) {
 	            	//revert scaling
 	            	node.height = oldHeight;
 	            	return;
@@ -381,7 +399,8 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
 	}
 
 	//@Override
-    public void getInitialisedStateNodes(final List<StateNode> stateNodes) {
+    @Override
+	public void getInitialisedStateNodes(final List<StateNode> stateNodes) {
         stateNodes.add(m_initial.get());
     }
 
@@ -415,7 +434,7 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
                     processCandidateTraits(candidates, m_traitList.get());
                 }
 
-                final Map<String,Node> allCandidates = new TreeMap<String,Node>();
+                final Map<String,Node> allCandidates = new TreeMap<>();
                 for (Node node: candidates) {
                     allCandidates.put(node.getID(),node);
                 }
@@ -451,22 +470,22 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
     }
 
 
-    private Node simulateCoalescent(final int iIsMonophyleticNode, final Map<String,Node> allCandidates, final Set<Node> candidates, final PopulationFunction demoFunction)
+    private Node simulateCoalescent(final int isMonophyleticNode, final Map<String,Node> allCandidates, final Set<Node> candidates, final PopulationFunction demoFunction)
             throws ConstraintViolatedException {
-        final List<Node> remainingCandidates = new ArrayList<Node>();
+        final List<Node> remainingCandidates = new ArrayList<>();
         final Set<String> taxaDone = new TreeSet<>();
-        for (final int iMonoNode : children[iIsMonophyleticNode]) {
+        for (final int monoNode : children[isMonophyleticNode]) {
             // create list of leaf nodes for this monophyletic MRCA
             final Set<Node> candidates2 = new HashSet<>();
-            final Set<String> bTaxonSet = taxonSets.get(iMonoNode);
-            for (String taxon : bTaxonSet) {
+            final Set<String> isTaxonSet = taxonSets.get(monoNode);
+            for (String taxon : isTaxonSet) {
                 candidates2.add(allCandidates.get(taxon));
             }
 
-            final Node MRCA = simulateCoalescent(iMonoNode, allCandidates, candidates2, demoFunction);
+            final Node MRCA = simulateCoalescent(monoNode, allCandidates, candidates2, demoFunction);
             remainingCandidates.add(MRCA);
 
-            taxaDone.addAll(bTaxonSet);
+            taxaDone.addAll(isTaxonSet);
         }
 
         for (final Node node : candidates) {
@@ -475,22 +494,22 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
             }
         }
 
-        final double upper = iIsMonophyleticNode < m_bounds.size() ?  m_bounds.get(iIsMonophyleticNode).upper : Double.POSITIVE_INFINITY;
+        final double upper = isMonophyleticNode < m_bounds.size() ?  m_bounds.get(isMonophyleticNode).upper : Double.POSITIVE_INFINITY;
         final Node MRCA = simulateCoalescentWithMax(remainingCandidates, demoFunction, upper);
         return MRCA;
     }
 
-    /**
-     * @param id the id to match
-     * @param nodes a list of nodes
-     * @return the node with the matching id;
-     */
-    private Node getNodeById(String id, List<Node> nodes) {
-        for (Node node : nodes) {
-            if (node.getID().equals(id)) return node;
-        }
-        return null;
-    }
+//    /**
+//     * @param id the id to match
+//     * @param nodes a list of nodes
+//     * @return the node with the matching id;
+//     */
+//    private Node getNodeById(String id, List<Node> nodes) {
+//        for (Node node : nodes) {
+//            if (node.getID().equals(id)) return node;
+//        }
+//        return null;
+//    }
 
     /**
      * @param nodes
@@ -658,11 +677,11 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
      * Coalesce two nodes in the active list. This method removes the two
      * (randomly selected) active nodes and replaces them with the new node at
      * the top of the active list.
-     * @param fMinHeight
+     * @param minHeight
      * @param height
      * @return
      */
-    private double coalesceTwoActiveNodes(final double fMinHeight, double height) throws ConstraintViolatedException {
+    private double coalesceTwoActiveNodes(final double minHeight, double height) throws ConstraintViolatedException {
         final int node1 = Randomizer.nextInt(activeNodeCount);
         int node2 = node1;
         while (node2 == node1) {
@@ -691,30 +710,30 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
         activeNodeCount += 1;
 
         // check if there is a calibration on this node
-        final Integer iConstraint = getDistrConstraint(newNode);
-        if (iConstraint != null) {
+        final Integer constraint = getDistrConstraint(newNode);
+        if (constraint != null) {
 //			for (int i = 0; i < 1000; i++) {
 //				try {
 //					height = distr.sample(1)[0][0];
 //				} catch (Exception e) {
 //					e.printStackTrace();
 //				}
-//				if (height > fMinHeight) {
+//				if (height > minHeight) {
 //					break;
 //				}
 //			} 
-            final double fMin = Math.max(m_bounds.get(iConstraint).lower, fMinHeight);
-            final double fMax = m_bounds.get(iConstraint).upper;
-            if (fMax < fMin) {
+            final double min = Math.max(m_bounds.get(constraint).lower, minHeight);
+            final double max = m_bounds.get(constraint).upper;
+            if (max < min) {
                 // failed to draw a matching height from the MRCA distribution
                 // TODO: try to scale rest of tree down
                 throw new ConstraintViolatedException();
             }
-            if (height < fMin || height > fMax) {
-            	if (fMax == Double.POSITIVE_INFINITY) {
-            		height = fMin + 0.1;
+            if (height < min || height > max) {
+            	if (max == Double.POSITIVE_INFINITY) {
+            		height = min + 0.1;
             	} else {
-            		height = fMin + Randomizer.nextDouble() * (fMax - fMin);
+            		height = min + Randomizer.nextDouble() * (max - min);
             	}
                 newNode.setHeight(height);
             }
@@ -740,31 +759,31 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
         return null;
     }
 
-    int traverse(final Node node, final Set<String> MRCATaxonSet, final int nNrOfMRCATaxa, final int[] nTaxonCount) {
+    int traverse(final Node node, final Set<String> MRCATaxonSet, final int nrOfMRCATaxa, final int[] taxonCount) {
         if (node.isLeaf()) {
-            nTaxonCount[0]++;
+            taxonCount[0]++;
             if (MRCATaxonSet.contains(node.getID())) {
                 return 1;
             } else {
                 return 0;
             }
         } else {
-            int iTaxons = traverse(node.getLeft(), MRCATaxonSet, nNrOfMRCATaxa, nTaxonCount);
-            final int nLeftTaxa = nTaxonCount[0];
-            nTaxonCount[0] = 0;
+            int taxons = traverse(node.getLeft(), MRCATaxonSet, nrOfMRCATaxa, taxonCount);
+            final int leftTaxa = taxonCount[0];
+            taxonCount[0] = 0;
             if (node.getRight() != null) {
-                iTaxons += traverse(node.getRight(), MRCATaxonSet, nNrOfMRCATaxa, nTaxonCount);
-                final int nRightTaxa = nTaxonCount[0];
-                nTaxonCount[0] = nLeftTaxa + nRightTaxa;
+                taxons += traverse(node.getRight(), MRCATaxonSet, nrOfMRCATaxa, taxonCount);
+                final int rightTaxa = taxonCount[0];
+                taxonCount[0] = leftTaxa + rightTaxa;
             }
-            if (iTaxons == nrOfTaxa + 127) {
-                iTaxons++;
+            if (taxons == nrOfTaxa + 127) {
+                taxons++;
             }
-            if (iTaxons == nNrOfMRCATaxa) {
+            if (taxons == nrOfMRCATaxa) {
                 // we are at the MRCA, return magic nr
                 return nrOfTaxa + 127;
             }
-            return iTaxons;
+            return taxons;
         }
     }
 
@@ -772,18 +791,18 @@ public class RandomTree extends Tree implements StateNodeInitialiser {
     @Override
     public String[] getTaxaNames() {
         if (m_sTaxaNames == null) {
-            final List<String> sTaxa;
+            final List<String> taxa;
             if (taxaInput.get() != null) {
-                sTaxa = taxaInput.get().getTaxaNames();
+                taxa = taxaInput.get().getTaxaNames();
             } else {
-                sTaxa = m_taxonset.get().asStringList();
+                taxa = m_taxonset.get().asStringList();
             }
-            m_sTaxaNames = sTaxa.toArray(new String[sTaxa.size()]);
+            m_sTaxaNames = taxa.toArray(new String[taxa.size()]);
         }
         return m_sTaxaNames;
     }
 
-    final private ArrayList<Node> nodeList = new ArrayList<Node>();
+    final private ArrayList<Node> nodeList = new ArrayList<>();
     private int activeNodeCount = 0;
 
 
diff --git a/src/beast/evolution/tree/TraitSet.java b/src/beast/evolution/tree/TraitSet.java
index 4b4e608..e95cc84 100644
--- a/src/beast/evolution/tree/TraitSet.java
+++ b/src/beast/evolution/tree/TraitSet.java
@@ -1,17 +1,17 @@
 package beast.evolution.tree;
 
-import java.util.Arrays;
-import java.util.Date;
-import java.util.HashMap;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
 import java.time.format.DateTimeParseException;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.BEASTObject;
 import beast.core.Input.Validate;
 import beast.core.util.Log;
 import beast.evolution.alignment.TaxonSet;
@@ -30,14 +30,14 @@ public class TraitSet extends BEASTObject {
         year, month, day
     }
 
-    public Input<String> traitNameInput = new Input<String>("traitname", "name of the trait, used as meta data name for the tree. " +
+    final public Input<String> traitNameInput = new Input<>("traitname", "name of the trait, used as meta data name for the tree. " +
             "Special traitnames that are recognized are '" + DATE_TRAIT + "','" + DATE_FORWARD_TRAIT + "' and '" + DATE_BACKWARD_TRAIT + "'.", Validate.REQUIRED);
-    public Input<Units> unitsInput = new Input<Units>("units", "name of the units in which values are posed, " +
+    final public Input<Units> unitsInput = new Input<>("units", "name of the units in which values are posed, " +
             "used for conversion to a real value. This can be " + Arrays.toString(Units.values()) + " (default 'year')", Units.year, Units.values());
-    public Input<String> traitsInput = new Input<String>("value", "traits encoded as taxon=value pairs separated by commas", Validate.REQUIRED);
-    public Input<TaxonSet> taxaInput = new Input<TaxonSet>("taxa", "contains list of taxa to map traits to", Validate.REQUIRED);
+    final public Input<String> traitsInput = new Input<>("value", "traits encoded as taxon=value pairs separated by commas", Validate.REQUIRED);
+    final public Input<TaxonSet> taxaInput = new Input<>("taxa", "contains list of taxa to map traits to", Validate.REQUIRED);
 
-    public Input<String> dateTimeFormatInput = new Input<String>("dateFormat", "the date/time format to be parsed, (e.g., 'dd/M/yyyy')");
+    final public Input<String> dateTimeFormatInput = new Input<>("dateFormat", "the date/time format to be parsed, (e.g., 'dd/M/yyyy')");
 
     final public static String DATE_TRAIT = "date";
     final public static String DATE_FORWARD_TRAIT = "date-forward";
@@ -63,7 +63,7 @@ public class TraitSet extends BEASTObject {
     boolean numeric = true;
     
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         if (traitsInput.get().matches("^\\s*$")) {
             return;
         }
@@ -71,23 +71,23 @@ public class TraitSet extends BEASTObject {
         // first, determine taxon numbers associated with traits
         // The Taxon number is the index in the alignment, and
         // used as node number in a tree.
-        map = new HashMap<String, Integer>();
+        map = new HashMap<>();
         List<String> labels = taxaInput.get().asStringList();
         String[] traits = traitsInput.get().split(",");
         taxonValues = new String[labels.size()];
         values = new double[labels.size()];
         for (String trait : traits) {
             trait = trait.replaceAll("\\s+", " ");
-            String[] sStrs = trait.split("=");
-            if (sStrs.length != 2) {
-                throw new Exception("could not parse trait: " + trait);
+            String[] strs = trait.split("=");
+            if (strs.length != 2) {
+                throw new IllegalArgumentException("could not parse trait: " + trait);
             }
-            String taxonID = normalize(sStrs[0]);
+            String taxonID = normalize(strs[0]);
             int taxonNr = labels.indexOf(taxonID);
             if (taxonNr < 0) {
-                throw new Exception("Trait (" + taxonID + ") is not a known taxon. Spelling error perhaps?");
+                throw new IllegalArgumentException("Trait (" + taxonID + ") is not a known taxon. Spelling error perhaps?");
             }
-            taxonValues[taxonNr] = normalize(sStrs[1]);
+            taxonValues[taxonNr] = normalize(strs[1]);
             values[taxonNr] = parseDouble(taxonValues[taxonNr]);
             map.put(taxonID, taxonNr);
             
@@ -105,9 +105,9 @@ public class TraitSet extends BEASTObject {
         // find extremes
         minValue = values[0];
         maxValue = values[0];
-        for (double fValue : values) {
-            minValue = Math.min(minValue, fValue);
-            maxValue = Math.max(maxValue, fValue);
+        for (double value : values) {
+            minValue = Math.min(minValue, value);
+            maxValue = Math.max(maxValue, value);
         }
 
         if (traitNameInput.get().equals(DATE_TRAIT) || traitNameInput.get().equals(DATE_FORWARD_TRAIT)) {
@@ -135,16 +135,16 @@ public class TraitSet extends BEASTObject {
     }
 
     @Deprecated // use getStringValue by name instead
-    public String getStringValue(int iTaxonNr) {
-        return taxonValues[iTaxonNr];
+    public String getStringValue(int taxonNr) {
+        return taxonValues[taxonNr];
     }
 
     @Deprecated // use getValue by name instead
-    public double getValue(int iTaxonNr) {
+    public double getValue(int taxonNr) {
         if (values == null) {
             return 0;
         }
-        return values[iTaxonNr];
+        return values[taxonNr];
     }
 
     public String getStringValue(String taxonName) {
@@ -166,10 +166,10 @@ public class TraitSet extends BEASTObject {
     /**
      * see if we can convert the string to a double value *
      */
-    private double parseDouble(String sStr) throws Exception {
+    private double parseDouble(String str) {
         // default, try to interpret the string as a number
         try {
-            return Double.parseDouble(sStr);
+            return Double.parseDouble(str);
         } catch (NumberFormatException e) {
             // does not look like a number
                 if (traitNameInput.get().equals(DATE_TRAIT) ||
@@ -179,17 +179,19 @@ public class TraitSet extends BEASTObject {
                         try {
                             double year;
                             if (dateTimeFormatInput.get() == null) {
-                                if (sStr.matches(".*[a-zA-Z].*")) {
-                                        sStr = sStr.replace('/', '-');
+                                if (str.matches(".*[a-zA-Z].*")) {
+                                        str = str.replace('/', '-');
                                 }
-                                long date = Date.parse(sStr);
+                                // following is deprecated, but the best thing around at the moment
+                                // see also comments in TipDatesInputEditor
+                                long date = Date.parse(str);
                                 year = 1970.0 + date / (60.0 * 60 * 24 * 365 * 1000);
-                                System.err.println("No date/time format provided, using default parsing: '" + sStr + "' parsed as '" + year + "'");
+                                Log.warning.println("No date/time format provided, using default parsing: '" + str + "' parsed as '" + year + "'");
                             } else {
                                 DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateTimeFormatInput.get());
-                                LocalDate date = LocalDate.parse(sStr, formatter);
+                                LocalDate date = LocalDate.parse(str, formatter);
 
-                                System.err.println("Using format '" + dateTimeFormatInput.get() + "' to parse '" + sStr +
+                                Log.warning.println("Using format '" + dateTimeFormatInput.get() + "' to parse '" + str +
                                         "' as: " + (date.getYear() + (date.getDayOfYear()-1.0) / (date.isLeapYear() ? 366.0 : 365.0)));
 
                                 year = date.getYear() + (date.getDayOfYear()-1.0) / (date.isLeapYear() ? 366.0 : 365.0);
@@ -204,7 +206,7 @@ public class TraitSet extends BEASTObject {
                                     return year;
                             }
                         } catch (DateTimeParseException e2) {
-                            System.err.println("Failed to parse date '" + sStr + "' using format '" + dateTimeFormatInput.get() + "'");
+                            Log.err.println("Failed to parse date '" + str + "' using format '" + dateTimeFormatInput.get() + "'");
                             System.exit(1);
                         }
                     }
@@ -216,25 +218,25 @@ public class TraitSet extends BEASTObject {
     /**
      * remove start and end spaces
      */
-    String normalize(String sStr) {
-        if (sStr.charAt(0) == ' ') {
-            sStr = sStr.substring(1);
+    String normalize(String str) {
+        if (str.charAt(0) == ' ') {
+            str = str.substring(1);
         }
-        if (sStr.endsWith(" ")) {
-            sStr = sStr.substring(0, sStr.length() - 1);
+        if (str.endsWith(" ")) {
+            str = str.substring(0, str.length() - 1);
         }
-        return sStr;
+        return str;
     }
 
-    public double getDate(double fHeight) {
+    public double getDate(double height) {
         if (traitNameInput.get().equals(DATE_TRAIT) || traitNameInput.get().equals(DATE_FORWARD_TRAIT)) {
-            return maxValue - fHeight;
+            return maxValue - height;
         }
 
         if (traitNameInput.get().equals(DATE_BACKWARD_TRAIT)) {
-            return minValue + fHeight;
+            return minValue + height;
         }
-        return fHeight;
+        return height;
     }
     
     /**
diff --git a/src/beast/evolution/tree/Tree.java b/src/beast/evolution/tree/Tree.java
index 3ff3565..e137768 100644
--- a/src/beast/evolution/tree/Tree.java
+++ b/src/beast/evolution/tree/Tree.java
@@ -1,27 +1,31 @@
 package beast.evolution.tree;
 
-import beast.core.*;
-import beast.evolution.alignment.TaxonSet;
-import beast.util.TreeParser;
-
 import java.io.PrintStream;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 
+import beast.core.Description;
+import beast.core.Input;
+import beast.core.Operator;
+import beast.core.StateNode;
+import beast.core.StateNodeInitialiser;
+import beast.core.util.Log;
+import beast.evolution.alignment.TaxonSet;
+import beast.util.TreeParser;
+
 
 @Description("Tree (the T in BEAST) representing gene beast.tree, species"
         + " beast.tree, language history, or other time-beast.tree"
         + " relationships among sequence data.")
 public class Tree extends StateNode implements TreeInterface {
-    public Input<Tree> m_initial = new Input<Tree>("initial", "tree to start with");
-    public Input<List<TraitSet>> m_traitList = new Input<List<TraitSet>>("trait",
+    final public Input<Tree> m_initial = new Input<>("initial", "tree to start with");
+    final public Input<List<TraitSet>> m_traitList = new Input<>("trait",
             "trait information for initializing traits (like node dates) in the tree",
-            new ArrayList<TraitSet>());
-    public Input<TaxonSet> m_taxonset = new Input<TaxonSet>("taxonset",
+            new ArrayList<>());
+    final public Input<TaxonSet> m_taxonset = new Input<>("taxonset",
             "set of taxa that correspond to the leafs in the tree");
-    public Input<String> nodeTypeInput = new Input<String>("nodetype",
+    final public Input<String> nodeTypeInput = new Input<>("nodetype",
             "type of the nodes in the beast.tree", Node.class.getName());
 
     /**
@@ -69,7 +73,7 @@ public class Tree extends StateNode implements TreeInterface {
     protected boolean traitsProcessed = false;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         if (m_initial.get() != null && !(this instanceof StateNodeInitialiser)) {
         	throw new RuntimeException("initial-input should be specified for tree that is not a StateNodeInitialiser");
 //            final Tree other = m_initial.get();
@@ -114,18 +118,18 @@ public class Tree extends StateNode implements TreeInterface {
 
     public void makeCaterpillar(final double minInternalHeight, final double step, final boolean finalize) {
         // make a caterpillar
-        final List<String> sTaxa = m_taxonset.get().asStringList();
+        final List<String> taxa = m_taxonset.get().asStringList();
         Node left = newNode();
         left.labelNr = 0;
         left.height = 0;
-        left.setID(sTaxa.get(0));
-        for (int i = 1; i < sTaxa.size(); i++) {
+        left.setID(taxa.get(0));
+        for (int i = 1; i < taxa.size(); i++) {
             final Node right = newNode();
             right.labelNr = i;
             right.height = 0;
-            right.setID(sTaxa.get(i));
+            right.setID(taxa.get(i));
             final Node parent = newNode();
-            parent.labelNr = sTaxa.size() + i - 1;
+            parent.labelNr = taxa.size() + i - 1;
             parent.height = minInternalHeight + i * step;
             left.parent = parent;
             parent.setLeft(left);
@@ -134,7 +138,7 @@ public class Tree extends StateNode implements TreeInterface {
             left = parent;
         }
         root = left;
-        leafNodeCount = sTaxa.size();
+        leafNodeCount = taxa.size();
         nodeCount = leafNodeCount * 2 - 1;
         internalNodeCount = leafNodeCount - 1;
 
@@ -199,8 +203,8 @@ public class Tree extends StateNode implements TreeInterface {
     /**
      * Construct a tree from newick string -- will not automatically adjust tips to zero.
      */
-    public Tree(final String sNewick) throws Exception {
-        this(new TreeParser(sNewick).getRoot());
+    public Tree(final String newick) {
+        this(new TreeParser(newick).getRoot());
     }
 
     /**
@@ -229,7 +233,8 @@ public class Tree extends StateNode implements TreeInterface {
      *
      * @return the number of nodes in the beast.tree
      */
-    public int getNodeCount() {
+    @Override
+	public int getNodeCount() {
         if (nodeCount < 0) {
             nodeCount = this.root.getNodeCount();
         }
@@ -238,14 +243,16 @@ public class Tree extends StateNode implements TreeInterface {
         return nodeCount;
     }
 
-    public int getInternalNodeCount() {
+    @Override
+	public int getInternalNodeCount() {
         if (internalNodeCount < 0) {
             internalNodeCount = root.getInternalNodeCount();
         }
         return internalNodeCount;
     }
 
-    public int getLeafNodeCount() {
+    @Override
+	public int getLeafNodeCount() {
         //TODO will this caching work if trees can have random numbers of tips during MCMC
         if (leafNodeCount < 0) {
             leafNodeCount = root.getLeafNodeCount();
@@ -256,8 +263,9 @@ public class Tree extends StateNode implements TreeInterface {
     /**
      * @return a list of external (leaf) nodes contained in this tree
      */
-    public List<Node> getExternalNodes() {
-        final ArrayList<Node> externalNodes = new ArrayList<Node>();
+    @Override
+	public List<Node> getExternalNodes() {
+        final ArrayList<Node> externalNodes = new ArrayList<>();
         for (int i = 0; i < getNodeCount(); i++) {
             final Node node = getNode(i);
             if (node.isLeaf()) externalNodes.add(node);
@@ -268,8 +276,9 @@ public class Tree extends StateNode implements TreeInterface {
     /**
      * @return a list of internal (ancestral) nodes contained in this tree, including the root node
      */
-    public List<Node> getInternalNodes() {
-        final ArrayList<Node> internalNodes = new ArrayList<Node>();
+    @Override
+	public List<Node> getInternalNodes() {
+        final ArrayList<Node> internalNodes = new ArrayList<>();
         for (int i = 0; i < getNodeCount(); i++) {
             final Node node = getNode(i);
             if (!node.isLeaf()) internalNodes.add(node);
@@ -277,7 +286,8 @@ public class Tree extends StateNode implements TreeInterface {
         return internalNodes;
     }
 
-    public Node getRoot() {
+    @Override
+	public Node getRoot() {
         return root;
     }
 
@@ -307,16 +317,19 @@ public class Tree extends StateNode implements TreeInterface {
         this.root = root;
     }
 
-    public Node getNode(final int iNodeNr) {
-        return m_nodes[iNodeNr];
-        //return getNode(iNodeNr, root);
+    @Override
+	public Node getNode(final int nodeNr) {
+        return m_nodes[nodeNr];
+        //return getNode(nodeNr, root);
     }
 
-    @Deprecated
     /**
      * @returns an array of taxon names in order of their node numbers.
+     * Note that in general no special order of taxa is assumed, just the order
+     * assumed in this tree. Consider using tree.m_taxonset.get().asStringList()
+     * instead.
      */
-    public String[] getTaxaNames() {
+    public String [] getTaxaNames() {
          if (m_sTaxaNames == null || (m_sTaxaNames.length == 1 && m_sTaxaNames[0] == null) || m_sTaxaNames.length == 0) {
             final TaxonSet taxonSet = m_taxonset.get();
             if (taxonSet != null) {
@@ -338,7 +351,7 @@ public class Tree extends StateNode implements TreeInterface {
 
         // sanity check
         if (m_sTaxaNames.length == 1 && m_sTaxaNames[0] == null) {
-            System.err.println("WARNING: tree interrogated for taxa, but the tree was not initialised properly. To fix this, specify the taxonset input");
+            Log.warning.println("WARNING: tree interrogated for taxa, but the tree was not initialised properly. To fix this, specify the taxonset input");
         }
         return m_sTaxaNames;
     }
@@ -360,52 +373,54 @@ public class Tree extends StateNode implements TreeInterface {
 
 
     /**
-     * copy meta data matching sPattern to double array
+     * copy meta data matching pattern to double array
      *
      * @param node     the node
-     * @param fT       the double array to be filled with meta data
-     * @param sPattern the name of the meta data
+     * @param t       the double array to be filled with meta data
+     * @param pattern the name of the meta data
      */
-    public void getMetaData(final Node node, final Double[] fT, final String sPattern) {
-        fT[Math.abs(node.getNr())] = (Double) node.getMetaData(sPattern);
+    @Override
+	public void getMetaData(final Node node, final Double[] t, final String pattern) {
+        t[Math.abs(node.getNr())] = (Double) node.getMetaData(pattern);
         if (!node.isLeaf()) {
-            getMetaData(node.getLeft(), fT, sPattern);
+            getMetaData(node.getLeft(), t, pattern);
             if (node.getRight() != null) {
-                getMetaData(node.getRight(), fT, sPattern);
+                getMetaData(node.getRight(), t, pattern);
             }
         }
     }
 
     /**
-     * copy meta data matching sPattern to double array
+     * copy meta data matching pattern to double array
      *
      * @param node     the node
-     * @param fT       the integer array to be filled with meta data
-     * @param sPattern the name of the meta data
+     * @param t       the integer array to be filled with meta data
+     * @param pattern the name of the meta data
      */
-    public void getMetaData(final Node node, final Integer[] fT, final String sPattern) {
-        fT[Math.abs(node.getNr())] = (Integer) node.getMetaData(sPattern);
+    public void getMetaData(final Node node, final Integer[] t, final String pattern) {
+        t[Math.abs(node.getNr())] = (Integer) node.getMetaData(pattern);
         if (!node.isLeaf()) {
-            getMetaData(node.getLeft(), fT, sPattern);
+            getMetaData(node.getLeft(), t, pattern);
             if (node.getRight() != null) {
-                getMetaData(node.getRight(), fT, sPattern);
+                getMetaData(node.getRight(), t, pattern);
             }
         }
     }
 
 
     /**
-     * traverse tree and assign meta-data values in fT to nodes in the
+     * traverse tree and assign meta-data values in t to nodes in the
      * tree to the meta-data field represented by the given pattern.
      * This only has an effect when setMetadata() in a subclass
      * of Node know how to process such value.
      */
-    public void setMetaData(final Node node, final Double[] fT, final String sPattern) {
-        node.setMetaData(sPattern, fT[Math.abs(node.getNr())]);
+    @Override
+	public void setMetaData(final Node node, final Double[] t, final String pattern) {
+        node.setMetaData(pattern, t[Math.abs(node.getNr())]);
         if (!node.isLeaf()) {
-            setMetaData(node.getLeft(), fT, sPattern);
+            setMetaData(node.getLeft(), t, pattern);
             if (node.getRight() != null) {
-                setMetaData(node.getRight(), fT, sPattern);
+                setMetaData(node.getRight(), t, pattern);
             }
         }
     }
@@ -452,7 +467,8 @@ public class Tree extends StateNode implements TreeInterface {
 //    }
 
     protected Node[] postCache = null;
-    public Node[] listNodesPostOrder(Node node, Node[] nodes) {
+    @Override
+	public Node[] listNodesPostOrder(Node node, Node[] nodes) {
         if( node != null ) {
             return TreeInterface.super.listNodesPostOrder(node, nodes);
         }
@@ -466,7 +482,8 @@ public class Tree extends StateNode implements TreeInterface {
      * @return list of nodes in array format.
      *         *
      */
-    public Node[] getNodesAsArray() {
+    @Override
+	public Node[] getNodesAsArray() {
         return m_nodes;
     }
 
@@ -536,28 +553,28 @@ public class Tree extends StateNode implements TreeInterface {
         }
         root = m_nodes[tree.root.getNr()];
         final Node[] otherNodes = tree.m_nodes;
-        final int iRoot = root.getNr();
-        assignFrom(0, iRoot, otherNodes);
-        root.height = otherNodes[iRoot].height;
+        final int rootNr = root.getNr();
+        assignFrom(0, rootNr, otherNodes);
+        root.height = otherNodes[rootNr].height;
         root.parent = null;
-        if (otherNodes[iRoot].getLeft() != null) {
-            root.setLeft(m_nodes[otherNodes[iRoot].getLeft().getNr()]);
+        if (otherNodes[rootNr].getLeft() != null) {
+            root.setLeft(m_nodes[otherNodes[rootNr].getLeft().getNr()]);
         } else {
             root.setLeft(null);
         }
-        if (otherNodes[iRoot].getRight() != null) {
-            root.setRight(m_nodes[otherNodes[iRoot].getRight().getNr()]);
+        if (otherNodes[rootNr].getRight() != null) {
+            root.setRight(m_nodes[otherNodes[rootNr].getRight().getNr()]);
         } else {
             root.setRight(null);
         }
-        assignFrom(iRoot + 1, nodeCount, otherNodes);
+        assignFrom(rootNr + 1, nodeCount, otherNodes);
     }
 
     /**
      * helper to assignFromFragile *
      */
-    private void assignFrom(final int iStart, final int iEnd, final Node[] otherNodes) {
-        for (int i = iStart; i < iEnd; i++) {
+    private void assignFrom(final int start, final int end, final Node[] otherNodes) {
+        for (int i = start; i < end; i++) {
             Node sink = m_nodes[i];
             Node src = otherNodes[i];
             sink.height = src.height;
@@ -574,7 +591,8 @@ public class Tree extends StateNode implements TreeInterface {
     }
 
 
-    public String toString() {
+    @Override
+	public String toString() {
         return root.toString();
     }
 
@@ -583,9 +601,9 @@ public class Tree extends StateNode implements TreeInterface {
      * StateNode implementation
      */
     @Override
-    public void setEverythingDirty(final boolean bDirty) {
-        setSomethingIsDirty(bDirty);
-        if (!bDirty) {
+    public void setEverythingDirty(final boolean isDirty) {
+        setSomethingIsDirty(isDirty);
+        if (!isDirty) {
             for( Node n : m_nodes ) {
                 n.isDirty = IS_CLEAN;
             }
@@ -599,22 +617,21 @@ public class Tree extends StateNode implements TreeInterface {
     }
 
     @Override
-    public int scale(final double fScale) throws Exception {
-        root.scale(fScale);
+    public int scale(final double scale) {
+        root.scale(scale);
         return getInternalNodeCount()- getDirectAncestorNodeCount();
     }
 
 
 //    /**
 //     * The same as scale but with option to scale all sampled nodes
-//     * @param fScale
+//     * @param scale
 //     * @param scaleSNodes if true all sampled nodes are scaled. Note, the most recent node is considered to
 //     *                    have height 0.
 //     * @return
-//     * @throws Exception
 //     */
-//    public int scale(double fScale, boolean scaleSNodes) throws Exception {
-//        ((ZeroBranchSANode)root).scale(fScale, scaleSNodes);
+//    public int scale(double scale, boolean scaleSNodes) {
+//        ((ZeroBranchSANode)root).scale(scale, scaleSNodes);
 //        if (scaleSNodes) {
 //            return getNodeCount() - 1 - getDirectAncestorNodeCount();
 //        } else {
@@ -627,12 +644,12 @@ public class Tree extends StateNode implements TreeInterface {
     /**
      * print translate block for NEXUS beast.tree file
      */
-    public static void printTranslate(final Node node, final PrintStream out, final int nNodeCount) {
-        final List<String> translateLines = new ArrayList<String>();
-        printTranslate(node, translateLines, nNodeCount);
+    public static void printTranslate(final Node node, final PrintStream out, final int nodeCount) {
+        final List<String> translateLines = new ArrayList<>();
+        printTranslate(node, translateLines, nodeCount);
         Collections.sort(translateLines);
-        for (final String sLine : translateLines) {
-            out.println(sLine);
+        for (final String line : translateLines) {
+            out.println(line);
         }
     }
 
@@ -641,33 +658,34 @@ public class Tree extends StateNode implements TreeInterface {
     /**
      * need this helper so that we can sort list of entries *
      */
-    static void printTranslate(Node node, List<String> translateLines, int nNodeCount) {
+    static void printTranslate(Node node, List<String> translateLines, int nodeCount) {
         if (node.isLeaf()) {
-            final String sNr = (node.getNr() + taxaTranslationOffset) + "";
-            String sLine = "\t\t" + "    ".substring(sNr.length()) + sNr + " " + node.getID();
-            if (node.getNr() < nNodeCount) {
-                sLine += ",";
+            final String nr = (node.getNr() + taxaTranslationOffset) + "";
+            String line = "\t\t" + "    ".substring(nr.length()) + nr + " " + node.getID();
+            if (node.getNr() < nodeCount) {
+                line += ",";
             }
-            translateLines.add(sLine);
+            translateLines.add(line);
         } else {
-            printTranslate(node.getLeft(), translateLines, nNodeCount);
+            printTranslate(node.getLeft(), translateLines, nodeCount);
             if (node.getRight() != null) {
-                printTranslate(node.getRight(), translateLines, nNodeCount);
+                printTranslate(node.getRight(), translateLines, nodeCount);
             }
         }
     }
 
-    public static void printTaxa(final Node node, final PrintStream out, final int nNodeCount) {
-        final List<String> translateLines = new ArrayList<String>();
-        printTranslate(node, translateLines, nNodeCount);
+    public static void printTaxa(final Node node, final PrintStream out, final int nodeCount) {
+        final List<String> translateLines = new ArrayList<>();
+        printTranslate(node, translateLines, nodeCount);
         Collections.sort(translateLines);
-        for (String sLine : translateLines) {
-            sLine = sLine.split("\\s+")[2];
-            out.println("\t\t\t" + sLine.replace(',', ' '));
+        for (String line : translateLines) {
+            line = line.split("\\s+")[2];
+            out.println("\t\t\t" + line.replace(',', ' '));
         }
     }
 
-    public void init(PrintStream out) throws Exception {
+    @Override
+	public void init(PrintStream out) {
         Node node = getRoot();
         out.println("#NEXUS\n");
         out.println("Begin taxa;");
@@ -683,21 +701,23 @@ public class Tree extends StateNode implements TreeInterface {
         out.print(";");
     }
 
-    public void log(int nSample, PrintStream out) {
+    @Override
+	public void log(int sample, PrintStream out) {
         Tree tree = (Tree) getCurrent();
-        out.print("tree STATE_" + nSample + " = ");
+        out.print("tree STATE_" + sample + " = ");
         // Don't sort, this can confuse CalculationNodes relying on the tree
         //tree.getRoot().sort();
         final int[] dummy = new int[1];
-        final String sNewick = tree.getRoot().toSortedNewick(dummy);
-        out.print(sNewick);
+        final String newick = tree.getRoot().toSortedNewick(dummy);
+        out.print(newick);
         out.print(";");
     }
 
     /**
      * @see beast.core.Loggable *
      */
-    public void close(PrintStream out) {
+    @Override
+	public void close(PrintStream out) {
         out.print("End;");
     }
 
@@ -706,7 +726,7 @@ public class Tree extends StateNode implements TreeInterface {
      */
     @Override
     public void fromXML(final org.w3c.dom.Node node) {
-        final String sNewick = node.getTextContent();
+        final String newick = node.getTextContent();
         final TreeParser parser = new TreeParser();
         try {
             parser.thresholdInput.setValue(1e-10, parser);
@@ -715,7 +735,7 @@ public class Tree extends StateNode implements TreeInterface {
         }
         try {
             parser.offsetInput.setValue(0, parser);
-            setRoot(parser.parseNewick(sNewick));
+            setRoot(parser.parseNewick(newick));
         } catch (Exception e) {
             // TODO Auto-generated catch block
             e.printStackTrace();
@@ -726,16 +746,19 @@ public class Tree extends StateNode implements TreeInterface {
     /**
      * Valuable implementation *
      */
-    public int getDimension() {
+    @Override
+	public int getDimension() {
         return getNodeCount();
     }
 
-    public double getArrayValue() {
+    @Override
+	public double getArrayValue() {
         return root.height;
     }
 
-    public double getArrayValue(int iValue) {
-        return m_nodes[iValue].height;
+    @Override
+	public double getArrayValue(int value) {
+        return m_nodes[value].height;
     }
 
     /**
@@ -762,15 +785,15 @@ public class Tree extends StateNode implements TreeInterface {
 
 
     /**
-     * Stores nodes with index i, for iStart <= i < iEnd
-     * (i.e. including iStart but not including iEnd)
+     * Stores nodes with index i, for start <= i < end
+     * (i.e. including start but not including end)
      *
-     * @param iStart the first index to be stored
-     * @param iEnd   nodes are stored up to but not including this index
+     * @param start the first index to be stored
+     * @param end   nodes are stored up to but not including this index
      */
-    private void storeNodes(final int iStart, final int iEnd) {
+    private void storeNodes(final int start, final int end) {
         // Use direct members for speed (we are talking 5-7% or more from total time for large trees :)
-        for (int i = iStart; i < iEnd; i++) {
+        for (int i = start; i < end; i++) {
             final Node sink = m_storedNodes[i];
             final Node src = m_nodes[i];
             sink.height = src.height;
@@ -884,14 +907,14 @@ public class Tree extends StateNode implements TreeInterface {
      * Convert age/height to the date time scale given by a trait set,
      * if one exists.  Otherwise just return the unconverted height.
      *
-     * @param fHeight
+     * @param height
      * @return date specified by height
      */
-    public double getDate(final double fHeight) {
+    public double getDate(final double height) {
         if (hasDateTrait()) {
-            return timeTraitSet.getDate(fHeight);
+            return timeTraitSet.getDate(height);
         } else
-            return fHeight;
+            return height;
     }
 
     /**
diff --git a/src/beast/evolution/tree/TreeDistribution.java b/src/beast/evolution/tree/TreeDistribution.java
index 7e59d8c..895a04f 100644
--- a/src/beast/evolution/tree/TreeDistribution.java
+++ b/src/beast/evolution/tree/TreeDistribution.java
@@ -7,15 +7,15 @@ import java.util.Random;
 import beast.core.Description;
 import beast.core.Distribution;
 import beast.core.Input;
-import beast.core.State;
 import beast.core.Input.Validate;
+import beast.core.State;
 import beast.evolution.tree.coalescent.TreeIntervals;
 
 
 @Description("Distribution on a tree, typically a prior such as Coalescent or Yule")
 public class TreeDistribution extends Distribution {
-    public Input<TreeInterface> treeInput = new Input<TreeInterface>("tree", "tree over which to calculate a prior or likelihood");
-    public Input<TreeIntervals> treeIntervalsInput = new Input<TreeIntervals>("treeIntervals", "Intervals for a phylogenetic beast tree", Validate.XOR, treeInput);
+    final public Input<TreeInterface> treeInput = new Input<>("tree", "tree over which to calculate a prior or likelihood");
+    final public Input<TreeIntervals> treeIntervalsInput = new Input<>("treeIntervals", "Intervals for a phylogenetic beast tree", Validate.XOR, treeInput);
 
     @Override
     public List<String> getArguments() {
diff --git a/src/beast/evolution/tree/TreeHeightLogger.java b/src/beast/evolution/tree/TreeHeightLogger.java
index d81b25b..2c93418 100644
--- a/src/beast/evolution/tree/TreeHeightLogger.java
+++ b/src/beast/evolution/tree/TreeHeightLogger.java
@@ -8,13 +8,13 @@ import beast.core.CalculationNode;
 import beast.core.Description;
 import beast.core.Function;
 import beast.core.Input;
-import beast.core.Loggable;
 import beast.core.Input.Validate;
+import beast.core.Loggable;
 
 
 @Description("Logger to report height of a tree")
 public class TreeHeightLogger extends CalculationNode implements Loggable, Function {
-    public Input<Tree> treeInput = new Input<Tree>("tree", "tree to report height for.", Validate.REQUIRED);
+    final public Input<Tree> treeInput = new Input<>("tree", "tree to report height for.", Validate.REQUIRED);
 
     @Override
     public void initAndValidate() {
@@ -22,7 +22,7 @@ public class TreeHeightLogger extends CalculationNode implements Loggable, Funct
     }
 
     @Override
-    public void init(PrintStream out) throws Exception {
+    public void init(PrintStream out) {
         final Tree tree = treeInput.get();
         if (getID() == null || getID().matches("\\s*")) {
             out.print(tree.getID() + ".height\t");
@@ -32,7 +32,7 @@ public class TreeHeightLogger extends CalculationNode implements Loggable, Funct
     }
 
     @Override
-    public void log(int nSample, PrintStream out) {
+    public void log(int sample, PrintStream out) {
         final Tree tree = treeInput.get();
         out.print(tree.getRoot().getHeight() + "\t");
     }
@@ -53,7 +53,7 @@ public class TreeHeightLogger extends CalculationNode implements Loggable, Funct
     }
 
     @Override
-    public double getArrayValue(int iDim) {
+    public double getArrayValue(int dim) {
         return treeInput.get().getRoot().getHeight();
     }
 }
diff --git a/src/beast/evolution/tree/TreeInterface.java b/src/beast/evolution/tree/TreeInterface.java
index c59c211..14a5c2f 100644
--- a/src/beast/evolution/tree/TreeInterface.java
+++ b/src/beast/evolution/tree/TreeInterface.java
@@ -5,7 +5,6 @@ package beast.evolution.tree;
 import java.util.List;
 
 import beast.evolution.alignment.TaxonSet;
-import beast.evolution.tree.Node;
 
 public interface TreeInterface {
     String getID();
@@ -25,8 +24,8 @@ public interface TreeInterface {
     
 	boolean somethingIsDirty();
 
-    public void getMetaData(Node node, Double[] fT, String sPattern);
-    public void setMetaData(Node node, Double[] fT, String sPattern);
+    public void getMetaData(Node node, Double[] t, String pattern);
+    public void setMetaData(Node node, Double[] t, String pattern);
 
     /*
     * Note that leaf nodes are always numbered 0,...,nodeCount-1
diff --git a/src/beast/evolution/tree/TreeTraceAnalysis.java b/src/beast/evolution/tree/TreeTraceAnalysis.java
index f559886..39c246e 100644
--- a/src/beast/evolution/tree/TreeTraceAnalysis.java
+++ b/src/beast/evolution/tree/TreeTraceAnalysis.java
@@ -17,18 +17,19 @@
 package beast.evolution.tree;
 
 
-import beast.util.CredibleSet;
-import beast.util.FrequencySet;
-import beast.util.NexusParser;
-
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 
+import beast.util.CredibleSet;
+import beast.util.FrequencySet;
+import beast.util.NexusParser;
+
 
 // TODO: Calculate mean node heights for trees in credible set.
 
@@ -87,7 +88,7 @@ public class TreeTraceAnalysis {
      */
     public void analyze(double credSetProbability) {
         // set credSetProbability
-        topologiesFrequencySet = new FrequencySet<String>();
+        topologiesFrequencySet = new FrequencySet<>();
         topologiesFrequencySet.setCredSetProbability(credSetProbability);
 
         for (Tree tree : treeInTrace) {
@@ -220,9 +221,9 @@ public class TreeTraceAnalysis {
          * get list of trees from file
          * @param treeFile
          * @return
-         * @throws Exception
+         * @throws IOException 
          */
-        public static List<Tree> getTrees (File treeFile) throws Exception {
+        public static List<Tree> getTrees (File treeFile) throws IOException {
             NexusParser parser = new NexusParser();
             parser.parseFile(treeFile);
             return parser.trees;
@@ -252,7 +253,7 @@ public class TreeTraceAnalysis {
          */
         public static List<Tree> getSubListOfTrees(List<Tree> rawTreeList, int start, int end) {
             assert start < end;
-            return new ArrayList<Tree>(rawTreeList.subList(start, end));
+            return new ArrayList<>(rawTreeList.subList(start, end));
         }
 
         public static List<Tree> getSubListOfTrees(List<Tree> rawTreeList, int start) {
@@ -281,7 +282,7 @@ public class TreeTraceAnalysis {
             inputFile = new File(args[0]);
         } else {
             System.out.println("Error: Expected nexus file, but not file name was provided.");
-            System.exit(0);
+            System.exit(1);
         }
 
         if (args.length > 1) {
@@ -290,7 +291,7 @@ public class TreeTraceAnalysis {
                 out = new PrintStream(new FileOutputStream(args[1]));
             } catch (FileNotFoundException e) {
                 System.out.println("Error: Unable to create output file.");
-                System.exit(0);
+                System.exit(1);
             }
         }
 
@@ -299,7 +300,7 @@ public class TreeTraceAnalysis {
             trees = TreeTraceAnalysis.Utils.getTrees(inputFile);
         } catch (Exception e) {
             System.out.println("Error occurred while parsing input file.");
-            System.exit(0);
+            System.exit(1);
         }
         TreeTraceAnalysis analysis = new TreeTraceAnalysis(trees); // default 0.1, 0.95
         analysis.analyze();
diff --git a/src/beast/evolution/tree/TreeUtils.java b/src/beast/evolution/tree/TreeUtils.java
index d8035c9..3998ca0 100644
--- a/src/beast/evolution/tree/TreeUtils.java
+++ b/src/beast/evolution/tree/TreeUtils.java
@@ -1,6 +1,11 @@
 package beast.evolution.tree;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
 
 /**
  * @author Alexei Drummond and Alexandra Gavryushkina
@@ -31,13 +36,14 @@ public class TreeUtils {
 
         return new Comparator<Node>() {
 
-            public int compare(Node node1, Node node2) {
+            @Override
+			public int compare(Node node1, Node node2) {
                 return node2.getLeafNodeCount() - node1.getLeafNodeCount();
             }
 
-            public boolean equals(Node node1, Node node2) {
-                return node1.getLeafNodeCount() == node2.getLeafNodeCount();
-            }
+//            public boolean equals(Node node1, Node node2) {
+//                return node1.getLeafNodeCount() == node2.getLeafNodeCount();
+//            }
         };
     }
 
@@ -46,7 +52,8 @@ public class TreeUtils {
 
         return new Comparator<Node>() {
 
-            public int compare(Node node1, Node node2) {
+            @Override
+			public int compare(Node node1, Node node2) {
                 int larger = node1.getLeafNodeCount() - node2.getLeafNodeCount();
 
                 if (larger != 0) return larger;
@@ -63,7 +70,8 @@ public class TreeUtils {
     public static Comparator<Node> createReverseNodeDensityMinNodeHeightComparator() {
         return new Comparator<Node>() {
 
-            public int compare(Node node1, Node node2) {
+            @Override
+			public int compare(Node node1, Node node2) {
                 int larger = node2.getLeafNodeCount() - node1.getLeafNodeCount();
 
 
@@ -93,7 +101,7 @@ public class TreeUtils {
 
     public static double getDoubleMetaData(Node node, String metaDataName) {
         Object metaData = node.getMetaData(metaDataName);
-        if (metaData instanceof Integer) return (double) ((Integer) metaData);
+        if (metaData instanceof Integer) return ((Integer) metaData);
         if (metaData instanceof Double) return (Double) metaData;
         if (metaData instanceof String) return Double.parseDouble((String) metaData);
         return -1;
@@ -249,7 +257,7 @@ public class TreeUtils {
      */
     public static double[] getIntervals(Tree tree) {
 
-        List<Double> heights = new ArrayList<Double>();
+        List<Double> heights = new ArrayList<>();
 
         for (Node node : tree.getInternalNodes()) {
             heights.add(node.getHeight());
@@ -276,7 +284,7 @@ public class TreeUtils {
      */
     public static Set<String> getDescendantLeaves(Tree tree, Node node) {
 
-        HashSet<String> set = new HashSet<String>();
+        HashSet<String> set = new HashSet<>();
         getDescendantLeaves(tree, node, set);
         return set;
     }
@@ -353,7 +361,7 @@ public class TreeUtils {
         } else {
             StringBuilder builder = new StringBuilder("(");
 
-            List<String> subTrees = new ArrayList<String>();
+            List<String> subTrees = new ArrayList<>();
             for (int i = 0; i < node.getChildCount(); i++) {
                 subTrees.add(sortedNewickTopology(node.getChild(i), isTaxaLabel));
             }
diff --git a/src/beast/evolution/tree/TreeWithMetaDataLogger.java b/src/beast/evolution/tree/TreeWithMetaDataLogger.java
index 990293d..1a00e0e 100644
--- a/src/beast/evolution/tree/TreeWithMetaDataLogger.java
+++ b/src/beast/evolution/tree/TreeWithMetaDataLogger.java
@@ -6,24 +6,24 @@ import java.text.DecimalFormat;
 import java.util.ArrayList;
 import java.util.List;
 
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Function;
 import beast.core.Input;
+import beast.core.Input.Validate;
 import beast.core.Loggable;
 import beast.core.StateNode;
-import beast.core.BEASTObject;
-import beast.core.Input.Validate;
 import beast.core.parameter.Parameter;
 import beast.evolution.branchratemodel.BranchRateModel;
 
 @Description("Logs tree annotated with metadata and/or rates")
 public class TreeWithMetaDataLogger extends BEASTObject implements Loggable {
-    public Input<Tree> treeInput = new Input<Tree>("tree", "tree to be logged", Validate.REQUIRED);
+    final public Input<Tree> treeInput = new Input<>("tree", "tree to be logged", Validate.REQUIRED);
     // TODO: make this input a list of valuables
-    public Input<List<Function>> parameterInput = new Input<List<Function>>("metadata", "meta data to be logged with the tree nodes",new ArrayList<>());
-    public Input<BranchRateModel.Base> clockModelInput = new Input<BranchRateModel.Base>("branchratemodel", "rate to be logged with branches of the tree");
-    public Input<Boolean> substitutionsInput = new Input<Boolean>("substitutions", "report branch lengths as substitutions (branch length times clock rate for the branch)", false);
-    public Input<Integer> decimalPlacesInput = new Input<Integer>("dp", "the number of decimal places to use writing branch lengths and rates, use -1 for full precision (default = full precision)", -1);
+    final public Input<List<Function>> parameterInput = new Input<>("metadata", "meta data to be logged with the tree nodes",new ArrayList<>());
+    final public Input<BranchRateModel.Base> clockModelInput = new Input<>("branchratemodel", "rate to be logged with branches of the tree");
+    final public Input<Boolean> substitutionsInput = new Input<>("substitutions", "report branch lengths as substitutions (branch length times clock rate for the branch)", false);
+    final public Input<Integer> decimalPlacesInput = new Input<>("dp", "the number of decimal places to use writing branch lengths and rates, use -1 for full precision (default = full precision)", -1);
 
     
     boolean someMetaDataNeedsLogging;
@@ -32,11 +32,11 @@ public class TreeWithMetaDataLogger extends BEASTObject implements Loggable {
     private DecimalFormat df;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         if (parameterInput.get().size() == 0 && clockModelInput.get() == null) {
         	someMetaDataNeedsLogging = false;
         	return;
-            //throw new Exception("At least one of the metadata and branchratemodel inputs must be defined");
+            //throw new IllegalArgumentException("At least one of the metadata and branchratemodel inputs must be defined");
         }
     	someMetaDataNeedsLogging = true;
     	// without substitution model, reporting substitutions == reporting branch lengths 
@@ -56,12 +56,12 @@ public class TreeWithMetaDataLogger extends BEASTObject implements Loggable {
     }
 
     @Override
-    public void init(PrintStream out) throws Exception {
+    public void init(PrintStream out) {
         treeInput.get().init(out);
     }
 
     @Override
-    public void log(int nSample, PrintStream out) {
+    public void log(int sample, PrintStream out) {
         // make sure we get the current version of the inputs
         Tree tree = (Tree) treeInput.get().getCurrent();
         List<Function> metadata = parameterInput.get();
@@ -72,7 +72,7 @@ public class TreeWithMetaDataLogger extends BEASTObject implements Loggable {
         }
         BranchRateModel.Base branchRateModel = clockModelInput.get();
         // write out the log tree with meta data
-        out.print("tree STATE_" + nSample + " = ");
+        out.print("tree STATE_" + sample + " = ");
         tree.getRoot().sort();
         out.print(toNewick(tree.getRoot(), metadata, branchRateModel));
         //out.print(tree.getRoot().toShortNewick(false));
@@ -115,7 +115,7 @@ public class TreeWithMetaDataLogger extends BEASTObject implements Loggable {
 		            buf.append(((BEASTObject)metadata).getID());
 		            buf.append('=');
 		            if (metadata instanceof Parameter<?>) {
-		            	Parameter p = (Parameter) metadata;
+		            	Parameter<?> p = (Parameter<?>) metadata;
 		            	int dim = p.getMinorDimension1();
 		            	if (dim > 1) {
 			            	buf.append('{');
diff --git a/src/beast/evolution/tree/coalescent/BayesianSkyline.java b/src/beast/evolution/tree/coalescent/BayesianSkyline.java
index 0251a3a..3d24932 100644
--- a/src/beast/evolution/tree/coalescent/BayesianSkyline.java
+++ b/src/beast/evolution/tree/coalescent/BayesianSkyline.java
@@ -6,15 +6,13 @@ import java.util.Arrays;
 import java.util.List;
 import java.util.Random;
 
+import beast.core.BEASTObject;
 import beast.core.Description;
-import beast.core.Distribution;
 import beast.core.Function;
 import beast.core.Input;
-import beast.core.State;
-import beast.core.BEASTObject;
 import beast.core.Input.Validate;
+import beast.core.State;
 import beast.core.parameter.IntegerParameter;
-import beast.evolution.speciation.SpeciesTreeDistribution;
 import beast.evolution.tree.Tree;
 import beast.evolution.tree.TreeDistribution;
 import beast.math.Binomial;
@@ -28,16 +26,16 @@ import beast.math.Binomial;
 public class BayesianSkyline extends TreeDistribution {
 //public class BayesianSkyline extends PopulationFunction.Abstract {
 
-    public Input<Function> popSizeParamInput = new Input<Function>("popSizes", "present-day population size. "
+    final public Input<Function> popSizeParamInput = new Input<>("popSizes", "present-day population size. "
             + "If time units are set to Units.EXPECTED_SUBSTITUTIONS then"
             + "the N0 parameter will be interpreted as N0 * mu. "
             + "Also note that if you are dealing with a diploid population " + "N0 will be out by a factor of 2.",
             Validate.REQUIRED);
-    public Input<IntegerParameter> groupSizeParamInput = new Input<IntegerParameter>("groupSizes",
+    final public Input<IntegerParameter> groupSizeParamInput = new Input<>("groupSizes",
             "the group sizes parameter", Validate.REQUIRED);
-    // public Input<Tree> treeInput = new Input<Tree>("tree",
+    // public Input<Tree> treeInput = new Input<>("tree",
     // "The tree containing coalescent node times for use in defining BSP.");
-//	public Input<TreeIntervals> m_treeIntervals = new Input<TreeIntervals>("treeIntervals",
+//	public Input<TreeIntervals> m_treeIntervals = new Input<>("treeIntervals",
 //			"The intervals of the tree containing coalescent node times for use in defining BSP.", Validate.REQUIRED);
 
     Function popSizes;
@@ -58,16 +56,16 @@ public class BayesianSkyline extends TreeDistribution {
     // * @param populationSize
     // * @param groupSizes
     // * @param tree
-    // * @throws Exception
     // */
     // public void init(RealParameter populationSize, IntegerParameter
-    // groupSizes, Tree tree) throws Exception {
+    // groupSizes, Tree tree) {
     // super.init(populationSize, groupSizes, tree);
     // }
 
-    public void initAndValidate() throws Exception {
+    @Override
+	public void initAndValidate() {
         if (treeInput.get() != null) {
-            throw new Exception("only tree intervals (not tree) should not be specified");
+            throw new IllegalArgumentException("only tree intervals (not tree) should not be specified");
         }
         intervals = treeIntervalsInput.get();
         groupSizes = groupSizeParamInput.get();
@@ -161,7 +159,7 @@ public class BayesianSkyline extends TreeDistribution {
 
     public List<String> getParameterIds() {
 
-        List<String> paramIDs = new ArrayList<String>();
+        List<String> paramIDs = new ArrayList<>();
         paramIDs.add(((BEASTObject) popSizes).getID());
         paramIDs.add(groupSizes.getID());
 
@@ -173,7 +171,7 @@ public class BayesianSkyline extends TreeDistribution {
      * a demographic model.
      */
     @Override
-    public double calculateLogP() throws Exception {
+    public double calculateLogP() {
         if (!m_bIsPrepared) {
             prepare();
         }
@@ -211,8 +209,8 @@ public class BayesianSkyline extends TreeDistribution {
             int diff = intervals.getCoalescentEvents(j) - 1;
             for (int k = 0; k < diff; k++) {
                 //cp.setN0(getPopSize(currentTime));
-                double fPopSize = getPopSize(currentTime);
-                logP += calculateIntervalLikelihood(fPopSize, 0.0, currentTime, intervals.getLineageCount(j) - k - 1,
+                double popSize = getPopSize(currentTime);
+                logP += calculateIntervalLikelihood(popSize, 0.0, currentTime, intervals.getLineageCount(j) - k - 1,
                         IntervalType.COALESCENT);
                 subIndex += 1;
                 if (subIndex >= groupSizes.getValue(groupIndex)) {
diff --git a/src/beast/evolution/tree/coalescent/Coalescent.java b/src/beast/evolution/tree/coalescent/Coalescent.java
index 9406e88..726206b 100644
--- a/src/beast/evolution/tree/coalescent/Coalescent.java
+++ b/src/beast/evolution/tree/coalescent/Coalescent.java
@@ -8,8 +8,8 @@ import java.util.Random;
 import beast.core.CalculationNode;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.State;
 import beast.core.Input.Validate;
+import beast.core.State;
 import beast.evolution.tree.TreeDistribution;
 import beast.math.Binomial;
 
@@ -23,15 +23,15 @@ import beast.math.Binomial;
         "in account, in other words, the constant required for making this a proper distribution that integrates " +
         "to unity is not calculated (partly, because we don't know how for sequentially sampled data).")
 public class Coalescent extends TreeDistribution {
-    public Input<PopulationFunction> popSizeInput = new Input<PopulationFunction>("populationModel", "A population size model", Validate.REQUIRED);
+    final public Input<PopulationFunction> popSizeInput = new Input<>("populationModel", "A population size model", Validate.REQUIRED);
 
     TreeIntervals intervals;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         intervals = treeIntervalsInput.get();
         if (intervals == null) {
-            throw new Exception("Expected treeIntervals to be specified");
+            throw new IllegalArgumentException("Expected treeIntervals to be specified");
         }
         calculateLogP();
     }
@@ -41,7 +41,7 @@ public class Coalescent extends TreeDistribution {
      * do the actual calculation *
      */
     @Override
-    public double calculateLogP() throws Exception {
+    public double calculateLogP() {
 
         logP = calculateLogLikelihood(intervals, popSizeInput.get());
 
diff --git a/src/beast/evolution/tree/coalescent/CompoundPopulationFunction.java b/src/beast/evolution/tree/coalescent/CompoundPopulationFunction.java
index b0dec41..847e69e 100644
--- a/src/beast/evolution/tree/coalescent/CompoundPopulationFunction.java
+++ b/src/beast/evolution/tree/coalescent/CompoundPopulationFunction.java
@@ -1,25 +1,16 @@
 package beast.evolution.tree.coalescent;
 
 
-import java.io.BufferedReader;
-import java.io.FileReader;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.Loggable;
 import beast.core.parameter.BooleanParameter;
 import beast.core.parameter.RealParameter;
-import beast.evolution.tree.coalescent.IntervalType;
-import beast.evolution.tree.coalescent.PopulationFunction;
-import beast.evolution.tree.coalescent.TreeIntervals;
-import beast.math.statistic.DiscreteStatistics;
 
 
 /**
@@ -29,20 +20,20 @@ import beast.math.statistic.DiscreteStatistics;
 @Description("An effective population size function based on coalecent times from a set of trees.")
 public class CompoundPopulationFunction extends PopulationFunction.Abstract implements Loggable {
 
-    public Input<RealParameter> popSizeParameterInput = new Input<RealParameter>("populationSizes",
+    final public Input<RealParameter> popSizeParameterInput = new Input<>("populationSizes",
             "population value at each point.", Input.Validate.REQUIRED);
 
-    public Input<BooleanParameter> indicatorsParameterInput = new Input<BooleanParameter>("populationIndicators",
+    final public Input<BooleanParameter> indicatorsParameterInput = new Input<>("populationIndicators",
             "Include/exclude population value from the population function.", Input.Validate.REQUIRED);
 
-    public Input<List<TreeIntervals>> treesInput = new Input<List<TreeIntervals>>("itree", "Coalecent intervals of this tree are " +
-            "used in the compound population function.", new ArrayList<TreeIntervals>(), Input.Validate.REQUIRED);
+    final public Input<List<TreeIntervals>> treesInput = new Input<>("itree", "Coalecent intervals of this tree are " +
+            "used in the compound population function.", new ArrayList<>(), Input.Validate.REQUIRED);
 
-    public Input<String> demographicTypeInput = new Input<String>("type", "Flavour of demographic: either linear or stepwise for " +
+    final public Input<String> demographicTypeInput = new Input<>("type", "Flavour of demographic: either linear or stepwise for " +
             " piecewise-linear or piecewise-constant.",
             "linear");
 
-    public Input<Boolean> useMiddleInput = new Input<Boolean>("useIntervalsMiddle", "When true, the demographic X axis points are " +
+    final public Input<Boolean> useMiddleInput = new Input<>("useIntervalsMiddle", "When true, the demographic X axis points are " +
             "in the middle of the coalescent intervals. By default they are at the beginning.",
             false);
 
@@ -63,7 +54,8 @@ public class CompoundPopulationFunction extends PopulationFunction.Abstract impl
             this.name = name;
         }
 
-        public String toString() {
+        @Override
+		public String toString() {
             return name;
         }
 
@@ -128,7 +120,7 @@ public class CompoundPopulationFunction extends PopulationFunction.Abstract impl
 
     @Override
     public List<String> getParameterIds() {
-        List<String> paramIDs = new ArrayList<String>();
+        List<String> paramIDs = new ArrayList<>();
         paramIDs.add(popSizeParameter.getID());
         paramIDs.add(indicatorsParameter.getID());
 
@@ -387,7 +379,8 @@ public class CompoundPopulationFunction extends PopulationFunction.Abstract impl
         return interval * Math.log(pop1 / pop0) / (pop1 - pop0);
     }
 
-    public double getIntegral(double start, double finish) {
+    @Override
+	public double getIntegral(double start, double finish) {
 
         double intensity = 0.0;
 
@@ -442,31 +435,31 @@ public class CompoundPopulationFunction extends PopulationFunction.Abstract impl
         nti.setMultifurcationLimit(0);
 
         // code probably incorrect for serial samples
-        final int nLineages = nti.getIntervalCount();
-        assert nLineages >= ttimes[nt].length : nLineages + " " + ttimes[nt].length;
+        final int lineages = nti.getIntervalCount();
+        assert lineages >= ttimes[nt].length : lineages + " " + ttimes[nt].length;
 
-        int iCount = 0;
+        int count = 0;
         for (int k = 0; k < ttimes[nt].length; ++k) {
-            double timeToCoal = nti.getInterval(iCount);
-            while (nti.getIntervalType(iCount) != IntervalType.COALESCENT) {
-                ++iCount;
-                timeToCoal += nti.getInterval(iCount);
+            double timeToCoal = nti.getInterval(count);
+            while (nti.getIntervalType(count) != IntervalType.COALESCENT) {
+                ++count;
+                timeToCoal += nti.getInterval(count);
             }
 
-            int linAtStart = nti.getLineageCount(iCount);
-            ++iCount;
+            int linAtStart = nti.getLineageCount(count);
+            ++count;
 
-            assert !(iCount == nLineages && linAtStart != 2);
+            assert !(count == lineages && linAtStart != 2);
 
-            int linAtEnd = (iCount == nLineages) ? 1 : nti.getLineageCount(iCount);
+            int linAtEnd = (count == lineages) ? 1 : nti.getLineageCount(count);
 
             while (linAtStart <= linAtEnd) {
-                ++iCount;
-                timeToCoal += nti.getInterval(iCount);
+                ++count;
+                timeToCoal += nti.getInterval(count);
 
                 linAtStart = linAtEnd;
-                ++iCount;
-                linAtEnd = nti.getLineageCount(iCount);
+                ++count;
+                linAtEnd = nti.getLineageCount(count);
             }
             ttimes[nt][k] = timeToCoal + (k == 0 ? 0 : ttimes[nt][k - 1]);
         }
@@ -588,7 +581,7 @@ public class CompoundPopulationFunction extends PopulationFunction.Abstract impl
     }
 
     @Override
-    public void init(PrintStream out) throws Exception {
+    public void init(PrintStream out) {
         // interval sizes
         out.print("popsSize0\t");
         for (int i = 0; i < alltimes.length; i++) {
@@ -597,7 +590,7 @@ public class CompoundPopulationFunction extends PopulationFunction.Abstract impl
     }
 
     @Override
-    public void log(int nSample, PrintStream out) {
+    public void log(int sample, PrintStream out) {
         // interval sizes
         out.print("0:" + popSizeParameter.getArrayValue(0) + "\t");
         for (int i = 0; i < alltimes.length - (type == Type.STEPWISE ? 1 : 0); i++) {
diff --git a/src/beast/evolution/tree/coalescent/ConstantPopulation.java b/src/beast/evolution/tree/coalescent/ConstantPopulation.java
index efb00ad..f64b189 100644
--- a/src/beast/evolution/tree/coalescent/ConstantPopulation.java
+++ b/src/beast/evolution/tree/coalescent/ConstantPopulation.java
@@ -41,7 +41,7 @@ import beast.core.parameter.RealParameter;
  */
 @Description("coalescent intervals for a constant population")
 public class ConstantPopulation extends PopulationFunction.Abstract {
-    public Input<RealParameter> popSizeParameter = new Input<RealParameter>("popSize",
+    final public Input<RealParameter> popSizeParameter = new Input<>("popSize",
             "constant (effective) population size value.", Validate.REQUIRED);
 
     //
@@ -68,19 +68,23 @@ public class ConstantPopulation extends PopulationFunction.Abstract {
 
     // Implementation of abstract methods
 
-    public List<String> getParameterIds() {
+    @Override
+	public List<String> getParameterIds() {
         return Collections.singletonList(popSizeParameter.get().getID());
     }
 
-    public double getPopSize(double t) {
+    @Override
+	public double getPopSize(double t) {
         return getN0();
     }
 
-    public double getIntensity(double t) {
+    @Override
+	public double getIntensity(double t) {
         return t / getN0();
     }
 
-    public double getInverseIntensity(double x) {
+    @Override
+	public double getInverseIntensity(double x) {
         return getN0() * x;
     }
 
diff --git a/src/beast/evolution/tree/coalescent/ExponentialGrowth.java b/src/beast/evolution/tree/coalescent/ExponentialGrowth.java
index d979f19..879e782 100644
--- a/src/beast/evolution/tree/coalescent/ExponentialGrowth.java
+++ b/src/beast/evolution/tree/coalescent/ExponentialGrowth.java
@@ -40,16 +40,17 @@ import beast.core.parameter.RealParameter;
  */
 @Description("Coalescent intervals for a exponentially growing population.")
 public class ExponentialGrowth extends PopulationFunction.Abstract {
-    public Input<RealParameter> popSizeParameterInput = new Input<RealParameter>("popSize",
+    final public Input<RealParameter> popSizeParameterInput = new Input<>("popSize",
             "present-day population size (defaults to 1.0). ");
-    public Input<RealParameter> growthRateParameterInput = new Input<RealParameter>("growthRate",
+    final public Input<RealParameter> growthRateParameterInput = new Input<>("growthRate",
             "growth rate is the exponent of the exponential growth");
 
     //
     // Public stuff
     //
 
-    public void initAndValidate() throws Exception {
+    @Override
+	public void initAndValidate() {
         if (popSizeParameterInput.get() != null) {
             popSizeParameterInput.get().setBounds(
             		Math.max(0.0, popSizeParameterInput.get().getLower()), 
@@ -103,7 +104,8 @@ public class ExponentialGrowth extends PopulationFunction.Abstract {
 //    }
 
     // Implementation of abstract methods
-    public double getPopSize(double t) {
+    @Override
+	public double getPopSize(double t) {
 
         double r = getGrowthRate();
         if (r == 0) {
@@ -126,7 +128,8 @@ public class ExponentialGrowth extends PopulationFunction.Abstract {
         }
     }
 
-    public double getIntensity(double t) {
+    @Override
+	public double getIntensity(double t) {
         double r = getGrowthRate();
         if (r == 0.0) {
             return t / getN0();
@@ -135,7 +138,8 @@ public class ExponentialGrowth extends PopulationFunction.Abstract {
         }
     }
 
-    public double getInverseIntensity(double x) {
+    @Override
+	public double getInverseIntensity(double x) {
 
         double r = getGrowthRate();
         if (r == 0.0) {
@@ -148,7 +152,8 @@ public class ExponentialGrowth extends PopulationFunction.Abstract {
 
     // Implementation of abstract methods
 
-    public List<String> getParameterIds() {
+    @Override
+	public List<String> getParameterIds() {
         return Collections.singletonList(popSizeParameterInput.get().getID());
     }
 
diff --git a/src/beast/evolution/tree/coalescent/IntervalType.java b/src/beast/evolution/tree/coalescent/IntervalType.java
index 70a9bbd..272b126 100644
--- a/src/beast/evolution/tree/coalescent/IntervalType.java
+++ b/src/beast/evolution/tree/coalescent/IntervalType.java
@@ -67,7 +67,8 @@ public enum IntervalType {
         this.name = name;
     }
 
-    public String toString() {
+    @Override
+	public String toString() {
         return name;
     }
 
diff --git a/src/beast/evolution/tree/coalescent/PopulationFunction.java b/src/beast/evolution/tree/coalescent/PopulationFunction.java
index e05a3f1..18d009e 100644
--- a/src/beast/evolution/tree/coalescent/PopulationFunction.java
+++ b/src/beast/evolution/tree/coalescent/PopulationFunction.java
@@ -1,18 +1,18 @@
 package beast.evolution.tree.coalescent;
 
+import java.util.List;
+
 import org.apache.commons.math.FunctionEvaluationException;
 import org.apache.commons.math.MaxIterationsExceededException;
 import org.apache.commons.math.analysis.UnivariateRealFunction;
 import org.apache.commons.math.analysis.integration.RombergIntegrator;
 
-import beast.core.*;
+import beast.core.CalculationNode;
+import beast.core.Description;
 import beast.math.Binomial;
 import beast.util.Randomizer;
 
 
-import java.util.List;
-
-
 /**
  * This interface provides methods that describe a population size function.
  *
@@ -110,7 +110,7 @@ public interface PopulationFunction extends UnivariateRealFunction {
      */
     double getThreshold();
 
-    @Description("An implementation of a population size function plugin." +
+    @Description("An implementation of a population size function beastObject." +
             "Also note that if you are dealing with a diploid population " +
             "N0 will be the number of alleles, not the number of individuals.")
     public abstract class Abstract extends CalculationNode implements PopulationFunction {
@@ -124,18 +124,21 @@ public interface PopulationFunction extends UnivariateRealFunction {
         }
 
         // general functions
-        public void initAndValidate() throws Exception {
+        @Override
+		public void initAndValidate() {
             prepare();
         }
 
-        public double getThreshold() {
+        @Override
+		public double getThreshold() {
             return 0;
         }
 
         /**
          * Calculates the integral 1/N(t) dt between start and finish.
          */
-        public double getIntegral(double start, double finish) {
+        @Override
+		public double getIntegral(double start, double finish) {
             return getIntensity(finish) - getIntensity(start);
         }
 
@@ -185,7 +188,8 @@ public interface PopulationFunction extends UnivariateRealFunction {
          * @param t the time
          * @return the intensity
          */
-        public double value(double t) {
+        @Override
+		public double value(double t) {
             return 1.0 / getPopSize(t);
         }
 
@@ -238,10 +242,10 @@ public interface PopulationFunction extends UnivariateRealFunction {
          */
         public static void testConsistency(PopulationFunction populationFunction, int steps, double maxTime) {
 
-            final double delta = maxTime / (double) steps;
+            final double delta = maxTime / steps;
 
             for (int i = 0; i <= steps; i++) {
-                final double time = (double) i * delta;
+                final double time = i * delta;
                 final double intensity = populationFunction.getIntensity(time);
                 final double newTime = populationFunction.getInverseIntensity(intensity);
 
diff --git a/src/beast/evolution/tree/coalescent/SampleOffValues.java b/src/beast/evolution/tree/coalescent/SampleOffValues.java
index f35e2ce..72a5f6d 100644
--- a/src/beast/evolution/tree/coalescent/SampleOffValues.java
+++ b/src/beast/evolution/tree/coalescent/SampleOffValues.java
@@ -14,17 +14,18 @@ import beast.util.Randomizer;
  */
 @Description("Sample values from a distribution")
 public class SampleOffValues extends Operator {
-    public Input<RealParameter> valuesInput = new Input<RealParameter>("values", "vector of target values", Input.Validate.REQUIRED);
+    final public Input<RealParameter> valuesInput = new Input<>("values", "vector of target values", Input.Validate.REQUIRED);
 
-    public Input<BooleanParameter> indicatorsInput = new Input<BooleanParameter>("indicators", "Sample only entries which are 'off'");
+    final public Input<BooleanParameter> indicatorsInput = new Input<>("indicators", "Sample only entries which are 'off'");
 
-    public Input<ParametricDistribution> distInput = new Input<ParametricDistribution>("dist",
+    final public Input<ParametricDistribution> distInput = new Input<>("dist",
             "distribution to sample from.", Input.Validate.REQUIRED);
 
     public final Input<Boolean> scaleAll =
-            new Input<Boolean>("all", "if true, sample all off values in one go.", false);
+            new Input<>("all", "if true, sample all off values in one go.", false);
 
-    public void initAndValidate() {
+    @Override
+	public void initAndValidate() {
     }
 
     @Override
@@ -57,17 +58,17 @@ public class SampleOffValues extends Operator {
 
             // available locations for direct sampling
             int[] loc = new int[idim];
-            int nLoc = 0;
+            int locIndex = 0;
 
             for (int i = 0; i < idim; ++i) {
                 if( !indicators.getValue(i) ) {
-                    loc[nLoc] = i + offset;
-                    ++nLoc;
+                    loc[locIndex] = i + offset;
+                    ++locIndex;
                 }
             }
 
-            if( nLoc > 0 ) {
-                final int index = loc[Randomizer.nextInt(nLoc)];
+            if( locIndex > 0 ) {
+                final int index = loc[Randomizer.nextInt(locIndex)];
                 try {
                     final double val = distribution.inverseCumulativeProbability(Randomizer.nextDouble());
                     hr = distribution.logDensity(data.getValue(index));
diff --git a/src/beast/evolution/tree/coalescent/ScaledPopulationFunction.java b/src/beast/evolution/tree/coalescent/ScaledPopulationFunction.java
index 8c65cfa..8247e82 100644
--- a/src/beast/evolution/tree/coalescent/ScaledPopulationFunction.java
+++ b/src/beast/evolution/tree/coalescent/ScaledPopulationFunction.java
@@ -8,7 +8,6 @@ import beast.core.Description;
 import beast.core.Input;
 import beast.core.Input.Validate;
 import beast.core.parameter.RealParameter;
-import beast.evolution.tree.coalescent.PopulationFunction;
 
 
 /**
@@ -18,10 +17,10 @@ import beast.evolution.tree.coalescent.PopulationFunction;
 
 @Description("Scale a demographic function by a constant factor")
 public class ScaledPopulationFunction extends PopulationFunction.Abstract {
-    public Input<PopulationFunction> popParameterInput = new Input<PopulationFunction>("population",
+    final public Input<PopulationFunction> popParameterInput = new Input<>("population",
             "population function to scale. ", Validate.REQUIRED);
 
-    public Input<RealParameter> scaleFactorInput = new Input<RealParameter>("factor",
+    final public Input<RealParameter> scaleFactorInput = new Input<>("factor",
             "scale population by this facor.", Validate.REQUIRED);
 
     public ScaledPopulationFunction() {
@@ -29,23 +28,27 @@ public class ScaledPopulationFunction extends PopulationFunction.Abstract {
 
     // Implementation of abstract methods
 
-    public List<String> getParameterIds() {
+    @Override
+	public List<String> getParameterIds() {
         List<String> ids = popParameterInput.get().getParameterIds();
         ids.add(scaleFactorInput.get().getID());
         return ids;
     }
 
-    public double getPopSize(double t) {
+    @Override
+	public double getPopSize(double t) {
         return popParameterInput.get().getPopSize(t) * scaleFactorInput.get().getValue();
     }
 
-    public double getIntensity(double t) {
-        double fIntensity = popParameterInput.get().getIntensity(t);
-        double fScale = scaleFactorInput.get().getValue();
-        return fIntensity / fScale;
+    @Override
+	public double getIntensity(double t) {
+        double intensity = popParameterInput.get().getIntensity(t);
+        double scale = scaleFactorInput.get().getValue();
+        return intensity / scale;
     }
 
-    public double getInverseIntensity(double x) {
+    @Override
+	public double getInverseIntensity(double x) {
         throw new RuntimeException("unimplemented");
     }
 
diff --git a/src/beast/evolution/tree/coalescent/TreeIntervals.java b/src/beast/evolution/tree/coalescent/TreeIntervals.java
index 611bdba..c79c9c8 100644
--- a/src/beast/evolution/tree/coalescent/TreeIntervals.java
+++ b/src/beast/evolution/tree/coalescent/TreeIntervals.java
@@ -49,13 +49,13 @@ import beast.util.HeapSort;
 @Description("Extracts the intervals from a tree. Points in the intervals " +
         "are defined by the heights of nodes in the tree.")
 public class TreeIntervals extends CalculationNode implements IntervalList {
-    public Input<Tree> treeInput = new Input<Tree>("tree", "tree for which to calculate the intervals", Validate.REQUIRED);
+    final public Input<Tree> treeInput = new Input<>("tree", "tree for which to calculate the intervals", Validate.REQUIRED);
 
     public TreeIntervals() {
         super();
     }
 
-    public TreeIntervals(Tree tree) throws Exception {
+    public TreeIntervals(Tree tree) {
         init(tree);
     }
 
@@ -124,7 +124,8 @@ public class TreeIntervals extends CalculationNode implements IntervalList {
         }
     }
 
-    public int getSampleCount() {
+    @Override
+	public int getSampleCount() {
         // Assumes a binary tree!
         return treeInput.get().getInternalNodeCount();
     }
@@ -132,7 +133,8 @@ public class TreeIntervals extends CalculationNode implements IntervalList {
     /**
      * get number of intervals
      */
-    public int getIntervalCount() {
+    @Override
+	public int getIntervalCount() {
         if (!intervalsKnown) {
             calculateIntervals();
         }
@@ -142,7 +144,8 @@ public class TreeIntervals extends CalculationNode implements IntervalList {
     /**
      * Gets an interval.
      */
-    public double getInterval(int i) {
+    @Override
+	public double getInterval(int i) {
         if (!intervalsKnown) {
             calculateIntervals();
         }
@@ -189,7 +192,8 @@ public class TreeIntervals extends CalculationNode implements IntervalList {
      * Required for s-coalescents, where new lineages are added as
      * earlier samples are come across.
      */
-    public int getLineageCount(int i) {
+    @Override
+	public int getLineageCount(int i) {
         if (!intervalsKnown) {
             calculateIntervals();
         }
@@ -205,7 +209,7 @@ public class TreeIntervals extends CalculationNode implements IntervalList {
 //
 //        if (lineages[interval] == null) {
 //
-//            List<Node> lines = new ArrayList<Node>();
+//            List<Node> lines = new ArrayList<>();
 //            for (int i = 0; i <= interval; i++) {
 //                if (lineagesAdded[i] != null) lines.addAll(lineagesAdded[i]);
 //                if (lineagesRemoved[i] != null) lines.removeAll(lineagesRemoved[i]);
@@ -219,7 +223,8 @@ public class TreeIntervals extends CalculationNode implements IntervalList {
     /**
      * Returns the number of coalescent events in an interval
      */
-    public int getCoalescentEvents(int i) {
+    @Override
+	public int getCoalescentEvents(int i) {
         if (!intervalsKnown) {
             calculateIntervals();
         }
@@ -234,7 +239,8 @@ public class TreeIntervals extends CalculationNode implements IntervalList {
     /**
      * Returns the type of interval observed.
      */
-    public IntervalType getIntervalType(int i) {
+    @Override
+	public IntervalType getIntervalType(int i) {
         if (!intervalsKnown) {
             calculateIntervals();
         }
@@ -260,7 +266,8 @@ public class TreeIntervals extends CalculationNode implements IntervalList {
      * get the total height of the genealogy represented by these
      * intervals.
      */
-    public double getTotalDuration() {
+    @Override
+	public double getTotalDuration() {
 
         if (!intervalsKnown) {
             calculateIntervals();
@@ -277,7 +284,8 @@ public class TreeIntervals extends CalculationNode implements IntervalList {
      * (i.e. whether is has exactly one coalescent event in each
      * subsequent interval)
      */
-    public boolean isBinaryCoalescent() {
+    @Override
+	public boolean isBinaryCoalescent() {
         if (!intervalsKnown) {
             calculateIntervals();
         }
@@ -295,7 +303,8 @@ public class TreeIntervals extends CalculationNode implements IntervalList {
      * (i.e. whether is has exactly one or more coalescent event in each
      * subsequent interval)
      */
-    public boolean isCoalescentOnly() {
+    @Override
+	public boolean isCoalescentOnly() {
         if (!intervalsKnown) {
             calculateIntervals();
         }
@@ -422,12 +431,12 @@ public class TreeIntervals extends CalculationNode implements IntervalList {
     }
 
     protected void addLineage(int interval, Node node) {
-        if (lineagesAdded[interval] == null) lineagesAdded[interval] = new ArrayList<Node>();
+        if (lineagesAdded[interval] == null) lineagesAdded[interval] = new ArrayList<>();
         lineagesAdded[interval].add(node);
     }
 
     protected void removeLineage(int interval, Node node) {
-        if (lineagesRemoved[interval] == null) lineagesRemoved[interval] = new ArrayList<Node>();
+        if (lineagesRemoved[interval] == null) lineagesRemoved[interval] = new ArrayList<>();
         lineagesRemoved[interval].add(node);
     }
 
diff --git a/src/beast/math/Binomial.java b/src/beast/math/Binomial.java
index e85ee3d..d675ac1 100644
--- a/src/beast/math/Binomial.java
+++ b/src/beast/math/Binomial.java
@@ -88,7 +88,7 @@ public class Binomial {
         choose2LUT[1] = 0;
         choose2LUT[2] = 1;
         for (int i = 3; i <= maxN; i++) {
-            choose2LUT[i] = ((double) (i * (i - 1))) * 0.5;
+            choose2LUT[i] = (i * (i - 1)) * 0.5;
         }
     }
 
diff --git a/src/beast/math/distributions/Beta.java b/src/beast/math/distributions/Beta.java
index 2a17b0e..084b041 100644
--- a/src/beast/math/distributions/Beta.java
+++ b/src/beast/math/distributions/Beta.java
@@ -14,8 +14,8 @@ import beast.core.parameter.RealParameter;
         "If the input x is a multidimensional parameter, each of the dimensions is considered as a " +
         "separate independent component.")
 public class Beta extends ParametricDistribution {
-    public Input<RealParameter> alphaInput = new Input<RealParameter>("alpha", "first shape parameter, defaults to 1");
-    public Input<RealParameter> betaInput = new Input<RealParameter>("beta", "the other shape parameter, defaults to 1");
+    final public Input<RealParameter> alphaInput = new Input<>("alpha", "first shape parameter, defaults to 1");
+    final public Input<RealParameter> betaInput = new Input<>("beta", "the other shape parameter, defaults to 1");
 
     static org.apache.commons.math.distribution.BetaDistribution m_dist = new BetaDistributionImpl(1, 1);
 
@@ -27,21 +27,22 @@ public class Beta extends ParametricDistribution {
     /**
      * make sure internal state is up to date *
      */
-    void refresh() {
-        double fAlpha;
-        double fBeta;
+    @SuppressWarnings("deprecation")
+	void refresh() {
+        double alpha;
+        double beta;
         if (alphaInput.get() == null) {
-            fAlpha = 1;
+            alpha = 1;
         } else {
-            fAlpha = alphaInput.get().getValue();
+            alpha = alphaInput.get().getValue();
         }
         if (betaInput.get() == null) {
-            fBeta = 1;
+            beta = 1;
         } else {
-            fBeta = betaInput.get().getValue();
+            beta = betaInput.get().getValue();
         }
-        m_dist.setAlpha(fAlpha);
-        m_dist.setBeta(fBeta);
+        m_dist.setAlpha(alpha);
+        m_dist.setBeta(beta);
     }
 
     @Override
@@ -50,4 +51,8 @@ public class Beta extends ParametricDistribution {
         return m_dist;
     }
 
+    @Override
+    public double getMean() {
+    	return m_dist.getAlpha() / (m_dist.getAlpha() + m_dist.getBeta());
+    }
 } // class Beta
diff --git a/src/beast/math/distributions/ChiSquare.java b/src/beast/math/distributions/ChiSquare.java
index b4b6068..68623cd 100644
--- a/src/beast/math/distributions/ChiSquare.java
+++ b/src/beast/math/distributions/ChiSquare.java
@@ -14,7 +14,7 @@ import beast.core.parameter.IntegerParameter;
         "If the input x is a multidimensional parameter, each of the dimensions is considered as a " +
         "separate independent component.")
 public class ChiSquare extends ParametricDistribution {
-    public Input<IntegerParameter> dfInput = new Input<IntegerParameter>("df", "degrees if freedin, defaults to 1");
+    final public Input<IntegerParameter> dfInput = new Input<>("df", "degrees if freedin, defaults to 1");
 
     static org.apache.commons.math.distribution.ChiSquaredDistribution m_dist = new ChiSquaredDistributionImpl(1);
 
@@ -26,17 +26,18 @@ public class ChiSquare extends ParametricDistribution {
     /**
      * make sure internal state is up to date *
      */
-    void refresh() {
-        int nDF;
+    @SuppressWarnings("deprecation")
+	void refresh() {
+        int dF;
         if (dfInput.get() == null) {
-            nDF = 1;
+            dF = 1;
         } else {
-            nDF = dfInput.get().getValue();
-            if (nDF <= 0) {
-                nDF = 1;
+            dF = dfInput.get().getValue();
+            if (dF <= 0) {
+                dF = 1;
             }
         }
-        m_dist.setDegreesOfFreedom(nDF);
+        m_dist.setDegreesOfFreedom(dF);
     }
 
     @Override
diff --git a/src/beast/math/distributions/Dirichlet.java b/src/beast/math/distributions/Dirichlet.java
index ff31b93..0a8d56b 100644
--- a/src/beast/math/distributions/Dirichlet.java
+++ b/src/beast/math/distributions/Dirichlet.java
@@ -15,10 +15,10 @@ import beast.core.parameter.RealParameter;
 @Description("Dirichlet distribution.  p(x_1,...,x_n;alpha_1,...,alpha_n) = 1/B(alpha) prod_{i=1}^K x_i^{alpha_i - 1} " +
         "where B() is the beta function B(alpha) = prod_{i=1}^K Gamma(alpha_i)/ Gamma(sum_{i=1}^K alpha_i}. ")
 public class Dirichlet extends ParametricDistribution {
-    public Input<RealParameter> alphaInput = new Input<RealParameter>("alpha", "coefficients of the Dirichlet distribution", Validate.REQUIRED);
+    final public Input<RealParameter> alphaInput = new Input<>("alpha", "coefficients of the Dirichlet distribution", Validate.REQUIRED);
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
     }
 
     @Override
@@ -29,8 +29,8 @@ public class Dirichlet extends ParametricDistribution {
     class DirichletImpl implements ContinuousDistribution {
         Double[] m_fAlpha;
 
-        void setAlpha(Double[] fAlpha) {
-            m_fAlpha = fAlpha;
+        void setAlpha(Double[] alpha) {
+            m_fAlpha = alpha;
         }
 
         @Override
@@ -61,22 +61,22 @@ public class Dirichlet extends ParametricDistribution {
 
 
     @Override
-    public double calcLogP(Function pX) throws Exception {
-        Double[] fAlpha = alphaInput.get().getValues();
+    public double calcLogP(Function pX) {
+        Double[] alpha = alphaInput.get().getValues();
         if (alphaInput.get().getDimension() != pX.getDimension()) {
-            throw new Exception("Dimensions of alpha and x should be the same, but dim(alpha)=" + alphaInput.get().getDimension()
+            throw new IllegalArgumentException("Dimensions of alpha and x should be the same, but dim(alpha)=" + alphaInput.get().getDimension()
                     + " and dim(x)=" + pX.getDimension());
         }
-        double fLogP = 0;
-        double fSumAlpha = 0;
+        double logP = 0;
+        double sumAlpha = 0;
         for (int i = 0; i < pX.getDimension(); i++) {
-            double fX = pX.getArrayValue(i);
-            fLogP += (fAlpha[i] - 1) * Math.log(fX);
-            fLogP -= org.apache.commons.math.special.Gamma.logGamma(fAlpha[i]);
-            fSumAlpha += fAlpha[i];
+            double x = pX.getArrayValue(i);
+            logP += (alpha[i] - 1) * Math.log(x);
+            logP -= org.apache.commons.math.special.Gamma.logGamma(alpha[i]);
+            sumAlpha += alpha[i];
         }
-        fLogP += org.apache.commons.math.special.Gamma.logGamma(fSumAlpha);
-        return fLogP;
+        logP += org.apache.commons.math.special.Gamma.logGamma(sumAlpha);
+        return logP;
     }
 
 }
diff --git a/src/beast/math/distributions/Exponential.java b/src/beast/math/distributions/Exponential.java
index 1d7e8f2..313b064 100644
--- a/src/beast/math/distributions/Exponential.java
+++ b/src/beast/math/distributions/Exponential.java
@@ -7,13 +7,14 @@ import org.apache.commons.math.distribution.ExponentialDistributionImpl;
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
 
 
 @Description("Exponential distribution.  f(x;\\lambda) = 1/\\lambda e^{-x/\\lambda}, if x >= 0 " +
         "If the input x is a multidimensional parameter, each of the dimensions is considered as a " +
         "separate independent component.")
 public class Exponential extends ParametricDistribution {
-    public Input<RealParameter> lambdaInpupt = new Input<RealParameter>("mean", "mean parameter, defaults to 1");
+    final public Input<RealParameter> lambdaInput = new Input<>("mean", "mean parameter, defaults to 1");
 
     static org.apache.commons.math.distribution.ExponentialDistribution m_dist = new ExponentialDistributionImpl(1);
 
@@ -25,18 +26,19 @@ public class Exponential extends ParametricDistribution {
     /**
      * make sure internal state is up to date *
      */
-    void refresh() {
-        double fLambda;
-        if (lambdaInpupt.get() == null) {
-            fLambda = 1;
+    @SuppressWarnings("deprecation")
+	void refresh() {
+        double lambda;
+        if (lambdaInput.get() == null) {
+            lambda = 1;
         } else {
-            fLambda = lambdaInpupt.get().getValue();
-            if (fLambda < 0) {
-                System.err.println("Exponential::Lambda should be positive not " + fLambda + ". Assigning default value.");
-                fLambda = 1;
+            lambda = lambdaInput.get().getValue();
+            if (lambda < 0) {
+                Log.err.println("Exponential::Lambda should be positive not " + lambda + ". Assigning default value.");
+                lambda = 1;
             }
         }
-        m_dist.setMean(fLambda);
+        m_dist.setMean(lambda);
     }
 
     @Override
diff --git a/src/beast/math/distributions/Gamma.java b/src/beast/math/distributions/Gamma.java
index 5d946f1..8e06ffc 100644
--- a/src/beast/math/distributions/Gamma.java
+++ b/src/beast/math/distributions/Gamma.java
@@ -8,14 +8,12 @@ import beast.core.Description;
 import beast.core.Input;
 import beast.core.parameter.RealParameter;
 
-
-
- at Description("Gamma distribution.    for x>0  g(x;alpha,beta) = \\frac{beta^{alpha}}{Gamma(alpha)} x^{alpha-1} e^{-beta {x}}" +
+ at Description("Gamma distribution. for x>0  g(x;alpha,beta) = 1/Gamma(alpha) beta^alpha} x^{alpha - 1} e^{-\frac{x}{beta}}" +
         "If the input x is a multidimensional parameter, each of the dimensions is considered as a " +
         "separate independent component.")
 public class Gamma extends ParametricDistribution {
-    public Input<RealParameter> alphaInput = new Input<RealParameter>("alpha", "shape parameter, defaults to 2");
-    public Input<RealParameter> betaInput = new Input<RealParameter>("beta", "scale parameter, defaults to 2");
+    final public Input<RealParameter> alphaInput = new Input<>("alpha", "shape parameter, defaults to 2");
+    final public Input<RealParameter> betaInput = new Input<>("beta", "scale parameter, defaults to 2");
 
     static org.apache.commons.math.distribution.GammaDistribution m_dist = new GammaDistributionImpl(1, 1);
 
@@ -27,21 +25,22 @@ public class Gamma extends ParametricDistribution {
     /**
      * make sure internal state is up to date *
      */
-    void refresh() {
-        double fAlpha;
-        double fBeta;
+    @SuppressWarnings("deprecation")
+	void refresh() {
+        double alpha;
+        double beta;
         if (alphaInput.get() == null) {
-            fAlpha = 2;
+            alpha = 2;
         } else {
-            fAlpha = alphaInput.get().getValue();
+            alpha = alphaInput.get().getValue();
         }
         if (betaInput.get() == null) {
-            fBeta = 2;
+            beta = 2;
         } else {
-            fBeta = betaInput.get().getValue();
+            beta = betaInput.get().getValue();
         }
-        m_dist.setAlpha(fAlpha);
-        m_dist.setBeta(fBeta);
+        m_dist.setAlpha(alpha);
+        m_dist.setBeta(beta);
     }
 
     @Override
@@ -52,6 +51,6 @@ public class Gamma extends ParametricDistribution {
 
     @Override
     public double getMean() {
-    	return offsetInput.get() + m_dist.getAlpha() / m_dist.getBeta();
+    	return offsetInput.get() + m_dist.getAlpha() * m_dist.getBeta();
     }
 } // class Gamma
diff --git a/src/beast/math/distributions/InverseGamma.java b/src/beast/math/distributions/InverseGamma.java
index ec76d70..176210e 100644
--- a/src/beast/math/distributions/InverseGamma.java
+++ b/src/beast/math/distributions/InverseGamma.java
@@ -15,8 +15,8 @@ import beast.core.parameter.RealParameter;
         "If the input x is a multidimensional parameter, each of the dimensions is considered as a " +
         "separate independent component.")
 public class InverseGamma extends ParametricDistribution {
-    public Input<RealParameter> alphaInput = new Input<RealParameter>("alpha", "shape parameter, defaults to 2");
-    public Input<RealParameter> betaInput = new Input<RealParameter>("beta", "scale parameter, defaults to 2");
+    final public Input<RealParameter> alphaInput = new Input<>("alpha", "shape parameter, defaults to 2");
+    final public Input<RealParameter> betaInput = new Input<>("beta", "scale parameter, defaults to 2");
 
     InverseGammaImpl dist = new InverseGammaImpl(2, 2);
 
@@ -29,19 +29,19 @@ public class InverseGamma extends ParametricDistribution {
      * ensure internal state is up to date *
      */
     void refresh() {
-        double fAlpha;
-        double fBeta;
+        double alpha;
+        double beta;
         if (alphaInput.get() == null) {
-            fAlpha = 2;
+            alpha = 2;
         } else {
-            fAlpha = alphaInput.get().getValue();
+            alpha = alphaInput.get().getValue();
         }
         if (betaInput.get() == null) {
-            fBeta = 2;
+            beta = 2;
         } else {
-            fBeta = betaInput.get().getValue();
+            beta = betaInput.get().getValue();
         }
-        dist.setAlphaBeta(fAlpha, fBeta);
+        dist.setAlphaBeta(alpha, beta);
     }
 
     @Override
@@ -56,13 +56,13 @@ public class InverseGamma extends ParametricDistribution {
         // log of the constant beta^alpha/Gamma(alpha)
         double C;
 
-        InverseGammaImpl(double fAlpha, double fBeta) {
-            setAlphaBeta(fAlpha, fBeta);
+        InverseGammaImpl(double alpha, double beta) {
+            setAlphaBeta(alpha, beta);
         }
 
-        void setAlphaBeta(double fAlpha, double fBeta) {
-            m_fAlpha = fAlpha;
-            m_fBeta = fBeta;
+        void setAlphaBeta(double alpha, double beta) {
+            m_fAlpha = alpha;
+            m_fBeta = beta;
             C = m_fAlpha * Math.log(m_fBeta) - org.apache.commons.math.special.Gamma.logGamma(m_fAlpha);
         }
 
@@ -82,17 +82,22 @@ public class InverseGamma extends ParametricDistribution {
         }
 
         @Override
-        public double density(double fX) {
-            double fLogP = logDensity(fX);
-            return Math.exp(fLogP);
+        public double density(double x) {
+            double logP = logDensity(x);
+            return Math.exp(logP);
         }
 
         @Override
-        public double logDensity(double fX) {
-            double fLogP = -(m_fAlpha + 1.0) * Math.log(fX) - (m_fBeta / fX) + C;
-            return fLogP;
+        public double logDensity(double x) {
+            double logP = -(m_fAlpha + 1.0) * Math.log(x) - (m_fBeta / x) + C;
+            return logP;
         }
     } // class OneOnXImpl
 
 
+    @Override
+    public double getMean() {
+    	return betaInput.get().getValue() / (alphaInput.get().getValue() - 1.0);
+    }
+    
 } // class InverseGamma
diff --git a/src/beast/math/distributions/LaplaceDistribution.java b/src/beast/math/distributions/LaplaceDistribution.java
index 5094e01..65ccdce 100644
--- a/src/beast/math/distributions/LaplaceDistribution.java
+++ b/src/beast/math/distributions/LaplaceDistribution.java
@@ -1,13 +1,11 @@
 package beast.math.distributions;
 
-import org.apache.commons.math.distribution.ContinuousDistribution;
-import org.apache.commons.math.distribution.NormalDistributionImpl;
 import org.apache.commons.math.MathException;
+import org.apache.commons.math.distribution.ContinuousDistribution;
 
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.parameter.RealParameter;
-import beast.math.distributions.LogNormalDistributionModel.LogNormalImpl;
 
 @Description("Laplace distribution.    f(x|\\mu,b) = \\frac{1}{2b} \\exp \\left( -\\frac{|x-\\mu|}{b} \\right)" +
         "The probability density function of the Laplace distribution is also reminiscent of the normal distribution; " +
@@ -15,8 +13,8 @@ import beast.math.distributions.LogNormalDistributionModel.LogNormalImpl;
         "the Laplace density is expressed in terms of the absolute difference from the mean. Consequently the Laplace " +
         "distribution has fatter tails than the normal distribution.")
 public class LaplaceDistribution extends ParametricDistribution {
-    public Input<RealParameter> muInput = new Input<RealParameter>("mu", "location parameter, defaults to 0");
-    public Input<RealParameter> scaleInput = new Input<RealParameter>("scale", "scale parameter, defaults to 1");
+    final public Input<RealParameter> muInput = new Input<>("mu", "location parameter, defaults to 0");
+    final public Input<RealParameter> scaleInput = new Input<>("scale", "scale parameter, defaults to 1");
 
     // the mean parameter
     double mu;
@@ -81,15 +79,20 @@ public class LaplaceDistribution extends ParametricDistribution {
         }
 
         @Override
-        public double density(double fX) {
+        public double density(double x) {
             // f(x|\mu,b) = \frac{1}{2b} \exp \left( -\frac{|x-\mu|}{b} \right) \,\!
-            return c * Math.exp(-Math.abs(fX - mu) / scale);
+            return c * Math.exp(-Math.abs(x - mu) / scale);
         }
 
         @Override
-        public double logDensity(double fX) {
-            return Math.log(c) - (Math.abs(fX - mu) / scale);
+        public double logDensity(double x) {
+            return Math.log(c) - (Math.abs(x - mu) / scale);
         }
     } // class LaplaceImpl
+    
+    @Override
+    public double getMean() {
+    	return mu;
+    }
 
 } // class
\ No newline at end of file
diff --git a/src/beast/math/distributions/LogNormalDistributionModel.java b/src/beast/math/distributions/LogNormalDistributionModel.java
index be56932..32620d0 100644
--- a/src/beast/math/distributions/LogNormalDistributionModel.java
+++ b/src/beast/math/distributions/LogNormalDistributionModel.java
@@ -16,14 +16,15 @@ import beast.core.parameter.RealParameter;
  */
 @Description("A log-normal distribution with mean and variance parameters.")
 public class LogNormalDistributionModel extends ParametricDistribution {
-    public Input<RealParameter> MParameterInput = new Input<RealParameter>("M", "M parameter of lognormal distribution. Equal to the mean of the log-transformed distribution.");
-    public Input<RealParameter> SParameterInput = new Input<RealParameter>("S", "S parameter of lognormal distribution. Equal to the standard deviation of the log-transformed distribution.");
-    public Input<Boolean> hasMeanInRealSpaceInput = new Input<Boolean>("meanInRealSpace", "Whether the M parameter is in real space, or in log-transformed space. Default false = log-transformed.", false);
+    final public Input<RealParameter> MParameterInput = new Input<>("M", "M parameter of lognormal distribution. Equal to the mean of the log-transformed distribution.");
+    final public Input<RealParameter> SParameterInput = new Input<>("S", "S parameter of lognormal distribution. Equal to the standard deviation of the log-transformed distribution.");
+    final public Input<Boolean> hasMeanInRealSpaceInput = new Input<>("meanInRealSpace", "Whether the M parameter is in real space, or in log-transformed space. Default false = log-transformed.", false);
 
     boolean hasMeanInRealSpace;
     LogNormalImpl dist = new LogNormalImpl(0, 1);
 
-    public void initAndValidate() throws Exception {
+    @Override
+	public void initAndValidate() {
         hasMeanInRealSpace = hasMeanInRealSpaceInput.get();
         if (MParameterInput.get() != null) {
             if (MParameterInput.get().getLower() == null) {
@@ -49,22 +50,22 @@ public class LogNormalDistributionModel extends ParametricDistribution {
      * make sure internal state is up to date *
      */
     void refresh() {
-        double fMean;
-        double fSigma;
+        double mean;
+        double sigma;
         if (SParameterInput.get() == null) {
-            fSigma = 1;
+            sigma = 1;
         } else {
-            fSigma = SParameterInput.get().getValue();
+            sigma = SParameterInput.get().getValue();
         }
         if (MParameterInput.get() == null) {
-            fMean = 0;
+            mean = 0;
         } else {
-            fMean = MParameterInput.get().getValue();
+            mean = MParameterInput.get().getValue();
         }
         if (hasMeanInRealSpace) {
-            fMean = Math.log(fMean) - (0.5 * fSigma * fSigma);
+            mean = Math.log(mean) - (0.5 * sigma * sigma);
         }
-        dist.setMeanAndStdDev(fMean, fSigma);
+        dist.setMeanAndStdDev(mean, sigma);
     }
 
     @Override
@@ -78,15 +79,16 @@ public class LogNormalDistributionModel extends ParametricDistribution {
         double m_fStdDev;
         NormalDistributionImpl m_normal = new NormalDistributionImpl(0, 1);
 
-        public LogNormalImpl(double fMean, double fStdDev) {
-            setMeanAndStdDev(fMean, fStdDev);
+        public LogNormalImpl(double mean, double stdDev) {
+            setMeanAndStdDev(mean, stdDev);
         }
 
-        void setMeanAndStdDev(double fMean, double fStdDev) {
-            m_fMean = fMean;
-            m_fStdDev = fStdDev;
-            m_normal.setMean(fMean);
-            m_normal.setStandardDeviation(fStdDev);
+        @SuppressWarnings("deprecation")
+		void setMeanAndStdDev(double mean, double stdDev) {
+            m_fMean = mean;
+            m_fStdDev = stdDev;
+            m_normal.setMean(mean);
+            m_normal.setStandardDeviation(stdDev);
         }
 
         @Override
@@ -105,19 +107,19 @@ public class LogNormalDistributionModel extends ParametricDistribution {
         }
 
         @Override
-        public double density(double fX) {
-            if( fX <= 0 ) {
+        public double density(double x) {
+            if( x <= 0 ) {
                 return 0;
             }
-            return m_normal.density(Math.log(fX)) / fX;
+            return m_normal.density(Math.log(x)) / x;
         }
 
         @Override
-        public double logDensity(double fX) {
-            if( fX <= 0 ) {
+        public double logDensity(double x) {
+            if( x <= 0 ) {
                 return  Double.NEGATIVE_INFINITY;
             }
-            return m_normal.logDensity(Math.log(fX)) - Math.log(fX);
+            return m_normal.logDensity(Math.log(x)) - Math.log(x);
         }
     } // class LogNormalImpl
 
@@ -130,7 +132,10 @@ public class LogNormalDistributionModel extends ParametricDistribution {
     			return offsetInput.get();
     		}
     	} else {
-    		throw new RuntimeException("Not implemented yet");
+    		double s = SParameterInput.get().getValue();
+    		double m = MParameterInput.get().getValue();
+    		return Math.exp(m + s * s/2.0);
+    		//throw new RuntimeException("Not implemented yet");
     	}
     }
 }
diff --git a/src/beast/math/distributions/MRCAPrior.java b/src/beast/math/distributions/MRCAPrior.java
index d41c0b2..238c584 100644
--- a/src/beast/math/distributions/MRCAPrior.java
+++ b/src/beast/math/distributions/MRCAPrior.java
@@ -2,13 +2,17 @@ package beast.math.distributions;
 
 
 import java.io.PrintStream;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
 
 import beast.core.Description;
 import beast.core.Distribution;
 import beast.core.Input;
-import beast.core.State;
 import beast.core.Input.Validate;
+import beast.core.State;
 import beast.evolution.alignment.TaxonSet;
 import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
@@ -17,19 +21,19 @@ import beast.evolution.tree.Tree;
 @Description("Prior over set of taxa, useful for defining monophyletic constraints and "
         + "distributions over MRCA times or (sets of) tips of trees")
 public class MRCAPrior extends Distribution {
-    public final Input<Tree> treeInput = new Input<Tree>("tree", "the tree containing the taxon set", Validate.REQUIRED);
-    public final Input<TaxonSet> taxonsetInput = new Input<TaxonSet>("taxonset",
+    public final Input<Tree> treeInput = new Input<>("tree", "the tree containing the taxon set", Validate.REQUIRED);
+    public final Input<TaxonSet> taxonsetInput = new Input<>("taxonset",
             "set of taxa for which prior information is available");
-    public final Input<Boolean> isMonophyleticInput = new Input<Boolean>("monophyletic",
+    public final Input<Boolean> isMonophyleticInput = new Input<>("monophyletic",
             "whether the taxon set is monophyletic (forms a clade without other taxa) or nor. Default is false.", false);
-    public final Input<ParametricDistribution> distInput = new Input<ParametricDistribution>("distr",
+    public final Input<ParametricDistribution> distInput = new Input<>("distr",
             "distribution used to calculate prior over MRCA time, "
                     + "e.g. normal, beta, gamma. If not specified, monophyletic must be true");
-    public final Input<Boolean> onlyUseTipsInput = new Input<Boolean>("tipsonly",
+    public final Input<Boolean> onlyUseTipsInput = new Input<>("tipsonly",
             "flag to indicate tip dates are to be used instead of the MRCA node. " +
                     "If set to true, the prior is applied to the height of all tips in the taxonset " +
                     "and the monophyletic flag is ignored. Default is false.", false);
-    public final Input<Boolean> useOriginateInput = new Input<Boolean>("useOriginate", "Use parent of clade instead of clade. Cannot be used with tipsonly, or on the root.", false);
+    public final Input<Boolean> useOriginateInput = new Input<>("useOriginate", "Use parent of clade instead of clade. Cannot be used with tipsonly, or on the root.", false);
 
     /**
      * shadow members *
@@ -49,17 +53,18 @@ public class MRCAPrior extends Distribution {
     // flag indicating taxon set is monophyletic
     boolean isMonophyletic = false;
     boolean onlyUseTips = false;
+    boolean useRoot = false;
     boolean useOriginate = false;
     
     boolean initialised = false;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         dist = distInput.get();
         tree = treeInput.get();
-        final List<String> sTaxaNames = new ArrayList<>();
-        for (final String sTaxon : tree.getTaxaNames()) {
-            sTaxaNames.add(sTaxon);
+        final List<String> taxaNames = new ArrayList<>();
+        for (final String taxon : tree.getTaxaNames()) {
+            taxaNames.add(taxon);
         }
         // determine nr of taxa in taxon set
         List<String> set = null;
@@ -68,7 +73,7 @@ public class MRCAPrior extends Distribution {
             nrOfTaxa = set.size();
         } else {
             // assume all taxa
-            nrOfTaxa = sTaxaNames.size();
+            nrOfTaxa = taxaNames.size();
         }
 
         onlyUseTips = onlyUseTipsInput.get();
@@ -80,29 +85,30 @@ public class MRCAPrior extends Distribution {
         	}
         }
         if (!onlyUseTips && !useOriginate && nrOfTaxa < 2) {
-            throw new Exception("At least two taxa are required in a taxon set");
+            throw new IllegalArgumentException("At least two taxa are required in a taxon set");
         }
         if (!onlyUseTips && taxonsetInput.get() == null) {
-            throw new Exception("Taxonset must be specified OR tipsonly be set to true");
+            throw new IllegalArgumentException("Taxonset must be specified OR tipsonly be set to true");
         }
         
        
         if (useOriginate && onlyUseTips) {
-        	throw new Exception("'useOriginate' and 'tipsOnly' cannot be both true");
+        	throw new IllegalArgumentException("'useOriginate' and 'tipsOnly' cannot be both true");
         }
-        if (useOriginate && nrOfTaxa == tree.getLeafNodeCount()) {
-        	throw new Exception("Cannot use originate of root. You can set useOriginate to false to fix this");
+        useRoot = nrOfTaxa == tree.getLeafNodeCount();
+        if (useOriginate && useRoot) {
+        	throw new IllegalArgumentException("Cannot use originate of root. You can set useOriginate to false to fix this");
         }
-
+        initialised = false;
     }
 
     boolean [] nodesTraversed;
     int nseen;
 
-    private Node getCommonAncestor(Node n1, Node n2) {
+    protected Node getCommonAncestor(Node n1, Node n2) {
         // assert n1.getTree() == n2.getTree();
         if( ! nodesTraversed[n1.getNr()] ) {
-           nodesTraversed[n1.getNr()] = true;
+            nodesTraversed[n1.getNr()] = true;
             nseen += 1;
         }
         if( ! nodesTraversed[n2.getNr()] ) {
@@ -110,19 +116,55 @@ public class MRCAPrior extends Distribution {
             nseen += 1;
         }
         while (n1 != n2) {
-            if (n1.getHeight() < n2.getHeight()) {
-                n1 = n1.getParent();
-                if( ! nodesTraversed[n1.getNr()] ) {
-                    nodesTraversed[n1.getNr()] = true;
-                    nseen += 1;
+	        double h1 = n1.getHeight();
+	        double h2 = n2.getHeight();
+	        if ( h1 < h2 ) {
+	            n1 = n1.getParent();
+	            if( ! nodesTraversed[n1.getNr()] ) {
+	                nodesTraversed[n1.getNr()] = true;
+	                nseen += 1;
+	            }
+	        } else if( h2 < h1 ) {
+	            n2 = n2.getParent();
+	            if( ! nodesTraversed[n2.getNr()] ) {
+	                nodesTraversed[n2.getNr()] = true;
+	                nseen += 1;
+	            }
+	        } else {
+	            //zero length branches hell
+	            Node n;
+	            double b1 = n1.getLength();
+	            double b2 = n2.getLength();
+	            if( b1 > 0 ) {
+	                n = n2;
+	            } else { // b1 == 0
+	                if( b2 > 0 ) {
+	                    n = n1;
+	                } else {
+	                    // both 0
+	                    n = n1;
+	                    while( n != null && n != n2 ) {
+	                        n = n.getParent();
+	                    }
+	                    if( n == n2 ) {
+	                        // n2 is an ancestor of n1
+	                        n = n1;
+	                    } else {
+	                        // always safe to advance n2
+	                        n = n2;
+	                    }
+	                }
+	            }
+	            if( n == n1 ) {
+                    n = n1 = n.getParent();
+                } else {
+                    n = n2 = n.getParent();
                 }
-            } else {
-                n2 = n2.getParent();
-                if( ! nodesTraversed[n2.getNr()] ) {
-                     nodesTraversed[n2.getNr()] = true;
-                     nseen += 1;
-                 }
-            }
+	            if( ! nodesTraversed[n.getNr()] ) {
+	                nodesTraversed[n.getNr()] = true;
+	                nseen += 1;
+	            } 
+	        }
         }
         return n1;
     }
@@ -141,7 +183,7 @@ public class MRCAPrior extends Distribution {
     }
 
     @Override
-    public double calculateLogP() throws Exception {
+    public double calculateLogP() {
     	if (!initialised) {
     		initialise();
     	}
@@ -156,21 +198,41 @@ public class MRCAPrior extends Distribution {
                 logP += dist.logDensity(MRCATime);
             }
             return logP;
+        } else if (useRoot) {
+        	if (dist != null) {
+                MRCATime = tree.getRoot().getDate();
+                logP += dist.logDensity(MRCATime);
+        	}
+    		return logP;
         } else {
             // internal node
             if( false) {
                 calcMRCAtime(tree.getRoot(), new int[1]);
             } else {
-                nodesTraversed = new boolean[tree.getNodeCount()];
-                nseen = 0;
-                final Node m = getCommonAncestor();
-                MRCATime = m.getDate();
-                isMonophyletic = nseen == 2 * taxonIndex.length - 1;
+            	Node m;
+            	if (taxonIndex.length == 1) {
+            		isMonophyletic = true;
+            		m = tree.getNode(taxonIndex[0]);
+            	} else {
+	                nodesTraversed = new boolean[tree.getNodeCount()];
+	                nseen = 0;
+                	m = getCommonAncestor();
+	                isMonophyletic = (nseen == 2 * taxonIndex.length - 1);
+            	}
+            	if (useOriginate) {
+            		if (!m.isRoot()) {
+            			MRCATime = m.getParent().getDate();
+            		} else {
+            			MRCATime = m.getDate();
+            		}
+            	} else {
+            		MRCATime = m.getDate();
+            	}
             }
         }
         if (isMonophyleticInput.get() && !isMonophyletic) {
-            logP = Double.NEGATIVE_INFINITY;
-            return Double.NEGATIVE_INFINITY;
+    		logP = Double.NEGATIVE_INFINITY;
+    		return Double.NEGATIVE_INFINITY;
         }
         if (dist != null) {
             logP = dist.logDensity(MRCATime); // - dist.offsetInput.get());
@@ -178,38 +240,39 @@ public class MRCAPrior extends Distribution {
         return logP;
     }
 
-    private void initialise() {
+    protected void initialise() {
         // determine which taxa are in the set
     	
         List<String> set = null;
         if (taxonsetInput.get() != null) {
             set = taxonsetInput.get().asStringList();
         }
-        final List<String> sTaxaNames = new ArrayList<>();
-        for (final String sTaxon : tree.getTaxaNames()) {
-            sTaxaNames.add(sTaxon);
+        final List<String> taxaNames = new ArrayList<>();
+        for (final String taxon : tree.getTaxaNames()) {
+            taxaNames.add(taxon);
         }
 
         taxonIndex = new int[nrOfTaxa];
         if ( set != null )  {  // m_taxonset.get() != null) {
             isInTaxaSet.clear();
             int k = 0;
-            for (final String sTaxon : set) {
-                final int iTaxon = sTaxaNames.indexOf(sTaxon);
-                if (iTaxon < 0) {
-                    throw new RuntimeException("Cannot find taxon " + sTaxon + " in data");
+            for (final String taxon : set) {
+                final int taxonIndex_ = taxaNames.indexOf(taxon);
+                if (taxonIndex_ < 0) {
+                    throw new RuntimeException("Cannot find taxon " + taxon + " in data");
                 }
-                if (isInTaxaSet.contains(sTaxon)) {
-                    throw new RuntimeException("Taxon " + sTaxon + " is defined multiple times, while they should be unique");
+                if (isInTaxaSet.contains(taxon)) {
+                    throw new RuntimeException("Taxon " + taxon + " is defined multiple times, while they should be unique");
                 }
-                isInTaxaSet.add(sTaxon);
-                taxonIndex[k++] = iTaxon;
+                isInTaxaSet.add(taxon);
+                taxonIndex[k++] = taxonIndex_;
             }
         } else {
             for (int i = 0; i < nrOfTaxa; i++) {
                 taxonIndex[i] = i;
             }
         }
+        initialised = true;
  	}
 
 	/**
@@ -217,24 +280,24 @@ public class MRCAPrior extends Distribution {
      * set. When all taxa in the set are visited, record the time.
      * *
      * @param node
-     * @param nTaxonCount
+     * @param taxonCount2
      */
-    int calcMRCAtime(final Node node, final int[] nTaxonCount) {
+    int calcMRCAtime(final Node node, final int[] taxonCount2) {
         if (node.isLeaf()) {
-            nTaxonCount[0]++;
+            taxonCount2[0]++;
             if (isInTaxaSet.contains(node.getID())) {
                 return 1;
             } else {
                 return 0;
             }
         } else {
-            int taxonCount = calcMRCAtime(node.getLeft(), nTaxonCount);
-            final int nLeftTaxa = nTaxonCount[0];
-            nTaxonCount[0] = 0;
+            int taxonCount = calcMRCAtime(node.getLeft(), taxonCount2);
+            final int leftTaxa = taxonCount2[0];
+            taxonCount2[0] = 0;
             if (node.getRight() != null) {
-                taxonCount += calcMRCAtime(node.getRight(), nTaxonCount);
-                final int nRightTaxa = nTaxonCount[0];
-                nTaxonCount[0] = nLeftTaxa + nRightTaxa;
+                taxonCount += calcMRCAtime(node.getRight(), taxonCount2);
+                final int rightTaxa = taxonCount2[0];
+                taxonCount2[0] = leftTaxa + rightTaxa;
                 if (taxonCount == nrOfTaxa) {
                 	if (nrOfTaxa == 1 && useOriginate) {
             			MRCATime = node.getDate();
@@ -252,7 +315,7 @@ public class MRCAPrior extends Distribution {
                 	} else {
                 		MRCATime = node.getDate();
                 	}
-                    isMonophyletic = (nTaxonCount[0] == nrOfTaxa);
+                    isMonophyletic = (taxonCount2[0] == nrOfTaxa);
                     return taxonCount + 1;
                 }
             }
@@ -285,7 +348,7 @@ public class MRCAPrior extends Distribution {
      * Loggable interface implementation follows *
      */
     @Override
-    public void init(final PrintStream out) throws Exception {
+    public void init(final PrintStream out) {
     	if (!initialised) {
     		initialise();
     	}
@@ -308,7 +371,7 @@ public class MRCAPrior extends Distribution {
     }
 
     @Override
-    public void log(final int nSample, final PrintStream out) {
+    public void log(final int sample, final PrintStream out) {
         if (onlyUseTips) {
             if (dist != null) {
                 out.print(getCurrentLogP() + "\t");
@@ -355,7 +418,7 @@ public class MRCAPrior extends Distribution {
     }
 
     @Override
-    public double getArrayValue(final int iDim) {
+    public double getArrayValue(final int dim) {
     	if (Double.isNaN(logP)) {
     		try {
     			calculateLogP();
@@ -363,7 +426,7 @@ public class MRCAPrior extends Distribution {
     			logP  = Double.NaN;
     		}
     	}
-        switch (iDim) {
+        switch (dim) {
             case 0:
                 return logP;
             case 1:
diff --git a/src/beast/math/distributions/MarkovChainDistribution.java b/src/beast/math/distributions/MarkovChainDistribution.java
index b8301f8..7541183 100644
--- a/src/beast/math/distributions/MarkovChainDistribution.java
+++ b/src/beast/math/distributions/MarkovChainDistribution.java
@@ -10,8 +10,8 @@ import org.apache.commons.math.distribution.GammaDistributionImpl;
 import beast.core.Description;
 import beast.core.Distribution;
 import beast.core.Input;
-import beast.core.State;
 import beast.core.Input.Validate;
+import beast.core.State;
 import beast.core.parameter.RealParameter;
 import beast.math.distributions.LogNormalDistributionModel.LogNormalImpl;
 
@@ -27,13 +27,13 @@ import beast.math.distributions.LogNormalDistributionModel.LogNormalImpl;
         "Handy for population parameters. ")
 public class MarkovChainDistribution extends Distribution {
 
-    public Input<Boolean> isJeffreysInput = new Input<Boolean>("jeffreys", "use Jeffrey's prior (default false)", false);
-    public Input<Boolean> isReverseInput = new Input<Boolean>("reverse", "parameter in reverse (default false)", false);
-    public Input<Boolean> useLogInput = new Input<Boolean>("uselog", "use logarithm of parameter values (default false)", false);
-    public Input<Double> shapeInput = new Input<Double>("shape", "shape parameter of the Gamma distribution (default 1.0 = exponential distribution) " +
+    final public Input<Boolean> isJeffreysInput = new Input<>("jeffreys", "use Jeffrey's prior (default false)", false);
+    final public Input<Boolean> isReverseInput = new Input<>("reverse", "parameter in reverse (default false)", false);
+    final public Input<Boolean> useLogInput = new Input<>("uselog", "use logarithm of parameter values (default false)", false);
+    final public Input<Double> shapeInput = new Input<>("shape", "shape parameter of the Gamma distribution (default 1.0 = exponential distribution) " +
     		" or precision parameter if the log normal is used.", 1.0);
-    public Input<RealParameter> parameterInput = new Input<RealParameter>("parameter", "chain parameter to calculate distribution over", Validate.REQUIRED);
-    public Input<Boolean> useLogNormalInput = new Input<Boolean>("useLogNormal", "use Log Normal distribution instead of Gamma (default false)", false);
+    final public Input<RealParameter> parameterInput = new Input<>("parameter", "chain parameter to calculate distribution over", Validate.REQUIRED);
+    final public Input<Boolean> useLogNormalInput = new Input<>("useLogNormal", "use Log Normal distribution instead of Gamma (default false)", false);
 
     // **************************************************************
     // Private instance variables
@@ -48,7 +48,7 @@ public class MarkovChainDistribution extends Distribution {
     boolean useLogNormal;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         reverse = isReverseInput.get();
         jeffreys = isJeffreysInput.get();
         uselog = useLogInput.get();
@@ -65,8 +65,9 @@ public class MarkovChainDistribution extends Distribution {
      *
      * @return the log likelihood.
      */
-    @Override
-    public double calculateLogP() throws Exception {
+    @SuppressWarnings("deprecation")
+	@Override
+    public double calculateLogP() {
         logP = 0.0;
         // jeffreys Prior!
         if (jeffreys) {
diff --git a/src/beast/math/distributions/Normal.java b/src/beast/math/distributions/Normal.java
index 7d36ebc..423b68e 100644
--- a/src/beast/math/distributions/Normal.java
+++ b/src/beast/math/distributions/Normal.java
@@ -15,9 +15,9 @@ import beast.core.parameter.RealParameter;
         "If the input x is a multidimensional parameter, each of the dimensions is considered as a " +
         "separate independent component.")
 public class Normal extends ParametricDistribution {
-    public Input<RealParameter> meanInput = new Input<RealParameter>("mean", "mean of the normal distribution, defaults to 0");
-    public Input<RealParameter> sigmaInput = new Input<RealParameter>("sigma", "variance of the normal distribution, defaults to 1");
-    public Input<RealParameter> tauInput = new Input<RealParameter>("tau", "precission of the normal distribution, defaults to 1", Validate.XOR, sigmaInput);
+    final public Input<RealParameter> meanInput = new Input<>("mean", "mean of the normal distribution, defaults to 0");
+    final public Input<RealParameter> sigmaInput = new Input<>("sigma", "variance of the normal distribution, defaults to 1");
+    final public Input<RealParameter> tauInput = new Input<>("tau", "precission of the normal distribution, defaults to 1", Validate.XOR, sigmaInput);
 
     static org.apache.commons.math.distribution.NormalDistribution dist = new NormalDistributionImpl(0, 1);
 
@@ -29,25 +29,26 @@ public class Normal extends ParametricDistribution {
     /**
      * make sure internal state is up to date *
      */
-    void refresh() {
-        double fMean;
-        double fSigma;
+    @SuppressWarnings("deprecation")
+	void refresh() {
+        double mean;
+        double sigma;
         if (meanInput.get() == null) {
-            fMean = 0;
+            mean = 0;
         } else {
-            fMean = meanInput.get().getValue();
+            mean = meanInput.get().getValue();
         }
         if (sigmaInput.get() == null) {
         	if (tauInput.get() == null) {
-        		fSigma = 1;
+        		sigma = 1;
         	} else {
-                fSigma = Math.sqrt(1.0/tauInput.get().getValue());
+                sigma = Math.sqrt(1.0/tauInput.get().getValue());
         	}
         } else {
-            fSigma = sigmaInput.get().getValue();
+            sigma = sigmaInput.get().getValue();
         }
-        dist.setMean(fMean);
-        dist.setStandardDeviation(fSigma);
+        dist.setMean(mean);
+        dist.setStandardDeviation(sigma);
     }
 
     @Override
diff --git a/src/beast/math/distributions/ParametricDistribution.java b/src/beast/math/distributions/ParametricDistribution.java
index a27e3a7..cbc7999 100644
--- a/src/beast/math/distributions/ParametricDistribution.java
+++ b/src/beast/math/distributions/ParametricDistribution.java
@@ -48,7 +48,7 @@ import beast.util.Randomizer;
         "parameters/valuables as inputs and can produce (cumulative) densities and inverse " +
         "cumulative densities.")
 public abstract class ParametricDistribution extends CalculationNode implements ContinuousDistribution {
-    public final Input<Double> offsetInput = new Input<Double>("offset", "offset of origin (defaults to 0)", 0.0);
+    public final Input<Double> offsetInput = new Input<>("offset", "offset of origin (defaults to 0)", 0.0);
 
     abstract public org.apache.commons.math.distribution.Distribution getDistribution();
 
@@ -57,22 +57,22 @@ public abstract class ParametricDistribution extends CalculationNode implements
      * If x is multidimensional, the components of x are assumed to be independent,
      * so the sum of log probabilities of all elements of x is returned as the prior.
      */
-    public double calcLogP(final Function x) throws Exception {
-        final double fOffset = offsetInput.get();
-        double fLogP = 0;
-        for (int i = 0; i < x.getDimension(); i++) {
-            final double fX = x.getArrayValue(i);
-            //fLogP += Math.log(density(fX));
-            fLogP += logDensity(fX, fOffset);
+    public double calcLogP(final Function fun) {
+        final double offset = offsetInput.get();
+        double logP = 0;
+        for (int i = 0; i < fun.getDimension(); i++) {
+            final double x = fun.getArrayValue(i);
+            //logP += Math.log(density(x));
+            logP += logDensity(x, offset);
         }
-        return fLogP;
+        return logP;
     }
 
     /*
      * This implementation is only suitable for univariate distributions.
      * Must be overwritten for multivariate ones.
      */
-    public Double[][] sample(final int size) throws Exception {
+    public Double[][] sample(final int size) throws MathException {
         final Double[][] sample = new Double[size][];
         for (int i = 0; i < sample.length; i++) {
             final double p = Randomizer.nextDouble();
@@ -91,7 +91,8 @@ public abstract class ParametricDistribution extends CalculationNode implements
      *                       computed due to convergence or other numerical errors.
      */
     //@Override
-    public double inverseCumulativeProbability(final double p) throws MathException {
+    @Override
+	public double inverseCumulativeProbability(final double p) throws MathException {
         final org.apache.commons.math.distribution.Distribution dist = getDistribution();
         double offset = getOffset();
         if (dist instanceof ContinuousDistribution) {
@@ -110,7 +111,8 @@ public abstract class ParametricDistribution extends CalculationNode implements
      * @return The pdf at point x.
      */
     //@Override
-    public double density(double x) {
+    @Override
+	public double density(double x) {
         final double offset = getOffset();
  //       if( x >= offset ) {
             x -= offset;
@@ -141,7 +143,8 @@ public abstract class ParametricDistribution extends CalculationNode implements
     }
 
     //@Override
-    public double logDensity(final double x) {
+    @Override
+	public double logDensity(final double x) {
         return logDensity(x, getOffset());
     }
 
@@ -158,7 +161,8 @@ public abstract class ParametricDistribution extends CalculationNode implements
      *                       computed due to convergence or other numerical errors.
      */
     //@Override
-    public double cumulativeProbability(final double x) throws MathException {
+    @Override
+	public double cumulativeProbability(final double x) throws MathException {
         return getDistribution().cumulativeProbability(x);
     }
 
@@ -176,7 +180,8 @@ public abstract class ParametricDistribution extends CalculationNode implements
      * @throws IllegalArgumentException if <code>x0 > x1</code>
      */
     //@Override
-    public double cumulativeProbability(final double x0, final double x1) throws MathException {
+    @Override
+	public double cumulativeProbability(final double x0, final double x1) throws MathException {
         return getDistribution().cumulativeProbability(x0, x1);
     }
 
diff --git a/src/beast/math/distributions/Poisson.java b/src/beast/math/distributions/Poisson.java
index 09659fb..2c61dcb 100644
--- a/src/beast/math/distributions/Poisson.java
+++ b/src/beast/math/distributions/Poisson.java
@@ -1,18 +1,18 @@
 package beast.math.distributions;
 
 
+import org.apache.commons.math.distribution.PoissonDistributionImpl;
+
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.parameter.RealParameter;
-import org.apache.commons.math.distribution.IntegerDistribution;
-import org.apache.commons.math.distribution.PoissonDistributionImpl;
 
 
 @Description("Poisson distribution, used as prior  f(k; lambda)=\\frac{lambda^k e^{-lambda}}{k!}  " +
         "If the input x is a multidimensional parameter, each of the dimensions is considered as a " +
         "separate independent component.")
 public class Poisson extends ParametricDistribution {
-    public Input<RealParameter> lambdaInput = new Input<RealParameter>("lambda", "rate parameter, defaults to 1");
+    final public Input<RealParameter> lambdaInput = new Input<>("lambda", "rate parameter, defaults to 1");
 
     static org.apache.commons.math.distribution.PoissonDistribution dist = new PoissonDistributionImpl(1);
 
@@ -39,7 +39,8 @@ public class Poisson extends ParametricDistribution {
     /**
      * make sure internal state is up to date *
      */
-    void refresh() {
+    @SuppressWarnings("deprecation")
+	void refresh() {
         double m_fLambda;
         if (lambdaInput.get() == null) {
             m_fLambda = 1;
@@ -58,4 +59,9 @@ public class Poisson extends ParametricDistribution {
         return dist;
     }
     
+    @Override
+    public double getMean() {
+    	return lambdaInput.get().getValue();
+    }
+    
 } // class Poisson
diff --git a/src/beast/math/distributions/Prior.java b/src/beast/math/distributions/Prior.java
index bda873a..0aa697f 100644
--- a/src/beast/math/distributions/Prior.java
+++ b/src/beast/math/distributions/Prior.java
@@ -4,8 +4,13 @@ package beast.math.distributions;
 import java.util.List;
 import java.util.Random;
 
-import beast.core.*;
+import beast.core.BEASTObject;
+import beast.core.Description;
+import beast.core.Distribution;
+import beast.core.Function;
+import beast.core.Input;
 import beast.core.Input.Validate;
+import beast.core.State;
 import beast.core.parameter.IntegerParameter;
 import beast.core.parameter.RealParameter;
 
@@ -14,8 +19,8 @@ import beast.core.parameter.RealParameter;
         "If x is multidimensional, the components of x are assumed to be independent, " +
         "so the sum of log probabilities of all elements of x is returned as the prior.")
 public class Prior extends Distribution {
-    public Input<Function> m_x = new Input<Function>("x", "point at which the density is calculated", Validate.REQUIRED);
-    public Input<ParametricDistribution> distInput = new Input<ParametricDistribution>("distr", "distribution used to calculate prior, e.g. normal, beta, gamma.", Validate.REQUIRED);
+    final public Input<Function> m_x = new Input<>("x", "point at which the density is calculated", Validate.REQUIRED);
+    final public Input<ParametricDistribution> distInput = new Input<>("distr", "distribution used to calculate prior, e.g. normal, beta, gamma.", Validate.REQUIRED);
 
     /**
      * shadows m_distInput *
@@ -23,13 +28,13 @@ public class Prior extends Distribution {
     protected ParametricDistribution dist;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         dist = distInput.get();
         calculateLogP();
     }
 
     @Override
-    public double calculateLogP() throws Exception {
+    public double calculateLogP() {
         Function x = m_x.get();
         if (x instanceof RealParameter || x instanceof IntegerParameter) {
         	// test that parameter is inside its bounds
diff --git a/src/beast/math/distributions/Uniform.java b/src/beast/math/distributions/Uniform.java
index 5e60e4b..555b157 100644
--- a/src/beast/math/distributions/Uniform.java
+++ b/src/beast/math/distributions/Uniform.java
@@ -11,8 +11,8 @@ import beast.core.Input;
 
 @Description("Uniform distribution over a given interval (including lower and upper values)")
 public class Uniform extends ParametricDistribution {
-    public Input<Double> lowerInput = new Input<Double>("lower", "lower bound on the interval, default 0", 0.0);
-    public Input<Double> upperInput = new Input<Double>("upper", "lower bound on the interval, default 1", 1.0);
+    final public Input<Double> lowerInput = new Input<>("lower", "lower bound on the interval, default 0", 0.0);
+    final public Input<Double> upperInput = new Input<>("upper", "lower bound on the interval, default 1", 1.0);
 
     UniformImpl distr = new UniformImpl();
 
@@ -21,11 +21,11 @@ public class Uniform extends ParametricDistribution {
     private boolean infiniteSupport;
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
         _lower = lowerInput.get();
         _upper = upperInput.get();
         if (_lower >= _upper) {
-            throw new Exception("Upper value should be higher than lower value");
+            throw new IllegalArgumentException("Upper value should be higher than lower value");
         }
         distr.setBounds(_lower, _upper);
         infiniteSupport = Double.isInfinite(_lower) || Double.isInfinite(_upper);
diff --git a/src/beast/math/statistic/DiscreteStatistics.java b/src/beast/math/statistic/DiscreteStatistics.java
index 0ef7e73..9005a83 100644
--- a/src/beast/math/statistic/DiscreteStatistics.java
+++ b/src/beast/math/statistic/DiscreteStatistics.java
@@ -53,7 +53,7 @@ public class DiscreteStatistics {
             }
         }
 
-        return m / (double) count;
+        return m / count;
     }
 
     /**
@@ -139,7 +139,7 @@ public class DiscreteStatistics {
             count = count - 1; // for ML estimate
         }
 
-        return var / (double) count;
+        return var / count;
     }
 
 
@@ -239,7 +239,7 @@ public class DiscreteStatistics {
      * @return variance of x (ML estimator)
      */
     public static double varianceSampleMean(double[] x, double mean) {
-        return variance(x, mean) / (double) x.length;
+        return variance(x, mean) / x.length;
     }
 
     /**
@@ -249,7 +249,7 @@ public class DiscreteStatistics {
      * @return variance of x (ML estimator)
      */
     public static double varianceSampleMean(double[] x) {
-        return variance(x) / (double) x.length;
+        return variance(x) / x.length;
     }
 
 
@@ -319,7 +319,7 @@ public class DiscreteStatistics {
         double minRange = Double.MAX_VALUE;
         int hpdIndex = 0;
 
-        final int diff = (int) Math.round(proportion * (double) x.length);
+        final int diff = (int) Math.round(proportion * x.length);
         for (int i = 0; i <= (x.length - diff); i++) {
             final double minValue = x[indices[i]];
             final double maxValue = x[indices[i + diff - 1]];
@@ -389,6 +389,6 @@ public class DiscreteStatistics {
             gm += Math.log(x[i]);
         }
 
-        return Math.exp(gm / (double) len);
+        return Math.exp(gm / len);
     }
 }
diff --git a/src/beast/math/statistic/RPNcalculator.java b/src/beast/math/statistic/RPNcalculator.java
index 2decd81..7c7d56d 100644
--- a/src/beast/math/statistic/RPNcalculator.java
+++ b/src/beast/math/statistic/RPNcalculator.java
@@ -2,13 +2,17 @@ package beast.math.statistic;
 
 
 
-import java.util.Map;
-import java.util.List;
-import java.util.HashMap;
-import java.util.ArrayList;
 import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
-import beast.core.*;
+import beast.core.CalculationNode;
+import beast.core.Description;
+import beast.core.Function;
+import beast.core.Input;
+import beast.core.Loggable;
 import beast.core.parameter.Parameter;
 
 
@@ -24,29 +28,30 @@ import beast.core.parameter.Parameter;
 public class RPNcalculator extends CalculationNode implements Loggable, Function {
 
 
-    public Input<String> strExpressionInput = new Input<String>("expression", "Expressions needed for the calculations", Input.Validate.REQUIRED);
-    public Input<List<Parameter>> parametersInput = new Input<List<Parameter>>("parameter", "Parameters needed for the calculations", new ArrayList<Parameter>());
+    final public Input<String> strExpressionInput = new Input<>("expression", "Expressions needed for the calculations", Input.Validate.REQUIRED);
+    final public Input<List<Parameter<?>>> parametersInput = new Input<>("parameter", "Parameters needed for the calculations", new ArrayList<>());
 
     private RPNexpressionCalculator[] expressions;
     private List<String> names;
 
-    private Map variables;
+    private Map<String, Object[]> variables;
     RPNexpressionCalculator.GetVariable[] vars;
     int dim;
 
-    public void initAndValidate() throws Exception {
+    @Override
+	public void initAndValidate() {
 
-        names = new ArrayList<String>();
+        names = new ArrayList<>();
         dim = parametersInput.get().get(0).getDimension();
 
         int pdim;
 
-        for (final Parameter p : parametersInput.get()) {
+        for (final Parameter<?> p : parametersInput.get()) {
 
             pdim = p.getDimension();
 
             if (pdim != dim && dim != 1 && pdim != 1) {
-                throw new Exception("error: all parameters have to have same length or be of dimension 1.");
+                throw new IllegalArgumentException("error: all parameters have to have same length or be of dimension 1.");
             }
             if (pdim > dim) dim = pdim;
 
@@ -55,7 +60,7 @@ public class RPNcalculator extends CalculationNode implements Loggable, Function
 
             for (int i = 0; i < pdim; i++) {
 
-                variables = new HashMap<String, Double[]>();
+                variables = new HashMap<>();
 
                 variables.put(p.getID(), p.getValues());
             }
@@ -66,11 +71,12 @@ public class RPNcalculator extends CalculationNode implements Loggable, Function
         for (int i = 0; i < dim; i++) {
             final int index = i;
             vars[i] = new RPNexpressionCalculator.GetVariable() {
-                public double get(final String name) {
-                    final Object[] values = ((Object[]) variables.get(name));
+                @Override
+				public double get(final String name) {
+                    final Object[] values = (variables.get(name));
                     if (values == null) {
                     	String ids = "";
-                        for (final Parameter p : parametersInput.get()) {
+                        for (final Parameter<?> p : parametersInput.get()) {
                     		ids += p.getID() +", ";
                     	}
                     	if (parametersInput.get().size() > 0) {
@@ -102,14 +108,15 @@ public class RPNcalculator extends CalculationNode implements Loggable, Function
     }
 
     private void updateValues() {
-        for (Parameter p : parametersInput.get()) {
+        for (Parameter<?> p : parametersInput.get()) {
             for (int i = 0; i < p.getDimension(); i++) {
                 variables.put(p.getID(), p.getValues());
             }
         }
     }
 
-    public int getDimension() {
+    @Override
+	public int getDimension() {
         return dim;
     }
 
@@ -139,7 +146,7 @@ public class RPNcalculator extends CalculationNode implements Loggable, Function
 
 
     @Override
-    public void init(final PrintStream out) throws Exception {
+    public void init(final PrintStream out) {
         if (dim == 1)
             out.print(this.getID() + "\t");
         else
@@ -148,7 +155,7 @@ public class RPNcalculator extends CalculationNode implements Loggable, Function
     }
 
     @Override
-    public void log(final int nSample, final PrintStream out) {
+    public void log(final int sample, final PrintStream out) {
         for (int i = 0; i < dim; i++)
             out.print(getStatisticValue(i) + "\t");
     }
@@ -159,8 +166,8 @@ public class RPNcalculator extends CalculationNode implements Loggable, Function
     }
 
     public List<String> getArguments() {
-        final List<String> arguments = new ArrayList<String>();
-        for (final Parameter par : parametersInput.get()) {
+        final List<String> arguments = new ArrayList<>();
+        for (final Parameter<?> par : parametersInput.get()) {
             arguments.add(par.getID());
         }
         return arguments;
diff --git a/src/beast/math/statistic/RPNexpressionCalculator.java b/src/beast/math/statistic/RPNexpressionCalculator.java
index 71e4cb0..626c6ca 100644
--- a/src/beast/math/statistic/RPNexpressionCalculator.java
+++ b/src/beast/math/statistic/RPNexpressionCalculator.java
@@ -93,7 +93,7 @@ public class RPNexpressionCalculator {
      * @return evaluate expression given context (i.e. variables)
      */
     public double evaluate(GetVariable variables) {
-        Stack<Double> stack = new Stack<Double>();
+        Stack<Double> stack = new Stack<>();
 
         for (Eelement elem : expression) {
             switch (elem.op) {
diff --git a/src/beast/util/AddOnManager.java b/src/beast/util/AddOnManager.java
index 962319c..3132022 100644
--- a/src/beast/util/AddOnManager.java
+++ b/src/beast/util/AddOnManager.java
@@ -31,26 +31,6 @@
 package beast.util;
 
 
-import beast.app.BEASTVersion;
-import beast.app.beastapp.BeastMain;
-import beast.app.util.Arguments;
-import beast.app.util.Utils;
-import beast.core.Description;
-import beast.core.util.Log;
-import beast.evolution.alignment.Alignment;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import javax.swing.*;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
 import java.io.*;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
@@ -63,11 +43,29 @@ import java.util.*;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
 import java.util.jar.JarInputStream;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 import java.util.zip.ZipEntry;
 import java.util.zip.ZipFile;
 
+import javax.swing.JOptionPane;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import beast.app.BEASTVersion;
+import beast.app.beastapp.BeastMain;
+import beast.app.util.Arguments;
+import beast.app.util.Utils;
+import beast.core.Description;
+import beast.core.util.Log;
+import beast.evolution.alignment.Alignment;
+
 /**
  * This class is used to manage beast 2 add-ons, and can
  * - install a new add on
@@ -83,17 +81,53 @@ public class AddOnManager {
 
     public final static String[] IMPLEMENTATION_DIR = {"beast", "snap"};
     public final static String TO_DELETE_LIST_FILE = "toDeleteList";
-    //configuration file
-    public final static String PACKAGES_XML = "https://raw.githubusercontent.com/CompEvol/CBAN/master/packages" + beastVersion.getVersion() + ".xml";
+    public final static String TO_INSTALL_LIST_FILE = "toInstallList";
+    public final static String BEAST_PACKAGE = "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 static final String INSTALLED = "installed";
-    public static final String NOT_INSTALLED = "un-installed";
+    public static final String NOT_INSTALLED = "not installed";
     
     public static final String NO_CONNECTION_MESSAGE = "Could not get an internet connection. "
     		+ "The BEAST Package Manager needs internet access in order to list available packages and download them for installation. "
     		+ "Possibly, some software (like security software, or a firewall) blocks the BEAST Package Manager.  "
     		+ "If so, you need to reconfigure such software to allow access.";
-    		
+
+
+    /**
+     * Exception thrown when reading a package repository fails.
+     */
+    public static class PackageListRetrievalException extends Exception {
+		private static final long serialVersionUID = 1L;
+
+		/**
+         * Constructor for new exception.
+         *
+         * @param message Message explaining what went wrong
+         * @param cause First exception thrown when processing package repositories
+         */
+        public PackageListRetrievalException(String message, Throwable cause) {
+            super(message, cause);
+        }
+    }
+
+    /**
+     * Exception thrown when an operation fails due to package dependency issues.
+     */
+    public static class DependencyResolutionException extends Exception {
+		private static final long serialVersionUID = 1L;
+
+        /**
+         * Constructor for new exception
+         *
+         * @param message message explaining what the dependency problem was.
+         */
+        public DependencyResolutionException(String message) {
+            super(message);
+        }
+    }
 
     /**
      * flag indicating add ons have been loaded at least once *
@@ -110,18 +144,16 @@ public class AddOnManager {
      * @return URLs containing list of downloadable packages.
      * @throws java.net.MalformedURLException
      */
-    public static List<String> getPackagesURL() throws MalformedURLException {
+    public static List<URL> getRepositoryURLs() throws MalformedURLException {
         // Java 7 introduced SNI support which is enabled by default.
         // http://stackoverflow.com/questions/7615645/ssl-handshake-alert-unrecognized-name-error-since-upgrade-to-java-1-7-0
         System.setProperty("jsse.enableSNIExtension", "false");
 
-        List<String> URLs = new ArrayList<>();
-        // hack for v2.3.2 only -- to share repository file, saving lots of edits for package releases
-        // next version should have single package file to cover all version
-        URLs.add(PACKAGES_XML.replaceAll("2.3.2", "2.3.1"));
+        List<URL> URLs = new ArrayList<>();
+        URLs.add(new URL(PACKAGES_XML));
 
-        File beastProps = new File(getPackageUserDir() + "/beauti.properties");
         // check beast.properties file exists in package directory
+        File beastProps = new File(getPackageUserDir() + "/beauti.properties");
         if (beastProps.exists()) {
             Properties prop = new Properties();
 
@@ -132,26 +164,26 @@ public class AddOnManager {
                 //# url
                 //packages.url=http://...
                 if (prop.containsKey("packages.url")) {
-                    for (String userURL : prop.getProperty("packages.url").split(","))
-                        URLs.add(userURL.trim());
+                    for (String userURLString : prop.getProperty("packages.url").split(",")) {
+                        URLs.add(new URL(userURLString));
+                    }
                 }
 
             } catch (IOException ex) {
                 ex.printStackTrace();
             }
         }
-
         return URLs;
     }
     
     /**
      * Write any third-party package repository URLs to the options file.
      * 
-     * @param URLs List of URLs.  The first is assumed to be the central
+     * @param urls List of URLs.  The first is assumed to be the central
      * package repository and is thus ignored.
      */
-    public static void savePackageURLs(List<String> URLs) {
-        if (URLs.size()<1)
+    public static void saveRepositoryURLs(List<URL> urls) {
+        if (urls.size()<1)
             return;
         
         File propsFile = new File(getPackageUserDir() + "/beauti.properties");
@@ -173,12 +205,12 @@ public class AddOnManager {
         }
         
         // Modify property
-        if (URLs.size()>1) {
+        if (urls.size()>1) {
             StringBuilder sb = new StringBuilder("");
-            for (int i=1; i<URLs.size(); i++) {
+            for (int i=1; i<urls.size(); i++) {
                 if (i>1)
                     sb.append(",");
-                sb.append(URLs.get(i));
+                sb.append(urls.get(i));
             }
             
             prop.setProperty("packages.url", sb.toString());
@@ -191,213 +223,316 @@ public class AddOnManager {
             prop.store(new FileOutputStream(propsFile),
                     "Automatically-generated by BEAUti.\n");
         } catch (IOException ex) {
-            Logger.getLogger(AddOnManager.class.getName()).log(Level.SEVERE, null, ex);
+            Log.err(ex.getMessage());
         }
     }
 
     /**
-     * create list of packages. The list is downloaded from a beast2 wiki page and
-     * parsed.
+     * Look through BEAST directories for installed packages and add these
+     * to the package database.
      *
-     * @return list of packages, encoded as pairs of description, urls.
-     * @throws java.io.IOException
-     * @throws javax.xml.parsers.ParserConfigurationException
-     * @throws org.xml.sax.SAXException
+     * @param packageMap package database
      */
-    public static List<Package> getPackages() throws IOException, ParserConfigurationException, SAXException {
-
-        List<Package> packages = new ArrayList<>();
-        List<String> sURLs = getPackagesURL();
+    public static void addInstalledPackages(Map<String, Package> packageMap) {
+        for (String dir : getBeastDirectories()) {
+            File versionXML = new File(dir + "/version.xml");
+            if (!versionXML.exists())
+                continue;
 
-        for (String sURL : sURLs) {
-            URL url = new URL(sURL);
-            InputStream is = url.openStream(); // throws an IOException
+            try {
+                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+                Document doc = factory.newDocumentBuilder().parse(versionXML);
+                doc.normalize();
+                // get name and version of package
+                Element addon = doc.getDocumentElement();
+                String packageName = addon.getAttribute("name");
+                String packageVersionString = addon.getAttribute("version");
+
+                Package pkg;
+                if (packageMap.containsKey(packageName)) {
+                    pkg = packageMap.get(packageName);
+                } else {
+                    pkg = new Package(packageName);
+                    packageMap.put(packageName, pkg);
+                }
 
-            if (sURL.endsWith(".xml")) {
-                addPackages(is, packages);
-            } 
+                PackageVersion installedVersion = new PackageVersion(packageVersionString);
+                Set<PackageDependency> installedVersionDependencies =
+                        new TreeSet<>((o1, o2) -> o1.dependencyName.compareTo(o2.dependencyName));
+
+                // get dependencies of add-n
+                NodeList nodes = doc.getElementsByTagName("depends");
+                for (int i = 0; i < nodes.getLength(); i++) {
+                    Element dependson = (Element) nodes.item(i);
+                    String dependencyName = dependson.getAttribute("on");
+                    String atLeastString = dependson.getAttribute("atleast");
+                    String atMostString = dependson.getAttribute("atmost");
+                    PackageDependency dependency =  new PackageDependency(
+                            dependencyName,
+                            atLeastString.isEmpty() ? null : new PackageVersion(atLeastString),
+                            atMostString.isEmpty() ? null : new PackageVersion(atMostString));
+
+                    installedVersionDependencies.add(dependency);
+                }
 
-            is.close();
+                pkg.setInstalled(installedVersion, installedVersionDependencies);
 
-//            write package xml page, if received from internet
+            } catch (ParserConfigurationException | SAXException | IOException e) {
+                e.printStackTrace();
+            }
         }
-        
-        // Ensure package list is in alphabetical order
-        Collections.sort(packages, (p1, p2) -> p1.packageName.toLowerCase().compareTo(p2.packageName.toLowerCase()));
-        
-        return packages;
+
+        // 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);
     }
 
-    public static void addPackages(InputStream is, List<Package> packages) throws ParserConfigurationException, IOException, SAXException {
+    /**
+     * Look through the packages defined in the XML files reached by the repository URLs
+     * and add these packages to the package database.
+     *
+     * @param packageMap package database
+     * @throws PackageListRetrievalException when one or more XMLs cannot be retrieved
+     */
+    public static void addAvailablePackages(Map<String, Package> packageMap) throws PackageListRetrievalException {
+
+        List<URL> urls;
+        try {
+            urls = getRepositoryURLs();
+        } catch (MalformedURLException e) {
+            throw new PackageListRetrievalException("Error parsing one or more repository URLs.", e);
+        }
+
+        List<URL> brokenPackageRepositories = new ArrayList<>();
+        Exception firstException = null;
 
-        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        DocumentBuilder builder = factory.newDocumentBuilder();
-        Document document = builder.parse(new InputSource(is));
+        for (URL url : urls) {
+            try (InputStream is = url.openStream()) {
+                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+                DocumentBuilder builder = factory.newDocumentBuilder();
+                Document document = builder.parse(new InputSource(is));
+
+                Element rootElement = document.getDocumentElement(); // <packages>
+                NodeList nodes = rootElement.getChildNodes();
+
+                for(int i = 0; i < nodes.getLength(); i++) {
+                    Node node = nodes.item(i);
+
+                    if(node instanceof Element){
+                        Element element = (Element) node;
+                        String packageName = element.getAttribute("name");
+                        Package pkg;
+                        if (packageMap.containsKey(packageName)) {
+                            pkg = packageMap.get(packageName);
+                        } else {
+                            pkg = new Package(packageName);
+                            packageMap.put(packageName, pkg);
+                        }
+                        pkg.setDescription(element.getAttribute("description"));
+
+                        PackageVersion packageVersion = new PackageVersion(element.getAttribute("version"));
+                        Set<PackageDependency> packageDependencies = new HashSet<>();
+
+                        NodeList depNodes = element.getElementsByTagName("depends");
+                        for (int j = 0; j < depNodes.getLength(); j++) {
+                            Element dependson = (Element) depNodes.item(j);
+                            String dependencyName = dependson.getAttribute("on");
+                            String atLeastString = dependson.getAttribute("atleast");
+                            String atMostString = dependson.getAttribute("atmost");
+                            PackageDependency dependency =  new PackageDependency(
+                                    dependencyName,
+                                    atLeastString.isEmpty() ? null : new PackageVersion(atLeastString),
+                                    atMostString.isEmpty() ? null : new PackageVersion(atMostString));
+
+                            packageDependencies.add(dependency);
+                        }
 
-        Element rootElement = document.getDocumentElement(); // <packages>
-        NodeList nodes = rootElement.getChildNodes();
+                        URL packageURL = new URL(element.getAttribute("url"));
 
-        for(int i = 0; i < nodes.getLength(); i++){
-            Node node = nodes.item(i);
+                        pkg.addAvailableVersion(packageVersion, packageURL, packageDependencies);
+                    }
+                }
+            } catch (IOException | ParserConfigurationException | SAXException e) {
+                if (brokenPackageRepositories.isEmpty())
+                    firstException = e;
 
-            if(node instanceof Element){
-                Package aPackage = new Package((Element) node);
-                if (!containsPackage(aPackage.packageName, packages))
-                    packages.add(aPackage);
-                else
-                    message("Multiple packages with name "
-                            + "'" + aPackage.packageName + "' "
-                            + "found in repositories.  Selecting first (version "
-                            + getPackage(aPackage.packageName, packages).latestVersion
-                            + ").");
+                brokenPackageRepositories.add(url);
             }
+        }
 
-        } // end for i
+        if (!brokenPackageRepositories.isEmpty()) {
+            String message = "Error reading the following package repository URLs:";
+            for (URL url : brokenPackageRepositories)
+                message += " " + url;
 
+            throw new PackageListRetrievalException(message, firstException);
+        }
     }
 
-    public static Package getPackage(String packageName, List<Package> packages) {
-        for (Package aPackage : packages) {
-            if (packageName.equalsIgnoreCase(aPackage.packageName))
-                return aPackage;
+    /**
+     * Looks through packages to be installed and uninstalls any that are already installed but
+     * do not match the version that is to be installed. Packages that are already installed and do
+     * match the version required are removed from packagesToInstall.
+     *
+     * @param packagesToInstall map from packages to versions to install
+     * @param useAppDir if fause, use user directory, otherwise use application directory
+     * @param customDir custom installation directory.
+     * @throws IOException thrown if packages cannot be deleted and delete list file cannot be written
+     */
+    public static void prepareForInstall(Map<Package, PackageVersion> packagesToInstall, boolean useAppDir, String customDir) throws IOException {
+
+        Map<Package, PackageVersion> ptiCopy = new HashMap<>(packagesToInstall);
+        for (Map.Entry<Package, PackageVersion> entry : ptiCopy.entrySet()) {
+            Package thisPkg = entry.getKey();
+            PackageVersion thisPkgVersion = entry.getValue();
+
+            if (thisPkg.isInstalled()) {
+                if (thisPkg.getInstalledVersion().equals(thisPkgVersion))
+                    packagesToInstall.remove(thisPkg);
+                else
+                    uninstallPackage(thisPkg, useAppDir, customDir);
+            }
         }
-        return null;
-    }
 
-    public static boolean containsPackage(String packageName, List<Package> packages) {
-        for (Package aPackage : packages) {
-            if (packageName.equalsIgnoreCase(aPackage.packageName))
-                return true;
+        if (getToDeleteListFile().exists()) {
+            // Write to-install file
+
+        	// RRB: what are the following two lines for?
+            //File toDeleteList = getToDeleteListFile();
+            //FileWriter outfile = new FileWriter(toDeleteList, true);
+            try (PrintStream ps = new PrintStream(getToInstallListFile())) {
+                for (Map.Entry<Package, PackageVersion> entry : packagesToInstall.entrySet()) {
+                    ps.println(entry.getKey() + ":" + entry.getValue());
+                }
+            } catch (IOException ex) {
+                message("Error writing to-install file: " + ex.getMessage() +
+                        " Installation may not resume successfully after restart.");
+            }
         }
-        return false;
     }
 
     /**
-     * download and unzip package from URL provided It is assumed the package
-     * consists of a zip file containing directories /lib with jars used by the
-     * add on /templates with beauti XML templates
+     * Download and install specified versions of packages.  Note that
+     * this method does not check dependencies.  It is assumed the contents
+     * of packagesToInstall has been assembled by fillOutDependencies.
      *
+     * It is further assumed that the URL points to a zip file containing
+     * a directory lib containing jars used by the package, as well as
+     * a directory named templates containing BEAUti XML templates.
      *
-     * @param aPackage
+     * @param packagesToInstall map from packages to versions to install
      * @param useAppDir if false, use user directory, otherwise use application directory
-     * @param customDir
-     * @param packages  if not null, install all dependent packages of aPackage, but not work for customDir != null
-     * @throws Exception
+     * @param customDir custom installation directory.
+     * @return list of strings representing directories into which packages were installed
+     * @throws IOException if URL cannot be accessed for some reason
      */
-    public static String installPackage(Package aPackage, boolean useAppDir, String customDir, List<Package> packages) throws Exception {
-        if (!aPackage.url.toLowerCase().endsWith(".zip")) {
-            throw new Exception("Package should be packaged in a zip file");
-        }
-//        String sName = URL2PackageName(sURL); // not safe to use
-        String sName = aPackage.packageName;
-
-        // install all dependent packages
-        if (customDir == null && packages != null) {
-            for (PackageDependency packageDependency : aPackage.dependencies) {
-                String s = packageDependency.dependson;
-                if (!s.equals("beast2")) {
-                    Package pDent = getPackage(s, packages);
-                    installPackage(pDent, useAppDir, null, packages);
+    public static Map<String, String> installPackages(Map<Package, PackageVersion> packagesToInstall, boolean useAppDir, String customDir) throws IOException {
+        Map<String, String> dirList = new HashMap<>();
+
+        for (Map.Entry<Package, PackageVersion> entry : packagesToInstall.entrySet()) {
+            Package thisPkg = entry.getKey();
+            PackageVersion thisPkgVersion = entry.getValue();
+
+            // create directory
+            URL templateURL = thisPkg.getVersionURL(thisPkgVersion);
+            ReadableByteChannel rbc = Channels.newChannel(templateURL.openStream());
+            String dirName = (useAppDir ? getPackageSystemDir() : getPackageUserDir()) + "/" + thisPkg.getName();
+            if (customDir != null) {
+                dirName = customDir + "/" + thisPkg.getName();
+            }
+            File dir = new File(dirName);
+            if (!dir.exists()) {
+                if (!dir.mkdirs()) {
+                    throw new IOException("Could not create directory " + dirName);
                 }
             }
-        }
+            // grab file from URL
+            String zipFile = dirName + "/" + thisPkg.getName() + ".zip";
+            FileOutputStream fos = new FileOutputStream(zipFile);
+            fos.getChannel().transferFrom(rbc, 0, 1 << 24);
 
-        // create directory
-        URL templateURL = new URL(aPackage.url);
-        ReadableByteChannel rbc = Channels.newChannel(templateURL.openStream());
-        String sDir = (useAppDir ? getPackageSystemDir() : getPackageUserDir()) + "/" + sName;
-        if (customDir != null) {
-            sDir = customDir + "/" + sName;
-        }
-        File dir = new File(sDir);
-        if (!dir.exists()) {
-            if (!dir.mkdirs()) {
-                throw new Exception("Could not create template directory " + sDir);
-            }
+            // unzip archive
+            doUnzip(zipFile, dirName);
+            fos.close();
+
+            dirList.put(thisPkg.getName(), dirName);
         }
-        // grab file from URL
-        String sZipFile = sDir + "/" + sName + ".zip";
-        FileOutputStream fos = new FileOutputStream(sZipFile);
-        fos.getChannel().transferFrom(rbc, 0, 1 << 24);
-
-        // unzip archive
-        doUnzip(sZipFile, sDir);
-        // refresh classes
-        loadExternalJars();
-        return sDir;
+
+        return dirList;
     }
 
-    public static String uninstallPackage(Package aPackage, boolean useAppDir, String customDir, List<Package> packages, boolean autoUninstall) throws Exception {
-        if (!aPackage.url.toLowerCase().endsWith(".zip")) {
-            throw new Exception("Package should be packaged in a zip file");
-        }
-//        String sName = URL2PackageName(sURL);
-        String sName = aPackage.packageName;
-
-        // uninstall all dependent packages
-        if (customDir == null && packages != null) {
-            for (Package p : packages) {
-                if (p.dependsOn(aPackage.packageName) && p.isInstalled()) {
-                    if (autoUninstall) {
-                        uninstallPackage(p, useAppDir, null, packages, true);
-                    } else {
-                        warning("Installed package (" + p.packageName + ") depends on the package (" + aPackage.packageName + "),\n" +
-                                "which will not work if " + aPackage.packageName + "is uninstalled.");
-                        return null;
-                    }
-                }
+    /**
+     * Get list of installed packages that depend on pkg.
+     *
+     * @param pkg package for which to retrieve installed dependencies
+     * @param packageMap package database
+     * @return list of names of installed packages dependent on pkg.
+     */
+    public static List<String> getInstalledDependencyNames(Package pkg, Map<String, Package> packageMap) {
+
+        List<String> dependencies = new ArrayList<>();
+
+        for (Package thisPkg : packageMap.values()) {
+            if (thisPkg.equals(pkg))
+                continue;
+
+            if (!thisPkg.isInstalled())
+                continue;
+
+            for (PackageDependency dependency : thisPkg.getInstalledVersionDependencies()) {
+                if (dependency.dependencyName.equals(pkg.getName()))
+                    dependencies.add(thisPkg.getName());
             }
         }
 
-        String sDir = (useAppDir ? getPackageSystemDir() : getPackageUserDir()) + "/" + sName;
+        return dependencies;
+    }
+
+    /**
+     * Uninstall the given package. Like installPackages(), this method does not perform any dependency
+     * checking - it just blindly removes the specified package. This is so that the method can be called
+     * while an installation is in process without falling over because of broken intermediate states.
+     *
+     * Before using, call getInstalledDependencies() to check for potential problems.
+     *
+     * @param pkg package to uninstall
+     * @param useAppDir if false, use user directory, otherwise use application directory
+     * @param customDir custom installation directory.
+     * @return name of directory package was removed from, or null if the package was not removed.
+     * @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 {
+
+        String dirName = (useAppDir ? getPackageSystemDir() : getPackageUserDir()) + "/" + pkg.getName();
         if (customDir != null) {
-            sDir = customDir + "/" + sName;
+            dirName = customDir + "/" + pkg.getName();
         }
-        File dir = new File(sDir);
+        File dir = new File(dirName);
         List<File> deleteFailed = new ArrayList<>();
         deleteRecursively(dir, deleteFailed);
 
         // write deleteFailed to file
         if (deleteFailed.size() > 0) {
             File toDeleteList = getToDeleteListFile();
-            FileWriter outfile= new FileWriter(toDeleteList, true);
+            FileWriter outfile = new FileWriter(toDeleteList, true);
             for (File file : deleteFailed) {
                 outfile.write(file.getAbsolutePath() + "\n");
             }
             outfile.close();
         }
-        return sDir;
+        return dirName;
     }
 
-    public static boolean checkIsInstalled(String packageName) {
-        boolean isInstalled = false;
-        List<String> sBeastDirs = getBeastDirectories();
-        for (String sDir : sBeastDirs) {
-            File f = new File(sDir + "/" + packageName);
-            if (f.exists()) {
-                isInstalled = true;
-            }
-        }
-        return isInstalled;
-    }
-
-    /** pretty format aPackage information in list of string form as produced by getAddOns() **/
-    public static String formatPackageInfo(Package aPackage) {
-        StringBuilder buf = new StringBuilder();
-        buf.append(aPackage.packageName);
-        if (aPackage.packageName.length() < 12) {
-            buf.append("             ".substring(aPackage.packageName.length()));
-        }
-        buf.append(" (");
-        if (aPackage.isInstalled()) {
-            buf.append("v");
-        }
-        buf.append(aPackage.getStatus());
-        buf.append(") : latest version " + aPackage.latestVersion);
-        buf.append((aPackage.getDependenciesString().length() > 0 ? " : depends on " + aPackage.getDependenciesString() : ""));
-        buf.append(" : " + aPackage.description.trim());
-        return buf.toString();
-    }
 
     private static void deleteRecursively(File file, List<File> deleteFailed) {
         if (file.isDirectory()) {
@@ -541,33 +676,106 @@ public class AddOnManager {
     }
 
     /**
+     * Delete files that could not be deleted earlier due to jar locking.
+     */
+    private static void processDeleteList() {
+        File toDeleteListFile = getToDeleteListFile();
+        if (toDeleteListFile.exists()) {
+            try {
+                BufferedReader fin = new BufferedReader(new FileReader(toDeleteListFile));
+                while (fin.ready()) {
+                    String str = fin.readLine();
+                    File file = new File(str);
+                    file.delete();
+                }
+                fin.close();
+                toDeleteListFile.delete();
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    /**
+     * Obtain file containing list of packages that need to be installed
+     * at startup.  This file only exists when packages have failed to upgrade
+     * due to jar file locking on Windows.
+     *
+     * @return to-install file
+     */
+    public static File getToInstallListFile() {
+        return new File(getPackageUserDir() + "/" + TO_INSTALL_LIST_FILE);
+    }
+
+    /**
+     * Completes installation procedure if packages could not be upgraded due to
+     * Windows preventing the deletion of jar files.
+     *
+     * @param packageMap package database
+     */
+    private static void processInstallList(Map<String, Package> packageMap) {
+        File toInstallListFile = getToInstallListFile();
+        if (toInstallListFile.exists()) {
+            try {
+                addAvailablePackages(packageMap);
+            } catch (PackageListRetrievalException e) {
+                message("Failed to resume package installation due to package list retrieval error: " + e.getMessage());
+                toInstallListFile.delete();
+                return;
+            }
+
+            Map<Package, PackageVersion>  packagesToInstall = new HashMap<>();
+            try (BufferedReader fin = new BufferedReader(new FileReader(toInstallListFile))) {
+                String line;
+                while ((line = fin.readLine()) != null) {
+                    String[] nameVerPair = line.split(":");
+
+                    Package pkg = packageMap.get(nameVerPair[0]);
+                    PackageVersion ver = new PackageVersion(nameVerPair[1]);
+                    packagesToInstall.put(pkg, ver);
+                }
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+
+            try {
+                installPackages(packagesToInstall, false, null);
+            } catch (IOException e) {
+                message("Failed to install packages due to I/O error: " + e.getMessage());
+            }
+
+            toInstallListFile.delete();
+        }
+    }
+
+    /**
      * return list of directories that may contain packages *
      */
     public static List<String> getBeastDirectories() {
-        List<String> sDirs = new ArrayList<>();
+        List<String> dirs = new ArrayList<>();
         // check if there is the BEAST environment variable is set
         if (System.getProperty("BEAST_ADDON_PATH") != null) {
-            String sBEAST = System.getProperty("BEAST_ADDON_PATH");
-            for (String sDir : sBEAST.split(":")) {
-                sDirs.add(sDir);
+            String BEAST = System.getProperty("BEAST_ADDON_PATH");
+            for (String dirName : BEAST.split(":")) {
+                dirs.add(dirName);
             }
         }
         if (System.getenv("BEAST_ADDON_PATH") != null) {
-            String sBEAST = System.getenv("BEAST_ADDON_PATH");
-            for (String sDir : sBEAST.split(":")) {
-                sDirs.add(sDir);
+            String BEAST = System.getenv("BEAST_ADDON_PATH");
+            for (String dirName : BEAST.split(":")) {
+                dirs.add(dirName);
             }
         }
 
         // add user package directory
-        sDirs.add(getPackageUserDir());
+        dirs.add(getPackageUserDir());
 
         // add application package directory
-        sDirs.add(getPackageSystemDir());
+        dirs.add(getPackageSystemDir());
 
         // add BEAST installation directory
         if (getBEASTInstallDir() != null)
-            sDirs.add(getBEASTInstallDir());
+            dirs.add(getBEASTInstallDir());
 
         // pick up directories in class path, useful when running in an IDE
         String strClassPath = System.getProperty("java.class.path");
@@ -580,8 +788,8 @@ public class AddOnManager {
                     // deal with the way Mac's appbundler sets up paths
                   	path = path.replaceAll("/[^/]*/Contents/Java", "");
                     // exclude Intellij build path out/production
-                    if (!sDirs.contains(path) && !path.contains("production")) {
-                        sDirs.add(path);
+                    if (!dirs.contains(path) && !path.contains("production")) {
+                        dirs.add(path);
                     }
                 }
             }
@@ -591,9 +799,9 @@ public class AddOnManager {
         // subdirectories that look like they may contain an package
         // this is detected by checking the subdirectory contains a lib or
         // templates directory
-        List<String> sSubDirs = new ArrayList<>();
-        for (String sDir : sDirs) {
-            File dir = new File(sDir);
+        List<String> subDirs = new ArrayList<>();
+        for (String dirName : dirs) {
+            File dir = new File(dirName);
             if (dir.isDirectory()) {
                 File[] files = dir.listFiles();
                 if (files == null)
@@ -603,7 +811,7 @@ public class AddOnManager {
                     if (file.isDirectory()) {
                         File versionFile = new File(file, "version.xml");
                         if (versionFile.exists())
-                            sSubDirs.add(file.getAbsolutePath());
+                            subDirs.add(file.getAbsolutePath());
                     }
                 }
             }
@@ -611,21 +819,26 @@ public class AddOnManager {
         // check version dependencies
 
 
-        sDirs.addAll(sSubDirs);
+        dirs.addAll(subDirs);
 
-        return sDirs;
+        return dirs;
     } // getBeastDirectories
 
     /**
      * load external jars in beast directories *
      */
-    public static void loadExternalJars() throws Exception {
+    public static void loadExternalJars() throws IOException {
         processDeleteList();
 
-        List<String> sDirs = getBeastDirectories();
-        checkDependencies(sDirs);
-        for (String sJarDir : sDirs) {
-            File versionFile = new File(sJarDir + "/version.xml");
+        TreeMap<String, Package> packages = new TreeMap<>();
+        addInstalledPackages(packages);
+
+        processInstallList(packages);
+
+        checkInstalledDependencies(packages);
+
+        for (String jarDirName : getBeastDirectories()) {
+            File versionFile = new File(jarDirName + "/version.xml");
             if (versionFile.exists()) {
                 try {
                     // print name and version of package
@@ -637,19 +850,19 @@ public class AddOnManager {
                 	// too bad, won't print out any info
                 }
             }
-            File jarDir = new File(sJarDir + "/lib");
+            File jarDir = new File(jarDirName + "/lib");
             if (!jarDir.exists()) {
-                jarDir = new File(sJarDir + "\\lib");
+                jarDir = new File(jarDirName + "\\lib");
             }
             if (jarDir.exists() && jarDir.isDirectory()) {
-                for (String sFile : jarDir.list()) {
-                    if (sFile.endsWith(".jar")) {
-                        Log.debug.print("Probing: " + sFile + " ");
+                for (String fileName : jarDir.list()) {
+                    if (fileName.endsWith(".jar")) {
+                        Log.debug.print("Probing: " + fileName + " ");
                         // check that we are not reload existing classes
                         String loadedClass = null;
                         try {
                             JarInputStream jarFile = new JarInputStream
-                                    (new FileInputStream(jarDir.getAbsolutePath() + "/" + sFile));
+                                    (new FileInputStream(jarDir.getAbsolutePath() + "/" + fileName));
                             JarEntry jarEntry;
 
                             while (loadedClass == null) {
@@ -661,20 +874,21 @@ public class AddOnManager {
                                     String className = jarEntry.getName().replaceAll("/", "\\.");
                                     className = className.substring(0, className.lastIndexOf('.'));
                                     try {
-                                        Object o = Class.forName(className);
+                                        /*Object o =*/ Class.forName(className);
                                         loadedClass = className;
                                     } catch (Exception e) {
                                         // TODO: handle exception
                                     }
                                 }
                             }
+                            jarFile.close();
                         } catch (Exception e) {
                             e.printStackTrace();
                         }
 
 
                         @SuppressWarnings("deprecation")
-                        URL url = new File(jarDir.getAbsolutePath() + "/" + sFile).toURL();
+                        URL url = new File(jarDir.getAbsolutePath() + "/" + fileName).toURL();
                         if (loadedClass == null) {
                             addURL(url);
                         } else {
@@ -688,81 +902,108 @@ public class AddOnManager {
         Alignment.findDataTypes();
     } // loadExternalJars
 
+    /**
+     * Populate given map with versions of packages to install which satisfy dependencies
+     * of those already present.
+     *
+     * @param packageMap database of installed and available packages
+     * @param packagesToInstall map to populate with package versions requiring installation.
+     * @throws DependencyResolutionException thrown when method fails to identify a consistent set of dependent packages
+     */
+    public static void populatePackagesToInstall(Map<String, Package> packageMap,
+                                                 Map<Package, PackageVersion> packagesToInstall) throws DependencyResolutionException {
 
-    /** try to delete files that could not be deleted earlier **/
-    private static void processDeleteList() {
-        File toDeleteLisFile = getToDeleteListFile();
-        if (toDeleteLisFile.exists()) {
-            try {
-                BufferedReader fin = new BufferedReader(new FileReader(toDeleteLisFile));
-                while (fin.ready()) {
-                    String sStr = fin.readLine();
-                    File file = new File(sStr);
-                    file.delete();
+        Map<Package, PackageVersion> copy = new HashMap<>(packagesToInstall);
+
+        for (Map.Entry<Package, PackageVersion> entry : copy.entrySet()) {
+            populatePackagesToInstall(packageMap, packagesToInstall, entry.getKey(), entry.getValue());
+        }
+
+    }
+
+    private static void populatePackagesToInstall(Map<String, Package> packageMap,
+                                             Map<Package, PackageVersion> packagesToInstall,
+                                          Package rootPackage, PackageVersion rootPackageVersion) throws DependencyResolutionException {
+
+        if (!rootPackage.getAvailableVersions().contains(rootPackageVersion))
+            throw new IllegalArgumentException("Package version " + rootPackageVersion + " is not available.");
+
+        Set<PackageDependency> dependencies = rootPackage.getDependencies(rootPackageVersion);
+        for (PackageDependency dependency : dependencies) {
+            if (!packageMap.containsKey(dependency.dependencyName))
+                throw new DependencyResolutionException("Package " + rootPackage
+                        + " depends on unknown package " + dependency.dependencyName);
+
+            Package depPkg = packageMap.get(dependency.dependencyName);
+            PackageVersion intendedVersion = packagesToInstall.get(depPkg);
+            if (intendedVersion == null) {
+                if (depPkg.isInstalled() && dependency.isMetBy(depPkg.getInstalledVersion()))
+                    continue;
+            } else {
+                if (dependency.isMetBy(intendedVersion))
+                    continue;
+                else
+                    throw new DependencyResolutionException("Package " + rootPackage + " depends on a different " +
+                            "version of package " + dependency.dependencyName + " to that required by another package.");
+            }
+
+            boolean foundCompatible = false;
+            for (PackageVersion depPkgVersion : depPkg.getAvailableVersions()) {
+                if (dependency.isMetBy(depPkgVersion)) {
+                    if (depPkg.isInstalled() && depPkgVersion.compareTo(depPkg.getInstalledVersion())<0)
+                        continue; // No downgrading of installed versions
+
+                    packagesToInstall.put(depPkg, depPkgVersion);
+
+                    try {
+                        populatePackagesToInstall(packageMap, packagesToInstall, depPkg, depPkgVersion);
+                        foundCompatible = true;
+                        break;
+                    } catch (DependencyResolutionException ignored) { }
+
+                    packagesToInstall.remove(depPkg);
                 }
-                fin.close();
-                toDeleteLisFile.delete();
-            } catch (Exception e) {
-                e.printStackTrace();
             }
+            if (!foundCompatible)
+                throw new DependencyResolutionException("Package " + rootPackage + " requires " + dependency + ", " +
+                        "but no installable version of that package was found.");
+
         }
     }
 
     /**
-     * go through list of directories collecting version and dependency information for
-     * all packages. Version and dependency info is stored in a file
+     * Checks that dependencies of all installed packages are met.
      *
-     * @param sDirs
+     * @param packageMap
      */
-    private static void checkDependencies(List<String> sDirs) {
-        HashMap<String, Double> packageVersion = new HashMap<>();
-        packageVersion.put("beast2", beastVersion.parseVersion(beastVersion.getVersion()));
-        List<PackageDependency> dependencies = new ArrayList<>();
-
-        // gather version and dependency info for all packages
-        for (String sDir : sDirs) {
-            File version = new File(sDir + "/version.xml");
-            if (version.exists()) {
-                try {
-                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-                    Document doc = factory.newDocumentBuilder().parse(version);
-                    doc.normalize();
-                    // get name and version of package
-                    Element addon = doc.getDocumentElement();
-                    String sAddon = addon.getAttribute("name");
-                    String sAddonVersion = addon.getAttribute("version");
-                    packageVersion.put(sAddon, beastVersion.parseVersion(sAddonVersion));
-
-                    // get dependencies of add-n
-                    NodeList nodes = doc.getElementsByTagName("depends");
-                    for (int i = 0; i < nodes.getLength(); i++) {
-                        Element dependson = (Element) nodes.item(i);
-                        PackageDependency dep = new PackageDependency();
-                        dep.packageName = sAddon;
-                        dep.dependson = dependson.getAttribute("on");
-                        String sAtLeast = dependson.getAttribute("atleast");
-                        dep.setAtLest(sAtLeast);
-                        String sAtMost = dependson.getAttribute("atmost");
-                        dep.setAtMost(sAtMost);
-                        dependencies.add(dep);
-                    }
+    private static void checkInstalledDependencies(Map<String, Package> packageMap) {
+        Map<PackageDependency,Package> dependencies = new HashMap<>();
 
-                } catch (Exception e) {
-                    e.printStackTrace();
-                }
-            }
+        // Collect installed package dependencies
+        for (Package pkg : packageMap.values()) {
+            if (!pkg.isInstalled())
+                continue;
+
+            for (PackageDependency dep : pkg.getInstalledVersionDependencies())
+                dependencies.put(dep, pkg);
         }
 
         // check dependencies
-        for (PackageDependency dep : dependencies) {
-            Double version = packageVersion.get(dep.dependson);
-            if (version == null) {
-                warning("Package " + dep.packageName + " requires another package (" + dep.dependson + ") which is not installed.\n" +
-                        "Either uninstall " + dep.packageName + " or install the " + dep.dependson + " add on.");
-            } else if (version > dep.atMost || version < dep.atLeast) {
-                warning("Package " + dep.packageName + " requires another package (" + dep.dependson + ") with version in range " +
-                        beastVersion.formatVersion(dep.atLeast) + " to " + beastVersion.formatVersion(dep.atMost) + " but " + dep.dependson + " has version " + beastVersion.formatVersion(version) + "\n" +
-                        "Either uninstall " + dep.packageName + " or install the correct version of " + dep.dependson + ".");
+        for (PackageDependency dep : dependencies.keySet()) {
+            Package depPackage = packageMap.get(dep.dependencyName);
+            Package requiredBy = dependencies.get(dep);
+            if (depPackage == null) {
+                warning("Package " + requiredBy.getName()
+                        + " requires another package (" + dep.dependencyName + ") which is not available.\n" +
+                        "Either uninstall " + requiredBy.getName() + " or ask the package maintainer for " +
+                        "information about this dependency.");
+            } else if (!depPackage.isInstalled()) {
+                warning("Package " + requiredBy.getName() + " requires another package (" + dep.dependencyName + ") which is not installed.\n" +
+                        "Either uninstall " + requiredBy.getName() + " or install the " + dep.dependencyName + " package.");
+            } else if (!dep.isMetBy(depPackage.getInstalledVersion())) {
+                warning("Package " +  requiredBy.getName() + " requires another package " + dep
+                        + " but the installed " + dep.dependencyName + " has version " + depPackage.getInstalledVersion() + ".\n" +
+                        "Either uninstall " + requiredBy.getName() + " or install the correct version of " + dep.dependencyName + ".");
             }
         }
     }
@@ -820,15 +1061,15 @@ public class AddOnManager {
             Class<?>[] parameters = new Class[]{URL.class};
             Method method = sysclass.getDeclaredMethod("addURL", parameters);
             method.setAccessible(true);
-            method.invoke(sysLoader, new Object[]{u});
+            method.invoke(sysLoader, u);
             Log.debug.println("Loaded URL " + u);
         } catch (Throwable t) {
             t.printStackTrace();
             throw new IOException("Error, could not add URL to system classloader");
         }
         String classpath = System.getProperty("java.class.path");
-        String sJar = u + "";
-        classpath += System.getProperty("path.separator") + sJar.substring(5);
+        String jar = u + "";
+        classpath += System.getProperty("path.separator") + jar.substring(5);
         System.setProperty("java.class.path", classpath);
         all_classes = null;
     }
@@ -855,7 +1096,7 @@ public class AddOnManager {
                 addDirContent(filepath, filepath.getAbsolutePath().length());
             } else if (path.endsWith(".jar")) {
 
-                JarFile jar;
+                JarFile jar = null;
                 try {
                     jar = new JarFile(filepath);
                 } catch (IOException e) {
@@ -869,6 +1110,11 @@ public class AddOnManager {
                         all_classes.add(entry.getName());
                     }
                 }
+                try {
+					jar.close();
+				} catch (IOException e) {
+                    Log.debug.println("WARNING: " + filepath + " could not be closed!");
+				}
             } else if (path.endsWith(".class")) {
                 all_classes.add(path);
             } else {
@@ -882,13 +1128,13 @@ public class AddOnManager {
             fileSep = "\\\\";
         }
         for (int i = 0; i < all_classes.size(); i++) {
-            String sStr = all_classes.get(i);
-            sStr = sStr.substring(0, sStr.length() - 6);
-            sStr = sStr.replaceAll(fileSep, ".");
-            if (sStr.startsWith(".")) {
-                sStr = sStr.substring(1);
+            String str = all_classes.get(i);
+            str = str.substring(0, str.length() - 6);
+            str = str.replaceAll(fileSep, ".");
+            if (str.startsWith(".")) {
+                str = str.substring(1);
             }
-            all_classes.set(i, sStr);
+            all_classes.set(i, str);
         }
 
     }
@@ -1047,7 +1293,15 @@ public class AddOnManager {
 
         // sort result
         result.addAll(names);
-        Collections.sort(result); //, new StringCompare());
+        Collections.sort(result, (s1, s2) -> {
+        	if (s1.equals(BEAST_PACKAGE)) {
+        		return -1;
+        	}
+        	if (s2.equals(BEAST_PACKAGE)) {
+        		return 1;
+        	}
+        	return s1.compareTo(s2);
+        }); //, new StringCompare());
 
         return result;
     }
@@ -1067,15 +1321,15 @@ public class AddOnManager {
 
         List<String> result = new ArrayList<>();
         for (int i = all_classes.size() - 1; i >= 0; i--) {
-            String sClass = all_classes.get(i);
-            sClass = sClass.replaceAll("/", ".");
-            //Log.debug.println(sClass + " " + pkgname);
+            String className = all_classes.get(i);
+            className = className.replaceAll("/", ".");
+            //Log.debug.println(className + " " + pkgname);
 
             // must match package
-            if (sClass.startsWith(pkgname)) {
-                //Log.debug.println(sClass);
+            if (className.startsWith(pkgname)) {
+                //Log.debug.println(className);
                 try {
-                    Class<?> clsNew = Class.forName(sClass);
+                    Class<?> clsNew = Class.forName(className);
 
                     // no abstract classes
                     if (!Modifier.isAbstract(clsNew.getModifiers()) &&
@@ -1083,10 +1337,10 @@ public class AddOnManager {
                             (cls.isInterface() && hasInterface(cls, clsNew)) ||
                             // must be derived from class
                             (!clsNew.isInterface() && isSubclass(cls, clsNew))) {
-                        result.add(sClass);
+                        result.add(className);
                     }
                 } catch (Throwable e) {
-                    Log.debug.println("Checking class: " + sClass);
+                    Log.debug.println("Checking class: " + className);
                     e.printStackTrace();
                 }
 
@@ -1094,7 +1348,15 @@ public class AddOnManager {
         }
 
         // sort result
-        Collections.sort(result); //, new StringCompare());
+        Collections.sort(result, (s1, s2) -> {
+        	if (s1.equals(BEAST_PACKAGE)) {
+        		return -1;
+        	}
+        	if (s2.equals(BEAST_PACKAGE)) {
+        		return 1;
+        	}
+        	return s1.compareTo(s2);
+        }); //, new StringCompare());
         // remove duplicates
         for (int i = result.size() - 1; i > 0; i--) {
             if (result.get(i).equals(result.get(i - 1))) {
@@ -1106,6 +1368,96 @@ public class AddOnManager {
     }
 
 
+    /*
+     * Command-line interface code
+     */
+
+    /**
+     * Pretty-print package information.
+     *
+     * @param ps print stream to which to print package info
+     * @param packageMap map from package names to package objects
+     */
+    public static void prettyPrintPackageInfo(PrintStream ps, Map<String, Package> packageMap) {
+
+        // Define headers here - need to know lengths
+        String nameHeader = "Name";
+        String statusHeader = "Installation Status";
+        String latestHeader = "Latest Version";
+        String depsHeader = "Dependencies";
+        String descriptionHeader = "Description";
+
+        int maxNameWidth = nameHeader.length();
+        int maxStatusWidth = statusHeader.length();
+        int maxLatestWidth = latestHeader.length();
+        int maxDepsWidth = depsHeader.length();
+
+        // Assemble list of packages (excluding beast2), keeping track of maximum field widths
+        List<Package> packageList = new ArrayList<>();
+        for (Package pkg : packageMap.values()) {
+//            if (pkg.getName().equals(BEAST_PACKAGE))
+//                continue;
+
+            packageList.add(pkg);
+
+            maxNameWidth = Math.max(pkg.getName().length(), maxNameWidth);
+            maxStatusWidth = Math.max(pkg.getStatusString().length(), maxStatusWidth);
+            maxLatestWidth = Math.max(maxLatestWidth, pkg.isAvailable()
+                            ? pkg.getLatestVersion().toString().length()
+                            :  Math.max(2, maxStatusWidth));
+            maxDepsWidth = Math.max(pkg.getDependenciesString().length(), maxDepsWidth);
+        }
+
+        // Assemble format strings
+        String nameFormat = "%-" + (maxNameWidth) + "s";
+        String statusFormat = "%-" + (maxStatusWidth) + "s";
+        String latestFormat = "%-" + (maxLatestWidth) + "s";
+        String depsFormat = "%-" + (maxDepsWidth) + "s";
+        String sep = " | ";
+
+        // Print headers
+        ps.printf(nameFormat, nameHeader); ps.print(sep);
+        ps.printf(statusFormat, statusHeader); ps.print(sep);
+        ps.printf(latestFormat, latestHeader); ps.print(sep);
+        ps.printf(depsFormat, depsHeader); ps.print(sep);
+        ps.printf("%s\n", descriptionHeader);
+
+        // Add horizontal rule under header
+        int totalWidth = maxNameWidth + maxStatusWidth
+                + maxLatestWidth + maxDepsWidth
+                + descriptionHeader.length() + 4*3;
+        for (int i=0; i<totalWidth; i++)
+            ps.print("-");
+        ps.println();
+
+
+        // Print formatted package information
+        for (Package pkg : packageList) {
+        	if (pkg.getName().equals(BEAST_PACKAGE)) {
+        		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);
+		        ps.printf(depsFormat, pkg.getDependenciesString()); ps.print(sep);
+		        ps.printf("%s\n", pkg.getDescription());
+        	}
+        }
+        for (int i=0; i<totalWidth; i++)
+            ps.print("-");
+        ps.println();
+        
+        // Print formatted package information
+        for (Package pkg : packageList) {
+        	if (!pkg.getName().equals(BEAST_PACKAGE)) {
+	            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);
+	            ps.printf(depsFormat, pkg.getDependenciesString()); ps.print(sep);
+	            ps.printf("%s\n", pkg.getDescription());
+        	}
+        }
+    }
+
+
     private static void printUsageAndExit(Arguments arguments) {
         arguments.printUsage("addonmanager", "");
         Log.info.println("\nExamples:");
@@ -1147,42 +1499,51 @@ public class AddOnManager {
                 System.setProperty("BEAST_ADDON_PATH", (path != null ? path + ":" : "") +customDir);
             }
 
-            List<String> sURLs = getPackagesURL();
+            List<URL> urlList = getRepositoryURLs();
             Log.debug.println("Packages user path : " + getPackageUserDir());
-            for (String sURL : sURLs) {
-                Log.debug.println("Access URL : " + sURL);
+            for (URL url : urlList) {
+                Log.debug.println("Access URL : " + url);
             }
             Log.debug.print("Getting list of packages ...");
-            List<Package> packages = null;
+            Map<String, Package> packageMap = new TreeMap<>(String::compareToIgnoreCase);
             try {
-            	packages = AddOnManager.getPackages();
-            } catch (IOException e) {
+                AddOnManager.addInstalledPackages(packageMap);
+                AddOnManager.addAvailablePackages(packageMap);
+            } catch (PackageListRetrievalException e) {
             	Log.warning.println(e.getMessage());
-            	Log.warning.println(NO_CONNECTION_MESSAGE);
+                if (e.getCause() instanceof IOException)
+                    Log.warning.println(NO_CONNECTION_MESSAGE);
             	return;
             }
             Log.debug.println("Done!\n");
 
             if (arguments.hasOption("list")) {
-                Log.info.println("Name : status : Description ");
-                for (Package aPackage : packages) {
-                    Log.info.println(formatPackageInfo(aPackage));
-                }
+                prettyPrintPackageInfo(Log.info, packageMap);
             }
 
             if (arguments.hasOption("add")) {
                 String name = arguments.getStringOption("add");
                 boolean processed = false;
-                for (Package aPackage : packages) {
+                for (Package aPackage : packageMap.values()) {
                     if (aPackage.packageName.equals(name)) {
                         processed = true;
                         if (!aPackage.isInstalled()) {
+                            Log.debug.println("Determine packages to install");
+                            Map<Package, PackageVersion> packagesToInstall = new HashMap<>();
+                            packagesToInstall.put(aPackage, aPackage.getLatestVersion());
+                            try {
+                                populatePackagesToInstall(packageMap, packagesToInstall);
+                            } catch (DependencyResolutionException ex) {
+                                Log.err("Installation aborted: " + ex.getMessage());
+                            }
                             Log.debug.println("Start installation");
-                            String dir = installPackage(aPackage, useAppDir, customDir, null);
-                            Log.info.println("Package " + name + " is installed in " + dir + ".");
+                            prepareForInstall(packagesToInstall, useAppDir, customDir);
+                            Map<String, String> dirs = installPackages(packagesToInstall, useAppDir, customDir);
+                            for (String pkgName : dirs.keySet())
+                                Log.info.println("Package " + pkgName + " is installed in " + dirs.get(pkgName) + ".");
                         } else {
                             Log.info.println("Installation aborted: " + name + " is already installed.");
-                            System.exit(0);
+                            System.exit(1);
                         }
                     }
                 }
@@ -1194,16 +1555,24 @@ public class AddOnManager {
             if (arguments.hasOption("del")) {
                 String name = arguments.getStringOption("del");
                 boolean processed = false;
-                for (Package aPackage : packages) {
+                for (Package aPackage : packageMap.values()) {
                     if (aPackage.packageName.equals(name)) {
                         processed = true;
                         if (aPackage.isInstalled()) {
-                            Log.debug.println("Start un-installation");
-                            String dir = uninstallPackage(aPackage, useAppDir, customDir, null, false);
-                            Log.info.println("Package " + name + " is uninstalled from " + dir + ".");
+                            List<String> deps = getInstalledDependencyNames(aPackage, packageMap);
+                            if (deps.isEmpty()) {
+                                Log.debug.println("Start un-installation");
+                                String dir = uninstallPackage(aPackage, useAppDir, customDir);
+                                Log.info.println("Package " + name + " is uninstalled from " + dir + ".");
+                            } else {
+                                Log.info.println("Un-installation aborted: " + name + " is used by these other packages: " +
+                                        String.join(", ", deps) + ".");
+                                Log.info.println("Remove these packages first.");
+                                System.exit(1);
+                            }
                         } else {
                             Log.info.println("Un-installation aborted: " + name + " is not installed yet.");
-                            System.exit(0);
+                            System.exit(1);
                         }
                     }
                 }
diff --git a/src/beast/util/ClusterTree.java b/src/beast/util/ClusterTree.java
index dcd95ce..a02ac4c 100644
--- a/src/beast/util/ClusterTree.java
+++ b/src/beast/util/ClusterTree.java
@@ -25,6 +25,14 @@
 package beast.util;
 
 
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
+import java.util.PriorityQueue;
+
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.StateNode;
@@ -36,10 +44,6 @@ import beast.evolution.alignment.distance.JukesCantorDistance;
 import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
 
-import java.text.DecimalFormat;
-import java.text.DecimalFormatSymbols;
-import java.util.*;
-
 
 
 
@@ -65,13 +69,13 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
 
     double EPSILON = 1e-10;
 
-    public Input<Type> clusterTypeInput = new Input<Type>("clusterType", "type of clustering algorithm used for generating initial beast.tree. " +
+    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());
-    public Input<Alignment> dataInput = new Input<Alignment>("taxa", "alignment data used for calculating distances for clustering");
+    final public Input<Alignment> dataInput = new Input<>("taxa", "alignment data used for calculating distances for clustering");
 
-    public Input<Distance> distanceInput = new Input<Distance>("distance", "method for calculating distance between two sequences (default Jukes Cantor)");
+    final public Input<Distance> distanceInput = new Input<>("distance", "method for calculating distance between two sequences (default Jukes Cantor)");
 
-    public Input<RealParameter> clockRateInput = new Input<RealParameter>("clock.rate",
+    final public Input<RealParameter> clockRateInput = new Input<>("clock.rate",
             "the clock rate parameter, used to divide all divergence times by, to convert from substitutions to times. (default 1.0)",
             new RealParameter(new Double[] {1.0}));
 
@@ -85,11 +89,11 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
     /**
      * Holds the Link type used calculate distance between clusters
      */
-    Type nLinkType = Type.single;
+    Type linkType = Type.single;
 
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
     	
         RealParameter clockRate = clockRateInput.get();
 
@@ -97,7 +101,7 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
     		taxaNames = dataInput.get().getTaxaNames();
     	} else {
     		if (m_taxonset.get() == null) {
-    			throw new Exception("At least one of taxa and taxonset input needs to be specified");
+    			throw new RuntimeException("At least one of taxa and taxonset input needs to be specified");
     		}
     		taxaNames = m_taxonset.get().asStringList();
     	}
@@ -142,18 +146,18 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
         	((Distance.Base) distance).setPatterns(dataInput.get());
         }
 
-        nLinkType = clusterTypeInput.get();
+        linkType = clusterTypeInput.get();
 
-        if (nLinkType == Type.upgma) nLinkType = Type.average;
+        if (linkType == Type.upgma) linkType = Type.average;
 
-        if (nLinkType == Type.neighborjoining || nLinkType == Type.neighborjoining2) {
+        if (linkType == Type.neighborjoining || linkType == Type.neighborjoining2) {
             distanceIsBranchLength = true;
         }
         final Node root = buildClusterer();
         setRoot(root);
         root.labelInternalNodes((getNodeCount() + 1) / 2);
         super.initAndValidate();
-        if (nLinkType == Type.neighborjoining2) {
+        if (linkType == Type.neighborjoining2) {
             // set tip dates to zero
             final Node[] nodes = getNodesAsArray();
             for (int i = 0; i < getLeafNodeCount(); i++) {
@@ -203,42 +207,43 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
         double m_fRightLength = 0;
         double m_fHeight = 0;
 
-        void setHeight(double fHeight1, double fHeight2) {
-            if (fHeight1 < EPSILON) {
-                fHeight1 = EPSILON;
+        void setHeight(double height1, double height2) {
+            if (height1 < EPSILON) {
+                height1 = EPSILON;
             }
-            if (fHeight2 < EPSILON) {
-                fHeight2 = EPSILON;
+            if (height2 < EPSILON) {
+                height2 = EPSILON;
             }
-            m_fHeight = fHeight1;
+            m_fHeight = height1;
             if (m_left == null) {
-                m_fLeftLength = fHeight1;
+                m_fLeftLength = height1;
             } else {
-                m_fLeftLength = fHeight1 - m_left.m_fHeight;
+                m_fLeftLength = height1 - m_left.m_fHeight;
             }
             if (m_right == null) {
-                m_fRightLength = fHeight2;
+                m_fRightLength = height2;
             } else {
-                m_fRightLength = fHeight2 - m_right.m_fHeight;
+                m_fRightLength = height2 - m_right.m_fHeight;
             }
         }
 
-        void setLength(double fLength1, double fLength2) {
-            if (fLength1 < EPSILON) {
-                fLength1 = EPSILON;
+        void setLength(double length1, double length2) {
+            if (length1 < EPSILON) {
+                length1 = EPSILON;
             }
-            if (fLength2 < EPSILON) {
-                fLength2 = EPSILON;
+            if (length2 < EPSILON) {
+                length2 = EPSILON;
             }
-            m_fLeftLength = fLength1;
-            m_fRightLength = fLength2;
-            m_fHeight = fLength1;
+            m_fLeftLength = length1;
+            m_fRightLength = length2;
+            m_fHeight = length1;
             if (m_left != null) {
                 m_fHeight += m_left.m_fHeight;
             }
         }
 
-        public String toString() {
+        @Override
+		public String toString() {
             final DecimalFormat myFormatter = new DecimalFormat("#.#####", new DecimalFormatSymbols(Locale.US));
 
             if (m_left == null) {
@@ -259,7 +264,7 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
             }
         }
 
-        Node toNode() throws Exception {
+        Node toNode() {
             final Node node = newNode();
             node.setHeight(m_fHeight);
             if (m_left == null) {
@@ -303,12 +308,12 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
      * used for priority queue for efficient retrieval of pair of clusters to merge*
      */
     class Tuple {
-        public Tuple(final double d, final int i, final int j, final int nSize1, final int nSize2) {
+        public Tuple(final double d, final int i, final int j, final int size1, final int size2) {
             m_fDist = d;
             m_iCluster1 = i;
             m_iCluster2 = j;
-            m_nClusterSize1 = nSize1;
-            m_nClusterSize2 = nSize2;
+            m_nClusterSize1 = size1;
+            m_nClusterSize2 = size2;
         }
 
         double m_fDist;
@@ -322,7 +327,8 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
      * comparator used by priority queue*
      */
     class TupleComparator implements Comparator<Tuple> {
-        public int compare(final Tuple o1, final Tuple o2) {
+        @Override
+		public int compare(final Tuple o1, final Tuple o2) {
             if (o1.m_fDist < o2.m_fDist) {
                 return -1;
             } else if (o1.m_fDist == o2.m_fDist) {
@@ -333,24 +339,24 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
     }
 
     // return distance according to distance metric
-    double distance(final int iTaxon1, final int iTaxon2) {
-        return distance.pairwiseDistance(iTaxon1, iTaxon2);
+    double distance(final int taxon1, final int taxon2) {
+        return distance.pairwiseDistance(taxon1, taxon2);
     } // distance
 
     // 1-norm
-    double distance(final double[] nPattern1, final double[] nPattern2) {
-        double fDist = 0;
+    double distance(final double[] pattern1, final double[] pattern2) {
+        double dist = 0;
         for (int i = 0; i < dataInput.get().getPatternCount(); i++) {
-            fDist += dataInput.get().getPatternWeight(i) * Math.abs(nPattern1[i] - nPattern2[i]);
+            dist += dataInput.get().getPatternWeight(i) * Math.abs(pattern1[i] - pattern2[i]);
         }
-        return fDist / dataInput.get().getSiteCount();
+        return dist / dataInput.get().getSiteCount();
     }
 
 
     @SuppressWarnings("unchecked")
-    public Node buildClusterer() throws Exception {
-        final int nTaxa = taxaNames.size();
-        if (nTaxa == 1) {
+    public Node buildClusterer() {
+        final int taxonCount = taxaNames.size();
+        if (taxonCount == 1) {
             // pathological case
             final Node node = newNode();
             node.setHeight(1);
@@ -360,26 +366,26 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
 
         // use array of integer vectors to store cluster indices,
         // starting with one cluster per instance
-        final List<Integer>[] nClusterID = new ArrayList[nTaxa];
-        for (int i = 0; i < nTaxa; i++) {
-            nClusterID[i] = new ArrayList<Integer>();
-            nClusterID[i].add(i);
+        final List<Integer>[] clusterID = new ArrayList[taxonCount];
+        for (int i = 0; i < taxonCount; i++) {
+            clusterID[i] = new ArrayList<>();
+            clusterID[i].add(i);
         }
         // calculate distance matrix
-        final int nClusters = nTaxa;
+        final int clusters = taxonCount;
 
         // used for keeping track of hierarchy
-        final NodeX[] clusterNodes = new NodeX[nTaxa];
-        if (nLinkType == Type.neighborjoining || nLinkType == Type.neighborjoining2) {
-            neighborJoining(nClusters, nClusterID, clusterNodes);
+        final NodeX[] clusterNodes = new NodeX[taxonCount];
+        if (linkType == Type.neighborjoining || linkType == Type.neighborjoining2) {
+            neighborJoining(clusters, clusterID, clusterNodes);
         } else {
-            doLinkClustering(nClusters, nClusterID, clusterNodes);
+            doLinkClustering(clusters, clusterID, clusterNodes);
         }
 
         // move all clusters in m_nClusterID array
         // & collect hierarchy
-        for (int i = 0; i < nTaxa; i++) {
-            if (nClusterID[i].size() > 0) {
+        for (int i = 0; i < taxonCount; i++) {
+            if (clusterID[i].size() > 0) {
                 return clusterNodes[i].toNode();
             }
         }
@@ -391,117 +397,117 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
      * This is roughly based on the RapidNJ simple implementation and runs at O(n^3)
      * More efficient implementations exist, see RapidNJ (or my GPU implementation :-))
      *
-     * @param nClusters
-     * @param nClusterID
+     * @param clusters
+     * @param clusterID
      * @param clusterNodes
      */
-    void neighborJoining(int nClusters, final List<Integer>[] nClusterID, final NodeX[] clusterNodes) {
+    void neighborJoining(int clusters, final List<Integer>[] clusterID, final NodeX[] clusterNodes) {
         final int n = taxaNames.size();
 
-        final double[][] fDist = new double[nClusters][nClusters];
-        for (int i = 0; i < nClusters; i++) {
-            fDist[i][i] = 0;
-            for (int j = i + 1; j < nClusters; j++) {
-                fDist[i][j] = getDistance0(nClusterID[i], nClusterID[j]);
-                fDist[j][i] = fDist[i][j];
+        final double[][] dist = new double[clusters][clusters];
+        for (int i = 0; i < clusters; i++) {
+            dist[i][i] = 0;
+            for (int j = i + 1; j < clusters; j++) {
+                dist[i][j] = getDistance0(clusterID[i], clusterID[j]);
+                dist[j][i] = dist[i][j];
             }
         }
 
-        final double[] fSeparationSums = new double[n];
-        final double[] fSeparations = new double[n];
-        final int[] nNextActive = new int[n];
+        final double[] separationSums = new double[n];
+        final double[] separations = new double[n];
+        final int[] nextActive = new int[n];
 
         //calculate initial separation rows
         for (int i = 0; i < n; i++) {
-            double fSum = 0;
+            double sum = 0;
             for (int j = 0; j < n; j++) {
-                fSum += fDist[i][j];
+                sum += dist[i][j];
             }
-            fSeparationSums[i] = fSum;
-            fSeparations[i] = fSum / (nClusters - 2);
-            nNextActive[i] = i + 1;
+            separationSums[i] = sum;
+            separations[i] = sum / (clusters - 2);
+            nextActive[i] = i + 1;
         }
 
-        while (nClusters > 2) {
+        while (clusters > 2) {
             // find minimum
-            int iMin1 = -1;
-            int iMin2 = -1;
-            double fMin = Double.MAX_VALUE;
+            int min1 = -1;
+            int min2 = -1;
+            double min = Double.MAX_VALUE;
             {
                 int i = 0;
                 while (i < n) {
-                    final double fSep1 = fSeparations[i];
-                    final double[] fRow = fDist[i];
-                    int j = nNextActive[i];
+                    final double sep1 = separations[i];
+                    final double[] row = dist[i];
+                    int j = nextActive[i];
                     while (j < n) {
-                        final double fSep2 = fSeparations[j];
-                        final double fVal = fRow[j] - fSep1 - fSep2;
-                        if (fVal < fMin) {
+                        final double sep2 = separations[j];
+                        final double val = row[j] - sep1 - sep2;
+                        if (val < min) {
                             // new minimum
-                            iMin1 = i;
-                            iMin2 = j;
-                            fMin = fVal;
+                            min1 = i;
+                            min2 = j;
+                            min = val;
                         }
-                        j = nNextActive[j];
+                        j = nextActive[j];
                     }
-                    i = nNextActive[i];
+                    i = nextActive[i];
                 }
             }
             // record distance
-            final double fMinDistance = fDist[iMin1][iMin2];
-            nClusters--;
-            final double fSep1 = fSeparations[iMin1];
-            final double fSep2 = fSeparations[iMin2];
-            final double fDist1 = (0.5 * fMinDistance) + (0.5 * (fSep1 - fSep2));
-            final double fDist2 = (0.5 * fMinDistance) + (0.5 * (fSep2 - fSep1));
-            if (nClusters > 2) {
+            final double minDistance = dist[min1][min2];
+            clusters--;
+            final double sep1 = separations[min1];
+            final double sep2 = separations[min2];
+            final double dist1 = (0.5 * minDistance) + (0.5 * (sep1 - sep2));
+            final double dist2 = (0.5 * minDistance) + (0.5 * (sep2 - sep1));
+            if (clusters > 2) {
                 // update separations  & distance
-                double fNewSeparationSum = 0;
-                final double fMutualDistance = fDist[iMin1][iMin2];
-                final double[] fRow1 = fDist[iMin1];
-                final double[] fRow2 = fDist[iMin2];
+                double newSeparationSum = 0;
+                final double mutualDistance = dist[min1][min2];
+                final double[] row1 = dist[min1];
+                final double[] row2 = dist[min2];
                 for (int i = 0; i < n; i++) {
-                    if (i == iMin1 || i == iMin2 || nClusterID[i].size() == 0) {
-                        fRow1[i] = 0;
+                    if (i == min1 || i == min2 || clusterID[i].size() == 0) {
+                        row1[i] = 0;
                     } else {
-                        final double fVal1 = fRow1[i];
-                        final double fVal2 = fRow2[i];
-                        final double fDistance = (fVal1 + fVal2 - fMutualDistance) / 2.0;
-                        fNewSeparationSum += fDistance;
+                        final double val1 = row1[i];
+                        final double val2 = row2[i];
+                        final double distance = (val1 + val2 - mutualDistance) / 2.0;
+                        newSeparationSum += distance;
                         // update the separationsum of cluster i.
-                        fSeparationSums[i] += (fDistance - fVal1 - fVal2);
-                        fSeparations[i] = fSeparationSums[i] / (nClusters - 2);
-                        fRow1[i] = fDistance;
-                        fDist[i][iMin1] = fDistance;
+                        separationSums[i] += (distance - val1 - val2);
+                        separations[i] = separationSums[i] / (clusters - 2);
+                        row1[i] = distance;
+                        dist[i][min1] = distance;
                     }
                 }
-                fSeparationSums[iMin1] = fNewSeparationSum;
-                fSeparations[iMin1] = fNewSeparationSum / (nClusters - 2);
-                fSeparationSums[iMin2] = 0;
-                merge(iMin1, iMin2, fDist1, fDist2, nClusterID, clusterNodes);
-                int iPrev = iMin2;
-                // since iMin1 < iMin2 we havenActiveRows[0] >= 0, so the next loop should be save
-                while (nClusterID[iPrev].size() == 0) {
-                    iPrev--;
+                separationSums[min1] = newSeparationSum;
+                separations[min1] = newSeparationSum / (clusters - 2);
+                separationSums[min2] = 0;
+                merge(min1, min2, dist1, dist2, clusterID, clusterNodes);
+                int prev = min2;
+                // since min1 < min2 we havenActiveRows[0] >= 0, so the next loop should be save
+                while (clusterID[prev].size() == 0) {
+                    prev--;
                 }
-                nNextActive[iPrev] = nNextActive[iMin2];
+                nextActive[prev] = nextActive[min2];
             } else {
-                merge(iMin1, iMin2, fDist1, fDist2, nClusterID, clusterNodes);
+                merge(min1, min2, dist1, dist2, clusterID, clusterNodes);
                 break;
             }
         }
 
         for (int i = 0; i < n; i++) {
-            if (nClusterID[i].size() > 0) {
+            if (clusterID[i].size() > 0) {
                 for (int j = i + 1; j < n; j++) {
-                    if (nClusterID[j].size() > 0) {
-                        final double fDist1 = fDist[i][j];
-                        if (nClusterID[i].size() == 1) {
-                            merge(i, j, fDist1, 0, nClusterID, clusterNodes);
-                        } else if (nClusterID[j].size() == 1) {
-                            merge(i, j, 0, fDist1, nClusterID, clusterNodes);
+                    if (clusterID[j].size() > 0) {
+                        final double dist1 = dist[i][j];
+                        if (clusterID[i].size() == 1) {
+                            merge(i, j, dist1, 0, clusterID, clusterNodes);
+                        } else if (clusterID[j].size() == 1) {
+                            merge(i, j, 0, dist1, clusterID, clusterNodes);
                         } else {
-                            merge(i, j, fDist1 / 2.0, fDist1 / 2.0, nClusterID, clusterNodes);
+                            merge(i, j, dist1 / 2.0, dist1 / 2.0, clusterID, clusterNodes);
                         }
                         break;
                     }
@@ -514,91 +520,91 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
      * Perform clustering using a link method
      * This implementation uses a priority queue resulting in a O(n^2 log(n)) algorithm
      *
-     * @param nClusters    number of clusters
-     * @param nClusterID
+     * @param clusters    number of clusters
+     * @param clusterID
      * @param clusterNodes
      */
-    void doLinkClustering(int nClusters, final List<Integer>[] nClusterID, final NodeX[] clusterNodes) {
-        final int nInstances = taxaNames.size();
-        final PriorityQueue<Tuple> queue = new PriorityQueue<Tuple>(nClusters * nClusters / 2, new TupleComparator());
-        final double[][] fDistance0 = new double[nClusters][nClusters];
-        for (int i = 0; i < nClusters; i++) {
-            fDistance0[i][i] = 0;
-            for (int j = i + 1; j < nClusters; j++) {
-                fDistance0[i][j] = getDistance0(nClusterID[i], nClusterID[j]);
-                fDistance0[j][i] = fDistance0[i][j];
-                queue.add(new Tuple(fDistance0[i][j], i, j, 1, 1));
+    void doLinkClustering(int clusters, final List<Integer>[] clusterID, final NodeX[] clusterNodes) {
+        final int instances = taxaNames.size();
+        final PriorityQueue<Tuple> queue = new PriorityQueue<>(clusters * clusters / 2, new TupleComparator());
+        final double[][] distance0 = new double[clusters][clusters];
+        for (int i = 0; i < clusters; i++) {
+            distance0[i][i] = 0;
+            for (int j = i + 1; j < clusters; j++) {
+                distance0[i][j] = getDistance0(clusterID[i], clusterID[j]);
+                distance0[j][i] = distance0[i][j];
+                queue.add(new Tuple(distance0[i][j], i, j, 1, 1));
             }
         }
-        while (nClusters > 1) {
-            int iMin1 = -1;
-            int iMin2 = -1;
+        while (clusters > 1) {
+            int min1 = -1;
+            int min2 = -1;
             // use priority queue to find next best pair to cluster
             Tuple t;
             do {
                 t = queue.poll();
             }
-            while (t != null && (nClusterID[t.m_iCluster1].size() != t.m_nClusterSize1 || nClusterID[t.m_iCluster2].size() != t.m_nClusterSize2));
-            iMin1 = t.m_iCluster1;
-            iMin2 = t.m_iCluster2;
-            merge(iMin1, iMin2, t.m_fDist/2.0, t.m_fDist/2.0, nClusterID, clusterNodes);
+            while (t != null && (clusterID[t.m_iCluster1].size() != t.m_nClusterSize1 || clusterID[t.m_iCluster2].size() != t.m_nClusterSize2));
+            min1 = t.m_iCluster1;
+            min2 = t.m_iCluster2;
+            merge(min1, min2, t.m_fDist/2.0, t.m_fDist/2.0, clusterID, clusterNodes);
             // merge  clusters
 
             // update distances & queue
-            for (int i = 0; i < nInstances; i++) {
-                if (i != iMin1 && nClusterID[i].size() != 0) {
-                    final int i1 = Math.min(iMin1, i);
-                    final int i2 = Math.max(iMin1, i);
-                    final double fDistance = getDistance(fDistance0, nClusterID[i1], nClusterID[i2]);
-                    queue.add(new Tuple(fDistance, i1, i2, nClusterID[i1].size(), nClusterID[i2].size()));
+            for (int i = 0; i < instances; i++) {
+                if (i != min1 && clusterID[i].size() != 0) {
+                    final int i1 = Math.min(min1, i);
+                    final int i2 = Math.max(min1, i);
+                    final double distance = getDistance(distance0, clusterID[i1], clusterID[i2]);
+                    queue.add(new Tuple(distance, i1, i2, clusterID[i1].size(), clusterID[i2].size()));
                 }
             }
 
-            nClusters--;
+            clusters--;
         }
     } // doLinkClustering
 
-    void merge(int iMin1, int iMin2, double fDist1, double fDist2, final List<Integer>[] nClusterID, final NodeX[] clusterNodes) {
-        if (iMin1 > iMin2) {
-            final int h = iMin1;
-            iMin1 = iMin2;
-            iMin2 = h;
-            final double f = fDist1;
-            fDist1 = fDist2;
-            fDist2 = f;
+    void merge(int min1, int min2, double dist1, double dist2, final List<Integer>[] clusterID, final NodeX[] clusterNodes) {
+        if (min1 > min2) {
+            final int h = min1;
+            min1 = min2;
+            min2 = h;
+            final double f = dist1;
+            dist1 = dist2;
+            dist2 = f;
         }
-        nClusterID[iMin1].addAll(nClusterID[iMin2]);
-        //nClusterID[iMin2].removeAllElements();
-        nClusterID[iMin2].removeAll(nClusterID[iMin2]);
+        clusterID[min1].addAll(clusterID[min2]);
+        //clusterID[min2].removeAllElements();
+        clusterID[min2].removeAll(clusterID[min2]);
 
         // track hierarchy
         final NodeX node = new NodeX();
-        if (clusterNodes[iMin1] == null) {
-            node.m_iLeftInstance = iMin1;
+        if (clusterNodes[min1] == null) {
+            node.m_iLeftInstance = min1;
         } else {
-            node.m_left = clusterNodes[iMin1];
-            clusterNodes[iMin1].m_parent = node;
+            node.m_left = clusterNodes[min1];
+            clusterNodes[min1].m_parent = node;
         }
-        if (clusterNodes[iMin2] == null) {
-            node.m_iRightInstance = iMin2;
+        if (clusterNodes[min2] == null) {
+            node.m_iRightInstance = min2;
         } else {
-            node.m_right = clusterNodes[iMin2];
-            clusterNodes[iMin2].m_parent = node;
+            node.m_right = clusterNodes[min2];
+            clusterNodes[min2].m_parent = node;
         }
         if (distanceIsBranchLength) {
-            node.setLength(fDist1, fDist2);
+            node.setLength(dist1, dist2);
         } else {
-            node.setHeight(fDist1, fDist2);
+            node.setHeight(dist1, dist2);
         }
-        clusterNodes[iMin1] = node;
+        clusterNodes[min1] = node;
     } // merge
 
     /**
      * calculate distance the first time when setting up the distance matrix *
      */
     double getDistance0(final List<Integer> cluster1, final List<Integer> cluster2) {
-        double fBestDist = Double.MAX_VALUE;
-        switch (nLinkType) {
+        double bestDist = Double.MAX_VALUE;
+        switch (linkType) {
             case single:
             case neighborjoining:
             case neighborjoining2:
@@ -608,7 +614,7 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
             case average:
             case mean:
                 // set up two instances for distance function
-                fBestDist = distance(cluster1.get(0), cluster2.get(0));
+                bestDist = distance(cluster1.get(0), cluster2.get(0));
                 break;
             case ward: {
                 // finds the distance of the change in caused by merging the cluster.
@@ -616,15 +622,17 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
                 // centroids of the cluster and its members.
                 final double ESS1 = calcESS(cluster1);
                 final double ESS2 = calcESS(cluster2);
-                final List<Integer> merged = new ArrayList<Integer>();
+                final List<Integer> merged = new ArrayList<>();
                 merged.addAll(cluster1);
                 merged.addAll(cluster2);
                 final double ESS = calcESS(merged);
-                fBestDist = ESS * merged.size() - ESS1 * cluster1.size() - ESS2 * cluster2.size();
+                bestDist = ESS * merged.size() - ESS1 * cluster1.size() - ESS2 * cluster2.size();
             }
             break;
+		default:
+			break;
         }
-        return fBestDist;
+        return bestDist;
     } // getDistance0
 
     /**
@@ -634,20 +642,20 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
      * @param cluster2 dito for second cluster
      * @return distance between clusters based on link type
      */
-    double getDistance(final double[][] fDistance, final List<Integer> cluster1, final List<Integer> cluster2) {
-        double fBestDist = Double.MAX_VALUE;
-        switch (nLinkType) {
+    double getDistance(final double[][] distance, final List<Integer> cluster1, final List<Integer> cluster2) {
+        double bestDist = Double.MAX_VALUE;
+        switch (linkType) {
             case single:
                 // find single link distance aka minimum link, which is the closest distance between
                 // any item in cluster1 and any item in cluster2
-                fBestDist = Double.MAX_VALUE;
+                bestDist = Double.MAX_VALUE;
                 for (int i = 0; i < cluster1.size(); i++) {
                     final int i1 = cluster1.get(i);
                     for (int j = 0; j < cluster2.size(); j++) {
                         final int i2 = cluster2.get(j);
-                        final double fDist = fDistance[i1][i2];
-                        if (fBestDist > fDist) {
-                            fBestDist = fDist;
+                        final double dist = distance[i1][i2];
+                        if (bestDist > dist) {
+                            bestDist = dist;
                         }
                     }
                 }
@@ -656,29 +664,29 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
             case adjcomplete:
                 // find complete link distance aka maximum link, which is the largest distance between
                 // any item in cluster1 and any item in cluster2
-                fBestDist = 0;
+                bestDist = 0;
                 for (int i = 0; i < cluster1.size(); i++) {
                     final int i1 = cluster1.get(i);
                     for (int j = 0; j < cluster2.size(); j++) {
                         final int i2 = cluster2.get(j);
-                        final double fDist = fDistance[i1][i2];
-                        if (fBestDist < fDist) {
-                            fBestDist = fDist;
+                        final double dist = distance[i1][i2];
+                        if (bestDist < dist) {
+                            bestDist = dist;
                         }
                     }
                 }
-                if (nLinkType == Type.complete) {
+                if (linkType == Type.complete) {
                     break;
                 }
                 // calculate adjustment, which is the largest within cluster distance
-                double fMaxDist = 0;
+                double maxDist = 0;
                 for (int i = 0; i < cluster1.size(); i++) {
                     final int i1 = cluster1.get(i);
                     for (int j = i + 1; j < cluster1.size(); j++) {
                         final int i2 = cluster1.get(j);
-                        final double fDist = fDistance[i1][i2];
-                        if (fMaxDist < fDist) {
-                            fMaxDist = fDist;
+                        final double dist = distance[i1][i2];
+                        if (maxDist < dist) {
+                            maxDist = dist;
                         }
                     }
                 }
@@ -686,65 +694,65 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
                     final int i1 = cluster2.get(i);
                     for (int j = i + 1; j < cluster2.size(); j++) {
                         final int i2 = cluster2.get(j);
-                        final double fDist = fDistance[i1][i2];
-                        if (fMaxDist < fDist) {
-                            fMaxDist = fDist;
+                        final double dist = distance[i1][i2];
+                        if (maxDist < dist) {
+                            maxDist = dist;
                         }
                     }
                 }
-                fBestDist -= fMaxDist;
+                bestDist -= maxDist;
                 break;
             case average:
                 // finds average distance between the elements of the two clusters
-                fBestDist = 0;
+                bestDist = 0;
                 for (int i = 0; i < cluster1.size(); i++) {
                     final int i1 = cluster1.get(i);
                     for (int j = 0; j < cluster2.size(); j++) {
                         final int i2 = cluster2.get(j);
-                        fBestDist += fDistance[i1][i2];
+                        bestDist += distance[i1][i2];
                     }
                 }
-                fBestDist /= (cluster1.size() * cluster2.size());
+                bestDist /= (cluster1.size() * cluster2.size());
                 break;
             case mean: {
                 // calculates the mean distance of a merged cluster (akak Group-average agglomerative clustering)
-                final List<Integer> merged = new ArrayList<Integer>();
+                final List<Integer> merged = new ArrayList<>();
                 merged.addAll(cluster1);
                 merged.addAll(cluster2);
-                fBestDist = 0;
+                bestDist = 0;
                 for (int i = 0; i < merged.size(); i++) {
                     final int i1 = merged.get(i);
                     for (int j = i + 1; j < merged.size(); j++) {
                         final int i2 = merged.get(j);
-                        fBestDist += fDistance[i1][i2];
+                        bestDist += distance[i1][i2];
                     }
                 }
                 final int n = merged.size();
-                fBestDist /= (n * (n - 1.0) / 2.0);
+                bestDist /= (n * (n - 1.0) / 2.0);
             }
             break;
             case centroid:
                 // finds the distance of the centroids of the clusters
-                final int nPatterns = dataInput.get().getPatternCount();
-                final double[] centroid1 = new double[nPatterns];
+                final int patterns = dataInput.get().getPatternCount();
+                final double[] centroid1 = new double[patterns];
                 for (int i = 0; i < cluster1.size(); i++) {
-                    final int iTaxon = cluster1.get(i);
-                    for (int j = 0; j < nPatterns; j++) {
-                        centroid1[j] += dataInput.get().getPattern(iTaxon, j);
+                    final int taxonIndex = cluster1.get(i);
+                    for (int j = 0; j < patterns; j++) {
+                        centroid1[j] += dataInput.get().getPattern(taxonIndex, j);
                     }
                 }
-                final double[] centroid2 = new double[nPatterns];
+                final double[] centroid2 = new double[patterns];
                 for (int i = 0; i < cluster2.size(); i++) {
-                    final int iTaxon = cluster2.get(i);
-                    for (int j = 0; j < nPatterns; j++) {
-                        centroid2[j] += dataInput.get().getPattern(iTaxon, j);
+                    final int taxonIndex = cluster2.get(i);
+                    for (int j = 0; j < patterns; j++) {
+                        centroid2[j] += dataInput.get().getPattern(taxonIndex, j);
                     }
                 }
-                for (int j = 0; j < nPatterns; j++) {
+                for (int j = 0; j < patterns; j++) {
                     centroid1[j] /= cluster1.size();
                     centroid2[j] /= cluster2.size();
                 }
-                fBestDist = distance(centroid1, centroid2);
+                bestDist = distance(centroid1, centroid2);
                 break;
             case ward: {
                 // finds the distance of the change in caused by merging the cluster.
@@ -752,15 +760,17 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
                 // centroids of the cluster and its members.
                 final double ESS1 = calcESS(cluster1);
                 final double ESS2 = calcESS(cluster2);
-                final List<Integer> merged = new ArrayList<Integer>();
+                final List<Integer> merged = new ArrayList<>();
                 merged.addAll(cluster1);
                 merged.addAll(cluster2);
                 final double ESS = calcESS(merged);
-                fBestDist = ESS * merged.size() - ESS1 * cluster1.size() - ESS2 * cluster2.size();
+                bestDist = ESS * merged.size() - ESS1 * cluster1.size() - ESS2 * cluster2.size();
             }
             break;
+		default:
+			break;
         }
-        return fBestDist;
+        return bestDist;
     } // getDistance
 
 
@@ -768,28 +778,28 @@ public class ClusterTree extends Tree implements StateNodeInitialiser {
      * calculated error sum-of-squares for instances wrt centroid *
      */
     double calcESS(final List<Integer> cluster) {
-        final int nPatterns = dataInput.get().getPatternCount();
-        final double[] centroid = new double[nPatterns];
+        final int patterns = dataInput.get().getPatternCount();
+        final double[] centroid = new double[patterns];
         for (int i = 0; i < cluster.size(); i++) {
-            final int iTaxon = cluster.get(i);
-            for (int j = 0; j < nPatterns; j++) {
-                centroid[j] += dataInput.get().getPattern(iTaxon, j);
+            final int taxonIndex = cluster.get(i);
+            for (int j = 0; j < patterns; j++) {
+                centroid[j] += dataInput.get().getPattern(taxonIndex, j);
             }
         }
-        for (int j = 0; j < nPatterns; j++) {
+        for (int j = 0; j < patterns; j++) {
             centroid[j] /= cluster.size();
         }
         // set up two instances for distance function
-        double fESS = 0;
+        double eSS = 0;
         for (int i = 0; i < cluster.size(); i++) {
-            final double[] instance = new double[nPatterns];
-            final int iTaxon = cluster.get(i);
-            for (int j = 0; j < nPatterns; j++) {
-                instance[j] += dataInput.get().getPattern(iTaxon, j);
+            final double[] instance = new double[patterns];
+            final int taxonIndex = cluster.get(i);
+            for (int j = 0; j < patterns; j++) {
+                instance[j] += dataInput.get().getPattern(taxonIndex, j);
             }
-            fESS += distance(centroid, instance);
+            eSS += distance(centroid, instance);
         }
-        return fESS / cluster.size();
+        return eSS / cluster.size();
     } // calcESS
 
     @Override
diff --git a/src/beast/util/CollectionUtils.java b/src/beast/util/CollectionUtils.java
index 98f5512..52ea801 100644
--- a/src/beast/util/CollectionUtils.java
+++ b/src/beast/util/CollectionUtils.java
@@ -20,9 +20,9 @@ public class CollectionUtils {
         return intersection(Arrays.asList(array1), Arrays.asList(array2));
     }
 
-    public static <E> int indexof(E sLabel, E[] m_sLabels) {
+    public static <E> int indexof(E label, E[] m_sLabels) {
         for (int i = 0; i < m_sLabels.length ; i++) {
-            if (m_sLabels[i].equals(sLabel)) {
+            if (m_sLabels[i].equals(label)) {
                 return i;
             }
         }
diff --git a/src/beast/util/CredibleSet.java b/src/beast/util/CredibleSet.java
index 5e2fb1e..379d856 100644
--- a/src/beast/util/CredibleSet.java
+++ b/src/beast/util/CredibleSet.java
@@ -21,7 +21,7 @@ public class CredibleSet<T> {
     public double targetCum = 1.0;
 
     public CredibleSet(double credSetProbability) {
-        credibleSetList = new ArrayList<T>();
+        credibleSetList = new ArrayList<>();
         this.credSetProbability = credSetProbability;
     }
 
diff --git a/src/beast/util/FrequencySet.java b/src/beast/util/FrequencySet.java
index 102417a..d79c71b 100644
--- a/src/beast/util/FrequencySet.java
+++ b/src/beast/util/FrequencySet.java
@@ -25,7 +25,12 @@
 
 package beast.util;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 
 /**
  * modified from BEAST 1 FrequencySet<T>
@@ -124,7 +129,7 @@ public class FrequencySet<T> {
      */
     @Override
     public boolean equals(Object obj) {
-        return (obj instanceof FrequencySet) && sortedList.equals(((FrequencySet) obj).sortedList);
+        return (obj instanceof FrequencySet) && sortedList.equals(((FrequencySet<?>) obj).sortedList);
     }
 
     public Map<T, Integer> getFrequencyMap() {
@@ -137,7 +142,7 @@ public class FrequencySet<T> {
      * @return
      */
     public CredibleSet<T> getCredibleSet(T target) {
-        CredibleSet<T> credibleSet = new CredibleSet<T>(getCredSetProbability());
+        CredibleSet<T> credibleSet = new CredibleSet<>(getCredSetProbability());
         credibleSet.setCredibleSetList(target, this);
         return credibleSet;
     }
@@ -171,13 +176,14 @@ public class FrequencySet<T> {
     // Private stuff
     //
 
-    private List<T> sortedList = new ArrayList<T>();
-    private Map<T, Integer> frequencyMap = new HashMap<T, Integer>();
+    private List<T> sortedList = new ArrayList<>();
+    private Map<T, Integer> frequencyMap = new HashMap<>();
     private boolean sorted = false;
     private double credSetProbability = 0;
 
     private Comparator<T> frequencyComparator = new Comparator<T>() {
-        public int compare(T obj1, T obj2) {
+        @Override
+		public int compare(T obj1, T obj2) {
             return frequencyMap.get(obj2) - frequencyMap.get(obj1);
         }
     };
diff --git a/src/beast/util/InputType.java b/src/beast/util/InputType.java
new file mode 100644
index 0000000..a431650
--- /dev/null
+++ b/src/beast/util/InputType.java
@@ -0,0 +1,66 @@
+package beast.util;
+
+/** helper class that shares common properties of Inputs and Param annotations **/
+public class InputType {
+
+	/** name of Input or Param annotation **/
+	String name;
+	
+	/** type of Input or Param annotation **/
+	Class<?> type;
+	
+	/** whether this is Input or Param annotation **/
+	boolean isInput;
+	
+	/** default value when no value is specified, if any **/
+	Object defaultValue;
+	
+	/** c'tor **/
+	public InputType(String name, Class<?> type, boolean isInput, Object defaultValue) {
+		this.name = name;
+		this.type = type;
+		this.isInput = isInput;
+		this.defaultValue = defaultValue;
+	}
+
+	
+	/** getters & setters **/
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Class<?> getType() {
+		return type;
+	}
+
+	public void setType(Class<?> type) {
+		this.type = type;
+	}
+	
+	public boolean isInput() {
+		return isInput;
+	}
+
+	public void setInput(boolean isInput) {
+		this.isInput = isInput;
+	}
+
+
+	public Object getDefaultValue() {
+		return defaultValue;
+	}
+
+
+	public void setDefaultValue(Object defaultValue) {
+		this.defaultValue = defaultValue;
+	}
+
+	@Override
+	public String toString() {
+		return getName() + " " + getType().getName() + " " + isInput() + " " + getDefaultValue();
+	}
+}
diff --git a/src/beast/util/JSONParser.java b/src/beast/util/JSONParser.java
index bf13f6c..b066054 100644
--- a/src/beast/util/JSONParser.java
+++ b/src/beast/util/JSONParser.java
@@ -1,5 +1,5 @@
 /*
- * File XMLParser.java
+ * File JSONParser.java
  *
  * Copyright (C) 2010 Remco Bouckaert remco at cs.auckland.ac.nz
  *
@@ -25,38 +25,53 @@
 package beast.util;
 
 
-import org.json.JSONArray;
-import org.json.JSONObject;
 
-import beast.app.beauti.PartitionContext;
-import beast.core.*;
-import beast.core.Input.Validate;
-import beast.core.Runnable;
-import beast.core.parameter.Parameter;
-import beast.core.parameter.RealParameter;
+
 
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
 import java.io.PrintStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-/** parses YABBY JSON file into a set of YABBY objects **/
-public class JSONParser {
-	final public static String ANALYSIS_ELEMENT = "analysis";
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
 
+import beast.app.beauti.PartitionContext;
+import beast.core.BEASTInterface;
+import beast.core.Input;
+import beast.core.Input.Validate;
+import beast.core.Param;
+import beast.core.Runnable;
+import beast.core.State;
+import beast.core.parameter.Map;
+import beast.core.parameter.Parameter;
+import beast.core.parameter.RealParameter;
+import beast.core.util.Log;
+import beast.util.XMLParser.NameValuePair;
+
+
+/** parses BEAST JSON file into a set of BEAST objects **/
+public class JSONParser {
 	final static String INPUT_CLASS = Input.class.getName();
-	final static String YOBJECT_CLASS = BEASTInterface.class.getName();
+	final static String BEAST_OBJECT_CLASS = BEASTInterface.class.getName();
 	final static String RUNNABLE_CLASS = Runnable.class.getName();
 
 	Runnable runnable;
 	State state;
 	/**
-	 * DOM document representation of XML file *
+	 * JSONObject document representation of JSON file *
 	 */
 	JSONObject doc;
 
@@ -72,52 +87,59 @@ public class JSONParser {
 	static HashMap<String, String> element2ClassMap;
 	static Set<String> reservedElements;
 	static {
-		element2ClassMap = new HashMap<String, String>();
-		reservedElements = new HashSet<String>();
+		element2ClassMap = new HashMap<>();
+		reservedElements = new HashSet<>();
 		for (String element : element2ClassMap.keySet()) {
 			reservedElements.add(element);
 		}
 	}
 
-	List<BEASTInterface> pluginsWaitingToInit;
-	List<JSONObject> nodesWaitingToInit;
+	class BEASTObjectWrapper {
+		public BEASTObjectWrapper(BEASTInterface object, JSONObject node) {
+			this.object = object;
+			this.node = node;
+		}
+		
+		BEASTInterface object;
+		JSONObject node;
+	}
+	List<BEASTObjectWrapper> objectsWaitingToInit;
 
 	public HashMap<String, String> getElement2ClassMap() {
 		return element2ClassMap;
 	}
 
-	String[] m_sNameSpaces;
+	String[] nameSpaces;
 
 	/**
 	 * Flag to indicate initAndValidate should be called after all inputs of a
-	 * plugin have been parsed
+	 * beastObject have been parsed
 	 */
-	boolean m_bInitialize = true;
+	boolean initialise = true;
 
 	/**
-	 * when parsing XML, missing inputs can be assigned default values through a
+	 * when parsing JSON, missing inputs can be assigned default values through a
 	 * RequiredInputProvider
 	 */
 	RequiredInputProvider requiredInputProvider = null;
 	PartitionContext partitionContext = null;
 
 	public JSONParser() {
-		pluginsWaitingToInit = new ArrayList<BEASTInterface>();
-		nodesWaitingToInit = new ArrayList<JSONObject>();
+		objectsWaitingToInit = new ArrayList<>();
 	}
 
-	public Runnable parseFile(File file) throws Exception {
+	public Runnable parseFile(File file) throws IOException, JSONException, JSONParserException {
 		// parse the JSON file into a JSONObject
 		
 		// first get rid of comments: remove all text on lines starting with space followed by //
 		// keep line breaks so that error reporting indicates the correct line.
 		BufferedReader fin = new BufferedReader(new FileReader(file));
 		StringBuffer buf = new StringBuffer();
-		String sStr = null;
+		String str = null;
 		while (fin.ready()) {
-			sStr = fin.readLine();
-			if (!sStr.matches("^\\s*//.*")) {
-				buf.append(sStr);
+			str = fin.readLine();
+			if (!str.matches("^\\s*//.*")) {
+				buf.append(str);
 			}
 			buf.append('\n');
 		}
@@ -126,39 +148,85 @@ public class JSONParser {
 		doc = new JSONObject(buf.toString());
 		processPlates(doc);
 
-		IDMap = new HashMap<String, BEASTInterface>();
-		likelihoodMap = new HashMap<String, Integer[]>();
-		IDNodeMap = new HashMap<String, JSONObject>();
+		int pointIdx = file.getName().lastIndexOf('.');
+        String baseName = pointIdx<0 ? file.getName() : file.getName().substring(0, pointIdx);
+
+        replaceVariable(doc, "filebase", baseName);
+
+        // Substitute occurrences of "$(seed)" with RNG seed
+        replaceVariable(doc, "seed", String.valueOf(Randomizer.getSeed()));
+
+		
+		IDMap = new HashMap<>();
+		likelihoodMap = new HashMap<>();
+		IDNodeMap = new HashMap<>();
 
 		parse();
 		// assert m_runnable == null || m_runnable instanceof Runnable;
 		if (runnable != null)
 			return runnable;
 		else {
-			throw new Exception("Run element does not point to a runnable object.");
+			throw new IOException("Run element does not point to a runnable object.");
 		}
 	} // parseFile
+	
+    /**
+     * @param node the node to do variable replacement in
+     * @param var the variable name to replace
+     * @param value the value to replace the variable name with
+     */
+    public static void replaceVariable(final Object json, final String var, final String value) {
+    	try {
+	        if (json instanceof JSONObject) {
+	            final JSONObject jsonobject = (JSONObject) json;
+	            for (String key : jsonobject.keySet()) {
+	                final Object attr = jsonobject.get(key);
+	                if (attr instanceof String) {
+	                	if (((String) attr).contains("$(" + var + ")")) {
+	                		String att = (String) attr;
+	                		att = att.replaceAll("\\$\\(" + var + "\\)", value);
+	                		jsonobject.put(key, att);
+	                	}
+	                } else if (attr instanceof JSONObject) {
+	                	replaceVariable(attr, var, value);
+	                } else if (attr instanceof JSONArray) {
+	                	replaceVariable(attr, var, value);
+	                }
+	            }
+		    } else if (json instanceof JSONArray) {
+		    	JSONArray array = (JSONArray) json;
+		    	for (int i = 0; i < array.length(); i++) {
+		        	Object o2 = array.get(i);
+	            	replaceVariable(o2, var, value);
+		        }
+	        } else {
+	        	// ignore
+	        }
+    	} catch (JSONException e) {
+    		// ignore?
+    	}
+    } // replaceVariable
 
 	/**
 	 * extract all elements (runnable or not) from an XML fragment. Useful for
 	 * retrieving all non-runnable elements when a template is instantiated by
 	 * Beauti *
 	 */
-	// public List<Plugin> parseTemplate(String sXML, HashMap<String, Plugin>
-	// sIDMap, boolean bInitialize) throws Exception {
-	// m_bInitialize = bInitialize;
+	// public List<BEASTObject> parseTemplate(String xml, HashMap<String, BEASTObject>
+	// idMap, boolean initialise) {
+	// m_bInitialize = initialise;
 	// // parse the XML file into a DOM document
 	// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 	// //factory.setValidating(true);
 	// doc = factory.newDocumentBuilder().parse(new InputSource(new
-	// StringReader(sXML)));
+	// StringReader(xml)));
 	// processPlates();
 	//
-	// IDMap = sIDMap;//new HashMap<String, Plugin>();
-	// likelihoodMap = new HashMap<String, Integer[]>();
-	// IDNodeMap = new HashMap<String, JSONObject>();
+	// IDMap = idMap;//new HashMap<>();
+	// likelihoodMap = new HashMap<>();
+	// IDNodeMap = new HashMap<>();
 	//
-	// List<Plugin> plugins = new ArrayList<Plugin>();
+	// List<BEASTObject> beastObjects = new ArrayList<>();
 	//
 	// // find top level beast element
 	// NodeList nodes = doc.getElementsByTagName("*");
@@ -167,15 +235,15 @@ public class JSONParser {
 	// }
 	// Node topNode = nodes.item(0);
 	// // sanity check that we are reading a beast 2 file
-	// double fVersion = getAttributeAsDouble(topNode, "version");
-	// if (!topNode.getNodeName().equals(BEAST_ELEMENT) || fVersion < 2.0 ||
-	// fVersion == Double.MAX_VALUE) {
-	// return plugins;
+	// double version = getAttributeAsDouble(topNode, "version");
+	// if (!topNode.getNodeName().equals(BEAST_ELEMENT) || version < 2.0 ||
+	// version == Double.MAX_VALUE) {
+	// return beastObjects;
 	// }
 	// // only process templates
-	// // String sType = getAttribute(topNode, "type");
-	// // if (sType == null || !sType.equals("template")) {
-	// // return plugins;
+	// // String typeName = getAttribute(topNode, "type");
+	// // if (typeName == null || !typeName.equals("template")) {
+	// // return beastObjects;
 	// // }
 	//
 	//
@@ -186,35 +254,36 @@ public class JSONParser {
 	// for (int i = 0; i < children.getLength(); i++) {
 	// if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
 	// Node child = children.item(i);
-	// System.err.println(child.getNodeName());
+	// Log.warning.println(child.getNodeName());
 	// if (!child.getNodeName().equals(MAP_ELEMENT)) {
-	// plugins.add(createObject(child, PLUGIN_CLASS, null));
+	// beastObjects.add(createObject(child, PLUGIN_CLASS, null));
 	// }
 	// }
 	// }
 	// initPlugins();
-	// return plugins;
+	// return beastObjects;
 	// } // parseTemplate
 
-	private void initPlugins() throws Exception {
+	private void initBEASTObjects() throws JSONParserException {
 		JSONObject node = null;
 		try {
-			for (int i = 0; i < pluginsWaitingToInit.size(); i++) {
-				BEASTInterface plugin = pluginsWaitingToInit.get(i);
-				node = nodesWaitingToInit.get(i);
-				plugin.initAndValidate();
+			for (int i = 0; i < objectsWaitingToInit.size(); i++) {
+				BEASTObjectWrapper bow = objectsWaitingToInit.get(i);
+				// for error handling, init node
+				node = bow.node;
+				bow.object.initAndValidate();
 			}
 		} catch (Exception e) {
 			// next lines for debugging only
-			// plugin.validateInputs();
-			// plugin.initAndValidate();
+			// beastObject.validateInputs();
+			// beastObject.initAndValidate();
 			e.printStackTrace();
 			throw new JSONParserException(node, "validate and intialize error: " + e.getMessage(), 110);
 		}
 	}
 
 	/**
-	 * Expand plates in JSON by duplicating the containing XML and replacing the
+	 * Expand plates in JSON by duplicating the containing JSON and replacing the
 	 * plate variable with the appropriate value.
 	 * "plate":{"var":"n",
 	 *  "range": ["CO1", "CO2", "Nuc"],
@@ -236,15 +305,14 @@ public class JSONParser {
 	 *  {"part":"Nuc"}
 	 *  {"otherpart":"Nuc.$(m)"}
 	 *  {"yetotherpart":"xyzNuc"}
-	 * @throws Exception 
 	 * 
 	 */
-	void processPlates(JSONObject node) throws Exception {
+	void processPlates(JSONObject node) throws IOException, JSONException, JSONParserException {
 		for (String key : node.keySet()) {
 			Object o = node.get(key);
 			if (o instanceof JSONObject) {
 				JSONObject child = (JSONObject) o;
-				processPlates((JSONObject) child);
+				processPlates(child);
 			}
 			if (o instanceof JSONArray) {
 				JSONArray list = (JSONArray) o;
@@ -262,10 +330,10 @@ public class JSONParser {
 		}
 	} // processPlates
 
-	private void unrollPlate(JSONArray list, JSONObject plate) throws Exception {
+	private void unrollPlate(JSONArray list, JSONObject plate) throws IOException, JSONParserException, JSONException {
 		int index = list.indexOf(plate);
 		if (index < 0) {
-			throw new Exception("Programmer error: plate should be in list");
+			throw new RuntimeException("Programmer error: plate should be in list");
 		}
 		list.remove(index);
 		if (plate.keySet().size() != 3 || 
@@ -311,18 +379,29 @@ public class JSONParser {
 			JSONObject orig = (JSONObject) o;
 			JSONObject copy = new JSONObject();
 			for (String key : orig.keySet()) {
-				Object value = orig.get(key);
-				Object copyValue = copyReplace(value, varStr, valueStr);
-				copy.put(key, copyValue);
+				try {
+					Object value = orig.get(key);
+					Object copyValue = copyReplace(value, varStr, valueStr);
+					copy.put(key, copyValue);
+				} catch (JSONException e) {
+					// T O D O Auto-generated catch block
+					e.printStackTrace();
+				}
 			}
 			return copy;
 		} else if (o instanceof JSONArray) {
 			JSONArray orig = (JSONArray) o;
 			JSONArray copy = new JSONArray();
 			for (int i = 0; i < orig.length(); i++) {
-				Object value = orig.get(i);
-				Object copyValue = copyReplace(value, varStr, valueStr);
-				copy.add(copyValue);
+				Object value;
+				try {
+					value = orig.get(i);
+					Object copyValue = copyReplace(value, varStr, valueStr);
+					copy.add(copyValue);
+				} catch (JSONException e) {
+					// T O D O Auto-generated catch block
+					e.printStackTrace();
+				}
 			}
 			return copy;			
 		}
@@ -330,85 +409,84 @@ public class JSONParser {
 	} // unrollPlate
 	
 
-	// /**
-	// * Parse an XML fragment representing a Plug-in
-	// * Only the run element or if that does not exist the last child element
-	// of
-	// * the top level <beast> element is considered.
-	// */
-	// public Plugin parseFragment(String sXML, boolean bInitialize) throws
-	// Exception {
-	// m_bInitialize = bInitialize;
-	// // parse the XML fragment into a DOM document
-	// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-	// doc = factory.newDocumentBuilder().parse(new InputSource(new
-	// StringReader(sXML)));
-	// doc.normalize();
-	// processPlates();
-	//
-	// IDMap = new HashMap<String, Plugin>();
-	// likelihoodMap = new HashMap<String, Integer[]>();
-	// IDNodeMap = new HashMap<String, Node>();
-	//
-	// // find top level beast element
-	// NodeList nodes = doc.getElementsByTagName("*");
-	// if (nodes == null || nodes.getLength() == 0) {
-	// throw new Exception("Expected top level beast element in XML");
-	// }
-	// Node topNode = nodes.item(0);
-	// initIDNodeMap(topNode);
-	// parseNameSpaceAndMap(topNode);
-	//
-	// NodeList children = topNode.getChildNodes();
-	// if (children.getLength() == 0) {
-	// throw new Exception("Need at least one child element");
-	// }
-	// int i = children.getLength() - 1;
-	// while (i >= 0 && (children.item(i).getNodeType() != Node.ELEMENT_NODE ||
-	// !children.item(i).getNodeName().equals("run"))) {
-	// i--;
-	// }
-	// if (i < 0) {
-	// i = children.getLength() - 1;
-	// while (i >= 0 && children.item(i).getNodeType() != Node.ELEMENT_NODE) {
-	// i--;
-	// }
-	// }
-	// if (i < 0) {
-	// throw new Exception("Need at least one child element");
-	// }
-	//
-	// Plugin plugin = createObject(children.item(i), PLUGIN_CLASS, null);
-	// initPlugins();
-	// return plugin;
-	// } // parseFragment
-	//
+	 /**
+	 * Parse an JSON fragment representing a list of BEASTObjects
+	 */
+    public List<Object> parseFragment(final String json, final boolean initialise) throws JSONParserException, JSONException {
+        this.initialise = initialise;
+		doc = new JSONObject(json);
+
+		// find top level beast element
+		JSONObject nodes = doc;
+		if (nodes == null || nodes.keySet().size() == 0) {
+			throw new JSONParserException(doc, "Expected top level 'beast' element in JSON fragment", 1001);
+		}
+		double version = getAttributeAsDouble(nodes, "version");
+		if (version < 2.0 || version == Double.MAX_VALUE) {
+			throw new JSONParserException(nodes, "Wrong version: only versions > 2.0 are supported", 101);
+		}
+
+		initIDNodeMap(doc);
+
+		parseNameSpaceAndMap(doc);
+  
+		List<Object> objects = new ArrayList<>();
+		try {
+			// find beast element
+			Object o = doc.get(XMLParser.BEAST_ELEMENT);
+			if (o == null) {
+				throw new JSONParserException(nodes, "Expected " + XMLParser.BEAST_ELEMENT + " top level object in file", 102);
+			}
+			if (!(o instanceof JSONArray)) {
+				throw new JSONParserException(nodes, "Expected " + XMLParser.BEAST_ELEMENT + " to be a list", 1020);
+			}
+			JSONArray analysis = (JSONArray) o;
+			for (int i = 0; i < analysis.length(); i++) {
+				o = analysis.get(i);
+				if (!(o instanceof JSONObject)) {
+					throw new JSONParserException(nodes, XMLParser.BEAST_ELEMENT + " should only contain objects", 1021);
+				}
+				JSONObject node = (JSONObject) o;
+				o = createObject(node, Object.class.getName());
+				objects.add(o);
+			}
+		} catch (JSONException e) {
+			throw new JSONParserException(nodes, e.getMessage(), 1004);
+		}
+		
+		if (initialise) {
+			initBEASTObjects();
+		}
+        return objects;
+    } // parseFragment
+
+    //
 	// /**
 	// * Parse XML fragment that will be wrapped in a beast element
-	// * before parsing. This allows for ease of creating Plugin objects,
+	// * before parsing. This allows for ease of creating BEASTObject objects,
 	// * like this:
 	// * Tree tree = (Tree) new
 	// XMLParser().parseBareFragment("<tree spec='beast.util.TreeParser' newick='((1:1,3:1):1,2:2)'/>");
 	// * to create a simple tree.
 	// */
-	// public Plugin parseBareFragment(String sXML, boolean bInitialize) throws
+	// public BEASTObject parseBareFragment(String xml, boolean initialise) throws
 	// Exception {
 	// // get rid of XML processing instruction
-	// sXML = sXML.replaceAll("<\\?xml[^>]*>", "");
-	// if (sXML.indexOf("<beast") > -1) {
-	// return parseFragment(sXML, bInitialize);
+	// xml = xml.replaceAll("<\\?xml[^>]*>", "");
+	// if (xml.indexOf("<beast") > -1) {
+	// return parseFragment(xml, initialise);
 	// } else {
-	// return parseFragment("<beast>" + sXML + "</beast>", bInitialize);
+	// return parseFragment("<beast>" + xml + "</beast>", initialise);
 	// }
 	// }
 	//
-	// public List<Plugin> parseBareFragments(String sXML, boolean bInitialize)
-	// throws Exception {
-	// m_bInitialize = bInitialize;
+	// public List<BEASTObject> parseBareFragments(String xml, boolean initialise)
+    //{
+	// m_bInitialize = initialise;
 	// // parse the XML fragment into a DOM document
 	// DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 	// doc = factory.newDocumentBuilder().parse(new InputSource(new
-	// StringReader(sXML)));
+	// StringReader(xml)));
 	// doc.normalize();
 	// processPlates();
 	//
@@ -422,39 +500,40 @@ public class JSONParser {
 	// parseNameSpaceAndMap(topNode);
 	//
 	// NodeList children = topNode.getChildNodes();
-	// List<Plugin> plugins = new ArrayList<Plugin>();
+	// List<BEASTObject> beastObjects = new ArrayList<>();
 	// for (int i = 0; i < children.getLength(); i++) {
 	// if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
-	// Plugin plugin = createObject(children.item(i), PLUGIN_CLASS, null);
-	// plugins.add(plugin);
+	// BEASTObject beastObject = createObject(children.item(i), PLUGIN_CLASS, null);
+	// beastObjects.add(beastObject);
 	// }
 	// }
 	// initPlugins();
-	// return plugins;
+	// return beastObjects;
 	// }
 
 	/**
 	 * parse BEAST file as DOM document
 	 * 
-	 * @throws Exception
+	 * @throws JSONParserException
 	 */
-	public void parse() throws Exception {
+	public void parse() throws JSONParserException {
 		// find top level beast element
 		JSONObject nodes = doc;
 		if (nodes == null || nodes.keySet().size() == 0) {
-			throw new Exception("Expected top level beast element in XML");
+			throw new JSONParserException(doc, "Expected top level beast element in JSON", 1001);
 		}
-		double fVersion = getAttributeAsDouble(nodes, "version");
-		if (fVersion < 2.0 || fVersion == Double.MAX_VALUE) {
+		double version = getAttributeAsDouble(nodes, "version");
+		if (version < 2.0 || version == Double.MAX_VALUE) {
 			throw new JSONParserException(nodes, "Wrong version: only versions > 2.0 are supported", 101);
 		}
 
 		initIDNodeMap(doc);
+
 		parseNameSpaceAndMap(doc);
 
 		// parseState();
 		parseRunElement(doc);
-		initPlugins();
+		initBEASTObjects();
 	} // parse
 
 	/**
@@ -462,9 +541,9 @@ public class JSONParser {
 	 * Throw exception when a duplicate id is encountered
 	 * 
 	 * @param node
-	 * @throws Exception
+	 * @throws JSONParserException
 	 */
-	void initIDNodeMap(JSONObject node) throws Exception {
+	void initIDNodeMap(JSONObject node) throws JSONParserException {
 		String ID = getID(node);
 		if (ID != null) {
 			if (IDNodeMap.containsKey(ID)) {
@@ -473,18 +552,22 @@ public class JSONParser {
 			IDNodeMap.put(ID, node);
 		}
 		for (Object key : node.keySet()) {
-			Object o = node.get((String) key);
-			if (o instanceof JSONObject) {
-				initIDNodeMap((JSONObject) o);
-			}
-			if (o instanceof JSONArray) {
-				JSONArray list = (JSONArray) o;
-				for (int i = 0; i < list.length(); i++) {
-					Object o2 = list.get(i);
-					if (o2 instanceof JSONObject) {
-						initIDNodeMap((JSONObject) o2);
+			try {
+				Object o = node.get((String) key);
+				if (o instanceof JSONObject) {
+					initIDNodeMap((JSONObject) o);
+				}
+				if (o instanceof JSONArray) {
+					JSONArray list = (JSONArray) o;
+					for (int i = 0; i < list.length(); i++) {
+						Object o2 = list.get(i);
+						if (o2 instanceof JSONObject) {
+							initIDNodeMap((JSONObject) o2);
+						}
 					}
 				}
+			} catch (JSONException e) {
+				throw new JSONParserException(node, e.getMessage(), 1002);
 			}
 		}
 	}
@@ -497,99 +580,115 @@ public class JSONParser {
 	 * name='snaplikelihood'>snap.likelihood.SnAPTreeLikelihood</map>
 	 * 
 	 * @param topNode
-	 * @throws XMLParserException
+	 * @throws JSONParserException
 	 */
-	void parseNameSpaceAndMap(JSONObject topNode) throws XMLParserException {
+	void parseNameSpaceAndMap(JSONObject topNode) throws JSONParserException {
 		// process namespaces
 		if (topNode.has("namespace")) {
-			String sNameSpace = getAttribute(topNode, "namespace");
-			setNameSpace(sNameSpace);
+			String nameSpace = getAttribute(topNode, "namespace");
+			setNameSpace(nameSpace);
 		} else {
 			// make sure that the default namespace is in there
-			if (m_sNameSpaces == null) {
-				m_sNameSpaces = new String[1];
-				m_sNameSpaces[0] = "";
+			if (nameSpaces == null) {
+				nameSpaces = new String[1];
+				nameSpaces[0] = "";
 			}
 		}
 
-		// // process map elements
-		// NodeList nodes = doc.getElementsByTagName(MAP_ELEMENT);
-		// for (int i = 0; i < nodes.getLength(); i++) {
-		// Node child = nodes.item(i);
-		// String sName = getAttribute(child, "name");
-		// if (sName == null) {
-		// throw new XMLParserException(child,
-		// "name attribute expected in map element", 300);
-		// }
-		// if (!element2ClassMap.containsKey(sName)) {
-		// // throw new XMLParserException(child, "name '" + sName +
-		// "' is already defined as " + m_sElement2ClassMap.get(sName), 301);
-		// // }
-		//
-		// // get class
-		// String sClass = child.getTextContent();
-		// // remove spaces
-		// sClass = sClass.replaceAll("\\s", "");
-		// // go through namespaces in order they are declared to find the
-		// correct class
-		// boolean bDone = false;
-		// for (String sNameSpace : m_sNameSpaces) {
-		// try {
-		// // sanity check: class should exist
-		// if (!bDone && Class.forName(sNameSpace + sClass) != null) {
-		// element2ClassMap.put(sName, sClass);
-		// System.err.println(sName + " => " + sNameSpace + sClass);
-		// String reserved = getAttribute(child, "reserved");
-		// if (reserved != null && reserved.toLowerCase().equals("true")) {
-		// reservedElements.add(sName);
-		// }
-		//
-		// bDone = true;
-		// }
-		// } catch (ClassNotFoundException e) {
-		// //System.err.println("Not found " + e.getMessage());
-		// // TODO: handle exception
-		// }
-		// }
-		// }
-		// }
+		// process map elements
+		if (topNode.has("map")) {
+			try {
+				Object o = topNode.get("map");
+				if (o instanceof JSONArray) {
+					JSONArray maps = (JSONArray) o;
+					for (int i = 0; i < maps.length(); i++) {
+						Object o2 = maps.get(i);
+						if (o2 instanceof JSONObject) {
+							JSONObject map = (JSONObject) o2;
+							if (map.has("name") && map.has("value") && map.length()==2) {
+								String mapName = map.getString("name");
+								String clazz = map.getString("value");
+								 // remove spaces
+								 clazz = clazz.replaceAll("\\s", "");
+								 // go through namespaces in order they are declared to find the
+								 // correct class
+								 boolean done = false;
+								 for (String nameSpace : nameSpaces) {
+									 // sanity check: class should exist
+									 try {
+										if (!done && Class.forName(nameSpace + clazz) != null) {
+											 element2ClassMap.put(mapName, clazz);
+											 Log.warning.println(mapName + " => " + nameSpace + clazz);
+											 done = true;
+											 //String reserved = getAttribute(child, "reserved");
+											 //if (reserved != null && reserved.toLowerCase().equals("true")) {
+											 //	 reservedElements.add(name);
+											 //}
+										 }
+									} catch (ClassNotFoundException e) {
+										// ignore -- it may be in another namespace
+										// there appears to be no good way to check a class exists other than to try and create one
+										// and test whether no exception is thrown.
+									}
+								 }
+								 if (!done) {
+									 Log.warning.println("WARNING: no class could be found for map " + mapName + " => " + clazz +". This map is ignored.");
+								 }
+
+							} else { 
+								throw new JSONParserException(map, "Expected a name and a value and nothing else", 1016);
+							}
+						} else {
+							throw new JSONParserException(topNode, "map should be a list of JSONObjects. Use for example map:[{name:\"OneOnX\", value:\"beast.math.distributions.OneOnX\"}] for a single map", 1013);
+						}
+					}
+				} else {
+					throw new JSONParserException(topNode, "map should be a list. Use for example map:[{name:\"OneOnX\", value:\"beast.math.distributions.OneOnX\"}] for a single map", 1014);
+				}
+			} catch (JSONException e) {
+				// should never get here, unless something is really wrong
+				e.printStackTrace();
+				throw new RuntimeException(e);
+			}
+		}		
 	} // parseNameSpaceAndMap
 
-	public void setNameSpace(String sNameSpaceStr) {
-		String[] sNameSpaces = sNameSpaceStr.split(":");
+	public void setNameSpace(String nameSpaceStr) {
+		String[] nameSpaces = nameSpaceStr.split(":");
 		// append dot after every non-zero namespace
-		m_sNameSpaces = new String[sNameSpaces.length + 1];
+		this.nameSpaces = new String[nameSpaces.length + 1];
 		int i = 0;
-		for (String sNameSpace : sNameSpaces) {
-			if (sNameSpace.length() > 0) {
-				if (sNameSpace.charAt(sNameSpace.length() - 1) != '.') {
-					sNameSpace += '.';
+		for (String nameSpace : nameSpaces) {
+			if (nameSpace.length() > 0) {
+				if (nameSpace.charAt(nameSpace.length() - 1) != '.') {
+					nameSpace += '.';
 				}
 			}
-			m_sNameSpaces[i++] = sNameSpace;
+			this.nameSpaces[i++] = nameSpace;
 		}
 		// make sure that the default namespace is in there
-		m_sNameSpaces[i] = "";
+		this.nameSpaces[i] = "";
 	}
 
-	void parseRunElement(JSONObject topNode) throws Exception {
-		// find mcmc element
-		Object o = doc.get(ANALYSIS_ELEMENT);
+	void parseRunElement(JSONObject topNode) throws JSONParserException {
+		// find beast element
+		try {
+		Object o = doc.get(XMLParser.BEAST_ELEMENT);
 		if (o == null) {
-			throw new JSONParserException(topNode, "Expected " + ANALYSIS_ELEMENT + " top level object in file", 102);
+			throw new JSONParserException(topNode, "Expected " + XMLParser.BEAST_ELEMENT + " top level object in file", 102);
 		}
 		if (!(o instanceof JSONArray)) {
-			throw new JSONParserException(topNode, "Expected " + ANALYSIS_ELEMENT + " to be a list", 1020);
+			throw new JSONParserException(topNode, "Expected " + XMLParser.BEAST_ELEMENT + " to be a list", 1020);
 		}
 		JSONArray analysis = (JSONArray) o;
 		runnable = null;
 		for (int i = 0; i < analysis.length(); i++) {
 			o = analysis.get(i);
 			if (!(o instanceof JSONObject)) {
-				throw new JSONParserException(topNode, ANALYSIS_ELEMENT + " should only contain objects", 1021);
+				throw new JSONParserException(topNode, XMLParser.BEAST_ELEMENT + " should only contain objects", 1021);
 			}
 			JSONObject node = (JSONObject) o;
-			o = createObject(node, RUNNABLE_CLASS, null);
+			o = createObject(node, RUNNABLE_CLASS);
 			if (o instanceof Runnable) {
 				if (runnable != null) {
 					 throw new JSONParserException(node, "Expected only one runnable element in file",  103);
@@ -600,30 +699,31 @@ public class JSONParser {
 		if (runnable == null) {
 			 throw new JSONParserException(topNode, "Expected at least one runnable element in file",  1030);
 		}
+		} catch (JSONException e) {
+			throw new JSONParserException(topNode, e.getMessage(), 1004);
+		}
 	} // parseRunElement
 
 	/**
-	 * Check that plugin is a class that is assignable to class with name
-	 * sClass. This involves a parameter clutch to deal with non-real
+	 * Check that BEASTObject is a class that is assignable to class with name
+	 * className. This involves a parameter clutch to deal with non-real
 	 * parameters. This needs a bit of work, obviously...
 	 */
-	boolean checkType(String sClass, BEASTInterface plugin) throws Exception {
+	boolean checkType(String className, BEASTInterface beastObject) throws JSONParserException {
 		// parameter clutch
-		if (plugin instanceof Parameter<?>) {
-			for (String nameSpace : m_sNameSpaces) {
-				//nameSpace = nameSpace.replaceAll("beast", "yabby");
-				if ((nameSpace + sClass).equals(RealParameter.class.getName())) {
+		if (beastObject instanceof Parameter<?>) {
+			for (String nameSpace : nameSpaces) {
+				if ((nameSpace + className).equals(RealParameter.class.getName())) {
 					return true;
 				}
 			}
 		}
-		if (sClass.equals(INPUT_CLASS)) {
+		if (className.equals(INPUT_CLASS)) {
 			return true;
 		}
-		for (String nameSpace : m_sNameSpaces) {
-			//nameSpace = nameSpace.replaceAll("beast", "yabby");
+		for (String nameSpace : nameSpaces) {
 			try {
-				if (Class.forName(nameSpace + sClass).isInstance(plugin)) {
+				if (Class.forName(nameSpace + className).isInstance(beastObject)) {
 					return true;
 				}
 			} catch (Exception e) {
@@ -633,19 +733,25 @@ public class JSONParser {
 		return false;
 	} // checkType
 
-	BEASTInterface createObject(JSONObject node, String className, BEASTInterface parent) throws Exception {
-		//className = className.replaceAll("beast", "yabby");
+	/** create a BEAST object based on the info in the node.
+	 * @param node
+	 * @param className default class name -- this means a spec attribute does not need to be 
+	 * specified if all outputs of this BEAST object have as Input type the class of this object.
+	 * @return
+	 * @throws JSONParserException
+	 */
+	BEASTInterface createObject(JSONObject node, String className) throws JSONParserException {
 		// try the IDMap first
 		String ID = getID(node);
 
 		if (ID != null) {
 			if (IDMap.containsKey(ID)) {
-				BEASTInterface plugin = IDMap.get(ID);
-				if (checkType(className, plugin)) {
-					return plugin;
+				BEASTInterface beastObject = IDMap.get(ID);
+				if (checkType(className, beastObject)) {
+					return beastObject;
 				}
 				throw new JSONParserException(node, "id=" + ID + ". Expected object of type " + className + " instead of "
-						+ plugin.getClass().getName(), 105);
+						+ beastObject.getClass().getName(), 105);
 			}
 		}
 
@@ -654,277 +760,389 @@ public class JSONParser {
 			// produce warning if there are other attributes than idref
 			if (node.keySet().size() > 1) {
 				// check if there is just 1 attribute
-				System.err.println("Element " + getAttribute((JSONObject) node.getParent(), "name") + " found with idref='" + IDRef
+				Log.warning.println("Element " + getAttribute((JSONObject) node.getParent(), "name") + " found with idref='" + IDRef
 						+ "'. All other attributes are ignored.\n");
 			}
 			if (IDMap.containsKey(IDRef)) {
-				BEASTInterface plugin = IDMap.get(IDRef);
-				if (checkType(className, plugin)) {
-					return plugin;
+				BEASTInterface beastObject = IDMap.get(IDRef);
+				if (checkType(className, beastObject)) {
+					return beastObject;
 				}
 				throw new JSONParserException(node, "id=" + IDRef + ". Expected object of type " + className + " instead of "
-						+ plugin.getClass().getName(), 106);
+						+ beastObject.getClass().getName(), 106);
 			} else if (IDNodeMap.containsKey(IDRef)) {
-				BEASTInterface plugin = createObject(IDNodeMap.get(IDRef), className, parent);
-				if (checkType(className, plugin)) {
-					return plugin;
+				BEASTInterface beastObject = createObject(IDNodeMap.get(IDRef), className);
+				if (checkType(className, beastObject)) {
+					return beastObject;
 				}
 				throw new JSONParserException(node, "id=" + IDRef + ". Expected object of type " + className + " instead of "
-						+ plugin.getClass().getName(), 107);
+						+ beastObject.getClass().getName(), 107);
 			}
 			throw new JSONParserException(node, "Could not find object associated with idref " + IDRef, 170);
 		}
 		// it's not in the ID map yet, so we have to create a new object
 		String specClass = className;
-		// String sElementName = node.getNodeName();
-
-		// if (element2ClassMap.containsKey(sElementName)) {
-		// sSpecClass = element2ClassMap.get(sElementName);
-		// }
+		String elementName = getElementName(node);
+		if (element2ClassMap.containsKey(elementName)) {
+			specClass = element2ClassMap.get(elementName);
+		}
 		String spec = getAttribute(node, "spec");
 		if (spec != null) {
 			specClass = spec;
 		}
-		//specClass = specClass.replaceAll("beast", "yabby");
 
-		Object o = null;
-		// try to create object from sSpecName, taking namespaces in account
-		try {
-			boolean bDone = false;
-			for (String nameSpace : m_sNameSpaces) {
-				try {
-					if (!bDone) {
-						//nameSpace = nameSpace.replaceAll("beast", "yabby");
-						Class<?> c = Class.forName(nameSpace + specClass); 
-						o = c.newInstance();
-						bDone = true;
-						break;
-					}
-				} catch (InstantiationException e) {
-					// we only get here when the class exists, but cannot be
-					// created
-					// for instance because it is abstract
-					throw new Exception("Cannot instantiate class. Please check the spec attribute.");
-				} catch (ClassNotFoundException e) {
-					// TODO: handle exception
-					System.err.println(e.getMessage());
+		String clazzName = null;
+		// determine clazzName from specName, taking name spaces in account
+		for (String nameSpace : nameSpaces) {
+			if (clazzName == null) {
+				if (XMLParserUtils.beastObjectNames.contains(nameSpace + specClass)) {
+					clazzName = nameSpace + specClass;
+					break;
 				}
 			}
-			if (!bDone) {
-				throw new Exception("Class could not be found. Did you mean " + guessClass(specClass) + "?");
-				// throw new ClassNotFoundException(sSpecClass);
-			}
-			// hack required to make log-parsing easier
-			if (o instanceof State) {
-				state = (State) o;
+		}
+		if (clazzName == null) {
+			// try to create the old-fashioned way by creating the class
+            boolean isDone = false;
+            for (final String nameSpace : nameSpaces) {
+                try {
+                    if (!isDone) {
+                        Class.forName(nameSpace + specClass);
+                        clazzName = nameSpace + specClass;
+                        isDone = true;
+                    }
+                } catch (ClassNotFoundException e) {
+                    // class does not exist -- try another namespace
+                }
+            }
+		}
+		if (clazzName == null) {
+			throw new JSONParserException(node, "Class could not be found. Did you mean " + XMLParserUtils.guessClass(specClass) + "?", 1017);
+			// throw new ClassNotFoundException(specClass);
+		}
+				
+		// sanity check		
+		try {
+			Class<?> clazz = Class.forName(clazzName);
+			if (!BEASTInterface.class.isAssignableFrom(clazz)) {
+				// if (o instanceof Input) {
+				// // if we got this far, it is a basic input,
+				// // that is, one of the form <input name='xyz'>value</input>
+				// String name = getAttribute(node, "name");
+				// if (name == null) {
+				// name = "value";
+				// }
+				// String text = node.getTextContent();
+				// if (text.length() > 0) {
+				// setInput(node, parent, name, text);
+				// }
+				// return null;
+				// } else {
+				throw new JSONParserException(node, "Expected object to be instance of BEASTObject", 108);
+				// }
 			}
-		} catch (Exception e) {
-			e.printStackTrace();
-			throw new JSONParserException(node, "Cannot create class: " + specClass + ". " + e.getMessage(), 122);
-		}
-		// sanity check
-		if (!(o instanceof BEASTInterface)) {
-			// if (o instanceof Input) {
-			// // if we got this far, it is a basic input,
-			// // that is, one of the form <input name='xyz'>value</input>
-			// String sName = getAttribute(node, "name");
-			// if (sName == null) {
-			// sName = "value";
-			// }
-			// String sText = node.getTextContent();
-			// if (sText.length() > 0) {
-			// setInput(node, parent, sName, sText);
-			// }
-			// return null;
-			// } else {
-			throw new JSONParserException(node, "Expected object to be instance of Plugin", 108);
-			// }
+		} catch (ClassNotFoundException e1) {
+			// should never happen since clazzName is in the list of classes collected by the AddOnManager
+			e1.printStackTrace();
+			throw new RuntimeException(e1);
 		}
-		// set id
-		BEASTInterface plugin = (BEASTInterface) o;
-		plugin.setID(ID);
-		register(node, plugin);
+		
 		// process inputs
-		parseInputs(plugin, node);
+		List<NameValuePair> inputInfo = parseInputs(node, clazzName);
+		BEASTInterface beastObject = createBeastObject(node, ID, clazzName, inputInfo);
 		// initialise
-		if (m_bInitialize) {
+		if (initialise) {
 			try {
-				plugin.validateInputs();
-				pluginsWaitingToInit.add(plugin);
-				nodesWaitingToInit.add(node);
-				// plugin.initAndValidate();
-			} catch (Exception e) {
+				beastObject.validateInputs();
+				objectsWaitingToInit.add(new BEASTObjectWrapper(beastObject, node));
+				// beastObject.initAndValidate();
+			} catch (IllegalArgumentException e) {
 				// next lines for debugging only
-				// plugin.validateInputs();
-				// plugin.initAndValidate();
+				// beastObject.validateInputs();
+				// beastObject.initAndValidate();
 				e.printStackTrace();
 				throw new JSONParserException(node, "validate and intialize error: " + e.getMessage(), 110);
 			}
 		}
-		return plugin;
+		return beastObject;
 	} // createObject
-
-	/**
-	 * find closest matching class to named class *
-	 */
-	String guessClass(String className) {
-		String sName = className;
-		if (className.contains(".")) {
-			sName = className.substring(className.lastIndexOf('.') + 1);
-		}
-		List<String> pluginNames = AddOnManager.find(beast.core.BEASTInterface.class, AddOnManager.IMPLEMENTATION_DIR);
-		int bestDistance = Integer.MAX_VALUE;
-		String closest = null;
-		for (String pluginName : pluginNames) {
-			String className2 = pluginName.substring(pluginName.lastIndexOf('.') + 1);
-			int distance = getLevenshteinDistance(sName, className2);
-
-			if (distance < bestDistance) {
-				bestDistance = distance;
-				closest = pluginName;
+	
+	private String getElementName(JSONObject node) {
+		Object o = node.getParent();
+		if (o == null) {
+			return null;
+		}
+		if (o instanceof JSONObject) {
+			JSONObject parent = ((JSONObject) o);
+			for (String s : parent.keySet()) {
+				try {
+					if (parent.get(s) == node) {
+						return s;
+					}
+				} catch (JSONException e) {
+					// should not get here
+					e.printStackTrace();
+				}
+			}
+		}
+		if (o instanceof JSONArray) {
+			JSONArray parent = ((JSONArray) o);
+			Object o2 = parent.getParent();
+			if (o2 == null) {
+				return null;
 			}
+			if (o2 instanceof JSONObject) {
+				JSONObject gparent = ((JSONObject) o2);
+				for (String s : gparent.keySet()) {
+					try {
+						if (gparent.get(s) == parent) {
+							return s;
+						}
+					} catch (JSONException e) {
+						// should not get here
+						e.printStackTrace();
+					}
+				}
+			}
+			
 		}
-		return closest;
+		return null;
 	}
 
-	/**
-	 * Compute edit distance between two strings = Levenshtein distance *
-	 */
-	public static int getLevenshteinDistance(String s, String t) {
-		if (s == null || t == null) {
-			throw new IllegalArgumentException("Strings must not be null");
-		}
-
-		int n = s.length(); // length of s
-		int m = t.length(); // length of t
-
-		if (n == 0) {
-			return m;
-		} else if (m == 0) {
-			return n;
-		}
-
-		int p[] = new int[n + 1]; // 'previous' cost array, horizontally
-		int d[] = new int[n + 1]; // cost array, horizontally
-		int _d[]; // placeholder to assist in swapping p and d
-
-		// indexes into strings s and t
-		int i; // iterates through s
-		int j; // iterates through t
-		char t_j; // jth character of t
-		int cost; // cost
-		for (i = 0; i <= n; i++) {
-			p[i] = i;
-		}
-		for (j = 1; j <= m; j++) {
-			t_j = t.charAt(j - 1);
-			d[0] = j;
-			for (i = 1; i <= n; i++) {
-				cost = s.charAt(i - 1) == t_j ? 0 : 1;
-				// minimum of cell to the left+1, to the top+1, diagonally left
-				// and up +cost
-				d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost);
-			}
-			// copy current distance counts to 'previous row' distance counts
-			_d = p;
-			p = d;
-			d = _d;
+	/** create BEASTInterface either using Inputs, or using annotated constructor **/
+	private BEASTInterface createBeastObject(JSONObject node, String ID, String clazzName, List<NameValuePair> inputInfo) throws JSONParserException {
+		BEASTInterface beastObject = useAnnotatedConstructor(node, ID, clazzName, inputInfo);
+		if (beastObject != null) {
+			return beastObject;
+		}
+		
+		// create new instance using class name
+		Object o = null;
+		try {
+			Class<?> c = Class.forName(clazzName); 
+				o = c.newInstance();
+		} catch (InstantiationException e) {
+			// we only get here when the class exists, but cannot be
+			// created for instance because it is abstract
+			throw new JSONParserException(node, "Cannot instantiate class. Please check the spec attribute.", 1006);
+		} catch (ClassNotFoundException e) {
+			// ignore -- class was found in beastObjectNames before
+		} catch (IllegalAccessException e) {
+			// T O D O Auto-generated catch block
+			e.printStackTrace();
+			throw new JSONParserException(node, "Cannot access class. Please check the spec attribute.", 1011);
 		}
+		
+		// set id
+		beastObject = (BEASTInterface) o;
+		beastObject.setID(ID);
 
-		// our last action in the above loop was to switch d and p, so p now
-		// actually has the most recent cost counts
-		return p[n];
-	}
+		// hack required to make log-parsing easier
+		if (o instanceof State) {
+			state = (State) o;
+		}
 
-	void parseInputs(BEASTInterface parent, JSONObject node) throws Exception {
+		// process inputs for annotated constructors
+		for (NameValuePair pair : inputInfo) {
+			setInput(node, beastObject, pair.name, pair.value);
+		}
+		
+		// fill in missing inputs, if an input provider is available
+		try {
+			if (requiredInputProvider != null) {
+				for (Input<?> input : beastObject.listInputs()) {
+					if (input.get() == null && input.getRule() == Validate.REQUIRED) {
+						Object o2 = requiredInputProvider.createInput(beastObject, input, partitionContext);
+						if (o2 != null) {
+							input.setValue(o2, beastObject);
+						}
+					}
+				}
+			}
+		} catch (Exception e) {
+			throw new JSONParserException(node, e.getMessage(), 1008);			
+		}
+		
 		// sanity check: all attributes should be valid input names
-		for (String name : node.keySet()) {
-			if (!(name.equals("id") || name.equals("idref") || name.equals("spec") || name.equals("name"))) {
-				try {
-					parent.getInput(name);
-				} catch (Exception e) {
-					throw new JSONParserException(node, e.getMessage(), 1006);
+		if (!(beastObject instanceof Map)) {
+			for (String name : node.keySet()) {
+				if (!(name.equals("id") || name.equals("idref") || name.equals("spec") || name.equals("name"))) {
+					try {
+						beastObject.getInput(name);
+					} catch (Exception e) {
+						throw new JSONParserException(node, e.getMessage(), 1009);
+					}
 				}
 			}
 		}
+		
+		// make sure object o is in outputs of inputs
+		for (NameValuePair pair : inputInfo) {
+			if (pair.value instanceof BEASTInterface) {
+				((BEASTInterface) pair.value).getOutputs().add((BEASTInterface) o);
+			}	
+		}
+		
 
-		if (node.keySet() != null) {
-			// parse inputs in occurrance of inputs in the parent object
-			// this determines the order in which initAndValidate is called
-			List<Input<?>> inputs = parent.listInputs();
-			Set<String> done = new HashSet<String>();
-			for (Input<?> input : inputs) {
-				String name = input.getName();
-				processInput(name, node, parent);
-				done.add(name);
-			}
-			
-			for (String name : node.keySet()) {
-				if (!done.contains(name)) {
-					// this can happen with Maps
-					processInput(name, node, parent);
+		register(node, beastObject);
+		return beastObject;
+	}
+
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private BEASTInterface useAnnotatedConstructor(JSONObject node, String _id, String clazzName, List<NameValuePair> inputInfo) throws JSONParserException {
+		Class<?> clazz = null;
+		try {
+			clazz = Class.forName(clazzName);
+		} catch (ClassNotFoundException e) {
+			// cannot get here, since we checked the class existed before
+			e.printStackTrace();
+		}
+	    Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();
+	    for (Constructor<?> ctor : allConstructors) {
+	    	// collect Param annotations on constructor parameters
+	    	Annotation[][] annotations = ctor.getParameterAnnotations();
+	    	List<Param> paramAnnotations = new ArrayList<>();
+	    	for (Annotation [] a0 : annotations) {
+		    	for (Annotation a : a0) {
+		    		if (a instanceof Param) {
+		    			paramAnnotations.add((Param) a);
+		    		}
+	    		}
+	    	}
+	    	
+	    	for (NameValuePair pair : inputInfo) {
+	    		pair.processed = false;
+	    	}
+	    	
+	    	Class<?>[] types  = ctor.getParameterTypes();	    	
+	    	if (types.length > 0 && paramAnnotations.size() == types.length) {
+				try {
+			    	// if all constructor parameters have Param annotations, try to call constructor
+		    		// first, build up argument list, then create object
+		    		Object [] args = new Object[types.length];
+		    		for (int i = 0; i < types.length; i++) {
+		    			Param param = paramAnnotations.get(i);
+		    			Type type = types[i];
+		    			if (type.getTypeName().equals("java.util.List")) {
+		    				if (args[i] == null) {
+		    					// no need to parameterise list due to type erasure
+		    					args[i] = new ArrayList();
+		    				}
+		    				List<Object> values = XMLParser.getListOfValues(param, inputInfo);
+		    				((List<Object>) args[i]).addAll(values);
+		    			} else {
+		    				args[i] = getValue(param, (Class<?>) type, inputInfo);
+		    			}
+		    		}
+		    		
+		    		// ensure all inputs are used
+		    		boolean allUsed = true;
+			    	for (NameValuePair pair : inputInfo) {
+			    		if (!pair.processed) {
+			    			allUsed= false;
+			    		}
+			    	}
+	
+			    	// if all inputs are used, call the constructor, otherwise, look for another constructor
+			    	if (allUsed) {
+			    		try {
+							Object o = ctor.newInstance(args);
+							BEASTInterface beastObject = (BEASTInterface) o;
+							register(node, beastObject);
+							return beastObject;
+						} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+							throw new JSONParserException(node, "Could not create object: " + e.getMessage(), 1012);
+						}
+			    	}
+				} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException
+						| InvocationTargetException e) {
+					// we get here when a param value cannot be constructed from a default value
+					// let's try the next constructor (if any)
 				}
+	    	}
+		}
+		return null;
+	}
+
+	/** get value from inputInfo, but use default if the Param name cannot be found in inputInfo
+	 *  RRB: would like to combine with XMLParser.getValue, but this may get ugly due to incompatible XML/JSON types
+	 */
+	private Object getValue(Param param, Class<?> clazz, List<NameValuePair> inputInfo) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+		for (NameValuePair pair : inputInfo) {
+			if (pair.name.equals(param.name())) {
+				pair.processed = true;
+				return pair.value;
 			}
 		}
 		
+		// could not find Param entry in inputInfo
 		
-		// // process element nodes
-		// NodeList children = node.getChildNodes();
-		// String sText = "";
-		// for (int i = 0; i < children.getLength(); i++) {
-		// Node child = children.item(i);
-		// if (child.getNodeType() == Node.ELEMENT_NODE) {
-		// String sElement = child.getNodeName();
-		// // resolve name of the input
-		// String sName = getAttribute(child, "name");
-		// if (sName == null) {
-		// sName = sElement;
-		// }
-		// // resolve base class
-		// String sClass = PLUGIN_CLASS;
-		// if (element2ClassMap.containsKey(sElement)) {
-		// sClass = element2ClassMap.get(sElement);
-		// }
-		// Plugin childItem = createObject(child, sClass, parent);
-		// if (childItem != null) {
-		// setInput(node, parent, sName, childItem);
-		// }
-		// nChildElements++;
-		// } else if (child.getNodeType() == Node.CDATA_SECTION_NODE ||
-		// child.getNodeType() == Node.TEXT_NODE) {
-		// sText += child.getTextContent();
-		// }
-		// }
-		// if (!sText.matches("\\s*")) {
-		// setInput(node, parent, "value", sText);
-		// }
-		//
-		// if (nChildElements == 0) {
-		// String sContent = node.getTextContent();
-		// if (sContent != null && sContent.length() > 0 &&
-		// sContent.replaceAll("\\s", "").length() > 0) {
-		// try {
-		// setInput(node, parent, "value", sContent);
-		// } catch (Exception e) {
-		// //
-		// }
-		// }
-		// }
+		// check if this parameter is required or optional
+		if (!param.optional()) {
+			throw new IllegalArgumentException();
+		}
 
-		// fill in missing inputs, if an input provider is available
-		if (requiredInputProvider != null) {
-			for (Input<?> input : parent.listInputs()) {
-				if (input.get() == null && input.getRule() == Validate.REQUIRED) {
-					Object o = requiredInputProvider.createInput(parent, input, partitionContext);
-					if (o != null) {
-						input.setValue(o, parent);
+		// try using a String constructor of the default value
+        Constructor<?> ctor;
+        String value = param.defaultValue();
+        Object v = value; 
+        try {
+        	ctor = clazz.getDeclaredConstructor(String.class);
+        } catch (NoSuchMethodException e) {
+        	// we get here if there is not String constructor
+        	// try integer constructor instead
+        	try {
+        		if (value.startsWith("0x")) {
+        			v = Integer.parseInt(value.substring(2), 16);
+        		} else {
+        			v = Integer.parseInt(value);
+        		}
+            	ctor = clazz.getDeclaredConstructor(int.class);
+            	
+        	} catch (NumberFormatException e2) {
+            	// could not parse as integer, try double instead
+        		v = Double.parseDouble(value);
+            	ctor = clazz.getDeclaredConstructor(double.class);
+        	}
+        }
+        ctor.setAccessible(true);
+        final Object o = ctor.newInstance(v);
+        return o;
+	}
+
+	List<NameValuePair> parseInputs(JSONObject node, String className) throws JSONParserException {
+		List<NameValuePair> inputInfo = new ArrayList<>();
+
+		if (node.keySet() != null) {
+			try {
+				// parse inputs in occurrence of inputs in the parent object
+				// this determines the order in which initAndValidate is called
+				List<InputType> inputs = XMLParserUtils.listInputs(Class.forName(className), null);
+				Set<String> done = new HashSet<>();
+				for (InputType input : inputs) {
+					String name = input.name;
+					processInput(name, node, inputInfo, inputs);
+					done.add(name);
+				}
+				
+				for (String name : node.keySet()) {
+					if (!done.contains(name)) {
+						// this can happen with Maps
+						processInput(name, node, inputInfo, inputs);
 					}
 				}
+			} catch (JSONParserException e) {
+				throw e;
+			} catch (Exception e) {
+				throw new JSONParserException(node, e.getMessage(), 1005);
 			}
 		}
+		
+		return inputInfo;
 	} // setInputs
 
-	private void processInput(String name, JSONObject node, BEASTInterface parent) throws Exception {
+	
+	private void processInput(String name, JSONObject node, List<NameValuePair> map, List<InputType> inputs) throws JSONParserException, JSONException {
 		if (node.has(name)) {
 			if (!(name.equals("id") || name.equals("idref") || name.equals("spec") || name.equals("name"))) {
 				Object o = node.get(name);
@@ -934,57 +1152,64 @@ public class JSONParser {
 						String IDRef = value.substring(1);
 						JSONObject element = new JSONObject();
 						element.put("idref", IDRef);
-						BEASTInterface plugin = createObject(element, YOBJECT_CLASS, parent);
-						setInput(node, parent, name, plugin);
+						BEASTInterface beastObject = createObject(element, BEAST_OBJECT_CLASS);
+						map.add(new NameValuePair(name, beastObject));
+						//setInput(node, parent, name, beastObject);
 					} else {
-						setInput(node, parent, name, value);
+						map.add(new NameValuePair(name, value));
+						//setInput(node, parent, name, value);
 					}
 				} else if (o instanceof Number) {
-					parent.setInputValue(name, o);
+					map.add(new NameValuePair(name, o));
+					//parent.setInputValue(name, o);
 				} else if (o instanceof Boolean) {
-					parent.setInputValue(name, o);
+					map.add(new NameValuePair(name, o));
+					//parent.setInputValue(name, o);
 				} else if (o instanceof JSONObject) {
 					JSONObject child = (JSONObject) o;
-					String className = getClassName(child, name, parent);
-					BEASTInterface childItem = createObject(child, className, parent);
+					String className = getClassName(child, name, inputs);
+					BEASTInterface childItem = createObject(child, className);
 					if (childItem != null) {
-						setInput(node, parent, name, childItem);
+						map.add(new NameValuePair(name, childItem));
+						//setInput(node, parent, name, childItem);
 					}
-					// nChildElements++;
+					// childElements++;
 				} else if (o instanceof JSONArray) {
 					JSONArray list = (JSONArray) o;
 					for (int i = 0; i < list.length(); i++) {
 						Object o2 = list.get(i);
 						if (o2 instanceof JSONObject) {
 							JSONObject child = (JSONObject) o2;
-							String className = getClassName(child, name, parent);
-							BEASTInterface childItem = createObject(child, className, parent);
+							String className = getClassName(child, name, inputs);
+							BEASTInterface childItem = createObject(child, className);
 							if (childItem != null) {
-								setInput(node, parent, name, childItem);
+								map.add(new NameValuePair(name, childItem));
+								//setInput(node, parent, name, childItem);
 							}
 						} else {
-							parent.setInputValue(name, o2);									
+							map.add(new NameValuePair(name, o2));
+							//parent.setInputValue(name, o2);									
 						}
 					}
 				} else {
-					throw new Exception("Developer error: Don't know how to handle this JSON construction");
+					throw new RuntimeException("Developer error: Don't know how to handle this JSON construction");
 				}
 			}
 		}		
 	}
 
-	void setInput(JSONObject node, BEASTInterface plugin, String name, BEASTInterface plugin2) throws JSONParserException {
+	private void setInput(JSONObject node, BEASTInterface beastObject, String name, Object value) throws JSONParserException {
 		try {
-			Input<?> input = plugin.getInput(name);
+			final Input<?> input = beastObject.getInput(name);
 			// test whether input was not set before, this is done by testing
 			// whether input has default value.
 			// for non-list inputs, this should be true if the value was not
 			// already set before
 			// for list inputs this is always true.
 			if (input.get() == input.defaultValue) {
-				plugin.setInputValue(name, plugin2);
+				beastObject.setInputValue(name, value);
 			} else {
-				throw new Exception("Multiple entries for non-list input " + input.getName());
+				throw new IOException("Multiple entries for non-list input " + input.getName());
 			}
 			return;
 		} catch (Exception e) {
@@ -995,41 +1220,26 @@ public class JSONParser {
 			if (e.getMessage().contains("101")) {
 				String type = "?";
 				try {
-					type = plugin.getInput(name).getType().getName().replaceAll(".*\\.", "");
+					type = beastObject.getInput(name).getType().getName().replaceAll(".*\\.", "");
 				} catch (Exception e2) {
-					// TODO: handle exception
+					// T O D O: handle exception
 				}
 				throw new JSONParserException(node, e.getMessage() + " expected '" + type + "' but got '"
-						+ plugin2.getClass().getName().replaceAll(".*\\.", "") + "'", 123);
+						+ value.getClass().getName().replaceAll(".*\\.", "") + "'", 123);
 			} else {
 				throw new JSONParserException(node, e.getMessage(), 130);
 			}
 		}
 	}
 
-	void setInput(JSONObject node, BEASTInterface plugin, String sName, String sValue) throws JSONParserException {
-		try {
-			plugin.setInputValue(sName, sValue);
-			return;
-		} catch (Exception e) {
-			try {
-				plugin.setInputValue(sName, sValue);
-			} catch (Exception e1) {
-				// TODO Auto-generated catch block
-				e1.printStackTrace();
-			}
-			throw new JSONParserException(node, e.getMessage(), 124);
-		}
-	}
-
 	/**
-	 * records id in IDMap, for ease of retrieving Plugins associated with
+	 * records id in IDMap, for ease of retrieving BeastObjects associated with
 	 * idrefs *
 	 */
-	void register(JSONObject node, BEASTInterface plugin) {
+	void register(JSONObject node, BEASTInterface beastObject) {
 		String ID = getID(node);
 		if (ID != null) {
-			IDMap.put(ID, plugin);
+			IDMap.put(ID, beastObject);
 		}
 	}
 
@@ -1047,7 +1257,11 @@ public class JSONParser {
 	 */
 	public static String getAttribute(JSONObject node, String attName) {
 		if (node.has(attName)) {
-			return node.get(attName).toString();
+			try {
+				return node.get(attName).toString();
+			} catch (JSONException e) {
+				return null;
+			}
 		}
 		return null;
 	}
@@ -1056,26 +1270,31 @@ public class JSONParser {
 	 * get integer value of attribute with given name *
 	 */
 	public static int getAttributeAsInt(JSONObject node, String attName) {
-		String sAtt = getAttribute(node, attName);
-		if (sAtt == null) {
+		String att = getAttribute(node, attName);
+		if (att == null) {
 			return -1;
 		}
-		return Integer.parseInt(sAtt);
+		return Integer.parseInt(att);
 	}
 
 	/**
-	 * get double value of attribute with given name *
+	 * get double value of attribute with given name 
+	 * @throws JSONParserException *
 	 */
-	public static double getAttributeAsDouble(JSONObject node, String attName) {
-		String sAtt = getAttribute(node, attName);
-		if (sAtt == null) {
+	public static double getAttributeAsDouble(JSONObject node, String attName) throws JSONParserException {
+		String att = getAttribute(node, attName);
+		if (att == null) {
 			return Double.MAX_VALUE;
 		}
-		return Double.parseDouble(sAtt);
+		try {
+			return Double.parseDouble(att);			
+		} catch (NumberFormatException e) {
+			throw new JSONParserException(node, "Could not parse number " + att, 1003);
+		}
 	}
 
 	public interface RequiredInputProvider {
-		Object createInput(BEASTInterface plugin, Input<?> input, PartitionContext context);
+		Object createInput(BEASTInterface beastObject, Input<?> input, PartitionContext context);
 	}
 
 	public void setRequiredInputProvider(RequiredInputProvider provider, PartitionContext context) {
@@ -1083,10 +1302,10 @@ public class JSONParser {
 		partitionContext = context;
 	}
 
-	String getClassName(JSONObject child, String name, BEASTInterface parent) throws Exception {
+	String getClassName(JSONObject child, String name, BEASTInterface parent) {
 		String className = getAttribute(child, "spec");
 		if (className == null) {
-			Input<?> input = parent.getInput(name);
+			final Input<?> input = parent.getInput(name);
 			Class<?> type = input.getType();
 			if (type == null) {
 				input.determineClass(parent);
@@ -1100,6 +1319,29 @@ public class JSONParser {
 		return className;
 	}
 
+	private String getClassName(JSONObject child, String name, List<InputType> inputs) {
+		String className = getAttribute(child, "spec");
+		if (className == null) {
+			// derive type from Input
+			for (InputType input : inputs) {
+				if (input.name.equals(name)) {
+					Class<?> type = input.type;
+					if (type == null) {
+						throw new RuntimeException("Programmer error: inputs should have their type set");
+					}
+					//if (type.isAssignableFrom(List.class)) {
+					//	System.err.println("XX");
+					//}
+					className = type.getName();
+				}
+			}
+		}
+		if (element2ClassMap.containsKey(className)) {
+			className = element2ClassMap.get(className);
+		}
+		return className;
+	}
+
 	/**
 	 * parses file and formats it using the XMLProducer *
 	 */
@@ -1110,10 +1352,16 @@ public class JSONParser {
 			System.setOut(System.err);
 			// parse the file
 			JSONParser parser = new JSONParser();
-			BEASTInterface plugin = parser.parseFile(new File(args[0]));
+			BEASTInterface beastObject = parser.parseFile(new File(args[0]));
 			// restore stdout
 			System.setOut(out);
-			System.out.println(new XMLProducer().toXML(plugin));
+			if (args.length > 1) {
+		        FileWriter outfile = new FileWriter(args[1]);
+		        outfile.write(new XMLProducer().toXML(beastObject));
+		        outfile.close();
+			} else {
+				System.out.println(new XMLProducer().toXML(beastObject));
+			}
 		} catch (Exception e) {
 			e.printStackTrace();
 		}
diff --git a/src/beast/util/JSONParserException.java b/src/beast/util/JSONParserException.java
index 5a568fa..44b0db5 100644
--- a/src/beast/util/JSONParserException.java
+++ b/src/beast/util/JSONParserException.java
@@ -25,15 +25,18 @@
 package beast.util;
 
 import org.json.JSONArray;
+import org.json.JSONException;
 import org.json.JSONObject;
 
 /**
  * Exception thrown by JSONParser
  * that keeps track of the JSONOBject that caused the anomaly.
  */
- at SuppressWarnings("serial")
-public class JSONParserException extends Exception {
-    /**
+public class JSONParserException extends XMLParserException {
+
+	private static final long serialVersionUID = 1L;
+
+	/**
      * JSONObject where the anomaly was in the vicinity *
      */
 	JSONObject node;
@@ -48,16 +51,17 @@ public class JSONParserException extends Exception {
      */
     int m_nErrorNr;
 
-    public JSONParserException(JSONObject node, String sMsg, int nErrorNr) {
-        super(sMsg);
+    public JSONParserException(JSONObject node, String msg, int errorNr) {
+        super(msg);
         this.node = node;
         m_sMsg = "";
-        m_nErrorNr = nErrorNr;
+        m_nErrorNr = errorNr;
     }
 
     // format message and resolve parent
-    public String getMessage() {
-        String msg = "\nError " + m_nErrorNr + " parsing the json input file\n\n" + m_sMsg + super.getMessage();
+    @Override
+	public String getMessage() {
+        String msg = "\nError " + m_nErrorNr + " parsing the json input file\n\n" + m_sMsg + super.getOriginalMessage();
         if (node == null) {
             return "NULL NODE\n" + msg;
         }
@@ -79,9 +83,14 @@ public class JSONParserException extends Exception {
 	            if (p instanceof JSONObject) {
 	            	JSONObject parent = (JSONObject) p;
 	            	for (String key : parent.keySet()) {
-	            		if (parent.get(key).equals(o)) {
-	            			name = "\"" + key + "\": ";
-	            		}
+	            		try {
+							if (parent.get(key).equals(o)) {
+								name = "\"" + key + "\": ";
+							}
+						} catch (JSONException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
 	            	}
 	            }
 	
@@ -107,9 +116,14 @@ public class JSONParserException extends Exception {
 	            if (p instanceof JSONObject) {
 	            	JSONObject parent = (JSONObject) p;
 	            	for (String key : parent.keySet()) {
-	            		if (parent.get(key).equals(o)) {
-	            			name = "\"" + key + "\": ";
-	            		}
+	            		try {
+							if (parent.get(key).equals(o)) {
+								name = "\"" + key + "\": ";
+							}
+						} catch (JSONException e) {
+							// TODO Auto-generated catch block
+							e.printStackTrace();
+						}
 	            	}
 	            }
 
@@ -129,7 +143,11 @@ public class JSONParserException extends Exception {
 
     String getAttribute(JSONObject node, String target) {
     	if (node.has(target)) {
-    		return  node.get(target).toString();
+    		try {
+				return  node.get(target).toString();
+			} catch (JSONException e) {
+				return null;
+			}
     	}
    		return null;
     } // getAttribute
diff --git a/src/beast/util/JSONProducer.java b/src/beast/util/JSONProducer.java
index ee3e499..22464f6 100644
--- a/src/beast/util/JSONProducer.java
+++ b/src/beast/util/JSONProducer.java
@@ -1,18 +1,26 @@
 package beast.util;
 
 import java.io.File;
+import java.io.IOException;
 import java.io.PrintStream;
-import java.lang.reflect.Field;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
-import beast.core.Input;
-import beast.core.BEASTObject;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.xml.sax.SAXException;
+
+import beast.app.BEASTVersion;
 import beast.core.BEASTInterface;
+import beast.core.Input;
+import beast.core.State;
+import beast.core.parameter.Parameter;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.tree.TraitSet;
 
@@ -29,29 +37,28 @@ import beast.evolution.tree.TraitSet;
  * 
  * JSON vs YAML: http://en.wikipedia.org/wiki/YAML
  * 
- * + JSON has editor support -- gedit, any javascript editor
+ * + JSON has editor support -- gedit, any Javascript editor
  * + JSON validation -- http://jsonlint.com/ for validation
- * + JSON = javascript, useful format for GUIs
- * - JSON bracket mathcing is not well supported in editors
+ * + JSON = Javascript, useful format for GUIs
+ * - JSON bracket matching is not well supported in editors
  * 
  * + YAML no issues with brackets
- * - YAML litte editor support
+ * - YAML little editor support
 */
 
 public class JSONProducer {
 
     /**
-     * list of objects already converted to XML, so an idref suffices
+     * list of objects already converted to JSON, so an idref suffices
      */
-    HashSet<BEASTInterface> isDone;
-    @SuppressWarnings("rawtypes")
-    HashSet<Input> isInputsDone;
+    Set<BEASTInterface> isDone;
+    Map<BEASTInterface, Set<String>> isInputsDone;
     /**
      * list of IDs of elements produces, used to prevent duplicate ID generation
      */
     HashSet<String> IDs;
     /**
-     * #spaces before elements in XML *
+     * #spaces before elements in JSON *
      */
     int indentCount;
     
@@ -63,40 +70,38 @@ public class JSONProducer {
 
     /**
      * Main entry point for this class
-     * Given a plug-in, produces the XML in BEAST 2 format
-     * representing the plug-in. This assumes plugin is Runnable
+     * Given a plug-in, produces the JSON in BEAST 2 format
+     * representing the plug-in. This assumes beastObject is Runnable
      */
-    public String toJSON(BEASTInterface plugin) {
-    	return toJSON(plugin, new ArrayList<BEASTInterface>());
+    public String toJSON(BEASTInterface beastObject) {
+    	return toJSON(beastObject, new ArrayList<>());
     }
 
-	@SuppressWarnings("rawtypes")
-    public String toJSON(BEASTInterface plugin, Collection<BEASTInterface> others) {
+    public String toJSON(BEASTInterface beastObject, Collection<BEASTInterface> others) {
         try {
             StringBuffer buf = new StringBuffer();
             //buf.append("{\"version\": \"2.0\",\n\"namespace\": \"" + DEFAULT_NAMESPACE + "\",\n\n" +
             //		"\"" + JSONParser.ANALYSIS_ELEMENT + "\": [\n");
-            buf.append("{version: \"2.0\",\nnamespace: \"" + DEFAULT_NAMESPACE + "\",\n\n" +
-            		JSONParser.ANALYSIS_ELEMENT + ": [\n");
+            buf.append("{version: \"" + (new BEASTVersion()).getMajorVersion() + "\",\nnamespace: \"" + DEFAULT_NAMESPACE + "\",\n\n" +
+            		XMLParser.BEAST_ELEMENT + ": [\n");
             //buf.append("\n\n");
-            isDone = new HashSet<BEASTInterface>();
-            isInputsDone = new HashSet<Input>();
-            IDs = new HashSet<String>();
+            isDone = new HashSet<>();
+            isInputsDone = new HashMap<>();
+            IDs = new HashSet<>();
             indentCount = 1;
             
-            List<BEASTInterface> priorityPlugins = new ArrayList<BEASTInterface>();
-            findPriorityPlugins(plugin, priorityPlugins);
-            for (BEASTInterface plugin2 : priorityPlugins) {
-            	if (!isDone.contains(plugin2)) {
-            		//String name = plugin2.getClass().getName();
+            List<BEASTInterface> priorityBeastObjects = new ArrayList<>();
+            findPriorityBeastObjects(beastObject, priorityBeastObjects);
+            for (BEASTInterface beastObject2 : priorityBeastObjects) {
+            	if (!isDone.contains(beastObject2)) {
             		//name = name.substring(name.lastIndexOf('.') + 1).toLowerCase();
-            		pluginToJSON(plugin2, BEASTInterface.class, buf, null, true);
+            		beastObjectToJSON(beastObject2, BEASTInterface.class, buf, null, true);
             		buf.append(",");
             	}
             }
             buf.append("\n\n");
             
-            pluginToJSON(plugin, BEASTInterface.class, buf, null, true);
+            beastObjectToJSON(beastObject, BEASTInterface.class, buf, null, true);
             String end = "\n]\n}";
             buf.append(end);
 
@@ -111,50 +116,29 @@ public class JSONProducer {
             e.printStackTrace();
             return null;
         }
-    } // toXML
+    } // toJSON
 
-    private void findPriorityPlugins(BEASTInterface plugin, List<BEASTInterface> priorityPlugins) throws IllegalArgumentException, IllegalAccessException {
-    	if (plugin.getClass().equals(Alignment.class)) {
-    		priorityPlugins.add(plugin);
+    private void findPriorityBeastObjects(BEASTInterface beastObject, List<BEASTInterface> priorityBeastObjects) throws IllegalArgumentException, IllegalAccessException {
+    	if (beastObject.getClass().equals(Alignment.class)) {
+    		priorityBeastObjects.add(beastObject);
     	}
-    	if (plugin instanceof TraitSet) {
-    		priorityPlugins.add(plugin);
+    	if (beastObject instanceof TraitSet) {
+    		priorityBeastObjects.add(beastObject);
     	}
-		for (BEASTInterface plugin2 : plugin.listActivePlugins()) {
-			findPriorityPlugins(plugin2, priorityPlugins);
+		for (BEASTInterface beastObject2 : beastObject.listActiveBEASTObjects()) {
+			findPriorityBeastObjects(beastObject2, priorityBeastObjects);
 		}
 	}
 
-	/**
-     * like modelToXML, but without the cleanup *
-     * For plugin without name
-     */
-//    @SuppressWarnings("rawtypes")
-//    public String toJSON(Plugin plugin, String sName) {
-//        try {
-//            StringBuffer buf = new StringBuffer();
-//            isDone = new HashSet<Plugin>();
-//            isInputsDone = new HashSet<Input>();
-//            ids = new HashSet<String>();
-//            indentCount = 0;
-//            pluginToJSON(plugin, Plugin.class, buf, sName, false);
-//            return buf.toString();
-//        } catch (Exception e) {
-//            e.printStackTrace();
-//            return null;
-//        }
-//    } // toRawJSON
-
-
-
-    public String stateNodeToJSON(BEASTInterface plugin) {
+
+
+    public String stateNodeToJSON(BEASTInterface beastObject) {
         try {
             StringBuffer buf = new StringBuffer();
-            //buf.append("<" + XMLParser.beast_ELEMENT + " version='2.0'>\n");
-            isDone = new HashSet<BEASTInterface>();
-            IDs = new HashSet<String>();
+            isDone = new HashSet<>();
+            IDs = new HashSet<>();
             indentCount = 1;
-            pluginToJSON(plugin, null, buf, null, false);
+            beastObjectToJSON(beastObject, null, buf, null, false);
             return buf.toString();
         } catch (Exception e) {
             e.printStackTrace();
@@ -165,13 +149,12 @@ public class JSONProducer {
 
 
     /**
-     * produce elements for a plugin with name sName, putting results in buf.
-     * It tries to create XML conforming to the XML transformation rules (see XMLParser)
+     * Produce JSON fragment for a beast object with given name, putting results in buf.
+     * It tries to create JSON conforming to the JSON transformation rules (see JSONParser)
      * that is moderately readable.
      */
-//    @SuppressWarnings("rawtypes")
-    void pluginToJSON(BEASTInterface plugin, Class<?> defaultType, StringBuffer buf, String name, boolean bIsTopLevel) throws Exception {
-        // determine element name, default is input, otherswise find one of the defaults
+    void beastObjectToJSON(BEASTInterface beastObject, Class<?> defaultType, StringBuffer buf, String name, boolean isTopLevel) {
+        // determine element name, default is input, otherwise find one of the defaults
 
     	String indent = "";
         for (int i = 0; i < indentCount; i++) {
@@ -190,51 +173,51 @@ public class JSONProducer {
         }
 
         boolean skipInputs = false;
-        if (isDone.contains(plugin)) {
-            // XML is already produced, we can idref it
+        if (isDone.contains(beastObject)) {
+            // JSON is already produced, we can idref it
         	buf.append((needsComma == true) ? ",\n" + indent + " " : ""); 
-            //buf.append("\"idref\": \"" + plugin.getID() + "\" ");
-            buf.append("idref: \"" + plugin.getID() + "\" ");
+            buf.append("idref: \"" + beastObject.getID() + "\" ");
             needsComma = true;
             skipInputs = true;
         } else {
             // see whether a reasonable id can be generated
-            if (plugin.getID() != null && !plugin.getID().equals("")) {
-                String sID = plugin.getID();
+            if (beastObject.getID() != null && !beastObject.getID().equals("")) {
+                String id = beastObject.getID();
                 // ensure ID is unique
-                if (IDs.contains(sID)) {
+                if (IDs.contains(id)) {
                     int k = 1;
-                    while (IDs.contains(sID + k)) {
+                    while (IDs.contains(id + k)) {
                         k++;
                     }
-                    sID = sID + k;
+                    id = id + k;
                 }
             	buf.append((needsComma == true) ? ",\n" + indent + " " : ""); 
-                //buf.append("\"id\": \"" + normalise(null, sID) + "\"");
-                buf.append("id: \"" + normalise(null, sID) + "\"");
+                buf.append("id: \"" + normalise(null, id) + "\"");
                 needsComma = true;
-                IDs.add(sID);
+                IDs.add(id);
             }
-            isDone.add(plugin);
+            isDone.add(beastObject);
         }
-        String sClassName = plugin.getClass().getName();
+        String className = beastObject.getClass().getName();
         if (skipInputs == false) {
             // only add spec element if it cannot be deduced otherwise (i.e., by idref)
-        	if (defaultType != null && !defaultType.getName().equals(sClassName)) {
+        	if (defaultType != null && !defaultType.getName().equals(className)) {
 	        	buf.append((needsComma == true) ? ",\n" + indent + " " : ""); 
-	            //buf.append("\"spec\": \"" + sClassName + "\"");
-	            buf.append("spec: \"" + sClassName + "\"");
+	            //buf.append("\"spec\": \"" + className + "\"");
+	            buf.append("spec: \"" + className + "\"");
 	            needsComma = true;
         	}
         }
 
         if (!skipInputs) {
-            // process inputs of this plugin
+            // process inputs of this beastObject
             // first, collect values as attributes
-            List<Input<?>> inputs = plugin.listInputs();
+            List<Input<?>> inputs = beastObject.listInputs();
+            //List<InputType> inputs = XMLParserUtils.listInputs(beastObject.getClass(), beastObject);
             for (Input<?> input : inputs) {
             	StringBuffer buf2 = new StringBuffer();
-                inputToJSON(input.getName(), plugin, buf2, true, indent);
+            	Object value = input.get();
+                inputToJSON(input, value, beastObject, buf2, true, indent);
                 if (buf2.length() > 0) {
                 	buf.append((needsComma == true) ? "," : "");
                 	buf.append(buf2);
@@ -245,7 +228,8 @@ public class JSONProducer {
             StringBuffer buf2 = new StringBuffer();
             for (Input<?> input : inputs) {
             	StringBuffer buf3 = new StringBuffer();
-                inputToJSON(input.getName(), plugin, buf3, false, indent);
+            	Object value = input.get();
+                inputToJSON(input, value, beastObject, buf3, false, indent);
                 if (buf3.length() > 0) {
                 	buf2.append((needsComma == true) ? ",\n" : "\n");
                 	buf2.append(buf3);
@@ -278,132 +262,140 @@ public class JSONProducer {
         
         buf.append("}");
         //}
-    } // pluginToJSON
+    } // beastObjectToJSON
 
 
-    /**
-     * produce JSON for an input of a plugin, both as attribute/value pairs for
-     * primitive inputs (if isShort=true) and as individual elements (if bShort=false)
+	/**
+     * produce JSON for an input of a beastObject, both as attribute/value pairs for
+     * primitive inputs (if isShort=true) and as individual elements (if isShort=false)
      *
-     * @param sInput: name of the input
-     * @param plugin: plugin to produce this input XML for
-     * @param buf:    gets XML results are appended
+     * @param input0: name of the input
+     * @param beastObject: beastObject to produce this input JSON for
+     * @param buf:    gets JSON results are appended
      * @param isShort: flag to indicate attribute/value format (true) or element format (false)
-     * @throws Exception
      */
     @SuppressWarnings({ "rawtypes", "unchecked" })
-    void inputToJSON(String input0, BEASTInterface plugin, StringBuffer buf, boolean isShort, String indent) throws Exception {
-        Field[] fields = plugin.getClass().getFields();
-        for (int i = 0; i < fields.length; i++) {
-            if (fields[i].getType().isAssignableFrom(Input.class)) {
-                Input input = (Input) fields[i].get(plugin);
-                if (input.getName().equals(input0)) {
-                    // found the input with name sInput
-                    if (input.get() != null) {
-                        // distinguish between Map, List, Plugin and primitive input types
-                        if (input.get() instanceof Map) {
-                            if (!isShort) {
-	                        	Map<String,?> map = (Map<String,?>) input.get();
-	                        	StringBuffer buf2 = new StringBuffer();
-	                        	// determine label widith
-	                        	int whiteSpaceWidth = 0;
-	                        	for (String key : map.keySet()) {
-	                        		whiteSpaceWidth = Math.max(whiteSpaceWidth, key.length());
-	                        	}
-	                        	boolean needsComma = false;
-	                        	List<String> keys = new ArrayList<String>();
-	                        	keys.addAll(map.keySet());
-	                        	Collections.sort(keys);
-	                        	for (String key : keys) {
-	                            	if (needsComma) {
-	                            		buf2.append(",\n");
-	                            	}
-	                        		buf2.append(indent + " " + key);
-	                        		for (int k = key.length(); k < whiteSpaceWidth; k++) {
-	                        			buf2.append(' ');
-	                        		}
-	                        		buf2.append(" :\"" + map.get(key) +"\"");
-	                        		needsComma = true;
-	                        	}
-	                        	buf.append(buf2);
-                            }
-                        	return;
-                        } else if (input.get() instanceof List) {
-                            if (!isShort) {
-                            	StringBuffer buf2 = new StringBuffer();
-                            	//buf2.append(indent + " \"" + input0 + "\": [\n");
-                            	buf2.append(indent + " " + input0 + ": [\n");
-                            	boolean needsComma = false;
-                            	int oldLen = buf2.length();
-                                for (Object o2 : (List) input.get()) {
-                                	if (needsComma) {
-                                		buf2.append(",\n");
-                                	}
-                                	StringBuffer buf3 = new StringBuffer();
-                                	if (o2 instanceof BEASTInterface) {
-                                		pluginToJSON((BEASTInterface) o2, input.getType(), buf3, null, false);
-                                	} else {
-                                		buf2.append(o2.toString());
-                                	}
-                                    buf2.append(buf3);
-                                    needsComma = oldLen < buf2.length();
-                                }
-                                if (buf2.length() != oldLen) {
-                                	buf.append(buf2);
-                                	buf.append("\n" + indent + "  ]");
-                                }
-                            }
-                            return;
-                        } else if (input.get() instanceof BEASTInterface) {
-                        	if (!input.get().equals(input.defaultValue)) {
-	                            if (isShort && isDone.contains((BEASTInterface) input.get())) {
-	                                buf.append(" " + input0 + ": \"@" + ((BEASTInterface) input.get()).getID() + "\"");
-	                                isInputsDone.add(input);
-	                            }
-	                            if (!isShort && !isInputsDone.contains(input)) {
-	                                pluginToJSON((BEASTInterface) input.get(), input.getType(), buf, input0, false);
-	                            }
-                        	}
-                            return;
-                        } else {
-                        	if (!input.get().equals(input.defaultValue)) {
-	                            // primitive type, see if
-	                            String sValue = input.get().toString();
-	                            if (isShort) {
-	                                if (sValue.indexOf('\n') < 0) {
-	                                    //buf.append(" \"" + input0 + "\": " + normalise(input, input.get().toString()) + "");
-	                                    buf.append(" " + input0 + ": " + normalise(input, input.get().toString()) + "");
-	                                }
-	                            } else {
-	                                if (sValue.indexOf('\n') >= 0) {
-//	                                    for (int j = 0; j < m_nIndent; j++) {
-//	                                        buf.append("    ");
-//	                                    }
-	                                    //if (sInput.equals("value")) {
-	                                    //    buf.append(input.get().toString());
-	                                    //} else {
-	                                        //buf.append(indent + "\"" + input0 + "\": " + normalise(input, input.get().toString()) + "");
-	                                        buf.append(indent + "" + input0 + ": " + normalise(input, input.get().toString()) + "");
-	                                    //}
-	                                }
-	                            }
-                        	}
-                            return;
+    private void inputToJSON(Input input, Object value, BEASTInterface beastObject, StringBuffer buf, boolean isShort, String indent) {
+        if (value != null) {
+        	
+            // distinguish between Map, List, BEASTObject and primitive input types
+            if (value instanceof Map) {
+                if (!isShort) {
+                	Map<String,?> map = (Map<String,?>) value;
+                	StringBuffer buf2 = new StringBuffer();
+                	
+                	// determine label width
+                	int whiteSpaceWidth = 0;
+                	for (String key : map.keySet()) {
+                		whiteSpaceWidth = Math.max(whiteSpaceWidth, key.length());
+                	}
+                	boolean needsComma = false;
+                	List<String> keys = new ArrayList<>();
+                	keys.addAll(map.keySet());
+                	Collections.sort(keys);
+                	for (String key : keys) {
+                    	if (needsComma) {
+                    		buf2.append(",\n");
+                    	}
+                		buf2.append(indent + " " + key);
+                		for (int k = key.length(); k < whiteSpaceWidth; k++) {
+                			buf2.append(' ');
+                		}
+                		buf2.append(" :\"" + map.get(key) +"\"");
+                		needsComma = true;
+                	}
+                	buf.append(buf2);
+                }
+            	return;
+            } else if (value instanceof List) {
+                if (!isShort) {
+                	StringBuffer buf2 = new StringBuffer();
+                	//buf2.append(indent + " \"" + input0 + "\": [\n");
+                	buf2.append(indent + " " + input.getName() + ": [\n");
+                	boolean needsComma = false;
+                	int oldLen = buf2.length();
+                    for (Object o2 : (List) value) {
+                    	if (needsComma) {
+                    		buf2.append(",\n");
+                    	}
+                    	StringBuffer buf3 = new StringBuffer();
+                    	if (o2 instanceof BEASTInterface) {
+                    		beastObjectToJSON((BEASTInterface) o2, input.getType(), buf3, null, false);
+                    	} else {
+                    		buf2.append(o2.toString());
+                    	}
+                        buf2.append(buf3);
+                        needsComma = oldLen < buf2.length();
+                    }
+                    if (buf2.length() != oldLen) {
+                    	buf.append(buf2);
+                    	buf.append("\n" + indent + "  ]");
+                    }
+                }
+                return;
+            } else if (value instanceof BEASTInterface) {
+            	if (!value.equals(input.defaultValue)) {
+            		
+            		// 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) {
+            			Parameter.Base parameter = (Parameter.Base) value;
+            			boolean isInState = false;
+            			for (Object o : parameter.getOutputs()) {
+            				if (o instanceof State) {
+            					isInState = true;
+            					break;
+            				}
+            			}
+            			if (!isInState) {
+            				if (isShort) {
+                                buf.append(" " + input.getName() + ": \"" + parameter.getValue() + "\"");
+            				} else {
+            					return;
+            				}
+            			}
+            		}
+            		
+                    if (isShort && isDone.contains(value)) {
+                        buf.append(" " + input.getName() + ": \"@" + ((BEASTInterface) value).getID() + "\"");
+                        if (!isInputsDone.containsKey(beastObject)) {
+                        	isInputsDone.put(beastObject, new HashSet<>());
+                        }
+                        isInputsDone.get(beastObject).add(input.getName());
+                    }
+                    if (!isShort && (!isInputsDone.containsKey(beastObject) ||
+                    		!isInputsDone.get(beastObject).contains(input.getName()))) {
+                        beastObjectToJSON((BEASTInterface) value, input.getType(), buf, input.getName(), false);
+                    }
+            	}
+                return;
+            } else {
+                // primitive type
+
+            	if (!value.equals(input.defaultValue)) {
+            		
+                    String valueString = value.toString();
+                    if (isShort) {
+                        if (valueString.indexOf('\n') < 0) {
+                            buf.append(" " + input.getName() + ": " + normalise(input, value.toString()) + "");
                         }
                     } else {
-                        // value=null, no XML to produce
-                        return;
+                        if (valueString.indexOf('\n') >= 0) {
+                                buf.append(indent + "" + input.getName() + ": " + normalise(input, value.toString()) + "");
+                        }
                     }
-                }
+            	}
+                return;
             }
+        } else {
+            // value=null, no JSON to produce
+            return;
         }
-        // should never get here
-        throw new Exception("Could not find input " + input0 + " in plugin " + plugin.getID() + " " + plugin.getClass().getName());
     } // inputToJSON
 
     
-   /** convert plain text string to XML string, replacing some entities **/
-    String normalise(Input<?> input, String str) {
+   /** convert plain text string to JSON string, replacing some entities **/
+    private String normalise(Input<?> input, String str) {
     	str = str.replaceAll("\\\\", "\\\\\\\\");
     	str = str.replaceAll("/", "\\\\/");
     	str = str.replaceAll("\b", "\\\\b");
@@ -422,11 +414,10 @@ public class JSONProducer {
     
 
 	
-	@SuppressWarnings("resource")
-	public static void main(String[] args) throws Exception {
-		// convert BEAST 2 XML to BEAST json file
+	public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, XMLParserException {
+		// convert BEAST 2 XML to BEAST JSON file
 		XMLParser parser = new XMLParser();
-		BEASTInterface plugin = parser.parseFile(new File(args[0]));
+		BEASTInterface beastObject = parser.parseFile(new File(args[0]));
 
 		String JSONFile = args[0].replace(".xml", ".json");
 		PrintStream out;
@@ -437,7 +428,7 @@ public class JSONProducer {
 		}
 		
 		JSONProducer writer = new JSONProducer();
-		String JSON = writer.toJSON(plugin);
+		String JSON = writer.toJSON(beastObject);
 		out.println(JSON);
 		out.close();
 		
diff --git a/src/beast/util/LogAnalyser.java b/src/beast/util/LogAnalyser.java
index 0b9e34f..de58c49 100644
--- a/src/beast/util/LogAnalyser.java
+++ b/src/beast/util/LogAnalyser.java
@@ -1,25 +1,26 @@
 package beast.util;
 
-import beast.app.BEASTVersion;
-import beast.app.util.Utils;
-import beast.core.util.ESS;
-import beast.core.util.Log;
+import static beast.util.OutputUtils.format;
 
 import java.io.BufferedReader;
 import java.io.File;
 import java.io.FileReader;
+import java.io.IOException;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
-import static beast.util.OutputUtils.format;
+import beast.app.BEASTVersion;
+import beast.app.util.Utils;
+import beast.core.util.ESS;
+import beast.core.util.Log;
 
 
 public class LogAnalyser {
     public static final int BURN_IN_PERCENTAGE = 10; // default
 
-    protected final String sFile;
+    protected final String fileName;
 
     /**
      * column labels in log file *
@@ -62,112 +63,115 @@ public class LogAnalyser {
     final protected static String BAR = "|---------|---------|---------|---------|---------|---------|---------|---------|";
 
     public LogAnalyser() {
-        sFile = null;
+        fileName = null;
     }
 
     /**
      *
      * @param args
-     * @param nBurnInPercentage  nBurnInPercentage typical = 10; percentage of data that can be ignored
-     * @throws Exception
+     * @param burnInPercentage  burnInPercentage typical = 10; percentage of data that can be ignored
+     * @throws IOException 
      */
-    public LogAnalyser(String[] args, int nBurnInPercentage) throws Exception {
-        sFile = args[args.length - 1];
-        readLogFile(sFile, nBurnInPercentage);
+    public LogAnalyser(String[] args, int burnInPercentage) throws IOException {
+        fileName = args[args.length - 1];
+        readLogFile(fileName, burnInPercentage);
         calcStats();
     }
 
-    public LogAnalyser(String[] args) throws Exception {
+    public LogAnalyser(String[] args) throws IOException {
         this(args, BURN_IN_PERCENTAGE);
     }
 
-    public LogAnalyser(String sFile, int nBurnInPercentage) throws Exception {
-        this.sFile = sFile;
-        readLogFile(sFile, nBurnInPercentage);
+    public LogAnalyser(String fileName, int burnInPercentage) throws IOException {
+        this.fileName = fileName;
+        readLogFile(fileName, burnInPercentage);
         calcStats();
     }
 
-    public LogAnalyser(String sFile, int nBurnInPercentage, boolean quiet) throws Exception {
-        this.sFile = sFile;
+    public LogAnalyser(String fileName, int burnInPercentage, boolean quiet) throws IOException {
+        this.fileName = fileName;
         this.quiet = quiet;
-        readLogFile(sFile, nBurnInPercentage);
+        readLogFile(fileName, burnInPercentage);
         calcStats();
     }
 
-    public LogAnalyser(String sFile) throws Exception {
-        this(sFile, BURN_IN_PERCENTAGE);
+    public LogAnalyser(String fileName) throws IOException {
+        this(fileName, BURN_IN_PERCENTAGE);
     }
 
-    protected void readLogFile(String sFile, int nBurnInPercentage) throws Exception {
-        log("\nLoading " + sFile);
-        BufferedReader fin = new BufferedReader(new FileReader(sFile));
-        String sStr;
+    @SuppressWarnings("unchecked")
+	protected void readLogFile(String fileName, int burnInPercentage) throws IOException {
+        log("\nLoading " + fileName);
+        BufferedReader fin = new BufferedReader(new FileReader(fileName));
+        String str;
         m_sPreAmble = "";
         m_sLabels = null;
-        int nData = 0;
+        int data = 0;
         // first, sweep through the log file to determine size of the log
         while (fin.ready()) {
-            sStr = fin.readLine();
-            if (sStr.indexOf('#') < 0 && sStr.matches(".*[0-9a-zA-Z].*")) {
+            str = fin.readLine();
+            if (str.indexOf('#') < 0 && str.matches(".*[0-9a-zA-Z].*")) {
                 if (m_sLabels == null)
-                    m_sLabels = sStr.split("\\s");
+                    m_sLabels = str.split("\\s");
                 else
-                    nData++;
+                    data++;
             } else {
-                m_sPreAmble += sStr + "\n";
+                m_sPreAmble += str + "\n";
             }
         }
-        int nLines = Math.max(1, nData / 80);
+        int lines = Math.max(1, data / 80);
         // reserve memory
-        int nItems = m_sLabels.length;
-        m_ranges = new List[nItems];
-        int nBurnIn = nData * nBurnInPercentage / 100;
-        m_fTraces = new Double[nItems][nData - nBurnIn];
-        fin = new BufferedReader(new FileReader(sFile));
-        nData = -nBurnIn - 1;
-        logln(", burnin " + nBurnInPercentage + "%, skipping " + nBurnIn + " log lines\n\n" + BAR);
+        int items = m_sLabels.length;
+        m_ranges = new List[items];
+        int burnIn = data * burnInPercentage / 100;
+        m_fTraces = new Double[items][data - burnIn];
+        fin.close();
+        fin = new BufferedReader(new FileReader(fileName));
+        data = -burnIn - 1;
+        logln(", burnin " + burnInPercentage + "%, skipping " + burnIn + " log lines\n\n" + BAR);
         // grab data from the log, ignoring burn in samples
-        m_types = new type[nItems];
+        m_types = new type[items];
         Arrays.fill(m_types, type.INTEGER);
         while (fin.ready()) {
-            sStr = fin.readLine();
+            str = fin.readLine();
             int i = 0;
-            if (sStr.indexOf('#') < 0 && sStr.matches("[0-9].*")) // {
-                //nData++;
-                if (++nData >= 0) //{
-                    for (String sStr2 : sStr.split("\\s")) {
+            if (str.indexOf('#') < 0 && str.matches("[0-9].*")) // {
+                //data++;
+                if (++data >= 0) //{
+                    for (String str2 : str.split("\\s")) {
                         try {
-                            if (sStr2.indexOf('.') >= 0) {
+                            if (str2.indexOf('.') >= 0) {
                                 m_types[i] = type.REAL;
                             }
-                            m_fTraces[i][nData] = Double.parseDouble(sStr2);
+                            m_fTraces[i][data] = Double.parseDouble(str2);
                         } catch (Exception e) {
                             if (m_ranges[i] == null) {
                                 m_ranges[i] = new ArrayList<>();
                             }
-                            if (!m_ranges[i].contains(sStr2)) {
-                                m_ranges[i].add(sStr2);
+                            if (!m_ranges[i].contains(str2)) {
+                                m_ranges[i].add(str2);
                             }
-                            m_fTraces[i][nData] = 1.0 * m_ranges[i].indexOf(sStr2);
+                            m_fTraces[i][data] = 1.0 * m_ranges[i].indexOf(str2);
                         }
                         i++;
                     }
             //}
             //}
-            if (nData % nLines == 0) {
+            if (data % lines == 0) {
                 log("*");
             }
         }
         logln("");
         // determine types
-        for (int i = 0; i < nItems; i++)
+        for (int i = 0; i < items; i++)
             if (m_ranges[i] != null)
                 if (m_ranges[i].size() == 2 && m_ranges[i].contains("true") && m_ranges[i].contains("false") ||
                         m_ranges[i].size() == 1 && (m_ranges[i].contains("true") || m_ranges[i].contains("false")))
                     m_types[i] = type.BOOL;
                 else
                     m_types[i] = type.NOMINAL;
-
+        
+        fin.close();
     } // readLogFile
 
     /**
@@ -176,29 +180,29 @@ public class LogAnalyser {
      */
     void calcStats() {
         logln("\nCalculating statistics\n\n" + BAR);
-        int nStars = 0;
-        int nItems = m_sLabels.length;
-        m_fMean = new Double[nItems];
-        m_fStdError = new Double[nItems];
-        m_fStdDev = new Double[nItems];
-        m_fMedian = new Double[nItems];
-        m_f95HPDlow = new Double[nItems];
-        m_f95HPDup = new Double[nItems];
-        m_fESS = new Double[nItems];
-        m_fACT = new Double[nItems];
-        m_fGeometricMean = new Double[nItems];
-        int nSampleInterval = (int) (m_fTraces[0][1] - m_fTraces[0][0]);
-        for (int i = 1; i < nItems; i++) {
+        int stars = 0;
+        int items = m_sLabels.length;
+        m_fMean = new Double[items];
+        m_fStdError = new Double[items];
+        m_fStdDev = new Double[items];
+        m_fMedian = new Double[items];
+        m_f95HPDlow = new Double[items];
+        m_f95HPDup = new Double[items];
+        m_fESS = new Double[items];
+        m_fACT = new Double[items];
+        m_fGeometricMean = new Double[items];
+        int sampleInterval = (int) (m_fTraces[0][1] - m_fTraces[0][0]);
+        for (int i = 1; i < items; i++) {
             // calc mean and standard deviation
-            Double[] fTrace = m_fTraces[i];
-            double fSum = 0, fSum2 = 0;
-            for (double f : fTrace) {
-                fSum += f;
-                fSum2 += f * f;
+            Double[] trace = m_fTraces[i];
+            double sum = 0, sum2 = 0;
+            for (double f : trace) {
+                sum += f;
+                sum2 += f * f;
             }
             if (m_types[i] != type.NOMINAL) {
-                m_fMean[i] = fSum / fTrace.length;
-                m_fStdDev[i] = Math.sqrt(fSum2 / fTrace.length - m_fMean[i] * m_fMean[i]);
+                m_fMean[i] = sum / trace.length;
+                m_fStdDev[i] = Math.sqrt(sum2 / trace.length - m_fMean[i] * m_fMean[i]);
             } else {
                 m_fMean[i] = Double.NaN;
                 m_fStdDev[i] = Double.NaN;
@@ -206,35 +210,35 @@ public class LogAnalyser {
 
             if (m_types[i] == type.REAL || m_types[i] == type.INTEGER) {
                 // calc median, and 95% HPD interval
-                Double[] fSorted = fTrace.clone();
-                Arrays.sort(fSorted);
-                m_fMedian[i] = fSorted[fTrace.length / 2];
+                Double[] sorted = trace.clone();
+                Arrays.sort(sorted);
+                m_fMedian[i] = sorted[trace.length / 2];
                 // n instances cover 95% of the trace, reduced down by 1 to match Tracer
-                int n = (int) ((fSorted.length - 1) * 95.0 / 100.0);
-                double fMinRange = Double.MAX_VALUE;
+                int n = (int) ((sorted.length - 1) * 95.0 / 100.0);
+                double minRange = Double.MAX_VALUE;
                 int hpdIndex = 0;
-                for (int k = 0; k < fSorted.length - n; k++) {
-                    double fRange = fSorted[k + n] - fSorted[k];
-                    if (fRange < fMinRange) {
-                        fMinRange = fRange;
+                for (int k = 0; k < sorted.length - n; k++) {
+                    double range = sorted[k + n] - sorted[k];
+                    if (range < minRange) {
+                        minRange = range;
                         hpdIndex = k;
                     }
                 }
-                m_f95HPDlow[i] = fSorted[hpdIndex];
-                m_f95HPDup[i] = fSorted[hpdIndex + n];
+                m_f95HPDlow[i] = sorted[hpdIndex];
+                m_f95HPDup[i] = sorted[hpdIndex + n];
 
                 // calc effective sample size
-                m_fACT[i] = ESS.ACT(m_fTraces[i], nSampleInterval);
-                m_fStdError[i] = ESS.stdErrorOfMean(fTrace, nSampleInterval);
-                m_fESS[i] = fTrace.length / (m_fACT[i] / nSampleInterval);
+                m_fACT[i] = ESS.ACT(m_fTraces[i], sampleInterval);
+                m_fStdError[i] = ESS.stdErrorOfMean(trace, sampleInterval);
+                m_fESS[i] = trace.length / (m_fACT[i] / sampleInterval);
 
                 // calc geometric mean
-                if (fSorted[0] > 0) {
+                if (sorted[0] > 0) {
                     // geometric mean is only defined when all elements are positive
                     double gm = 0;
-                    for (double f : fTrace)
+                    for (double f : trace)
                         gm += Math.log(f);
-                    m_fGeometricMean[i] = Math.exp(gm / (double) fTrace.length);
+                    m_fGeometricMean[i] = Math.exp(gm / trace.length);
                 } else
                     m_fGeometricMean[i] = Double.NaN;
             } else {
@@ -245,33 +249,33 @@ public class LogAnalyser {
                 m_fESS[i] = Double.NaN;
                 m_fGeometricMean[i] = Double.NaN;
             }
-            while (nStars < 80 * (i + 1) / nItems) {
+            while (stars < 80 * (i + 1) / items) {
                 log("*");
-                nStars++;
+                stars++;
             }
         }
         logln("\n");
     } // calcStats
 
-    public void setData(Double[][] fTraces, String[] sLabels, type[] types) {
-        m_fTraces = fTraces.clone();
-        m_sLabels = sLabels.clone();
+    public void setData(Double[][] traces, String[] labels, type[] types) {
+        m_fTraces = traces.clone();
+        m_sLabels = labels.clone();
         m_types = types.clone();
         calcStats();
     }
 
-    public void setData(Double[] fTrace, int nSampleStep) {
-        Double[][] fTraces = new Double[2][];
-        fTraces[0] = new Double[fTrace.length];
-        for (int i = 0; i < fTrace.length; i++) {
-            fTraces[0][i] = (double) i * nSampleStep;
+    public void setData(Double[] trace, int sampleStep) {
+        Double[][] traces = new Double[2][];
+        traces[0] = new Double[trace.length];
+        for (int i = 0; i < trace.length; i++) {
+            traces[0][i] = (double) i * sampleStep;
         }
-        fTraces[1] = fTrace.clone();
-        setData(fTraces, new String[]{"column", "data"}, new type[]{type.REAL, type.REAL});
+        traces[1] = trace.clone();
+        setData(traces, new String[]{"column", "data"}, new type[]{type.REAL, type.REAL});
     }
 
-    public int indexof(String sLabel) {
-        return CollectionUtils.indexof(sLabel, m_sLabels);
+    public int indexof(String label) {
+        return CollectionUtils.indexof(label, m_sLabels);
 	}
 
     /**
@@ -288,124 +292,124 @@ public class LogAnalyser {
     	return m_fTraces[index].clone();
     }
 
-    public Double [] getTrace(String sLabel) {
-    	return m_fTraces[indexof(sLabel)].clone();
+    public Double [] getTrace(String label) {
+    	return m_fTraces[indexof(label)].clone();
     }
 
-    public double getMean(String sLabel) {
-        return getMean(indexof(sLabel));
+    public double getMean(String label) {
+        return getMean(indexof(label));
     }
 
-    public double getStdError(String sLabel) {
-        return getStdError(indexof(sLabel));
+    public double getStdError(String label) {
+        return getStdError(indexof(label));
     }
 
-    public double getStdDev(String sLabel) {
-        return getStdDev(indexof(sLabel));
+    public double getStdDev(String label) {
+        return getStdDev(indexof(label));
     }
 
-    public double getMedian(String sLabel) {
-        return getMedian(indexof(sLabel));
+    public double getMedian(String label) {
+        return getMedian(indexof(label));
     }
 
-    public double get95HPDup(String sLabel) {
-        return get95HPDup(indexof(sLabel));
+    public double get95HPDup(String label) {
+        return get95HPDup(indexof(label));
     }
 
-    public double get95HPDlow(String sLabel) {
-        return get95HPDlow(indexof(sLabel));
+    public double get95HPDlow(String label) {
+        return get95HPDlow(indexof(label));
     }
 
-    public double getESS(String sLabel) {
-        return getESS(indexof(sLabel));
+    public double getESS(String label) {
+        return getESS(indexof(label));
     }
 
-    public double getACT(String sLabel) {
-        return getACT(indexof(sLabel));
+    public double getACT(String label) {
+        return getACT(indexof(label));
     }
 
-    public double getGeometricMean(String sLabel) {
-        return getGeometricMean(indexof(sLabel));
+    public double getGeometricMean(String label) {
+        return getGeometricMean(indexof(label));
     }
 
-    public double getMean(int iColumn) {
-        return m_fMean[iColumn];
+    public double getMean(int column) {
+        return m_fMean[column];
     }
 
-    public double getStdDev(int iColumn) {
-        return m_fStdDev[iColumn];
+    public double getStdDev(int column) {
+        return m_fStdDev[column];
     }
 
-    public double getStdError(int iColumn) {
-        return m_fStdError[iColumn];
+    public double getStdError(int column) {
+        return m_fStdError[column];
     }
 
-    public double getMedian(int iColumn) {
-        return m_fMedian[iColumn];
+    public double getMedian(int column) {
+        return m_fMedian[column];
     }
 
-    public double get95HPDup(int iColumn) {
-        return m_f95HPDup[iColumn];
+    public double get95HPDup(int column) {
+        return m_f95HPDup[column];
     }
 
-    public double get95HPDlow(int iColumn) {
-        return m_f95HPDlow[iColumn];
+    public double get95HPDlow(int column) {
+        return m_f95HPDlow[column];
     }
 
-    public double getESS(int iColumn) {
-        return m_fESS[iColumn];
+    public double getESS(int column) {
+        return m_fESS[column];
     }
 
-    public double getACT(int iColumn) {
-        return m_fACT[iColumn];
+    public double getACT(int column) {
+        return m_fACT[column];
     }
 
-    public double getGeometricMean(int iColumn) {
-        return m_fGeometricMean[iColumn];
+    public double getGeometricMean(int column) {
+        return m_fGeometricMean[column];
     }
 
-    public double getMean(Double[] fTrace) {
-        setData(fTrace, 1);
+    public double getMean(Double[] trace) {
+        setData(trace, 1);
         return m_fMean[1];
     }
 
-    public double getStdDev(Double[] fTrace) {
-        setData(fTrace, 1);
+    public double getStdDev(Double[] trace) {
+        setData(trace, 1);
         return m_fStdDev[1];
     }
 
-    public double getMedian(Double[] fTrace) {
-        setData(fTrace, 1);
+    public double getMedian(Double[] trace) {
+        setData(trace, 1);
         return m_fMedian[1];
     }
 
-    public double get95HPDup(Double[] fTrace) {
-        setData(fTrace, 1);
+    public double get95HPDup(Double[] trace) {
+        setData(trace, 1);
         return m_f95HPDup[1];
     }
 
-    public double get95HPDlow(Double[] fTrace) {
-        setData(fTrace, 1);
+    public double get95HPDlow(Double[] trace) {
+        setData(trace, 1);
         return m_f95HPDlow[1];
     }
 
-    public double getESS(Double[] fTrace) {
-        setData(fTrace, 1);
+    public double getESS(Double[] trace) {
+        setData(trace, 1);
         return m_fESS[1];
     }
 
-    public double getACT(Double[] fTrace, int nSampleStep) {
-        setData(fTrace, nSampleStep);
+    public double getACT(Double[] trace, int sampleStep) {
+        setData(trace, sampleStep);
         return m_fACT[1];
     }
 
-    public double getGeometricMean(Double[] fTrace) {
-        setData(fTrace, 1);
+    public double getGeometricMean(Double[] trace) {
+        setData(trace, 1);
         return m_fGeometricMean[1];
     }
 
     public String getLogFile() {
-        return sFile;
+        return fileName;
     }
 
     /**
@@ -431,17 +435,17 @@ public class LogAnalyser {
             Thread.sleep(100);
         } catch (Exception e) {
         }
-        int nMax = 0;
+        int max = 0;
         for (int i = 1; i < m_sLabels.length; i++)
-            nMax = Math.max(m_sLabels[i].length(), nMax);
-        String sSpace = "";
-        for (int i = 0; i < nMax; i++)
-            sSpace += " ";
+            max = Math.max(m_sLabels[i].length(), max);
+        String space = "";
+        for (int i = 0; i < max; i++)
+            space += " ";
 
-        out.println("item" + sSpace.substring(4) + " " + prefixHead +
+        out.println("item" + space.substring(4) + " " + prefixHead +
         		format("mean") + format("stderr")  + format("stddev")  + format("median")  + format("95%HPDlo")  + format("95%HPDup")  + format("ACT")  + format("ESS")  + format("geometric-mean"));
         for (int i = 1; i < m_sLabels.length; i++) {
-            out.println(m_sLabels[i] + sSpace.substring(m_sLabels[i].length()) + SPACE + (prefix == null ? "" : prefix + SPACE) +
+            out.println(m_sLabels[i] + space.substring(m_sLabels[i].length()) + SPACE + (prefix == null ? "" : prefix + SPACE) +
                     format(m_fMean[i]) + SPACE + format(m_fStdError[i]) + SPACE + format(m_fStdDev[i]) +
                     SPACE + format(m_fMedian[i]) + SPACE + format(m_f95HPDlow[i]) + SPACE + format(m_f95HPDup[i]) +
                     SPACE + format(m_fACT[i]) + SPACE + format(m_fESS[i]) + SPACE + format(m_fGeometricMean[i]));
@@ -500,12 +504,12 @@ public class LogAnalyser {
 
     protected void log(String s) {
         if (!quiet)
-            System.err.print(s);
+            Log.warning.print(s);
     }
 
     protected void logln(String s) {
         if (!quiet)
-            System.err.println(s);
+        	Log.warning.println(s);
     }
 
     static void printUsageAndExit() {
diff --git a/src/beast/util/LogComparator.java b/src/beast/util/LogComparator.java
index 6894405..291acbc 100644
--- a/src/beast/util/LogComparator.java
+++ b/src/beast/util/LogComparator.java
@@ -1,15 +1,15 @@
 package beast.util;
 
 
-import beast.app.BEASTVersion;
-import beast.app.util.Utils;
+import static beast.util.OutputUtils.format;
 
 import java.io.File;
 import java.io.PrintStream;
 import java.util.ArrayList;
 import java.util.List;
 
-import static beast.util.OutputUtils.format;
+import beast.app.BEASTVersion;
+import beast.app.util.Utils;
 
 /**
  * Compare log files to find the set of parameters same between logs but having significantly different value.
@@ -42,10 +42,10 @@ public class LogComparator {
         compareLogs();
     }
 
-    public double getZScore(String sLabel) {
-        int index = matchedLabels.indexOf(sLabel);
+    public double getZScore(String label) {
+        int index = matchedLabels.indexOf(label);
         if (index < 0)
-            throw new IllegalArgumentException("Cannot find " + sLabel + " from matched parameter list !");
+            throw new IllegalArgumentException("Cannot find " + label + " from matched parameter list !");
 
         return zScore[index];
     }
@@ -90,18 +90,18 @@ public class LogComparator {
             }
         }
 
-        int nMax = 0;
+        int max = 0;
         for (int i = 1; i < matchedLabels.size(); i++)
-            nMax = Math.max(matchedLabels.get(i).length(), nMax);
-        String sSpace = "";
-        for (int i = 0; i < nMax; i++)
-            sSpace += " ";
+            max = Math.max(matchedLabels.get(i).length(), max);
+        String space = "";
+        for (int i = 0; i < max; i++)
+            space += " ";
 
         out.println("Comparing log " + analyser1.getLogFile() + " and " + analyser2.getLogFile() + "\n");
 
         List<String> significantLabels = new ArrayList<>();
         if (verbose) {
-            out.println("item" + sSpace.substring(4) + " " + prefixHead + "   " + format("ZScore") +
+            out.println("item" + space.substring(4) + " " + prefixHead + "   " + format("ZScore") +
                     format("mean1") + format("stderr1") + format("mean2") + format("stderr2"));
 
             for (int i = 1; i < matchedLabels.size(); i++) {
@@ -115,7 +115,7 @@ public class LogComparator {
                 double m2 = analyser2.getMean(index2);
                 double se2 = analyser2.getStdError(index2);
 
-                out.println(mLabel + sSpace.substring(mLabel.length()) + SPACE + (prefix == null ? "" : prefix + SPACE) +
+                out.println(mLabel + space.substring(mLabel.length()) + SPACE + (prefix == null ? "" : prefix + SPACE) +
                         (zScore[i] > 2 ? STAR : NON_STAR) + SPACE + format(zScore[i]) + SPACE +
                         format(m1) + SPACE + format(se1) + SPACE + format(m2) + SPACE + format(se2));
 
diff --git a/src/beast/util/MersenneTwisterFast.java b/src/beast/util/MersenneTwisterFast.java
index 3a8b937..5071480 100644
--- a/src/beast/util/MersenneTwisterFast.java
+++ b/src/beast/util/MersenneTwisterFast.java
@@ -50,7 +50,6 @@
 package beast.util;
 
 import java.io.FileNotFoundException;
-import java.io.PrintStream;
 import java.io.Serializable;
 
 import beast.math.GammaFunction;
@@ -339,7 +338,7 @@ public class MersenneTwisterFast implements Serializable {
         z ^= (z << 15) & TEMPERING_MASK_C;      // TEMPERING_SHIFT_T(z)
         z ^= (z >>> 18);                        // TEMPERING_SHIFT_L(z)
 
-        return (((long) y) << 32) + (long) z;
+        return (((long) y) << 32) + z;
     }
 
 
@@ -698,7 +697,7 @@ public class MersenneTwisterFast implements Serializable {
      * @param lambda
      * @return 
      */
-    private double poissonian_reject(double lambda) {
+    private long poissonian_reject(double lambda) {
         double sq = Math.sqrt(2.0*lambda);
         double alxm = Math.log(lambda);
         double g = lambda*alxm-GammaFunction.lnGamma(lambda+1.0);
@@ -716,39 +715,44 @@ public class MersenneTwisterFast implements Serializable {
 
         } while (nextDouble()>t);
 
-        return em;
+        return Math.round(em);
     }
 
     /**
-     * Direct method: only efficient for small lambda.
+     * Inverse CDF method: only efficient for small lambda.  Warning:
+     * this method assumes that lambda < 12 by including a fail-safe
+     * loop abort which truncates the possible sample values to <500.
+     * (Numerical implementations of the cDF method can occasionally
+     * lead to infinite loops due to floating point errors.)
      * 
      * @param lambda
      * @return 
      */
-    private double poissonian_knuth(double lambda) {
-        double L = Math.exp(-lambda);
-        double p;
-        int k;
+    private long poissonian_icdf(double lambda) {
+        double p = nextDouble();
 
-        for (k = 0, p = 1; p>=L; k++)
-            p = p*nextDouble();
+        double factor = Math.exp(-lambda);
+        double  acc = factor;
+        int n=0;
 
-        return k-1;
+        while (p>acc && n<500) {
+            n += 1;
+            factor *= lambda/n;
+            acc += factor;
+        }
+
+        return n;
     }
 
     /**
-     * Sample from a Poissonian distribution.  Note that samples are expressed
-     * as doubles, allowing for sensible convergence to the appropriate
-     * Gaussian when extremely large lambdas are used.  Be aware however that
-     * systematic errors due to rounding start to creep in for lambda>1e14.
-     * Can we improve on this?
-     * 
-     * @param lambda
-     * @return Draw from Pois(lambda).
+     * Sample from a Poissonian distribution.
+     *
+     * @param lambda mean of Poissonian distribution
+     * @return Draw from Pois(lambda). Note: returns a double for historical reasons.
      */
     public double nextPoisson(double lambda) {
         if (lambda<12)
-            return poissonian_knuth(lambda);
+            return poissonian_icdf(lambda);
 
         return poissonian_reject(lambda);
     }
@@ -758,21 +762,19 @@ public class MersenneTwisterFast implements Serializable {
      */
     public static void main (String [] args) throws FileNotFoundException {
         
-        double lambda = 1e12;
+        double lambda = 1e14;
         int reps=100000;
         
-        double sqrtlambda = Math.sqrt(lambda);
         double [] vals = new double[reps];
 
-        PrintStream outf = new PrintStream("vals.txt");
+//        PrintStream outf = new PrintStream("vals.txt");
         
         for (int i=0; i<reps; i++) {
             double val = Randomizer.nextPoisson(lambda);
-            //double val = Randomizer.nextGaussian()*sqrtlambda + lambda;
             vals[i] = val;
-            outf.println(val);
+//            outf.println(val);
         }
-        outf.close();
+//        outf.close();
         
         System.out.format("E[x]=%g\n",DiscreteStatistics.mean(vals));
         System.out.format("Var[x]=%g\n", DiscreteStatistics.variance(vals));
diff --git a/src/beast/util/NexusParser.java b/src/beast/util/NexusParser.java
index e29cc07..bf88ce9 100644
--- a/src/beast/util/NexusParser.java
+++ b/src/beast/util/NexusParser.java
@@ -1,18 +1,35 @@
 package beast.util;
 
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
 import beast.core.util.Log;
-import beast.evolution.alignment.*;
+import beast.evolution.alignment.Alignment;
+import beast.evolution.alignment.FilteredAlignment;
+import beast.evolution.alignment.Sequence;
+import beast.evolution.alignment.Taxon;
+import beast.evolution.alignment.TaxonSet;
 import beast.evolution.datatype.DataType;
 import beast.evolution.datatype.StandardData;
 import beast.evolution.datatype.UserDataType;
 import beast.evolution.tree.TraitSet;
 import beast.evolution.tree.Tree;
 
-import java.io.*;
-import java.util.*;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
 
 /**
  * parses nexus file and grabs alignment and calibration from the file *
@@ -27,7 +44,7 @@ public class NexusParser {
      * Beast II objects reconstructed from the file*
      */
     public Alignment m_alignment;
-    public List<Alignment> filteredAlignments = new ArrayList<Alignment>();
+    public List<Alignment> filteredAlignments = new ArrayList<>();
     public TraitSet traitSet;
 
     public List<String> taxa;
@@ -58,7 +75,7 @@ public class NexusParser {
      *
      * @param file the file to parse.
      */
-    public void parseFile(final File file) throws Exception {
+    public void parseFile(final File file) throws IOException {
         final String fileName = file.getName().replaceAll(".*[\\/\\\\]", "").replaceAll("\\..*", "");
 
         parseFile(fileName, new FileReader(file));
@@ -69,8 +86,10 @@ public class NexusParser {
      *
      * @param id     a name to give to the parsed results
      * @param reader a reader to parse from
+     * TODO: RRB: throws IOException now instead of just Exception. 
+     * java.text.ParseException seems more appropriate, but requires keeping track of the position in the file, which is non-trivial 
      */
-    public void parseFile(final String id, final Reader reader) throws Exception {
+    public void parseFile(final String id, final Reader reader) throws IOException {
         lineNr = 0;
         final BufferedReader fin;
         if (reader instanceof BufferedReader) {
@@ -80,44 +99,44 @@ public class NexusParser {
         }
         try {
             while (fin.ready()) {
-                final String sStr = nextLine(fin);
-                if (sStr == null) {
+                final String str = nextLine(fin);
+                if (str == null) {
                     return;
                 }
-                final String sLower = sStr.toLowerCase();
-                if (sLower.matches("^\\s*begin\\s+data;\\s*$") || sLower.matches("^\\s*begin\\s+characters;\\s*$")) {
+                final String lower = str.toLowerCase();
+                if (lower.matches("^\\s*begin\\s+data;\\s*$") || lower.matches("^\\s*begin\\s+characters;\\s*$")) {
                     m_alignment = parseDataBlock(fin);
                     m_alignment.setID(id);
-                } else if (sLower.matches("^\\s*begin\\s+calibration;\\s*$")) {
+                } else if (lower.matches("^\\s*begin\\s+calibration;\\s*$")) {
                     traitSet = parseCalibrationsBlock(fin);
-                } else if (sLower.matches("^\\s*begin\\s+assumptions;\\s*$") ||
-                        sLower.matches("^\\s*begin\\s+sets;\\s*$") ||
-                        sLower.matches("^\\s*begin\\s+mrbayes;\\s*$")) {
+                } else if (lower.matches("^\\s*begin\\s+assumptions;\\s*$") ||
+                        lower.matches("^\\s*begin\\s+sets;\\s*$") ||
+                        lower.matches("^\\s*begin\\s+mrbayes;\\s*$")) {
                     parseAssumptionsBlock(fin);
-                } else if (sLower.matches("^\\s*begin\\s+taxa;\\s*$")) {
+                } else if (lower.matches("^\\s*begin\\s+taxa;\\s*$")) {
                     parseTaxaBlock(fin);
-                } else if (sLower.matches("^\\s*begin\\s+trees;\\s*$")) {
+                } else if (lower.matches("^\\s*begin\\s+trees;\\s*$")) {
                     parseTreesBlock(fin);
                 }
             }
         } catch (Exception e) {
             e.printStackTrace();
-            throw new Exception("Around line " + lineNr + "\n" + e.getMessage());
+            throw new IOException("Around line " + lineNr + "\n" + e.getMessage());
         }
     } // parseFile
 
-    private void parseTreesBlock(final BufferedReader fin) throws Exception {
-        trees = new ArrayList<Tree>();
+    private void parseTreesBlock(final BufferedReader fin) throws IOException {
+        trees = new ArrayList<>();
         // read to first non-empty line within trees block
-        String sStr = fin.readLine().trim();
-        while (sStr.equals("")) {
-            sStr = fin.readLine().trim();
+        String str = fin.readLine().trim();
+        while (str.equals("")) {
+            str = fin.readLine().trim();
         }
 
         int origin = -1;
 
         // if first non-empty line is "translate" then parse translate block
-        if (sStr.toLowerCase().contains("translate")) {
+        if (str.toLowerCase().contains("translate")) {
             translationMap = parseTranslateBlock(fin);
             origin = getIndexedTranslationMapOrigin(translationMap);
             if (origin != -1) {
@@ -126,25 +145,25 @@ public class NexusParser {
         }
 
         // read trees
-        while (sStr != null) {
-            if (sStr.toLowerCase().startsWith("tree ")) {
-                final int i = sStr.indexOf('(');
+        while (str != null) {
+            if (str.toLowerCase().startsWith("tree ")) {
+                final int i = str.indexOf('(');
                 if (i > 0) {
-                    sStr = sStr.substring(i);
+                    str = str.substring(i);
                 }
                 TreeParser treeParser;
 
                 if (origin != -1) {
-                    treeParser = new TreeParser(taxa, sStr, origin, false);
+                    treeParser = new TreeParser(taxa, str, origin, false);
                 } else {
                     try {
-                        treeParser = new TreeParser(taxa, sStr, 0, false);
+                        treeParser = new TreeParser(taxa, str, 0, false);
                     } catch (ArrayIndexOutOfBoundsException e) {
-                        treeParser = new TreeParser(taxa, sStr, 1, false);
+                        treeParser = new TreeParser(taxa, str, 1, false);
                     }
                 }
 //                catch (NullPointerException e) {
-//                    treeParser = new TreeParser(m_taxa, sStr, 1);
+//                    treeParser = new TreeParser(m_taxa, str, 1);
 //                }
 
                 for (final NexusParserListener listener : listeners) {
@@ -157,16 +176,16 @@ public class NexusParser {
 
 //				Node tree = treeParser.getRoot();
 //				tree.sort();
-//				tree.labelInternalNodes(nNrOfLabels);
+//				tree.labelInternalNodes(nrOfLabels);
             }
-            sStr = fin.readLine();
-            if (sStr != null) sStr = sStr.trim();
+            str = fin.readLine();
+            if (str != null) str = str.trim();
         }
     }
 
     private List<String> getIndexedTranslationMap(final Map<String, String> translationMap, final int origin) {
 
-        System.out.println("translation map size = " + translationMap.size());
+        Log.info.println("translation map size = " + translationMap.size());
 
         final String[] taxa = new String[translationMap.size()];
 
@@ -182,7 +201,7 @@ public class NexusParser {
      */
     private int getIndexedTranslationMapOrigin(final Map<String, String> translationMap) {
 
-        final SortedSet<Integer> indices = new TreeSet<Integer>();
+        final SortedSet<Integer> indices = new TreeSet<>();
 
         int count = 0;
         for (final String key : translationMap.keySet()) {
@@ -204,7 +223,7 @@ public class NexusParser {
      */
     private Map<String, String> parseTranslateBlock(final BufferedReader reader) throws IOException {
 
-        final Map<String, String> translationMap = new HashMap<String, String>();
+        final Map<String, String> translationMap = new HashMap<>();
 
         String line = reader.readLine();
         final StringBuilder translateBlock = new StringBuilder();
@@ -217,95 +236,95 @@ public class NexusParser {
             final String[] translation = taxaTranslation.split("[\t ]+");
             if (translation.length == 2) {
                 translationMap.put(translation[0], translation[1]);
-//                System.out.println(translation[0] + " -> " + translation[1]);
+//                Log.info.println(translation[0] + " -> " + translation[1]);
             } else {
-                System.err.println("Ignoring translation:" + Arrays.toString(translation));
+                Log.warning.println("Ignoring translation:" + Arrays.toString(translation));
             }
         }
         return translationMap;
     }
 
-    private void parseTaxaBlock(final BufferedReader fin) throws Exception {
-        taxa = new ArrayList<String>();
-        int nTaxaExpected = -1;
-        String sStr;
+    private void parseTaxaBlock(final BufferedReader fin) throws IOException {
+        taxa = new ArrayList<>();
+        int expectedTaxonCount = -1;
+        String str;
         do {
-            sStr = nextLine(fin);
-            if (sStr.toLowerCase().matches("\\s*dimensions\\s.*")) {
-                sStr = sStr.substring(sStr.toLowerCase().indexOf("ntax=") + 5);
-                sStr = sStr.replaceAll(";", "");
-                nTaxaExpected = Integer.parseInt(sStr.trim());
-            } else if (sStr.toLowerCase().trim().equals("taxlabels")) {
+            str = nextLine(fin);
+            if (str.toLowerCase().matches("\\s*dimensions\\s.*")) {
+                str = str.substring(str.toLowerCase().indexOf("ntax=") + 5);
+                str = str.replaceAll(";", "");
+                expectedTaxonCount = Integer.parseInt(str.trim());
+            } else if (str.toLowerCase().trim().equals("taxlabels")) {
                 do {
-                    sStr = nextLine(fin);
-                    sStr = sStr.replaceAll(";", "");
-                    sStr = sStr.trim();
-                    if (sStr.length() > 0 && !sStr.toLowerCase().equals("end")) {
-                    	String [] sStrs = sStr.split("\\s+");
-                    	for (int i = 0; i < sStrs.length; i++) {
-                        	String taxon = sStrs[i];
+                    str = nextLine(fin);
+                    str = str.replaceAll(";", "");
+                    str = str.trim();
+                    if (str.length() > 0 && !str.toLowerCase().equals("end")) {
+                    	String [] strs = str.split("\\s+");
+                    	for (int i = 0; i < strs.length; i++) {
+                        	String taxon = strs[i];
                             if (taxon.charAt(0) == '\'' || taxon.charAt(0) == '\"') {
-                            	while (i < sStrs.length && taxon.charAt(0) != taxon.charAt(taxon.length() - 1)) {
+                            	while (i < strs.length && taxon.charAt(0) != taxon.charAt(taxon.length() - 1)) {
                             		i++;
-                            		if (i == sStrs.length) {
-                            			throw new Exception("Unclosed quote starting with " + taxon);
+                            		if (i == strs.length) {
+                            			throw new IOException("Unclosed quote starting with " + taxon);
                             		}
-                            		taxon += " " + sStrs[i];
+                            		taxon += " " + strs[i];
                             	}
                             	taxon = taxon.substring(1, taxon.length() - 1);
                             }
                             taxa.add(taxon);
                     	}
                     }
-                } while (!sStr.toLowerCase().equals("end"));
+                } while (!str.toLowerCase().equals("end"));
             }
-        } while (!sStr.toLowerCase().equals("end"));
-        if (nTaxaExpected >= 0 && taxa.size() != nTaxaExpected) {
-            throw new Exception("Number of taxa (" + taxa.size() + ") is not equal to 'dimension' " +
-            		"field (" + nTaxaExpected + ") specified in 'taxa' block");
+        } while (!str.toLowerCase().equals("end"));
+        if (expectedTaxonCount >= 0 && taxa.size() != expectedTaxonCount) {
+            throw new IOException("Number of taxa (" + taxa.size() + ") is not equal to 'dimension' " +
+            		"field (" + expectedTaxonCount + ") specified in 'taxa' block");
         }
     }
 
     /**
      * parse calibrations block and create TraitSet *
      */
-    TraitSet parseCalibrationsBlock(final BufferedReader fin) throws Exception {
+    TraitSet parseCalibrationsBlock(final BufferedReader fin) throws IOException {
         final TraitSet traitSet = new TraitSet();
         traitSet.traitNameInput.setValue("date", traitSet);
-        String sStr;
+        String str;
         do {
-            sStr = nextLine(fin);
-            if (sStr.toLowerCase().contains("options")) {
-                String sScale = getAttValue("scale", sStr);
-                if (sScale.endsWith("s")) {
-                    sScale = sScale.substring(0, sScale.length() - 1);
+            str = nextLine(fin);
+            if (str.toLowerCase().contains("options")) {
+                String scale = getAttValue("scale", str);
+                if (scale.endsWith("s")) {
+                    scale = scale.substring(0, scale.length() - 1);
                 }
-                traitSet.unitsInput.setValue(sScale, traitSet);
+                traitSet.unitsInput.setValue(scale, traitSet);
             }
-        } while (sStr.toLowerCase().contains("tipcalibration"));
+        } while (str.toLowerCase().contains("tipcalibration"));
 
-        String sText = "";
+        String text = "";
         while (true) {
-            sStr = nextLine(fin);
-            if (sStr.contains(";")) {
+            str = nextLine(fin);
+            if (str.contains(";")) {
                 break;
             }
-            sText += sStr;
-        }
-        final String[] sStrs = sText.split(",");
-        sText = "";
-        for (final String sStr2 : sStrs) {
-            final String[] sParts = sStr2.split(":");
-            final String sDate = sParts[0].replaceAll(".*=\\s*", "");
-            final String[] sTaxa = sParts[1].split("\\s+");
-            for (final String sTaxon : sTaxa) {
-                if (!sTaxon.matches("^\\s*$")) {
-                    sText += sTaxon + "=" + sDate + ",\n";
+            text += str;
+        }
+        final String[] strs = text.split(",");
+        text = "";
+        for (final String str2 : strs) {
+            final String[] parts = str2.split(":");
+            final String date = parts[0].replaceAll(".*=\\s*", "");
+            final String[] taxa = parts[1].split("\\s+");
+            for (final String taxon : taxa) {
+                if (!taxon.matches("^\\s*$")) {
+                    text += taxon + "=" + date + ",\n";
                 }
             }
         }
-        sText = sText.substring(0, sText.length() - 2);
-        traitSet.traitsInput.setValue(sText, traitSet);
+        text = text.substring(0, text.length() - 2);
+        traitSet.traitsInput.setValue(text, traitSet);
         final TaxonSet taxa = new TaxonSet();
         taxa.initByName("alignment", m_alignment);
         traitSet.taxaInput.setValue(taxa, traitSet);
@@ -318,105 +337,105 @@ public class NexusParser {
     /**
      * parse data block and create Alignment *
      */
-    public Alignment parseDataBlock(final BufferedReader fin) throws Exception {
+    public Alignment parseDataBlock(final BufferedReader fin) throws IOException {
 
         final Alignment alignment = new Alignment();
 
-        String sStr;
-        int nTaxa = -1;
-        int nChar = -1;
-        int nTotalCount = 4;
-        String sMissing = "?";
-        String sGap = "-";
+        String str;
+        int taxonCount = -1;
+        int charCount = -1;
+        int totalCount = 4;
+        String missing = "?";
+        String gap = "-";
         // indicates character matches the one in the first sequence
-        String sMatchChar = null;
+        String matchChar = null;
         do {
-            sStr = nextLine(fin);
+            str = nextLine(fin);
 
             //dimensions ntax=12 nchar=898;
-            if (sStr.toLowerCase().contains("dimensions")) {
-                while (sStr.indexOf(';') < 0) {
-                    sStr += nextLine(fin);
+            if (str.toLowerCase().contains("dimensions")) {
+                while (str.indexOf(';') < 0) {
+                    str += nextLine(fin);
                 }
-                sStr = sStr.replace(";", " ");
+                str = str.replace(";", " ");
 
-                final String sChar = getAttValue("nchar", sStr);
-                if (sChar == null) {
-                    throw new Exception("nchar attribute expected (e.g. 'dimensions char=123') expected, not " + sStr);
+                final String character = getAttValue("nchar", str);
+                if (character == null) {
+                    throw new IOException("nchar attribute expected (e.g. 'dimensions char=123') expected, not " + str);
                 }
-                nChar = Integer.parseInt(sChar);
-                final String sTaxa = getAttValue("ntax", sStr);
-                if (sTaxa != null) {
-                    nTaxa = Integer.parseInt(sTaxa);
+                charCount = Integer.parseInt(character);
+                final String taxa = getAttValue("ntax", str);
+                if (taxa != null) {
+                    taxonCount = Integer.parseInt(taxa);
                 }
-            } else if (sStr.toLowerCase().contains("format")) {
-                while (sStr.indexOf(';') < 0) {
-                    sStr += nextLine(fin);
+            } else if (str.toLowerCase().contains("format")) {
+                while (str.indexOf(';') < 0) {
+                    str += nextLine(fin);
                 }
-                sStr = sStr.replace(";", " ");
+                str = str.replace(";", " ");
 
                 //format datatype=dna interleave=no gap=-;
-                final String sDataType = getAttValue("datatype", sStr);
-                final String sSymbols;
-                if (getAttValue("symbols", sStr) == null) {
-                    sSymbols = getAttValue("symbols", sStr);
+                final String dataTypeName = getAttValue("datatype", str);
+                final String symbols;
+                if (getAttValue("symbols", str) == null) {
+                    symbols = getAttValue("symbols", str);
                 } else {
-                    sSymbols = getAttValue("symbols", sStr).replaceAll("\\s", "");
+                    symbols = getAttValue("symbols", str).replaceAll("\\s", "");
                 }
-                if (sDataType == null) {
-                    System.out.println("Warning: expected datatype (e.g. something like 'format datatype=dna;') not '" + sStr + "' Assuming integer dataType");
+                if (dataTypeName == null) {
+                    Log.warning.println("Warning: expected datatype (e.g. something like 'format datatype=dna;') not '" + str + "' Assuming integer dataType");
                     alignment.dataTypeInput.setValue("integer", alignment);
-                    if (sSymbols != null && (sSymbols.equals("01") || sSymbols.equals("012"))) {
-                        nTotalCount = sSymbols.length();
+                    if (symbols != null && (symbols.equals("01") || symbols.equals("012"))) {
+                        totalCount = symbols.length();
                     }
-                } else if (sDataType.toLowerCase().equals("rna") || sDataType.toLowerCase().equals("dna") || sDataType.toLowerCase().equals("nucleotide")) {
+                } else if (dataTypeName.toLowerCase().equals("rna") || dataTypeName.toLowerCase().equals("dna") || dataTypeName.toLowerCase().equals("nucleotide")) {
                     alignment.dataTypeInput.setValue("nucleotide", alignment);
-                    nTotalCount = 4;
-                } else if (sDataType.toLowerCase().equals("aminoacid") || sDataType.toLowerCase().equals("protein")) {
+                    totalCount = 4;
+                } else if (dataTypeName.toLowerCase().equals("aminoacid") || dataTypeName.toLowerCase().equals("protein")) {
                     alignment.dataTypeInput.setValue("aminoacid", alignment);
-                    nTotalCount = 20;
-                } else if (sDataType.toLowerCase().equals("standard")) {
+                    totalCount = 20;
+                } else if (dataTypeName.toLowerCase().equals("standard")) {
                     alignment.dataTypeInput.setValue("standard", alignment);
-                    nTotalCount = sSymbols.length();
-//                    if (sSymbols == null || sSymbols.equals("01")) {
+                    totalCount = symbols.length();
+//                    if (symbols == null || symbols.equals("01")) {
 //                        alignment.dataTypeInput.setValue("binary", alignment);
-//                        nTotalCount = 2;
+//                        totalCount = 2;
 //                    }  else {
 //                        alignment.dataTypeInput.setValue("standard", alignment);
-//                        nTotalCount = sSymbols.length();
+//                        totalCount = symbols.length();
 //                    }
-                } else if (sDataType.toLowerCase().equals("binary")) {
+                } else if (dataTypeName.toLowerCase().equals("binary")) {
                     alignment.dataTypeInput.setValue("binary", alignment);
-                    nTotalCount = 2;
+                    totalCount = 2;
                 } else {
                     alignment.dataTypeInput.setValue("integer", alignment);
-                    if (sSymbols != null && (sSymbols.equals("01") || sSymbols.equals("012"))) {
-                        nTotalCount = sSymbols.length();
+                    if (symbols != null && (symbols.equals("01") || symbols.equals("012"))) {
+                        totalCount = symbols.length();
                     }
                 }
-                final String sMissingChar = getAttValue("missing", sStr);
-                if (sMissingChar != null) {
-                    sMissing = sMissingChar;
+                final String missingChar = getAttValue("missing", str);
+                if (missingChar != null) {
+                    missing = missingChar;
                 }
-                final String sGapChar = getAttValue("gap", sStr);
-                if (sGapChar != null) {
-                    sGap = sGapChar;
+                final String gapChar = getAttValue("gap", str);
+                if (gapChar != null) {
+                    gap = gapChar;
                 }
-                sMatchChar = getAttValue("matchchar", sStr);
+                matchChar = getAttValue("matchchar", str);
             }
-        } while (!sStr.trim().toLowerCase().startsWith("matrix") && !sStr.toLowerCase().contains("charstatelabels"));
+        } while (!str.trim().toLowerCase().startsWith("matrix") && !str.toLowerCase().contains("charstatelabels"));
 
         if (alignment.dataTypeInput.get().equals("standard")) {
         	StandardData type = new StandardData();
-            type.setInputValue("nrOfStates", nTotalCount);
+            type.setInputValue("nrOfStates", totalCount);
         	type.initAndValidate();
             alignment.setInputValue("userDataType", type);
         }
 
         //reading CHARSTATELABELS block
-        if (sStr.toLowerCase().contains("charstatelabels")) {
+        if (str.toLowerCase().contains("charstatelabels")) {
             if (!alignment.dataTypeInput.get().equals("standard")) {
-                new Exception("If CHATSTATELABELS block is specified then DATATYPE has to be Standard");
+                new Exception("If CHARSTATELABELS block is specified then DATATYPE has to be Standard");
             }
             StandardData standardDataType = (StandardData)alignment.userDataTypeInput.get();
             int[] maxNumberOfStates = new int[] {0};
@@ -424,19 +443,19 @@ public class NexusParser {
             ArrayList<UserDataType> charDescriptions = processCharstatelabelsTokens(tokens, maxNumberOfStates);
 
 //            while (true) {
-//                sStr = nextLine(fin);
-//                if (sStr.contains(";")) {
+//                str = nextLine(fin);
+//                if (str.contains(";")) {
 //                    break;
 //                }
-//                String[] sStrSplit = sStr.split("/");
+//                String[] strSplit = str.split("/");
 //                ArrayList<String> states = new ArrayList<>();
 //
-//                if (sStrSplit.length < 2) {
-//                    charDescriptions.add(new UserDataType(sStrSplit[0], states));
+//                if (strSplit.length < 2) {
+//                    charDescriptions.add(new UserDataType(strSplit[0], states));
 //                    continue;
 //                }
 //
-//                String stateStr = sStrSplit[1];
+//                String stateStr = strSplit[1];
 //
 //                //add a comma at the end of the string if the last non-whitespace character is not a comma or all the
 //                // characters are whitespaces in the string. Also remove whitespaces at the end of the string.
@@ -480,7 +499,7 @@ public class NexusParser {
 //                                end = stateStr.indexOf("'", end+2);
 //                            } while (stateStr.charAt(end+1) == '\'' || end == -1);
 //                            if (end == -1) {
-//                                System.out.println("Incorrect description in charstatelabels. Single quote found in line ");
+//                                Log.info.println("Incorrect description in charstatelabels. Single quote found in line ");
 //                            }
 //                            end++;
 //                            states.add(stateStr.substring(begin, end));
@@ -491,12 +510,12 @@ public class NexusParser {
 //                            break;
 //                    }
 //                }
-//                // oldTODO make sStrSplit[0] look nicer (remove whitespaces and may be numbers at the beginning)
-//                charDescriptions.add(new UserDataType(sStrSplit[0], states));
+//                // oldTODO make strSplit[0] look nicer (remove whitespaces and may be numbers at the beginning)
+//                charDescriptions.add(new UserDataType(strSplit[0], states));
 //                maxNumberOfStates = Math.max(maxNumberOfStates, states.size());
 //            }
             standardDataType.setInputValue("charstatelabels", charDescriptions);
-            standardDataType.setInputValue("nrOfStates", Math.max(maxNumberOfStates[0], nTotalCount));
+            standardDataType.setInputValue("nrOfStates", Math.max(maxNumberOfStates[0], totalCount));
             standardDataType.initAndValidate();
             for (UserDataType dataType : standardDataType.charStateLabelsInput.get()) {
             	dataType.initAndValidate();
@@ -504,102 +523,102 @@ public class NexusParser {
         }
 
         //skipping before MATRIX block
-        while (!sStr.toLowerCase().contains(("matrix"))) {
-            sStr = nextLine(fin);
+        while (!str.toLowerCase().contains(("matrix"))) {
+            str = nextLine(fin);
         }
 
         // read character data
         // Use string builder for efficiency
-        final Map<String, StringBuilder> seqMap = new HashMap<String, StringBuilder>();
-        final List<String> sTaxa = new ArrayList<String>();
-        String sPrevTaxon = null;
+        final Map<String, StringBuilder> seqMap = new HashMap<>();
+        final List<String> taxa = new ArrayList<>();
+        String prevTaxon = null;
         int seqLen = 0;
         while (true) {
-            sStr = nextLine(fin);
-            if (sStr.contains(";")) {
+            str = nextLine(fin);
+            if (str.contains(";")) {
                 break;
             }
 
-            int iStart = 0, iEnd;
-            final String sTaxon;
-            while (Character.isWhitespace(sStr.charAt(iStart))) {
-                iStart++;
+            int start = 0, end;
+            final String taxon;
+            while (Character.isWhitespace(str.charAt(start))) {
+                start++;
             }
-            if (sStr.charAt(iStart) == '\'' || sStr.charAt(iStart) == '\"') {
-                final char c = sStr.charAt(iStart);
-                iStart++;
-                iEnd = iStart;
-                while (sStr.charAt(iEnd) != c) {
-                    iEnd++;
+            if (str.charAt(start) == '\'' || str.charAt(start) == '\"') {
+                final char c = str.charAt(start);
+                start++;
+                end = start;
+                while (str.charAt(end) != c) {
+                    end++;
                 }
-                sTaxon = sStr.substring(iStart, iEnd);
+                taxon = str.substring(start, end);
                 seqLen = 0;
-                iEnd++;
+                end++;
             } else {
-                iEnd = iStart;
-                while (iEnd < sStr.length() && !Character.isWhitespace(sStr.charAt(iEnd))) {
-                    iEnd++;
+                end = start;
+                while (end < str.length() && !Character.isWhitespace(str.charAt(end))) {
+                    end++;
                 }
-                if (iEnd < sStr.length()) {
-                    sTaxon = sStr.substring(iStart, iEnd);
+                if (end < str.length()) {
+                    taxon = str.substring(start, end);
                     seqLen = 0;
-                } else if ((sPrevTaxon == null || seqLen == nChar) && iEnd == sStr.length()) {
-                    sTaxon = sStr.substring(iStart, iEnd);
+                } else if ((prevTaxon == null || seqLen == charCount) && end == str.length()) {
+                    taxon = str.substring(start, end);
                     seqLen = 0;
                 } else {
-                    sTaxon = sPrevTaxon;
-                    if (sTaxon == null) {
-                        throw new Exception("Could not recognise taxon");
+                    taxon = prevTaxon;
+                    if (taxon == null) {
+                        throw new IOException("Could not recognise taxon");
                     }
-                    iEnd = iStart;
+                    end = start;
                 }
             }
-            sPrevTaxon = sTaxon;
-            final String sData = sStr.substring(iEnd);
-            for (int k = 0; k < sData.length(); k++) {
-            	if (!Character.isWhitespace(sData.charAt(k))) {
+            prevTaxon = taxon;
+            final String data = str.substring(end);
+            for (int k = 0; k < data.length(); k++) {
+            	if (!Character.isWhitespace(data.charAt(k))) {
             		seqLen++;
             	}
             }
             // Do this once outside loop- save on multiple regex compilations
-            //sData = sData.replaceAll("\\s", "");
+            //data = data.replaceAll("\\s", "");
 
-//			String [] sStrs = sStr.split("\\s+");
-//			String sTaxon = sStrs[0];
-//			for (int k = 1; k < sStrs.length - 1; k++) {
-//				sTaxon += sStrs[k];
+//			String [] strs = str.split("\\s+");
+//			String taxon = strs[0];
+//			for (int k = 1; k < strs.length - 1; k++) {
+//				taxon += strs[k];
 //			}
-//			sTaxon = sTaxon.replaceAll("'", "");
-//			System.err.println(sTaxon);
-//			String sData = sStrs[sStrs.length - 1];
+//			taxon = taxon.replaceAll("'", "");
+//			Log.warning.println(taxon);
+//			String data = strs[strs.length - 1];
 
-            if (seqMap.containsKey(sTaxon)) {
-                seqMap.put(sTaxon, seqMap.get(sTaxon).append(sData));
+            if (seqMap.containsKey(taxon)) {
+                seqMap.put(taxon, seqMap.get(taxon).append(data));
             } else {
-                seqMap.put(sTaxon, new StringBuilder(sData));
-                sTaxa.add(sTaxon);
+                seqMap.put(taxon, new StringBuilder(data));
+                taxa.add(taxon);
             }
         }
-        if (nTaxa > 0 && sTaxa.size() > nTaxa) {
-            throw new Exception("Wrong number of taxa. Perhaps a typo in one of the taxa: " + sTaxa);
+        if (taxonCount > 0 && taxa.size() > taxonCount) {
+            throw new IOException("Wrong number of taxa. Perhaps a typo in one of the taxa: " + taxa);
         }
 
         HashSet<String> sortedAmbiguities = new HashSet<>();
-        for (final String sTaxon : sTaxa) {
-            final StringBuilder bsData = seqMap.get(sTaxon);
-            String sData = bsData.toString().replaceAll("\\s", "");
-            seqMap.put(sTaxon, new StringBuilder(sData));
+        for (final String taxon : taxa) {
+            final StringBuilder bsData = seqMap.get(taxon);
+            String data = bsData.toString().replaceAll("\\s", "");
+            seqMap.put(taxon, new StringBuilder(data));
 
             //collect all ambiguities in the sequence
-            List<String> ambiguities = new ArrayList<String>();
-            Matcher m = Pattern.compile("\\{(.*?)\\}").matcher(sData);
+            List<String> ambiguities = new ArrayList<>();
+            Matcher m = Pattern.compile("\\{(.*?)\\}").matcher(data);
             while (m.find()) {
                 int mLength = m.group().length();
                 ambiguities.add(m.group().substring(1, mLength-1));
             }
 
             //sort elements of ambiguity sets
-            String sData_without_ambiguities = sData.replaceAll("\\{(.*?)\\}", "?");
+            String data_without_ambiguities = data.replaceAll("\\{(.*?)\\}", "?");
             for (String amb : ambiguities) {
                 List<Integer> ambInt = new ArrayList<>();
                 for (int i=0; i<amb.length(); i++) {
@@ -608,10 +627,10 @@ public class NexusParser {
                 		ambInt.add(Integer.parseInt(amb.charAt(i) + ""));
                 	} else {
                 		// ignore
-                		if (sData != sData_without_ambiguities) {
-                			Log.warning.println("Ambiguity found in " + sTaxon + " that is treated as missing value");
+                		if (data != data_without_ambiguities) {
+                			Log.warning.println("Ambiguity found in " + taxon + " that is treated as missing value");
                 		}
-                		sData = sData_without_ambiguities; 
+                		data = data_without_ambiguities; 
                 	}
                 }
                 Collections.sort(ambInt);
@@ -623,39 +642,44 @@ public class NexusParser {
             }
 
             //check the length of the sequence (treat ambiguity sets as single characters)
-            if (sData_without_ambiguities.length() != nChar) {
-                throw new Exception(sStr + "\nExpected sequence of length " + nChar + " instead of " + sData.length() + " for taxon " + sTaxon);
+            if (data_without_ambiguities.length() != charCount) {
+                throw new IOException(str + "\nExpected sequence of length " + charCount + " instead of " + data.length() + " for taxon " + taxon);
             }
 
             // map to standard missing and gap chars
-            sData = sData.replace(sMissing.charAt(0), DataType.MISSING_CHAR);
-            sData = sData.replace(sGap.charAt(0), DataType.GAP_CHAR);
+            data = data.replace(missing.charAt(0), DataType.MISSING_CHAR);
+            data = data.replace(gap.charAt(0), DataType.GAP_CHAR);
 
             // resolve matching char, if any
-            if (sMatchChar != null && sData.contains(sMatchChar)) {
-                final char cMatchChar = sMatchChar.charAt(0);
-                final String sBaseData = seqMap.get(sTaxa.get(0)).toString();
-                for (int i = 0; i < sData.length(); i++) {
-                    if (sData.charAt(i) == cMatchChar) {
-                        final char cReplaceChar = sBaseData.charAt(i);
-                        sData = sData.substring(0, i) + cReplaceChar + (i + 1 < sData.length() ? sData.substring(i + 1) : "");
+            if (matchChar != null && data.contains(matchChar)) {
+                final char cMatchChar = matchChar.charAt(0);
+                final String baseData = seqMap.get(taxa.get(0)).toString();
+                for (int i = 0; i < data.length(); i++) {
+                    if (data.charAt(i) == cMatchChar) {
+                        final char cReplaceChar = baseData.charAt(i);
+                        data = data.substring(0, i) + cReplaceChar + (i + 1 < data.length() ? data.substring(i + 1) : "");
                     }
                 }
             }
 
-//            alignment.setInputValue(sTaxon, sData);
-            final Sequence sequence = new Sequence();
-            sequence.init(nTotalCount, sTaxon, sData);
-            sequence.setID(generateSequenceID(sTaxon));
-            alignment.sequenceInput.setValue(sequence, alignment);
+            if (alignment.dataTypeInput.get().equals("nucleotide") || 
+            	alignment.dataTypeInput.get().equals("binary")  ||
+            	alignment.dataTypeInput.get().equals("aminoacid") ) {
+            	alignment.setInputValue(taxon, data);
+            } else {
+	            final Sequence sequence = new Sequence();
+	            sequence.init(totalCount, taxon, data);
+	            sequence.setID(generateSequenceID(taxon));
+	            alignment.sequenceInput.setValue(sequence, alignment);
+            }
         }
 
 
         if (alignment.dataTypeInput.get().equals("standard")) {
             //convert sortedAmbiguities to a whitespace separated string of ambiguities
             String ambiguitiesStr = "";
-            for (String sAmb: sortedAmbiguities) {
-                ambiguitiesStr += sAmb + " ";
+            for (String amb: sortedAmbiguities) {
+                ambiguitiesStr += amb + " ";
             }
             if (ambiguitiesStr.length() > 0) {
             	ambiguitiesStr = ambiguitiesStr.substring(0, ambiguitiesStr.length()-1);
@@ -664,8 +688,8 @@ public class NexusParser {
         }
 
         alignment.initAndValidate();
-        if (nTaxa > 0 && nTaxa != alignment.getNrTaxa()) {
-            throw new Exception("dimensions block says there are " + nTaxa + " taxa, but there were " + alignment.getNrTaxa() + " taxa found");
+        if (taxonCount > 0 && taxonCount != alignment.getTaxonCount()) {
+            throw new IOException("dimensions block says there are " + taxonCount + " taxa, but there were " + alignment.getTaxonCount() + " taxa found");
         }
         return alignment;
     } // parseDataBlock
@@ -684,36 +708,36 @@ public class NexusParser {
      * end;
      * 
      */
-    void parseAssumptionsBlock(final BufferedReader fin) throws Exception {
-        String sStr;
+    void parseAssumptionsBlock(final BufferedReader fin) throws IOException {
+        String str;
         do {
-            sStr = nextLine(fin);
-            if (sStr.toLowerCase().matches("\\s*charset\\s.*")) {
+            str = nextLine(fin);
+            if (str.toLowerCase().matches("\\s*charset\\s.*")) {
             	// remove text in brackets (as TreeBase files are wont to contain)
-                sStr = sStr.replaceAll("\\(.*\\)", "");
+                str = str.replaceAll("\\(.*\\)", "");
                 // clean up spaces
-                sStr = sStr.replaceAll("^\\s+", "");
-                sStr = sStr.replaceAll("\\s*-\\s*", "-");
-                sStr = sStr.replaceAll("\\s*\\\\\\s*", "\\\\");
-                sStr = sStr.replaceAll("\\s*;", "");
-                final String[] sStrs = sStr.trim().split("\\s+");
-                final String sID = sStrs[1];
-                String sRange = "";
-                for (int i = 3; i < sStrs.length; i++) {
-                    sRange += sStrs[i] + " ";
+                str = str.replaceAll("^\\s+", "");
+                str = str.replaceAll("\\s*-\\s*", "-");
+                str = str.replaceAll("\\s*\\\\\\s*", "\\\\");
+                str = str.replaceAll("\\s*;", "");
+                final String[] strs = str.trim().split("\\s+");
+                final String id = strs[1];
+                String rangeString = "";
+                for (int i = 3; i < strs.length; i++) {
+                    rangeString += strs[i] + " ";
                 }
-                sRange = sRange.trim().replace(' ', ',');
+                rangeString = rangeString.trim().replace(' ', ',');
                 final FilteredAlignment alignment = new FilteredAlignment();
-                alignment.setID(sID);
+                alignment.setID(id);
                 alignment.alignmentInput.setValue(m_alignment, alignment);
-                alignment.filterInput.setValue(sRange, alignment);
+                alignment.filterInput.setValue(rangeString, alignment);
                 alignment.initAndValidate();
                 filteredAlignments.add(alignment);
-            } else if (sStr.toLowerCase().matches("\\s*wtset\\s.*")) {
-            	String [] strs = sStr.split("=");
+            } else if (str.toLowerCase().matches("\\s*wtset\\s.*")) {
+            	String [] strs = str.split("=");
             	if (strs.length > 1) {
-            		sStr = strs[strs.length - 1].trim();
-            		strs = sStr.split("\\s+");
+            		str = strs[strs.length - 1].trim();
+            		strs = str.split("\\s+");
             		int [] weights = new int[strs.length];
             		for (int i = 0; i< strs.length; i++) {
             			weights[i] = Integer.parseInt(strs[i]);
@@ -724,8 +748,8 @@ public class NexusParser {
             						"does not match number of sites in alignment(" + m_alignment.getSiteCount()+ ")");
             			}
             			StringBuilder weightStr = new StringBuilder();
-            			for (String str : strs) {
-            				weightStr.append(str);
+            			for (String str2 : strs) {
+            				weightStr.append(str2);
             				weightStr.append(',');
             			}
             			weightStr.delete(weightStr.length() - 1, weightStr.length());
@@ -737,7 +761,7 @@ public class NexusParser {
             	}
             }
 
-        } while (!sStr.toLowerCase().contains("end;"));
+        } while (!str.toLowerCase().contains("end;"));
     }
 
     /**
@@ -747,45 +771,45 @@ public class NexusParser {
      * TAXSET 'spa' = 'spa_138a_Cerb' 'spa_JB_Eyre1' 'spa_JB_Eyre2';
      * END; [Sets]
      */
-    void parseSetsBlock(final BufferedReader fin) throws Exception {
-        String sStr;
+    void parseSetsBlock(final BufferedReader fin) throws IOException {
+        String str;
         do {
-            sStr = nextLine(fin);
-            if (sStr.toLowerCase().matches("\\s*taxset\\s.*")) {
-                sStr = sStr.replaceAll("^\\s+", "");
-                sStr = sStr.replaceAll(";", "");
-                final String[] sStrs = sStr.split("\\s+");
-                String sID = sStrs[1];
-                sID = sID.replaceAll("'\"", "");
+            str = nextLine(fin);
+            if (str.toLowerCase().matches("\\s*taxset\\s.*")) {
+                str = str.replaceAll("^\\s+", "");
+                str = str.replaceAll(";", "");
+                final String[] strs = str.split("\\s+");
+                String id = strs[1];
+                id = id.replaceAll("'\"", "");
                 final TaxonSet set = new TaxonSet();
-                set.setID(sID);
-                for (int i = 3; i < sStrs.length; i++) {
-                    sID = sStrs[i];
-                    sID = sID.replaceAll("'\"", "");
+                set.setID(id);
+                for (int i = 3; i < strs.length; i++) {
+                    id = strs[i];
+                    id = id.replaceAll("'\"", "");
                     final Taxon taxon = new Taxon();
-                    taxon.setID(sID);
+                    taxon.setID(id);
                     set.taxonsetInput.setValue(taxon, set);
                 }
                 taxonsets.add(set);
             }
-        } while (!sStr.toLowerCase().contains("end;"));
+        } while (!str.toLowerCase().contains("end;"));
     }
 
-    public static String generateSequenceID(final String sTaxon) {
-        String sID = "seq_" + sTaxon;
+    public static String generateSequenceID(final String taxon) {
+        String id = "seq_" + taxon;
         int i = 0;
-        while (g_sequenceIDs.contains(sID + (i > 0 ? i : ""))) {
+        while (g_sequenceIDs.contains(id + (i > 0 ? i : ""))) {
             i++;
         }
-        sID = sID + (i > 0 ? i : "");
-        g_sequenceIDs.add(sID);
-        return sID;
+        id = id + (i > 0 ? i : "");
+        g_sequenceIDs.add(id);
+        return id;
     }
 
     /**
      * read line from nexus file *
      */
-    String readLine(final BufferedReader fin) throws Exception {
+    String readLine(final BufferedReader fin) throws IOException {
         if (!fin.ready()) {
             return null;
         }
@@ -796,47 +820,47 @@ public class NexusParser {
     /**
      * read next line from nexus file that is not a comment and not empty *
      */
-    String nextLine(final BufferedReader fin) throws Exception {
-        String sStr = readLine(fin);
-        if (sStr == null) {
+    String nextLine(final BufferedReader fin) throws IOException {
+        String str = readLine(fin);
+        if (str == null) {
             return null;
         }
-        if (sStr.contains("[")) {
-            final int iStart = sStr.indexOf('[');
-            int iEnd = sStr.indexOf(']', iStart);
-            while (iEnd < 0) {
-                sStr += readLine(fin);
-                iEnd = sStr.indexOf(']', iStart);
+        if (str.contains("[")) {
+            final int start = str.indexOf('[');
+            int end = str.indexOf(']', start);
+            while (end < 0) {
+                str += readLine(fin);
+                end = str.indexOf(']', start);
             }
-            sStr = sStr.substring(0, iStart) + sStr.substring(iEnd + 1);
-            if (sStr.matches("^\\s*$")) {
+            str = str.substring(0, start) + str.substring(end + 1);
+            if (str.matches("^\\s*$")) {
                 return nextLine(fin);
             }
         }
-        if (sStr.matches("^\\s*$")) {
+        if (str.matches("^\\s*$")) {
             return nextLine(fin);
         }
-        return sStr;
+        return str;
     }
 
     /**
      * return attribute value as a string *
      */
-    String getAttValue(final String sAttribute, final String sStr) {
-        final Pattern pattern = Pattern.compile(".*" + sAttribute + "\\s*=\\s*([^\\s;]+).*");
-        final Matcher matcher = pattern.matcher(sStr.toLowerCase());
+    String getAttValue(final String attribute, final String str) {
+        final Pattern pattern = Pattern.compile(".*" + attribute + "\\s*=\\s*([^\\s;]+).*");
+        final Matcher matcher = pattern.matcher(str.toLowerCase());
         if (!matcher.find()) {
             return null;
         }
-        String sAtt = matcher.group(1);
-        if (sAtt.startsWith("\"") && sAtt.endsWith("\"")) {
-            final int iStart = matcher.start(1);
-            sAtt = sStr.substring(iStart + 1, sStr.indexOf('"', iStart + 1));
+        String att = matcher.group(1);
+        if (att.startsWith("\"") && att.endsWith("\"")) {
+            final int start = matcher.start(1);
+            att = str.substring(start + 1, str.indexOf('"', start + 1));
         }
-        return sAtt;
+        return att;
     }
 
-    private ArrayList<String> readInCharstatelablesTokens(final BufferedReader fin) throws Exception {
+    private ArrayList<String> readInCharstatelablesTokens(final BufferedReader fin) throws IOException {
 
         ArrayList<String> tokens = new ArrayList<>();
         String token="";
@@ -844,13 +868,13 @@ public class NexusParser {
         int mode = WAITING;
         int numberOfQuotes=0;
         boolean endOfBlock=false;
-        String sStr;
+        String str;
 
         while (!endOfBlock) {
-            sStr = nextLine(fin);
+            str = nextLine(fin);
             Character nextChar;
-            for (int i=0; i< sStr.length(); i++) {
-                nextChar=sStr.charAt(i);
+            for (int i=0; i< str.length(); i++) {
+                nextChar=str.charAt(i);
                 switch (mode) {
                     case WAITING:
                         if (!Character.isWhitespace(nextChar)) {
@@ -931,7 +955,7 @@ public class NexusParser {
         return tokens;
     }
 
-    private ArrayList<UserDataType> processCharstatelabelsTokens(ArrayList<String> tokens, int[] maxNumberOfStates) throws Exception {
+    private ArrayList<UserDataType> processCharstatelabelsTokens(ArrayList<String> tokens, int[] maxNumberOfStates) throws IOException {
 
         ArrayList<UserDataType> charDescriptions = new ArrayList<>();
 
@@ -952,7 +976,7 @@ public class NexusParser {
                         mode = STATES;
                     } else if (token.equals(",")) {
                         if (charNumber > charDescriptions.size()+1) {
-                            throw new Exception("Character descriptions should go in the ascending order and there " +
+                            throw new IOException("Character descriptions should go in the ascending order and there " +
                                     "should not be any description missing.");
                         }
                         charDescriptions.add(new UserDataType(charName, states));
@@ -968,7 +992,7 @@ public class NexusParser {
                 case STATES:
                     if (token.equals(",")) {
                         if (charNumber > charDescriptions.size()+1) {
-                            throw new Exception("Character descriptions should go in the ascending order and there " +
+                            throw new IOException("Character descriptions should go in the ascending order and there " +
                                     "should not be any description missing.");
                         }
                         charDescriptions.add(new UserDataType(charName, states));
@@ -1001,12 +1025,12 @@ public class NexusParser {
                 System.out.println(parser.trees.size() + " trees");
             }
             if (parser.m_alignment != null) {
-                final String sXML = new XMLProducer().toXML(parser.m_alignment);
-                System.out.println(sXML);
+                final String xml = new XMLProducer().toXML(parser.m_alignment);
+                System.out.println(xml);
             }
             if (parser.traitSet != null) {
-                final String sXML = new XMLProducer().toXML(parser.traitSet);
-                System.out.println(sXML);
+                final String xml = new XMLProducer().toXML(parser.traitSet);
+                System.out.println(xml);
             }
         } catch (Exception e) {
             // TODO Auto-generated catch block
diff --git a/src/beast/util/OutputUtils.java b/src/beast/util/OutputUtils.java
index 9839c8e..09d2acd 100644
--- a/src/beast/util/OutputUtils.java
+++ b/src/beast/util/OutputUtils.java
@@ -31,29 +31,29 @@ public class OutputUtils {
         }
         if (Math.abs(d) > 1e-4 || d == 0) {
             DecimalFormat f = new DecimalFormat("#0.######", new DecimalFormatSymbols(Locale.US));
-            String sStr = f.format(d);
-            if (sStr.length() > 8) {
-                sStr = sStr.substring(0, 8);
+            String str = f.format(d);
+            if (str.length() > 8) {
+                str = str.substring(0, 8);
             }
-            while (sStr.length() < 8) {
-                sStr += " ";
+            while (str.length() < 8) {
+                str += " ";
             }
-            return sStr;
+            return str;
         } else {
             DecimalFormat f = new DecimalFormat("0.##E0", new DecimalFormatSymbols(Locale.US));
-            String sStr = f.format(d);
-            if (sStr.length() > 8) {
-                String [] sStrs = sStr.split("E");
-                sStr =  sStrs[0].substring(0, 8 - sStrs[1].length() - 1) + "E" + sStrs[1];
+            String str = f.format(d);
+            if (str.length() > 8) {
+                String [] strs = str.split("E");
+                str =  strs[0].substring(0, 8 - strs[1].length() - 1) + "E" + strs[1];
             }
-            while (sStr.length() < 8) {
-                sStr += " ";
+            while (str.length() < 8) {
+                str += " ";
             }
-            return sStr;
+            return str;
         }
     }
 
-    public static String toString(List list) {
+    public static String toString(List<?> list) {
         String s = "";
         for (int i = 0; i < list.size(); i++) {
             if (i > 0) s += ", ";
diff --git a/src/beast/util/Package.java b/src/beast/util/Package.java
index 6db3228..d0e6ac8 100644
--- a/src/beast/util/Package.java
+++ b/src/beast/util/Package.java
@@ -1,18 +1,11 @@
 package beast.util;
 
-import beast.core.Description;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.NodeList;
+import static beast.util.AddOnManager.NOT_INSTALLED;
 
-import javax.xml.parsers.DocumentBuilderFactory;
-import java.io.File;
-import java.util.List;
-import java.util.Set;
-import java.util.TreeSet;
+import java.net.URL;
+import java.util.*;
 
-import static beast.util.AddOnManager.NOT_INSTALLED;
-import static beast.util.AddOnManager.getBeastDirectories;
+import beast.core.Description;
 
 /**
  * BEAUti Package managed by AddOnManager
@@ -23,120 +16,166 @@ import static beast.util.AddOnManager.getBeastDirectories;
  */
 @Description("BEAUti package managed by package manager, also named as add-on previously")
 public class Package {
-    public String description = "";
-    public String url = "";
-    public String packageName = "";
-    public String installedVersion = ""; // get from local /version.xml
-    public String latestVersion = ""; // get from packages.xml
+    protected String packageName, description;
+    protected PackageVersion installedVersion;
+    protected Set<PackageDependency> installedVersionDeps;
+    protected TreeMap<PackageVersion, URL> availableVersionURLs;
+    protected TreeMap<PackageVersion, Set<PackageDependency>> availableVersionDeps;
+
+    public Package(String name) {
+        this.packageName = name;
+        this.description = "";
+
+        availableVersionURLs = new TreeMap<>();
+        availableVersionDeps = new TreeMap<>();
+    }
 
-    public Set<PackageDependency> dependencies = new TreeSet<PackageDependency>();
+    public String getName() {
+        return packageName;
+    }
 
-    public Package(Element packageE) {
-        url = packageE.getAttribute("url");
-//        packageName = URL2PackageName(url);
-        packageName = packageE.getAttribute("name");
-        latestVersion = packageE.getAttribute("version");
-        description = packageE.getAttribute("description");
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
 
-        NodeList nodes = packageE.getElementsByTagName("depends");
-        setVersionDependencies(nodes);
+    /**
+     * @return true iff package is available online.
+     */
+    public boolean isAvailable() {
+        return !availableVersionURLs.isEmpty();
     }
 
-    public void setVersionDependencies(NodeList nodes) {
-        for (int i = 0; i < nodes.getLength(); i++) {
-            Element depend_on = (Element) nodes.item(i);
+    /**
+     * @param version version of package
+     * @return true iff version of package is available
+     */
+    public boolean isAvailable(PackageVersion version) {
+        return availableVersionURLs.containsKey(version);
+    }
 
-            installedVersion = getVersionDependencyFromLocal(packageName, dependencies);
+    public void addAvailableVersion(PackageVersion version, URL url, Set<PackageDependency> dependencies) {
+        availableVersionURLs.put(version, url);
+        availableVersionDeps.put(version, dependencies);
+    }
 
-            if (installedVersion == null) {
-                installedVersion = "";
-                PackageDependency dep = getPackageDependency(packageName, depend_on);
-                dependencies.add(dep);
-            }
-        }
+    public void setInstalled(PackageVersion version, Set<PackageDependency> dependencies) {
+        installedVersion = version;
+        installedVersionDeps = dependencies;
     }
 
-    public String getVersionDependencyFromLocal(String packageName, Set<PackageDependency> dependencies) {
-        List<String> sBeastDirs = getBeastDirectories();
-
-        // gather dependency info for this package
-        for (String sDir : sBeastDirs) {
-            File f = new File(sDir + "/" + packageName);
-            if (f.exists()) {
-                File vf = new File(sDir + "/" + packageName + "/version.xml");
-
-                if (vf.exists()) {
-                    try {
-                        // parse installed version.xml
-                        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-                        Document doc = factory.newDocumentBuilder().parse(vf);
-                        doc.normalize();
-                        // get name and version of package
-                        Element packageE = doc.getDocumentElement();
-//                        String packageName = packageE.getAttribute("name");
-                        String installedVersion = packageE.getAttribute("version");
-
-                        // get dependencies of add-n
-                        NodeList nodes = doc.getElementsByTagName("depends");
-                        for (int i = 0; i < nodes.getLength(); i++) {
-                            Element depend_on = (Element) nodes.item(i);
-
-                            PackageDependency dep = getPackageDependency(packageName, depend_on);
-                            dependencies.add(dep);
-                        }
-
-                        return installedVersion;
-                    } catch (Exception e) {
-                        e.printStackTrace();
-                    }
-                }
-            }
-        }
+    public PackageVersion getInstalledVersion() {
+        return installedVersion;
+    }
 
-        return null;
+    public boolean isInstalled() {
+        return installedVersion != null;
     }
 
-    private PackageDependency getPackageDependency(String packageName, Element depend_on) {
-        PackageDependency dep = new PackageDependency();
-        dep.packageName = packageName;
-        dep.dependson = depend_on.getAttribute("on");
+    /**
+     * @return true if a newer version is available.
+     */
+    public boolean newVersionAvailable() {
+        return isAvailable() &&
+                (!isInstalled() || getLatestVersion().compareTo(getInstalledVersion()) > 0);
+    }
 
-        String sAtLeast = depend_on.getAttribute("atleast");
-        dep.setAtLest(sAtLeast);
-        String sAtMost = depend_on.getAttribute("atmost");
-        dep.setAtMost(sAtMost);
-        return dep;
+    public Set<PackageDependency> getInstalledVersionDependencies() {
+        return installedVersionDeps;
     }
 
-    public boolean isInstalled() {
-        return installedVersion.trim().length() > 0;
+    public String getStatusString() {
+        return isInstalled() ? installedVersion.getVersionString() : NOT_INSTALLED;
     }
 
-    public String getStatus() {
-        return isInstalled() ? installedVersion : NOT_INSTALLED;
+    /**
+     * @return latest available version of package.
+     */
+    public PackageVersion getLatestVersion() {
+        return availableVersionURLs.isEmpty()
+                ? null
+                : availableVersionURLs.lastKey();
+    }
+
+    /**
+     * @return URL corresponding to latest available version of package.
+     */
+    public URL getLatestVersionURL() {
+        return isAvailable()
+                ? availableVersionURLs.lastEntry().getValue()
+                : null;
+    }
+
+    /**
+     * Retrieve URL corresponding to particular available version of package.
+     *
+     * @param version version of package
+     * @return URL
+     */
+    public URL getVersionURL(PackageVersion version) {
+        return isAvailable(version)
+                ? availableVersionURLs.get(version)
+                : null;
+    }
+
+    public Set<PackageDependency> getLatestVersionDependencies() {
+        return isAvailable()
+                ? availableVersionDeps.lastEntry().getValue()
+                : null;
+    }
+
+    public Set<PackageDependency> getDependencies(PackageVersion version) {
+        return availableVersionDeps.get(version);
     }
 
     /**
-     * the latest package info is online
-     * @return
+     * @return list of available package versions, sorted in order of decreasing version.
      */
-    public String getLatestVersion() {
-        return latestVersion;
+    public List<PackageVersion> getAvailableVersions() {
+        List<PackageVersion> versionList = new ArrayList<>(availableVersionURLs.keySet());
+        Collections.sort(versionList);
+        Collections.reverse(versionList);
+        return versionList;
     }
 
-    public boolean dependsOn(String packageName) {
-        for (PackageDependency packageDependency : dependencies) {
-            if (packageDependency.compareTo(packageName) == 0)
+    public boolean latestVersionDependsOn(Package pkg) {
+
+        if (!isAvailable())
+            throw new IllegalStateException("Requested latest available version dependencies " +
+                    "when there is no available version.");
+
+        for (PackageDependency packageDependency : availableVersionDeps.lastEntry().getValue()) {
+            if (packageDependency.dependencyName.equals(pkg.packageName))
+                return true;
+        }
+        return false;
+    }
+
+    public boolean installedVersionDependsOn(Package pkg) {
+
+        if (!isInstalled())
+            throw new IllegalStateException("Requested installed version dependencies " +
+                    "when there is no installed version.");
+
+        for (PackageDependency packageDependency : installedVersionDeps) {
+            if (packageDependency.dependencyName.equals(pkg.packageName))
                 return true;
         }
         return false;
     }
 
     public String getDependenciesString() {
+
+        if (availableVersionDeps.isEmpty())
+            return "";
+
         String depString = "";
-        for (PackageDependency packageDependency : dependencies) {
-            String s = packageDependency.dependson;
-            if (!s.equalsIgnoreCase("beast2")) {
+        for (PackageDependency packageDependency : availableVersionDeps.lastEntry().getValue()) {
+            String s = packageDependency.dependencyName;
+            if (!s.equalsIgnoreCase(AddOnManager.BEAST_PACKAGE)) {
                 depString +=  s + ", ";
             }
         }
@@ -146,15 +185,16 @@ public class Package {
         return depString;
     }
 
-    public String toString() {
-        return description;
+    @Override
+	public String toString() {
+        return packageName;
     }
 
     public String toHTML() {
         String html = "<html>";
         html += "<h1>" + packageName + "</h1>";
-        html += "<p>Installed version: " + (isInstalled() ? installedVersion : "not installed") + "</p>";
-        html += "<p>Latestversion: " + latestVersion + "</p>";
+        html += "<p>Installed version: " + getStatusString() + "</p>";
+        html += "<p>Latest version: " + (isAvailable() ? getLatestVersion() : "NA") + "</p>";
         html += "<p>" + description +"</p>";
         html += "</html>";
         return html;
diff --git a/src/beast/util/PackageDependency.java b/src/beast/util/PackageDependency.java
index dc20639..e5c6208 100644
--- a/src/beast/util/PackageDependency.java
+++ b/src/beast/util/PackageDependency.java
@@ -1,5 +1,6 @@
 package beast.util;
 
+
 /*
  * File PackageDependency.java
  *
@@ -32,40 +33,50 @@ package beast.util;
 
 import beast.core.Description;
 
-import static beast.util.AddOnManager.beastVersion;
-
 /**
  * modified by Walter Xie
  */
- at Description("BEAUti plugin dependency class")
-public class PackageDependency implements Comparable {
-    String packageName;
-    String dependson;
-    Double atLeast;
-    Double atMost;
+ at Description("BEAUti beastObject dependency class")
+public class PackageDependency {
+    public final String dependencyName;
+    public final PackageVersion atLeast, atMost;
 
-    public void setAtLest(String sAtLeast) {
-        if (sAtLeast == null || sAtLeast.length() == 0) {
-            atLeast = 0.0;
-        } else {
-            atLeast = beastVersion.parseVersion(sAtLeast);
-        }
+    public PackageDependency(String dependencyName,
+                             PackageVersion minimumVersion,
+                             PackageVersion maximumVersion) {
+    	if (dependencyName.equals("beast2")) {
+    		dependencyName = AddOnManager.BEAST_PACKAGE;
+    	}
+        this.dependencyName = dependencyName;
+        
+        atLeast = minimumVersion;
+        atMost = maximumVersion;
     }
 
-    public void setAtMost(String sAtMost) {
-        if (sAtMost == null || sAtMost.length() == 0) {
-            atMost = Double.POSITIVE_INFINITY;
-        } else {
-            atMost = beastVersion.parseVersion(sAtMost);
-        }
+    /**
+     * Test to see whether given version of package satisfies
+     * version range of this package dependency.
+     *
+     * @param version version of package to check
+     * @return true iff version meets criterion
+     */
+    public boolean isMetBy(PackageVersion version) {
+        return (atLeast == null || version.compareTo(atLeast)>=0)
+                && (atMost == null || version.compareTo(atMost)<=0);
     }
 
-    @Override
-    public int compareTo(Object o) {
-        return dependson.toUpperCase().compareTo(o.toString().toUpperCase());
+    public String getRangeString() {
+        if (atLeast != null && atMost != null)
+            return "versions " + atLeast + " to " + atMost;
+
+        if (atLeast != null)
+            return "version " + atLeast + " or greater";
+
+        return "version " + atMost + " or lesser";
     }
 
-    public String toString() {
-        return dependson;
+    @Override
+	public String toString() {
+        return dependencyName + " " + getRangeString();
     }
 }
diff --git a/src/beast/util/PackageVersion.java b/src/beast/util/PackageVersion.java
new file mode 100644
index 0000000..9d76504
--- /dev/null
+++ b/src/beast/util/PackageVersion.java
@@ -0,0 +1,128 @@
+package beast.util;
+
+import beast.app.util.Version;
+
+/**
+ * Note: this class has a natural ordering that is not necessarily
+ * consistent with equals(). The definition of equals() tests for
+ * equality of version strings, while (for example) compareTo() returns
+ * 0 for versions with version strings "2.0" and "2".
+ *
+ * @author Tim Vaughan <tgvaughan at gmail.com>
+ */
+public class PackageVersion extends Version implements Comparable<PackageVersion> {
+
+    String versionString;
+
+    public PackageVersion(String versionString) {
+        this.versionString = versionString;
+    }
+
+    @Override
+    public String getVersion() {
+        return versionString;
+    }
+
+    @Override
+    public String getVersionString() {
+        return versionString;
+    }
+
+    @Override
+    public String getDateString() {
+        return null;
+    }
+
+    @Override
+    public String[] getCredits() {
+        return null;
+    }
+
+    @Override
+    public String toString() {
+        return versionString;
+    }
+
+    @Override
+    public int compareTo(PackageVersion otherVersion) {
+        return compareVersionStrings(this.versionString, otherVersion.versionString);
+    }
+
+    /**
+     * Compare package version strings.
+     *
+     * @param versionA first version string
+     * @param versionB second version string
+     * @return -1, 0 or 1 if versionA is less than, equal to or greater than versionB
+     */
+    private int compareVersionStrings(String versionA, String versionB) {
+
+        String[] partsA = versionA.split("\\.");
+        String[] partsB = versionB.split("\\.");
+
+        int n = Math.max(partsA.length, partsB.length);
+
+        for (int i=0; i<n; i++) {
+            int partAint, partBint;
+            String partAstr, partBstr;
+
+            if (i<partsA.length) {
+                partAint = Integer.parseInt("0" + partsA[i].replaceAll("(^[0-9]*).*$", "$1"));
+                partAstr = partsA[i].replaceAll("^[0-9]*(.*)$", "$1");
+            } else {
+                partAint = 0;
+                partAstr = "";
+            }
+
+            if (i<partsB.length) {
+                partBint = Integer.parseInt("0" + partsB[i].replaceAll("(^[0-9]*).*$", "$1"));
+                partBstr = partsB[i].replaceAll("^[0-9]*(.*)$", "$1");
+            } else {
+                partBint = 0;
+                partBstr = "";
+            }
+
+            if (partAint<partBint)
+                return -1;
+
+            if (partAint>partBint)
+                return 1;
+
+            // 1.0 > 1.0-alpha
+            if (partAstr.isEmpty() && !partBstr.isEmpty())
+                return 1;
+
+            // 1.0-alpha < 1.0
+            if (!partAstr.isEmpty() && partBstr.isEmpty())
+                return -1;
+
+            int strComp = partAstr.compareTo(partBstr);
+            if (strComp != 0)
+                return strComp;
+        }
+
+        return 0;
+    }
+
+    /**
+     * Compare with object o.
+     *
+     * @param o object with which to test for equality.
+     * @return true iff the version strings are exactly equal.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        PackageVersion that = (PackageVersion) o;
+
+        return versionString.equals(that.versionString);
+
+    }
+
+    @Override
+    public int hashCode() {
+        return versionString.hashCode();
+    }
+}
diff --git a/src/beast/util/Randomizer.java b/src/beast/util/Randomizer.java
index ad907a7..5b83172 100644
--- a/src/beast/util/Randomizer.java
+++ b/src/beast/util/Randomizer.java
@@ -49,6 +49,8 @@
 
 package beast.util;
 
+import beast.core.util.Log;
+
 /**
  * Handy utility functions which have some Mathematical relevance.
  *
@@ -114,7 +116,7 @@ public class Randomizer {
 
         }
         for (int i = 0; i < pdf.length; i++) {
-            System.out.println(i + "\t" + pdf[i]);
+            Log.err.println(i + "\t" + pdf[i]);
         }
         throw new Error("randomChoiceUnnormalized falls through -- negative components in input distribution?");
     }
@@ -247,7 +249,7 @@ public class Randomizer {
      * a default instance of this class, access is synchronized.
      * 
      * @param lambda mean of Poissonian distribution
-     * @return sample
+     * @return sample (as double for historical reasons)
      */
     public static double nextPoisson(double lambda) {
         synchronized (random) {
diff --git a/src/beast/util/TreeParser.java b/src/beast/util/TreeParser.java
index eba871d..4e65d22 100644
--- a/src/beast/util/TreeParser.java
+++ b/src/beast/util/TreeParser.java
@@ -24,12 +24,29 @@
 */
 package beast.util;
 
+import java.text.DecimalFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.List;
+import java.util.Map;
+
+import org.antlr.v4.runtime.ANTLRInputStream;
+import org.antlr.v4.runtime.BaseErrorListener;
+import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.RecognitionException;
+import org.antlr.v4.runtime.Recognizer;
+import org.antlr.v4.runtime.misc.NotNull;
+import org.antlr.v4.runtime.misc.ParseCancellationException;
+import org.antlr.v4.runtime.tree.ParseTree;
+
 import beast.core.Description;
 import beast.core.Input;
 import beast.core.StateNode;
 import beast.core.StateNodeInitialiser;
 import beast.core.util.Log;
 import beast.evolution.alignment.Alignment;
+import beast.evolution.alignment.Taxon;
 import beast.evolution.alignment.TaxonSet;
 import beast.evolution.tree.Node;
 import beast.evolution.tree.Tree;
@@ -37,14 +54,6 @@ import beast.evolution.tree.TreeUtils;
 import beast.util.treeparser.NewickBaseVisitor;
 import beast.util.treeparser.NewickLexer;
 import beast.util.treeparser.NewickParser;
-import org.antlr.v4.runtime.*;
-import org.antlr.v4.runtime.misc.NotNull;
-import org.antlr.v4.runtime.misc.ParseCancellationException;
-import org.antlr.v4.runtime.tree.ParseTree;
-import java.text.DecimalFormat;
-import java.util.*;
-import java.util.logging.Level;
-import java.util.logging.Logger;
 
 @Description("Create beast.tree by parsing from a specification of a beast.tree in Newick format " +
         "(includes parsing of any meta data in the Newick string).")
@@ -103,7 +112,7 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
      * Ensure the class behaves properly, even when inputs are not specified.
      */
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
     	boolean sortNodesAlphabetically = false;
 
         if (dataInput.get() != null) {
@@ -138,8 +147,8 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
             }
 //            m_bIsLabelledNewick = false;
         }
-        final String sNewick = newickInput.get();
-        if (sNewick == null || sNewick.equals("")) {
+        final String newick = newickInput.get();
+        if (newick == null || newick.equals("")) {
             // can happen while initalising Beauti
             final Node dummy = new Node();
             setRoot(dummy);
@@ -206,19 +215,19 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
 
                 DecimalFormat format = new DecimalFormat("#.##");
 
-                System.out.println("WARNING: Adjust tip heights attribute set to 'true' in " + getClass().getSimpleName());
-                System.out.println("         has resulted in significant (>" + format.format(SCALE_FACTOR_THRESHOLD*100.0) + "%) change in tree length.");
-                System.out.println("         Use "+adjustTipHeightsInput.getName()+"='false' to override this default.");
-                System.out.printf( "  original max tip age = %8.3f\n", maxTipHeight);
-                System.out.printf( "       new max tip age = %8.3f\n", 0.0);
-                System.out.printf( "  original tree length = %8.3f\n", treeLength);
-                System.out.printf( "       new tree length = %8.3f\n", treeLength+extraTreeLength);
-                System.out.printf( "       TL scale factor = %8.3f\n", scaleFactor);
+                Log.info.println("WARNING: Adjust tip heights attribute set to 'true' in " + getClass().getSimpleName());
+                Log.info.println("         has resulted in significant (>" + format.format(SCALE_FACTOR_THRESHOLD*100.0) + "%) change in tree length.");
+                Log.info.println("         Use "+adjustTipHeightsInput.getName()+"='false' to override this default.");
+                Log.info.printf( "  original max tip age = %8.3f\n", maxTipHeight);
+                Log.info.printf( "       new max tip age = %8.3f\n", 0.0);
+                Log.info.printf( "  original tree length = %8.3f\n", treeLength);
+                Log.info.printf( "       new tree length = %8.3f\n", treeLength+extraTreeLength);
+                Log.info.printf( "       TL scale factor = %8.3f\n", scaleFactor);
             }
         }
 
         if( m_taxonset.get() == null && labels != null && isLabelledNewickInput.get() ) {
-            m_taxonset.setValue(new TaxonSet(TaxonSet.createTaxonList(labels)), this);
+            m_taxonset.setValue(new TaxonSet(Taxon.createTaxonList(labels)), this);
         }
 
         initStateNodes();
@@ -227,7 +236,7 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
     public TreeParser() {
     }
 
-    public TreeParser(final Alignment alignment, final String newick) throws Exception {
+    public TreeParser(final Alignment alignment, final String newick) {
         dataInput.setValue(alignment, this);
         newickInput.setValue(newick, this);
         initAndValidate();
@@ -243,17 +252,16 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
      *                  so, name(node with nodeNumber) = taxaNames[nodeNumber-offset]
      * @param adjustTipHeightsWhenMissingDateTraits
      *                  true if tip heights should be adjusted to zero
-     * @throws Exception
      */
     public TreeParser(final List<String> taxaNames,
                       final String newick,
                       final int offset,
-                      final boolean adjustTipHeightsWhenMissingDateTraits) throws Exception {
+                      final boolean adjustTipHeightsWhenMissingDateTraits) {
 
         if (taxaNames == null) {
             isLabelledNewickInput.setValue(true, this);
         } else {
-            m_taxonset.setValue(new TaxonSet(TaxonSet.createTaxonList(taxaNames)), this);
+            m_taxonset.setValue(new TaxonSet(Taxon.createTaxonList(taxaNames)), this);
         }
         newickInput.setValue(newick, this);
         offsetInput.setValue(offset, this);
@@ -268,7 +276,7 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
      *
      * @param newick a string representing a tree in newick format
      */
-    public TreeParser(final String newick) throws Exception {
+    public TreeParser(final String newick) {
         this(newick, false, true, true, 1);
     }
 
@@ -276,21 +284,19 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
      * @param newick                a string representing a tree in newick format
      * @param adjustTipHeights      true if the tip heights should be adjusted to 0 (i.e. contemporaneous) after reading in tree.
      * @param allowSingleChildNodes true if internal nodes with single children are allowed
-     * @throws Exception
      */
     public TreeParser(final String newick,
                       final boolean adjustTipHeights,
-                      final boolean allowSingleChildNodes) throws Exception {
+                      final boolean allowSingleChildNodes) {
         this(newick, adjustTipHeights, allowSingleChildNodes, true, 1);
     }
 
     /**
      * @param newick           a string representing a tree in newick format
      * @param adjustTipHeights true if the tip heights should be adjusted to 0 (i.e. contemporaneous) after reading in tree.
-     * @throws Exception
      */
     public TreeParser(final String newick,
-                      final boolean adjustTipHeights) throws Exception {
+                      final boolean adjustTipHeights) {
         this(newick, adjustTipHeights, true, true, 1);
     }
 
@@ -302,13 +308,12 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
      * @param offset                if isLabeled == false and node labeling starts with x
      *                              then offset should be x. When isLabeled == true offset should
      *                              be 1 as by default.
-     * @throws Exception
      */
     public TreeParser(final String newick,
                       final boolean adjustTipHeights,
                       final boolean allowSingleChildNodes,
                       final boolean isLabeled,
-                      final int offset) throws Exception {
+                      final int offset) {
 
         newickInput.setValue(newick, this);
         isLabelledNewickInput.setValue(isLabeled, this);
@@ -485,7 +490,9 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
                         || postCtx.label().number().INT() == null)
                     integerLeafLabels = false;
 
-                String postText = postCtx.getText();
+                // RRB: next line is for debugging only?
+                @SuppressWarnings("unused")
+				String postText = postCtx.getText();
 
                 // Treat labels as node numbers in certain situations
                 if (!isLabelledNewickInput.get()
@@ -512,32 +519,50 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
             if (node.getChildCount()==1 && !allowSingleChildInput.get())
                 throw new ParseCancellationException("Node with single child found.");
 
-            if (node.getChildCount()>2)
-                throw new ParseCancellationException("Node with two or more children found.");
+            // Use length-zero edges to binarize multifurcations.
+            if (node.getChildCount()>2) {
+                List<Node> children = new ArrayList<>(node.getChildren());
+                Node prevDummy = node;
+                for (int i=1; i<children.size()-1; i++) {
+                    Node child = children.get(i);
+
+                    Node dummyNode = newNode();
+                    dummyNode.setNr(-1);
+                    dummyNode.setHeight(0);
+                    prevDummy.addChild(dummyNode);
+
+                    node.removeChild(child);
+                    dummyNode.addChild(child);
+
+                    prevDummy = dummyNode;
+                }
+                node.removeChild(children.get(children.size()-1));
+                prevDummy.addChild(children.get(children.size()-1));
+            }
 
             return node;
         }
 
         /**
-         * Try to map sStr into an index.
+         * Try to map str into an index.
          */
-        private int getLabelIndex(final String sStr) {
+        private int getLabelIndex(final String str) {
 
             // look it up in list of taxa
-            for (int nIndex = 0; nIndex < labels.size(); nIndex++) {
-                if (sStr.equals(labels.get(nIndex))) {
-                    return nIndex;
+            for (int index = 0; index < labels.size(); index++) {
+                if (str.equals(labels.get(index))) {
+                    return index;
                 }
             }
 
             // if createUnrecognizedTaxon==true, then do it now, otherwise labels will not be populated and
             // out of bounds error will occur in m_sLabels later.
             if (createUnrecognizedTaxa) {
-                labels.add(sStr);
+                labels.add(str);
                 return labels.size() - 1;
             }
 
-            throw new ParseCancellationException("Label '" + sStr + "' in Newick beast.tree could " +
+            throw new ParseCancellationException("Label '" + str + "' in Newick beast.tree could " +
                     "not be identified. Perhaps taxa or taxonset is not specified?");
         }
 
@@ -549,8 +574,8 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
          * @param root root of tree
          */
         private void convertLengthToHeight(final Node root) {
-            final double fTotalHeight = convertLengthToHeight(root, 0);
-            offset(root, -fTotalHeight);
+            final double totalHeight = convertLengthToHeight(root, 0);
+            offset(root, -totalHeight);
         }
 
         /**
@@ -558,21 +583,21 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
          * results in heights from 0 to -total_height_of_tree.
          *
          * @param node node of a clade to convert
-         * @param fHeight Parent height.
+         * @param height Parent height.
          * @return total height of clade
          */
-        private double convertLengthToHeight(final Node node, final double fHeight) {
-            final double fLength = node.getHeight();
-            node.setHeight((fHeight - fLength) * scaleInput.get());
+        private double convertLengthToHeight(final Node node, final double height) {
+            final double length = node.getHeight();
+            node.setHeight((height - length) * scaleInput.get());
             if (node.isLeaf()) {
                 return node.getHeight();
             } else {
-                final double fLeft = convertLengthToHeight(node.getLeft(), fHeight - fLength);
+                final double left = convertLengthToHeight(node.getLeft(), height - length);
                 if (node.getRight() == null) {
-                    return fLeft;
+                    return left;
                 }
-                final double fRight = convertLengthToHeight(node.getRight(), fHeight - fLength);
-                return Math.min(fLeft, fRight);
+                final double right = convertLengthToHeight(node.getRight(), height - length);
+                return Math.min(left, right);
             }
         }
 
@@ -581,19 +606,19 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
          * node heights that is produced by convertLengthToHeight(node, height).
          *
          * @param node node of clade to offset
-         * @param fDelta offset
+         * @param delta offset
          */
-        private void offset(final Node node, final double fDelta) {
-            node.setHeight(node.getHeight() + fDelta);
+        private void offset(final Node node, final double delta) {
+            node.setHeight(node.getHeight() + delta);
             if (node.isLeaf()) {
                 if (node.getHeight() < thresholdInput.get()) {
                     node.setHeight(0);
                 }
             }
             if (!node.isLeaf()) {
-                offset(node.getLeft(), fDelta);
+                offset(node.getLeft(), delta);
                 if (node.getRight() != null) {
-                    offset(node.getRight(), fDelta);
+                    offset(node.getRight(), delta);
                 }
             }
         }
@@ -637,4 +662,5 @@ public class TreeParser extends Tree implements StateNodeInitialiser {
             stateNodes.add(m_initial.get());
         }
     }
+
 }
diff --git a/src/beast/util/XMLParser.java b/src/beast/util/XMLParser.java
index 71e15a6..46acc9d 100644
--- a/src/beast/util/XMLParser.java
+++ b/src/beast/util/XMLParser.java
@@ -25,10 +25,45 @@
 package beast.util;
 
 
+import static beast.util.XMLParserUtils.processPlates;
+import static beast.util.XMLParserUtils.replaceVariable;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.io.StringReader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
 import beast.app.beauti.PartitionContext;
-import beast.core.*;
+import beast.core.BEASTInterface;
+import beast.core.Distribution;
+import beast.core.Input;
 import beast.core.Input.Validate;
+import beast.core.Logger;
+import beast.core.Operator;
+import beast.core.Param;
 import beast.core.Runnable;
+import beast.core.State;
+import beast.core.parameter.Map;
 import beast.core.parameter.Parameter;
 import beast.core.parameter.RealParameter;
 import beast.core.util.Log;
@@ -36,19 +71,6 @@ import beast.evolution.alignment.Alignment;
 import beast.evolution.alignment.Sequence;
 import beast.evolution.tree.Tree;
 
-import org.w3c.dom.*;
-import org.xml.sax.InputSource;
-
-import javax.xml.parsers.DocumentBuilderFactory;
-
-import java.io.File;
-import java.io.PrintStream;
-import java.io.StringReader;
-import java.util.*;
-
-import static beast.util.XMLParserUtils.processPlates;
-import static beast.util.XMLParserUtils.replaceVariable;
-
 
 /**
  * XMLParser process Beast 2 XML and constructs an MCMC object
@@ -136,7 +158,7 @@ public class XMLParser {
     final static String LOG_CLASS = Logger.class.getName();
     final static String OPERATOR_CLASS = Operator.class.getName();
     final static String REAL_PARAMETER_CLASS = RealParameter.class.getName();
-    final static String PLUGIN_CLASS = BEASTInterface.class.getName();
+    final static String BEAST_INTERFACE_CLASS = BEASTInterface.class.getName();
     final static String INPUT_CLASS = Input.class.getName();
     final static String TREE_CLASS = Tree.class.getName();
     final static String RUNNABLE_CLASS = Runnable.class.getName();
@@ -175,10 +197,11 @@ public class XMLParser {
     HashMap<String, Integer[]> likelihoodMap;
     HashMap<String, Node> IDNodeMap;
 
+
     static HashMap<String, String> element2ClassMap;
     static Set<String> reservedElements;
     static {
-        element2ClassMap = new HashMap<String, String>();
+        element2ClassMap = new HashMap<>();
         element2ClassMap.put(DISTRIBUTION_ELEMENT, LIKELIHOOD_CLASS);
         element2ClassMap.put(OPERATOR_ELEMENT, OPERATOR_CLASS);
         element2ClassMap.put(INPUT_ELEMENT, INPUT_CLASS);
@@ -188,13 +211,24 @@ public class XMLParser {
         element2ClassMap.put(SEQUENCE_ELEMENT, SEQUENCE_CLASS);
         element2ClassMap.put(TREE_ELEMENT, TREE_CLASS);
         element2ClassMap.put(REAL_PARAMETER_ELEMENT, REAL_PARAMETER_CLASS);
-        reservedElements = new HashSet<String>();
+        reservedElements = new HashSet<>();
         for (final String element : element2ClassMap.keySet()) {
         	reservedElements.add(element);
         }
     }
-    
-    List<BEASTInterface> pluginsWaitingToInit;
+
+    public static class NameValuePair {
+		String name;
+		Object value;
+		boolean processed;
+		public NameValuePair(String name, Object value) {
+			this.name = name;
+			this.value = value;
+			processed = false;
+		}
+	}
+
+    List<BEASTInterface> beastObjectsWaitingToInit;
     List<Node> nodesWaitingToInit;
 
     public HashMap<String, String> getElement2ClassMap() {
@@ -202,13 +236,13 @@ public class XMLParser {
     }
 
 
-    String[] m_sNameSpaces;
+    String[] nameSpaces;
 
     /**
      * Flag to indicate initAndValidate should be called after
-     * all inputs of a plugin have been parsed
+     * all inputs of a beast object have been parsed
      */
-    boolean m_bInitialize = true;
+    boolean needsInitialisation = true;
 
     /**
      * when parsing XML, missing inputs can be assigned default values through
@@ -218,11 +252,11 @@ public class XMLParser {
     PartitionContext partitionContext = null;
 
     public XMLParser() {
-        pluginsWaitingToInit = new ArrayList<BEASTInterface>();
-        nodesWaitingToInit = new ArrayList<Node>();
+        beastObjectsWaitingToInit = new ArrayList<>();
+        nodesWaitingToInit = new ArrayList<>();
     }
 
-    public Runnable parseFile(final File file) throws Exception {
+    public Runnable parseFile(final File file) throws SAXException, IOException, ParserConfigurationException, XMLParserException {
         // parse the XML file into a DOM document
         final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
         //factory.setValidating(true);
@@ -243,9 +277,9 @@ public class XMLParser {
         replaceVariable(doc.getElementsByTagName(BEAST_ELEMENT).item(0), "seed",
                 String.valueOf(Randomizer.getSeed()));
         
-        IDMap = new HashMap<String, BEASTInterface>();
-        likelihoodMap = new HashMap<String, Integer[]>();
-        IDNodeMap = new HashMap<String, Node>();
+        IDMap = new HashMap<>();
+        likelihoodMap = new HashMap<>();
+        IDNodeMap = new HashMap<>();
 
         
         parse();
@@ -253,47 +287,50 @@ public class XMLParser {
         if (m_runnable != null)
             return m_runnable;
         else {
-            throw new Exception("Run element does not point to a runnable object.");
+            throw new XMLParserException("Run element does not point to a runnable object.");
         }
     } // parseFile
 
     /**
      * extract all elements (runnable or not) from an XML fragment.
      * Useful for retrieving all non-runnable elements when a template
-     * is instantiated by Beauti *
+     * is instantiated by Beauti 
+     * @throws ParserConfigurationException 
+     * @throws IOException 
+     * @throws SAXException *
      */
-    public List<BEASTInterface> parseTemplate(final String sXML, final HashMap<String, BEASTInterface> sIDMap, final boolean bInitialize) throws Exception {
-        m_bInitialize = bInitialize;
+    public List<BEASTInterface> parseTemplate(final String xml, final HashMap<String, BEASTInterface> idMap, final boolean initialise) throws XMLParserException, SAXException, IOException, ParserConfigurationException {
+        needsInitialisation = initialise;
         // parse the XML file into a DOM document
         final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
         //factory.setValidating(true);
-        doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(sXML)));
+        doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
         doc.normalize();
         processPlates(doc,PLATE_ELEMENT);
         
         //XMLParserUtils.saveDocAsXML(doc, "/tmp/beast2.xml");
 
-        IDMap = sIDMap;//new HashMap<String, Plugin>();
-        likelihoodMap = new HashMap<String, Integer[]>();
-        IDNodeMap = new HashMap<String, Node>();
+        IDMap = idMap;//new HashMap<>();
+        likelihoodMap = new HashMap<>();
+        IDNodeMap = new HashMap<>();
 
-        final List<BEASTInterface> plugins = new ArrayList<BEASTInterface>();
+        final List<BEASTInterface> beastObjects = new ArrayList<>();
 
         // find top level beast element
         final NodeList nodes = doc.getElementsByTagName("*");
         if (nodes == null || nodes.getLength() == 0) {
-            throw new Exception("Expected top level beast element in XML");
+            throw new XMLParserException("Expected top level beast element in XML");
         }
         final Node topNode = nodes.item(0);
         // sanity check that we are reading a beast 2 file
-        final double fVersion = getAttributeAsDouble(topNode, "version");
-        if (!topNode.getNodeName().equals(BEAST_ELEMENT) || fVersion < 2.0 || fVersion == Double.MAX_VALUE) {
-            return plugins;
+        final double version = getAttributeAsDouble(topNode, "version");
+        if (!topNode.getNodeName().equals(BEAST_ELEMENT) || version < 2.0 || version == Double.MAX_VALUE) {
+            return beastObjects;
         }
         // only process templates
-//        String sType = getAttribute(topNode, "type");
-//        if (sType == null || !sType.equals("template")) {
-//        	return plugins;
+//        String typeName = getAttribute(topNode, "type");
+//        if (typeName == null || !typeName.equals("template")) {
+//        	return beastObjects;
 //        }
 
 
@@ -304,28 +341,28 @@ public class XMLParser {
         for (int i = 0; i < children.getLength(); i++) {
             if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
                 final Node child = children.item(i);
-                System.err.println(child.getNodeName());
+                Log.warning.println(child.getNodeName());
                 if (!child.getNodeName().equals(MAP_ELEMENT)) {
-                    plugins.add(createObject(child, PLUGIN_CLASS, null));
+                    beastObjects.add(createObject(child, BEAST_INTERFACE_CLASS));
                 }
             }
         }
-        initPlugins();
-        return plugins;
+        initBEASTObjects();
+        return beastObjects;
     } // parseTemplate
 
-    private void initPlugins() throws Exception {
+    private void initBEASTObjects() throws XMLParserException {
     	Node node = null;
         try {
-        	for (int i = 0; i < pluginsWaitingToInit.size(); i++) {
-        		final BEASTInterface plugin = pluginsWaitingToInit.get(i);
+        	for (int i = 0; i < beastObjectsWaitingToInit.size(); i++) {
+        		final BEASTInterface beastObject = beastObjectsWaitingToInit.get(i);
         		node = nodesWaitingToInit.get(i);
-        		plugin.initAndValidate();
+        		beastObject.initAndValidate();
         	}
         } catch (Exception e) {
             // next lines for debugging only
-            //plugin.validateInputs();
-            //plugin.initAndValidate();
+            //beastObject.validateInputs();
+            //beastObject.initAndValidate();
             e.printStackTrace();
             throw new XMLParserException(node, "validate and intialize error: " + e.getMessage(), 110);
         }
@@ -335,23 +372,28 @@ public class XMLParser {
      * Parse an XML fragment representing a Plug-in
      * Only the run element or if that does not exist the last child element of
      * the top level <beast> element is considered.
+     * @throws XMLParserException 
      */
-    public BEASTInterface parseFragment(final String sXML, final boolean bInitialize) throws Exception {
-        m_bInitialize = bInitialize;
+    public BEASTInterface parseFragment(final String xml, final boolean initialise) throws XMLParserException  {
+        needsInitialisation = initialise;
         // parse the XML fragment into a DOM document
         final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(sXML)));
+        try {
+			doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
+		} catch (SAXException | IOException | ParserConfigurationException e) {
+			throw new RuntimeException(e);
+		}
         doc.normalize();
         processPlates(doc,PLATE_ELEMENT);
 
-        IDMap = new HashMap<String, BEASTInterface>();
-        likelihoodMap = new HashMap<String, Integer[]>();
-        IDNodeMap = new HashMap<String, Node>();
+        IDMap = new HashMap<>();
+        likelihoodMap = new HashMap<>();
+        IDNodeMap = new HashMap<>();
 
         // find top level beast element
         final NodeList nodes = doc.getElementsByTagName("*");
         if (nodes == null || nodes.getLength() == 0) {
-            throw new Exception("Expected top level beast element in XML");
+            throw new XMLParserException("Expected top level beast element in XML");
         }
         final Node topNode = nodes.item(0);
         initIDNodeMap(topNode);
@@ -359,7 +401,7 @@ public class XMLParser {
 
         final NodeList children = topNode.getChildNodes();
         if (children.getLength() == 0) {
-            throw new Exception("Need at least one child element");
+            throw new XMLParserException("Need at least one child element");
         }
         int i = children.getLength() - 1;
         while (i >= 0 && (children.item(i).getNodeType() != Node.ELEMENT_NODE ||
@@ -373,74 +415,73 @@ public class XMLParser {
             }
         }
         if (i < 0) {
-            throw new Exception("Need at least one child element");
+            throw new XMLParserException("Need at least one child element");
         }
 
-        final BEASTInterface plugin = createObject(children.item(i), PLUGIN_CLASS, null);
-        initPlugins();
-        return plugin;
+        final BEASTInterface beastObject = createObject(children.item(i), BEAST_INTERFACE_CLASS);
+        initBEASTObjects();
+        return beastObject;
     } // parseFragment
 
     /**
      * Parse XML fragment that will be wrapped in a beast element
-     * before parsing. This allows for ease of creating Plugin objects,
+     * before parsing. This allows for ease of creating beast objects,
      * like this:
      * Tree tree = (Tree) new XMLParser().parseBareFragment("<tree spec='beast.util.TreeParser' newick='((1:1,3:1):1,2:2)'/>");
      * to create a simple tree.
      */
-    public BEASTInterface parseBareFragment(String sXML, final boolean bInitialize) throws Exception {
+    public BEASTInterface parseBareFragment(String xml, final boolean initialise) throws XMLParserException {
         // get rid of XML processing instruction
-        sXML = sXML.replaceAll("<\\?xml[^>]*>", "");
-        if (sXML.contains("<beast")) {
-            return parseFragment(sXML, bInitialize);
+        xml = xml.replaceAll("<\\?xml[^>]*>", "");
+        if (xml.contains("<beast")) {
+            return parseFragment(xml, initialise);
         } else {
-            return parseFragment("<beast>" + sXML + "</beast>", bInitialize);
+            return parseFragment("<beast>" + xml + "</beast>", initialise);
         }
     }
 
-    public List<BEASTInterface> parseBareFragments(final String sXML, final boolean bInitialize) throws Exception {
-        m_bInitialize = bInitialize;
+    public List<BEASTInterface> parseBareFragments(final String xml, final boolean initialise) throws XMLParserException, SAXException, IOException, ParserConfigurationException {
+        needsInitialisation = initialise;
         // parse the XML fragment into a DOM document
         final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(sXML)));
+        doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
         doc.normalize();
         processPlates(doc,PLATE_ELEMENT);
 
         // find top level beast element
         final NodeList nodes = doc.getElementsByTagName("*");
         if (nodes == null || nodes.getLength() == 0) {
-            throw new Exception("Expected top level beast element in XML");
+            throw new XMLParserException("Expected top level beast element in XML");
         }
         final Node topNode = nodes.item(0);
         initIDNodeMap(topNode);
         parseNameSpaceAndMap(topNode);
 
         final NodeList children = topNode.getChildNodes();
-        final List<BEASTInterface> plugins = new ArrayList<BEASTInterface>();
+        final List<BEASTInterface> beastObjects = new ArrayList<>();
         for (int i = 0; i < children.getLength(); i++) {
             if (children.item(i).getNodeType() == Node.ELEMENT_NODE) {
-                final BEASTInterface plugin = createObject(children.item(i), PLUGIN_CLASS, null);
-                plugins.add(plugin);
+                final BEASTInterface beastObject = createObject(children.item(i), BEAST_INTERFACE_CLASS);
+                beastObjects.add(beastObject);
             }
         }
-        initPlugins();
-        return plugins;
+        initBEASTObjects();
+        return beastObjects;
     }
 
     /**
      * parse BEAST file as DOM document
-     *
-     * @throws Exception
+     * @throws XMLParserException 
      */
-    public void parse() throws Exception {
+    public void parse() throws XMLParserException {
         // find top level beast element
         final NodeList nodes = doc.getElementsByTagName("*");
         if (nodes == null || nodes.getLength() == 0) {
-            throw new Exception("Expected top level beast element in XML");
+            throw new XMLParserException("Expected top level beast element in XML");
         }
         final Node topNode = nodes.item(0);
-        final double fVersion = getAttributeAsDouble(topNode, "version");
-        if (fVersion < 2.0 || fVersion == Double.MAX_VALUE) {
+        final double version = getAttributeAsDouble(topNode, "version");
+        if (version < 2.0 || version == Double.MAX_VALUE) {
             throw new XMLParserException(topNode, "Wrong version: only versions > 2.0 are supported", 101);
         }
 
@@ -449,7 +490,7 @@ public class XMLParser {
 
         //parseState();
         parseRunElement(topNode);
-        initPlugins();
+        initBEASTObjects();
     } // parse
 
 
@@ -458,15 +499,15 @@ public class XMLParser {
      * Throw exception when a duplicate id is encountered
      *
      * @param node
-     * @throws Exception
+     * @throws XMLParserException
      */
-    void initIDNodeMap(final Node node) throws Exception {
-        final String sID = getID(node);
-        if (sID != null) {
-            if (IDNodeMap.containsKey(sID)) {
-                throw new XMLParserException(node, "IDs should be unique. Duplicate id '" + sID + "' found", 104);
+    void initIDNodeMap(final Node node) throws XMLParserException {
+        final String id = getID(node);
+        if (id != null) {
+            if (IDNodeMap.containsKey(id)) {
+                throw new XMLParserException(node, "IDs should be unique. Duplicate id '" + id + "' found", 104);
             }
-            IDNodeMap.put(sID, node);
+            IDNodeMap.put(id, node);
         }
         final NodeList children = node.getChildNodes();
         for (int i = 0; i < children.getLength(); i++) {
@@ -487,13 +528,13 @@ public class XMLParser {
     void parseNameSpaceAndMap(final Node topNode) throws XMLParserException {
         // process namespaces
         if (hasAtt(topNode, "namespace")) {
-            final String sNameSpace = getAttribute(topNode, "namespace");
-            setNameSpace(sNameSpace);
+            final String nameSpace = getAttribute(topNode, "namespace");
+            setNameSpace(nameSpace);
         } else {
             // make sure that the default namespace is in there
-            if (m_sNameSpaces == null) {
-                m_sNameSpaces = new String[1];
-                m_sNameSpaces[0] = "";
+            if (this.nameSpaces == null) {
+                this.nameSpaces = new String[1];
+                this.nameSpaces[0] = "";
             }
         }
 
@@ -501,36 +542,35 @@ public class XMLParser {
         final NodeList nodes = doc.getElementsByTagName(MAP_ELEMENT);
         for (int i = 0; i < nodes.getLength(); i++) {
             final Node child = nodes.item(i);
-            final String sName = getAttribute(child, "name");
-            if (sName == null) {
+            final String name = getAttribute(child, "name");
+            if (name == null) {
                 throw new XMLParserException(child, "name attribute expected in map element", 300);
             }
-            if (!element2ClassMap.containsKey(sName)) {
-//                throw new XMLParserException(child, "name '" + sName + "' is already defined as " + m_sElement2ClassMap.get(sName), 301);
+            if (!element2ClassMap.containsKey(name)) {
+//                throw new XMLParserException(child, "name '" + name + "' is already defined as " + m_sElement2ClassMap.get(name), 301);
 //            }
 
 	            // get class
-	            String sClass = child.getTextContent();
+	            String clazz = child.getTextContent();
 	            // remove spaces
-	            sClass = sClass.replaceAll("\\s", "");
-	            //sClass = sClass.replaceAll("beast", "yabby");
+	            clazz = clazz.replaceAll("\\s", "");
 	            // go through namespaces in order they are declared to find the correct class
-	            boolean bDone = false;
-	            for (final String sNameSpace : m_sNameSpaces) {
+	            boolean isDone = false;
+	            for (final String nameSpace : this.nameSpaces) {
 	                try {
 	                    // sanity check: class should exist
-	                    if (!bDone && Class.forName(sNameSpace + sClass) != null) {
-	                        element2ClassMap.put(sName, sClass);
-	                        Log.debug.println(sName + " => " + sNameSpace + sClass);
+	                    if (!isDone && Class.forName(nameSpace + clazz) != null) {
+	                        element2ClassMap.put(name, clazz);
+	                        Log.debug.println(name + " => " + nameSpace + clazz);
 	                        final String reserved = getAttribute(child, "reserved");
 	                        if (reserved != null && reserved.toLowerCase().equals("true")) {
-	                        	reservedElements.add(sName);
+	                        	reservedElements.add(name);
 	                        }
 	
-	                        bDone = true;
+	                        isDone = true;
 	                    }
 	                } catch (ClassNotFoundException e) {
-	                    //System.err.println("Not found " + e.getMessage());
+	                    // Log.warning.println("Not found " + e.getMessage());
 	                    // TODO: handle exception
 	                }
 	            }
@@ -538,25 +578,25 @@ public class XMLParser {
         }
     } // parseNameSpaceAndMap
 
-    public void setNameSpace(final String sNameSpaceStr) {
-        final String[] sNameSpaces = sNameSpaceStr.split(":");
+    public void setNameSpace(final String nameSpaceStr) {
+        final String[] nameSpaces = nameSpaceStr.split(":");
         // append dot after every non-zero namespace
-        m_sNameSpaces = new String[sNameSpaces.length + 1];
+        this.nameSpaces = new String[nameSpaces.length + 1];
         int i = 0;
-        for (String sNameSpace : sNameSpaces) {
-            sNameSpace = sNameSpace.trim();
-            if (sNameSpace.length() > 0) {
-                if (sNameSpace.charAt(sNameSpace.length() - 1) != '.') {
-                    sNameSpace += '.';
+        for (String nameSpace : nameSpaces) {
+            nameSpace = nameSpace.trim();
+            if (nameSpace.length() > 0) {
+                if (nameSpace.charAt(nameSpace.length() - 1) != '.') {
+                    nameSpace += '.';
                 }
             }
-            m_sNameSpaces[i++] = sNameSpace;
+            this.nameSpaces[i++] = nameSpace;
         }
         // make sure that the default namespace is in there
-        m_sNameSpaces[i] = "";
+        this.nameSpaces[i] = "";
     }
 
-    void parseRunElement(final Node topNode) throws Exception {
+    void parseRunElement(final Node topNode) throws XMLParserException {
         // find mcmc element
         final NodeList nodes = doc.getElementsByTagName(RUN_ELEMENT);
         if (nodes.getLength() == 0) {
@@ -567,383 +607,544 @@ public class XMLParser {
         }
         final Node mcmc = nodes.item(0);
 
-        m_runnable = (Runnable) createObject(mcmc, RUNNABLE_CLASS, null);
+        m_runnable = (Runnable) createObject(mcmc, RUNNABLE_CLASS);
     } // parseMCMC
 
     /**
-     * Check that plugin is a class that is assignable to class with name sClass.
+     * Check that beast object is a class that is assignable to class with name className.
      * This involves a parameter clutch to deal with non-real parameters.
      * This needs a bit of work, obviously...
+     * @throws ClassNotFoundException 
      */
-    boolean checkType(final String sClass, final BEASTInterface plugin) throws Exception {
-        if (sClass.equals(INPUT_CLASS) || Class.forName(sClass).isInstance(plugin)) {
-            return true;
-        }
+    boolean checkType(final String className, final BEASTInterface beastObject, Node node) throws XMLParserException  {
+        try {
+			if (className.equals(INPUT_CLASS) || Class.forName(className).isInstance(beastObject)) {
+			    return true;
+			}
+		} catch (ClassNotFoundException e) {
+			throw new XMLParserException(node, "Class not found:" + e.getMessage(), 444);
+		}
         // parameter clutch
-        if (sClass.equals(RealParameter.class.getName()) && plugin instanceof Parameter<?>) {
+        if (className.equals(RealParameter.class.getName()) && beastObject instanceof Parameter<?>) {
             return true;
         }
         return false;
     } // checkType
 
-    BEASTInterface createObject(final Node node, final String sClass, final BEASTInterface parent) throws Exception {
-    	//sClass = sClass.replaceAll("beast", "yabby");
+    BEASTInterface createObject(final Node node, final String classname) throws XMLParserException {
         // try the IDMap first
-        final String sID = getID(node);
+        final String id = getID(node);
 
-        if (sID != null) {
-            if (IDMap.containsKey(sID)) {
-                final BEASTInterface plugin = IDMap.get(sID);
-                if (checkType(sClass, plugin)) {
-                    return plugin;
+        if (id != null) {
+            if (IDMap.containsKey(id)) {
+                final BEASTInterface beastObject = IDMap.get(id);
+                if (checkType(classname, beastObject, node)) {
+                    return beastObject;
                 }
-                throw new XMLParserException(node, "id=" + sID + ". Expected object of type " + sClass + " instead of " + plugin.getClass().getName(), 105);
+                throw new XMLParserException(node, "id=" + id + ". Expected object of type " + classname + " instead of " + beastObject.getClass().getName(), 105);
             }
         }
 
-        final String sIDRef = getIDRef(node);
-        if (sIDRef != null) {
+        final String dRef = getIDRef(node);
+        if (dRef != null) {
             // produce warning if there are other attributes than idref
             if (node.getAttributes().getLength() > 1) {
                 // check if there are just 2 attributes and other attribute is 'name' and/or 'id'
             	final int offset = (getAttribute(node, "id") == null? 0: 1) + (getAttribute(node, "name") == null? 0: 1);
                 if (node.getAttributes().getLength() > 1 + offset) {
-                    Log.warning.println("Element " + node.getNodeName() + " found with idref='" + sIDRef + "'. All other attributes are ignored.\n");
+                    Log.warning.println("Element " + node.getNodeName() + " found with idref='" + dRef + "'. All other attributes are ignored.\n");
                 }
             }
-            if (IDMap.containsKey(sIDRef)) {
-                final BEASTInterface plugin = IDMap.get(sIDRef);
-                if (checkType(sClass, plugin)) {
-                    return plugin;
+            if (IDMap.containsKey(dRef)) {
+                final BEASTInterface beastObject = IDMap.get(dRef);
+                if (checkType(classname, beastObject, node)) {
+                    return beastObject;
                 }
-                throw new XMLParserException(node, "id=" + sIDRef + ". Expected object of type " + sClass + " instead of " + plugin.getClass().getName(), 106);
-            } else if (IDNodeMap.containsKey(sIDRef)) {
-                final BEASTInterface plugin = createObject(IDNodeMap.get(sIDRef), sClass, parent);
-                if (checkType(sClass, plugin)) {
-                    return plugin;
+                throw new XMLParserException(node, "id=" + dRef + ". Expected object of type " + classname + " instead of " + beastObject.getClass().getName(), 106);
+            } else if (IDNodeMap.containsKey(dRef)) {
+                final BEASTInterface beastObject = createObject(IDNodeMap.get(dRef), classname);
+                if (checkType(classname, beastObject, node)) {
+                    return beastObject;
                 }
-                throw new XMLParserException(node, "id=" + sIDRef + ". Expected object of type " + sClass + " instead of " + plugin.getClass().getName(), 107);
+                throw new XMLParserException(node, "id=" + dRef + ". Expected object of type " + classname + " instead of " + beastObject.getClass().getName(), 107);
             }
-            throw new XMLParserException(node, "Could not find object associated with idref " + sIDRef, 170);
+            throw new XMLParserException(node, "Could not find object associated with idref " + dRef, 170);
         }
         // it's not in the ID map yet, so we have to create a new object
-        String sSpecClass = sClass;
-        final String sElementName = node.getNodeName();
+        String specClass = classname;
+        final String elementName = node.getNodeName();
 
 
-        if (element2ClassMap.containsKey(sElementName)) {
-            sSpecClass = element2ClassMap.get(sElementName);
+        if (element2ClassMap.containsKey(elementName)) {
+            specClass = element2ClassMap.get(elementName);
         }
-        final String sSpec = getAttribute(node, "spec");
-        if (sSpec != null) {
-            sSpecClass = sSpec;
+        final String spec = getAttribute(node, "spec");
+        if (spec != null) {
+            specClass = spec;
         }
-    	//sSpecClass = sSpecClass.replaceAll("beast", "yabby");
     	
-    	if (sSpecClass.indexOf("BEASTInterface") > 0) {
-    		System.out.println(sSpecClass);
-    	}
-
-    	Object o = null;
-        // try to create object from sSpecName, taking namespaces in account
-        try {
-            boolean bDone = false;
-            for (final String sNameSpace : m_sNameSpaces) {
+    	//if (specClass.indexOf("BEASTInterface") > 0) {
+    	//	Log.info.println(specClass);
+    	//}
+        
+		String clazzName = null;
+		// determine clazzName from specName, taking name spaces in account
+		for (String nameSpace : nameSpaces) {
+			if (clazzName == null) {
+				if (XMLParserUtils.beastObjectNames.contains(nameSpace + specClass)) {
+					clazzName = nameSpace + specClass;
+					break;
+				}
+			}
+		}
+		if (clazzName == null) {
+			// try to create the old-fashioned way by creating the class
+            boolean isDone = false;
+            for (final String nameSpace : nameSpaces) {
                 try {
-                    if (!bDone) {
-                    	//sNameSpace = sNameSpace.replaceAll("beast", "yabby");
-                        o = Class.forName(sNameSpace + sSpecClass).newInstance();
-                        bDone = true;
+                    if (!isDone) {
+                        Class.forName(nameSpace + specClass);
+                        clazzName = nameSpace + specClass;
+                        isDone = true;
                     }
-                } catch (InstantiationException e) {
-                    // we only get here when the class exists, but cannot be created
-                    // for instance because it is abstract or an interface
-
-                    throw new Exception("Cannot instantiate class (" + sSpecClass + "). Please check the spec attribute.");
                 } catch (ClassNotFoundException e) {
-                    // TODO: handle exception
-                }
-            }
-            if (!bDone) {
-                throw new Exception("Class could not be found. Did you mean " + guessClass(sSpecClass) + "?");
-                //throw new ClassNotFoundException(sSpecClass);
-            }
-            // hack required to make log-parsing easier
-            if (o instanceof State) {
-                m_state = (State) o;
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-            throw new XMLParserException(node, "Cannot create class: " + sSpecClass + ". " + e.getMessage(), 122);
-        }
-        // sanity check
-        if (!(o instanceof BEASTInterface)) {
-            if (o instanceof Input) {
-                // if we got this far, it is a basic input,
-                // that is, one of the form <input name='xyz'>value</input>
-                String sName = getAttribute(node, "name");
-                if (sName == null) {
-                    sName = "value";
-                }
-                final String sText = node.getTextContent();
-                if (sText.length() > 0) {
-                    setInput(node, parent, sName, sText);
+                    // class does not exist -- try another namespace
                 }
-                return null;
-            } else {
-                throw new XMLParserException(node, "Expected object to be instance of Plugin", 108);
             }
-        }
-        // set id
-        final BEASTInterface plugin = (BEASTInterface) o;
-        plugin.setID(sID);
-        register(node, plugin);
-        // process inputs
-        parseInputs(plugin, node);
+		}
+		if (clazzName == null) {
+			throw new XMLParserException(node, "Class could not be found. Did you mean " + XMLParserUtils.guessClass(specClass) + "?", 1017);
+			// throw new ClassNotFoundException(specClass);
+		}
+				
+		// sanity check		
+		try {
+			Class<?> clazz = Class.forName(clazzName);
+			if (!BEASTInterface.class.isAssignableFrom(clazz)) {
+				throw new XMLParserException(node, "Expected object to be instance of BEASTObject", 108);
+			}
+		} catch (ClassNotFoundException e1) {
+			// should never happen since clazzName is in the list of classes collected by the AddOnManager
+			e1.printStackTrace();
+			throw new RuntimeException(e1);
+		}
+		
+		// process inputs
+		List<NameValuePair> inputInfo = parseInputs(node, clazzName);
+		BEASTInterface beastObject = createBeastObject(node, id, clazzName, inputInfo);
+
         // initialise
-        if (m_bInitialize) {
+        if (needsInitialisation) {
             try {
-                plugin.validateInputs();
-                pluginsWaitingToInit.add(plugin);
+                beastObject.validateInputs();
+                beastObjectsWaitingToInit.add(beastObject);
                 nodesWaitingToInit.add(node);
-                //plugin.initAndValidate();
-            } catch (Exception e) {
+            } catch (IllegalArgumentException e) {
                 // next lines for debugging only
-                //plugin.validateInputs();
-                //plugin.initAndValidate();
+                //beastObject.validateInputs();
+                //beastObject.initAndValidate();
                 e.printStackTrace();
                 throw new XMLParserException(node, "validate and intialize error: " + e.getMessage(), 110);
             }
         }
-        return plugin;
+        return beastObject;
     } // createObject
 
-    /**
-     * find closest matching class to named class *
-     */
-    String guessClass(final String sClass) {
-        String sName = sClass;
-        if (sClass.contains(".")) {
-            sName = sClass.substring(sClass.lastIndexOf('.') + 1);
-        }
-        final List<String> sPluginNames = AddOnManager.find(beast.core.BEASTInterface.class, AddOnManager.IMPLEMENTATION_DIR);
-        int nBestDistance = Integer.MAX_VALUE;
-        String sClosest = null;
-        for (final String sPlugin : sPluginNames) {
-            final String sClassName = sPlugin.substring(sPlugin.lastIndexOf('.') + 1);
-            final int nDistance = getLevenshteinDistance(sName, sClassName);
-
-
-            if (nDistance < nBestDistance) {
-                nBestDistance = nDistance;
-                sClosest = sPlugin;
-            }
-        }
-        return sClosest;
-    }
+    
+	/** create BEASTInterface either using Inputs, or using annotated constructor **/
+	private BEASTInterface createBeastObject(Node node, String ID, String clazzName, List<NameValuePair> inputInfo) throws XMLParserException {
+		BEASTInterface beastObject = useAnnotatedConstructor(node, ID, clazzName, inputInfo);
+		if (beastObject != null) {
+			return beastObject;
+		}
+		
+		// create new instance using class name
+		Object o = null;
+		try {
+			Class<?> c = Class.forName(clazzName); 
+				o = c.newInstance();
+		} catch (InstantiationException e) {
+			// we only get here when the class exists, but cannot be
+			// created for instance because it is abstract
+			throw new XMLParserException(node, "Cannot instantiate class. Please check the spec attribute.", 1006);
+		} catch (ClassNotFoundException e) {
+			// ignore -- class was found in beastObjectNames before
+		} catch (IllegalAccessException e) {
+			// T O D O Auto-generated catch block
+			e.printStackTrace();
+			throw new XMLParserException(node, "Cannot access class. Please check the spec attribute.", 1011);
+		}
+		
+		// set id
+		beastObject = (BEASTInterface) o;
+		beastObject.setID(ID);
+
+		// hack required to make log-parsing easier
+		if (o instanceof State) {
+			m_state = (State) o;
+		}
+
+		// process inputs for annotated constructors
+		for (NameValuePair pair : inputInfo) {
+			if (pair.value instanceof BEASTInterface) {
+				setInput(node, beastObject, pair.name, (BEASTInterface) pair.value);
+			} else if (pair.value instanceof String) {
+				setInput(node, beastObject, pair.name, (String) pair.value);
+			} else {
+				throw new RuntimeException("Programmer error: value should be String or BEASTInterface");
+			}
+		}
+		
+		// fill in missing inputs, if an input provider is available
+		try {
+			if (requiredInputProvider != null) {
+				for (Input<?> input : beastObject.listInputs()) {
+					if (input.get() == null && input.getRule() == Validate.REQUIRED) {
+						Object o2 = requiredInputProvider.createInput(beastObject, input, partitionContext);
+						if (o2 != null) {
+							input.setValue(o2, beastObject);
+						}
+					}
+				}
+			}
+		} catch (Exception e) {
+			throw new XMLParserException(node, e.getMessage(), 1008);			
+		}
+		
+		// sanity check: all attributes should be valid input names
+		if (!(beastObject instanceof Map)) {
+			for (NameValuePair pair : inputInfo) {
+				String name = pair.name;
+				if (!(name.equals("id") || name.equals("idref") || name.equals("spec") || name.equals("name"))) {
+					try {
+						beastObject.getInput(name);
+					} catch (Exception e) {
+						throw new XMLParserException(node, e.getMessage(), 1009);
+					}
+				}
+			}
+		}
+		
+		// make sure object o is in outputs of inputs
+		for (NameValuePair pair : inputInfo) {
+			if (pair.value instanceof BEASTInterface) {
+				((BEASTInterface) pair.value).getOutputs().add((BEASTInterface) o);
+			}	
+		}
+		
+
+		register(node, beastObject);
+		return beastObject;
+	}
 
+    
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private BEASTInterface useAnnotatedConstructor(Node node, String _id, String clazzName, List<NameValuePair> inputInfo) throws XMLParserException {
+		Class<?> clazz = null;
+		try {
+			clazz = Class.forName(clazzName);
+		} catch (ClassNotFoundException e) {
+			// cannot get here, since we checked the class existed before
+			e.printStackTrace();
+		}
+	    Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();
+	    for (Constructor<?> ctor : allConstructors) {
+	    	Annotation[][] annotations = ctor.getParameterAnnotations();
+	    	List<Param> paramAnnotations = new ArrayList<>();
+	    	for (Annotation [] a0 : annotations) {
+		    	for (Annotation a : a0) {
+		    		if (a instanceof Param) {
+		    			paramAnnotations.add((Param) a);
+		    		}
+	    		}
+	    	}
+	    	
+	    	for (NameValuePair pair : inputInfo) {
+	    		pair.processed = false;
+	    	}
+
+	    	Class<?>[] types  = ctor.getParameterTypes();
+    		//Type[] gtypes = ctor.getGenericParameterTypes();
+	    	if (types.length > 0 && paramAnnotations.size() == types.length) {
+		    	try {
+		    		Object [] args = new Object[types.length];
+		    		for (int i = 0; i < types.length; i++) {
+		    			Param param = paramAnnotations.get(i);
+		    			Type type = types[i];
+		    			if (type.getTypeName().equals("java.util.List")) {
+		    				if (args[i] == null) {
+		    					// no need to parameterise list due to type erasure
+		    					args[i] = new ArrayList();
+		    				}
+		    				List<Object> values = getListOfValues(param, inputInfo);
+		    				((List)args[i]).addAll(values);
+		    			} else {
+		    				args[i] = getValue(param, types[i], inputInfo);
+		    			}
+		    		}
+
+		    		// ensure all inputs are used
+		    		boolean allUsed = true;
+			    	for (NameValuePair pair : inputInfo) {
+			    		if (!pair.processed) {
+			    			allUsed= false;
+			    		}
+			    	}
+
+			    	if (allUsed) {
+				    	try {
+							Object o = ctor.newInstance(args);
+							BEASTInterface beastObject = (BEASTInterface) o;
+							register(node, beastObject);
+							return beastObject;
+						} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+							throw new XMLParserException(node, "Could not create object: " + e.getMessage(), 1012);
+						}
+			    	}
+				} catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException
+						| InvocationTargetException e) {
+					// we get here when a param value cannot be constructed from a default value
+					// let's try the next constructor (if any)
+				}
+
+	    	}
+		}
+		return null;
+	}
 
-    /**
-     * Compute edit distance between two strings = Levenshtein distance *
-     */
-    public static int getLevenshteinDistance(final String s, final String t) {
-        if (s == null || t == null) {
-            throw new IllegalArgumentException("Strings must not be null");
+	private Object getValue(Param param, Class<?> type, List<NameValuePair> inputInfo) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+		for (NameValuePair pair : inputInfo) {
+			if (pair.name.equals(param.name())) {
+				pair.processed = true;
+				if (type.isAssignableFrom(Integer.class)) {
+					return Integer.parseInt((String) pair.value);
+				}
+				if (type.isAssignableFrom(Double.class)) {
+					return Double.parseDouble((String) pair.value);
+				}
+				return pair.value;
+			}
+		}
+		
+		// could not find Param entry in inputInfo
+		
+		// check if this parameter is required or optional
+		if (!param.optional()) {
+			throw new IllegalArgumentException();
+		}
+
+		// try using a String constructor of the default value
+        Constructor<?> ctor;
+        String value = param.defaultValue();
+        Object v = value; 
+        try {
+        	ctor = type.getDeclaredConstructor(String.class);
+        } catch (NoSuchMethodException e) {
+        	// we get here if there is not String constructor
+        	// try integer constructor instead
+        	try {
+        		if (value.startsWith("0x")) {
+        			v = Integer.parseInt(value.substring(2), 16);
+        		} else {
+        			v = Integer.parseInt(value);
+        		}
+            	ctor = type.getDeclaredConstructor(int.class);
+            	
+        	} catch (NumberFormatException e2) {
+            	// could not parse as integer, try double instead
+        		v = Double.parseDouble(value);
+            	ctor = type.getDeclaredConstructor(double.class);
+        	}
         }
+        ctor.setAccessible(true);
+        final Object o = ctor.newInstance(v);
+        return o;
+	}
 
-        final int n = s.length(); // length of s
-        final int m = t.length(); // length of t
-
-        if (n == 0) {
-            return m;
-        } else if (m == 0) {
-            return n;
-        }
+	static List<Object> getListOfValues(Param param, List<NameValuePair> inputInfo) {
+		List<Object> values = new ArrayList<>();
+		for (NameValuePair pair : inputInfo) {
+			if (pair.name.equals(param.name())) {
+				values.add(pair.value);
+				pair.processed = true;
+			}
+		}
+		return values;
+	}
 
-        int p[] = new int[n + 1]; //'previous' cost array, horizontally
-        int d[] = new int[n + 1]; // cost array, horizontally
-        int _d[]; //placeholder to assist in swapping p and d
-
-        // indexes into strings s and t
-        int i; // iterates through s
-        int j; // iterates through t
-        char t_j; // jth character of t
-        int cost; // cost
-        for (i = 0; i <= n; i++) {
-            p[i] = i;
-        }
-        for (j = 1; j <= m; j++) {
-            t_j = t.charAt(j - 1);
-            d[0] = j;
-            for (i = 1; i <= n; i++) {
-                cost = s.charAt(i - 1) == t_j ? 0 : 1;
-                // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
-                d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost);
-            }
-            // copy current distance counts to 'previous row' distance counts
-            _d = p;
-            p = d;
-            d = _d;
-        }
 
-        // our last action in the above loop was to switch d and p, so p now
-        // actually has the most recent cost counts
-        return p[n];
+	@Deprecated // use XMLParserUtils.getLevenshteinDistance instead
+    public static int getLevenshteinDistance(final String s, final String t) {
+    	return XMLParserUtils.getLevenshteinDistance(s, t);
     }
-
-    void parseInputs(final BEASTInterface parent, final Node node) throws Exception {
+    
+    private List<NameValuePair> parseInputs(Node node, String clazzName) throws XMLParserException {
+    	List<NameValuePair> inputInfo = new ArrayList<>();
         // first, process attributes
-        final NamedNodeMap atts = node.getAttributes();
+        NamedNodeMap atts = node.getAttributes();
         if (atts != null) {
             for (int i = 0; i < atts.getLength(); i++) {
-                final String sName = atts.item(i).getNodeName();
-                if (!(sName.equals("id") ||
-                        sName.equals("idref") ||
-                        sName.equals("spec") ||
-                        sName.equals("name"))) {
-                    final String sValue = atts.item(i).getNodeValue();
-                    if (sValue.startsWith("@")) {
-                        final String sIDRef = sValue.substring(1);
+                final String name = atts.item(i).getNodeName();
+                if (!(name.equals("id") ||
+                        name.equals("idref") ||
+                        name.equals("spec") ||
+                        name.equals("name"))) {
+                    final String value = atts.item(i).getNodeValue();
+                    if (value.startsWith("@")) {
+                        final String idRef = value.substring(1);
                         final Element element = doc.createElement("input");
-                        element.setAttribute("idref", sIDRef);
+                        element.setAttribute("idref", idRef);
                         // add child in case things go belly up, and an XMLParserException is thrown
                         node.appendChild(element);
-                        final BEASTInterface plugin = createObject(element, PLUGIN_CLASS, parent);
-                        // it is save to remove the elment now
+                        final BEASTInterface beastObject = createObject(element, BEAST_INTERFACE_CLASS);
+                        // it is save to remove the element now
                         node.removeChild(element);
-                        setInput(node, parent, sName, plugin);
+                        inputInfo.add(new NameValuePair(name, beastObject));
                     } else {
-                        setInput(node, parent, sName, sValue);
+                        inputInfo.add(new NameValuePair(name, value));
                     }
                 }
             }
         }
         // process element nodes
         final NodeList children = node.getChildNodes();
-        int nChildElements = 0;
-        String sText = "";
+        int childElements = 0;
+        String text = "";
         for (int i = 0; i < children.getLength(); i++) {
             final Node child = children.item(i);
             if (child.getNodeType() == Node.ELEMENT_NODE) {
-                final String sElement = child.getNodeName();
+                final String element = child.getNodeName();
                 // resolve name of the input
-                String sName = getAttribute(child, "name");
-                if (sName == null) {
-                    sName = sElement;
+                String name = getAttribute(child, "name");
+                if (name == null) {
+                    name = element;
                 }
                 // resolve base class
-                String sClass = PLUGIN_CLASS;
-                if (element2ClassMap.containsKey(sElement)) {
-                    sClass = element2ClassMap.get(sElement);
+                String classname = BEAST_INTERFACE_CLASS;
+                if (element2ClassMap.containsKey(element)) {
+                    classname = element2ClassMap.get(element);
                 }
-                final BEASTInterface childItem = createObject(child, sClass, parent);
-                if (childItem != null) {
-                    setInput(node, parent, sName, childItem);
+                // test for special cases: <xyz>value</xyz>  and <input name="xyz">value</input>
+                // where value is a string
+                boolean done = false;
+                atts = child.getAttributes();
+                if (atts.getLength() == 0 || (element.equals("input") && atts.getLength() == 1 && name != null)) {
+                	NodeList grantchildren = child.getChildNodes();
+                	boolean hasElements = false;
+                	for (int j = 0; j < grantchildren.getLength(); j++) {
+                		if (grantchildren.item(j).getNodeType() == Node.ELEMENT_NODE) {
+                			hasElements = true;
+                			break;
+                		}
+                	}
+                	if (!hasElements) {
+                		String content = child.getTextContent();
+                		inputInfo.add(new NameValuePair(name, content));
+                		done = true;
+                	}
                 }
-                nChildElements++;
+                
+                // create object from element, if not already done so
+                if (!done) {
+                    final BEASTInterface childItem = createObject(child, classname);
+                    if (childItem != null) {
+                    	inputInfo.add(new NameValuePair(name, childItem));
+                    }                		
+            	}
+                childElements++;
             } else if (child.getNodeType() == Node.CDATA_SECTION_NODE ||
                     child.getNodeType() == Node.TEXT_NODE) {
-                sText += child.getTextContent();
+                text += child.getTextContent();
             }
         }
-        if (!sText.matches("\\s*")) {
-            setInput(node, parent, "value", sText);
+        if (!text.matches("\\s*")) {
+        	inputInfo.add(new NameValuePair("value", text));
         }
 
-        if (nChildElements == 0) {
-            final String sContent = node.getTextContent();
-            if (sContent != null && sContent.length() > 0 && sContent.replaceAll("\\s", "").length() > 0) {
+        if (childElements == 0) {
+            final String content = node.getTextContent();
+            if (content != null && content.length() > 0 && content.replaceAll("\\s", "").length() > 0) {
                 try {
-                    setInput(node, parent, "value", sContent);
+                	inputInfo.add(new NameValuePair("value", content));
                 } catch (Exception e) {
                     //
                 }
             }
         }
 
-        // fill in missing inputs, if an input provider is available
-        if (requiredInputProvider != null) {
-            for (final Input<?> input : parent.listInputs()) {
-                if (input.get() == null && input.getRule() == Validate.REQUIRED) {
-                    final Object o = requiredInputProvider.createInput(parent, input, partitionContext);
-                    if (o != null) {
-                        input.setValue(o, parent);
-                    }
-                }
-            }
-        }
+        return inputInfo;
     } // setInputs
 
-    void setInput(final Node node, final BEASTInterface plugin, final String sName, final BEASTInterface plugin2) throws XMLParserException {
+    void setInput(final Node node, final BEASTInterface beastObject, final String name, final BEASTInterface beastObject2) throws XMLParserException {
         try {
-            final Input<?> input = plugin.getInput(sName);
+            final Input<?> input = beastObject.getInput(name);
             // test whether input was not set before, this is done by testing whether input has default value.
             // for non-list inputs, this should be true if the value was not already set before
             // for list inputs this is always true.
             if (input.get() == input.defaultValue) {
-                plugin.setInputValue(sName, plugin2);
+                beastObject.setInputValue(name, beastObject2);
             } else {
-                throw new Exception("Multiple entries for non-list input " + input.getName());
+                throw new XMLParserException("Multiple entries for non-list input " + input.getName());
             }
             return;
         } catch (Exception e) {
-        	if (sName.equals("xml:base")) {
+        	if (name.equals("xml:base")) {
         		// ignore xml:base attributes introduces by XML entities
         		return;
         	}
             if (e.getMessage().contains("101")) {
-                String sType = "?";
+                String type = "?";
                 try {
-                    sType = plugin.getInput(sName).getType().getName().replaceAll(".*\\.", "");
+                    type = beastObject.getInput(name).getType().getName().replaceAll(".*\\.", "");
                 } catch (Exception e2) {
                     // TODO: handle exception
                 }
                 throw new XMLParserException(node, e.getMessage() +
-                        " expected '" + sType +
-                        "' but got '" + plugin2.getClass().getName().replaceAll(".*\\.", "") + "'"
+                        " expected '" + type +
+                        "' but got '" + beastObject2.getClass().getName().replaceAll(".*\\.", "") + "'"
                         , 123);
             } else {
                 throw new XMLParserException(node, e.getMessage(), 130);
             }
         }
-        //throw new XMLParserException(node, "no such input '"+sName+"' for element <" + node.getNodeName() + ">", 167);
+        //throw new XMLParserException(node, "no such input '"+name+"' for element <" + node.getNodeName() + ">", 167);
     }
 
-    void setInput(final Node node, final BEASTInterface plugin, final String sName, final String sValue) throws XMLParserException {
+    void setInput(final Node node, final BEASTInterface beastObject, final String name, final String value) throws XMLParserException {
         try {
-			plugin.setInputValue(sName, sValue);
+			beastObject.setInputValue(name, value);
             return;
         } catch (Exception e) {
-        	if (sName.equals("xml:base")) {
+        	if (name.equals("xml:base")) {
         		// ignore xml:base attributes introduces by XML entities
         		return;
         	}
             try {
-				plugin.setInputValue(sName, sValue);
+				beastObject.setInputValue(name, value);
 			} catch (Exception e1) {
 				// TODO Auto-generated catch block
 				e1.printStackTrace();
 			}
             throw new XMLParserException(node, e.getMessage(), 124);
         }
-        //throw new XMLParserException(node, "no such input '"+sName+"' for element <" + node.getNodeName() + ">", 168);
+        //throw new XMLParserException(node, "no such input '"+name+"' for element <" + node.getNodeName() + ">", 168);
     }
 
     /**
-     * records id in IDMap, for ease of retrieving Plugins associated with idrefs *
+     * records id in IDMap, for ease of retrieving beast objects associated with idrefs *
      */
-    void register(final Node node, final BEASTInterface plugin) {
-        final String sID = getID(node);
-        if (sID != null) {
-            IDMap.put(sID, plugin);
+    void register(final Node node, final BEASTInterface beastObject) {
+        final String id = getID(node);
+        if (id != null) {
+            IDMap.put(id, beastObject);
         }
     }
 
-    public static String getID(final Node node) { // throws Exception {
+    public static String getID(final Node node) { 
         return getAttribute(node, "id");
     } // getID
 
-    public static String getIDRef(final Node node) {// throws Exception {
+    public static String getIDRef(final Node node) {
         return getAttribute(node, "idref");
     } // getIDRef
 
@@ -951,14 +1152,14 @@ public class XMLParser {
      * get string value of attribute with given name
      * as opposed to double or integer value (see methods below) *
      */
-    public static String getAttribute(final Node node, final String sAttName) { // throws Exception {
+    public static String getAttribute(final Node node, final String attName) { 
         final NamedNodeMap atts = node.getAttributes();
         if (atts == null) {
             return null;
         }
         for (int i = 0; i < atts.getLength(); i++) {
-            final String sName = atts.item(i).getNodeName();
-            if (sName.equals(sAttName)) {
+            final String name = atts.item(i).getNodeName();
+            if (name.equals(attName)) {
                 return atts.item(i).getNodeValue();
             }
         }
@@ -968,34 +1169,34 @@ public class XMLParser {
     /**
      * get integer value of attribute with given name *
      */
-    public static int getAttributeAsInt(final Node node, final String sAttName) { //throws Exception {
-        final String sAtt = getAttribute(node, sAttName);
-        if (sAtt == null) {
+    public static int getAttributeAsInt(final Node node, final String attName) { 
+        final String att = getAttribute(node, attName);
+        if (att == null) {
             return -1;
         }
-        return Integer.parseInt(sAtt);
+        return Integer.parseInt(att);
     }
 
     /**
      * get double value of attribute with given name *
      */
-    public static double getAttributeAsDouble(final Node node, final String sAttName) { // throws Exception {
-        final String sAtt = getAttribute(node, sAttName);
-        if (sAtt == null) {
+    public static double getAttributeAsDouble(final Node node, final String attName) { 
+        final String att = getAttribute(node, attName);
+        if (att == null) {
             return Double.MAX_VALUE;
         }
-        return Double.parseDouble(sAtt);
+        return Double.parseDouble(att);
     }
 
     /**
      * test whether a node contains a attribute with given name *
      */
-    boolean hasAtt(final Node node, final String sAttributeName) {
+    boolean hasAtt(final Node node, final String attributeName) {
         final NamedNodeMap atts = node.getAttributes();
         if (atts != null) {
             for (int i = 0; i < atts.getLength(); i++) {
-                final String sName = atts.item(i).getNodeName();
-                if (sName.equals(sAttributeName)) {
+                final String name = atts.item(i).getNodeName();
+                if (name.equals(attributeName)) {
                     return true;
                 }
             }
@@ -1004,7 +1205,7 @@ public class XMLParser {
     }
 
     public interface RequiredInputProvider {
-		Object createInput(BEASTInterface plugin, Input<?> input, PartitionContext context);
+		Object createInput(BEASTInterface beastObject, Input<?> input, PartitionContext context);
     }
 
     public void setRequiredInputProvider(final RequiredInputProvider provider, final PartitionContext context) {
@@ -1022,14 +1223,13 @@ public class XMLParser {
             System.setOut(System.err);
             // parse the file
             final XMLParser parser = new XMLParser();
-            final BEASTInterface plugin = parser.parseFile(new File(args[0]));
+            final BEASTInterface beastObject = parser.parseFile(new File(args[0]));
             // restore stdout
             System.setOut(out);
-            System.out.println(new XMLProducer().toXML(plugin));
+            System.out.println(new XMLProducer().toXML(beastObject));
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
-
-
+    
 } // class XMLParser
diff --git a/src/beast/util/XMLParserException.java b/src/beast/util/XMLParserException.java
index 780c324..9aa5136 100644
--- a/src/beast/util/XMLParserException.java
+++ b/src/beast/util/XMLParserException.java
@@ -32,9 +32,12 @@ import org.w3c.dom.Node;
  * that keeps track of the DOM Node that caused the
  * anomaly.
  */
- at SuppressWarnings("serial")
 public class XMLParserException extends Exception {
     /**
+	 * 
+	 */
+	private static final long serialVersionUID = 1L;
+	/**
      * DOM Node where the anomaly was in the vicinity *
      */
     Node _node;
@@ -47,66 +50,75 @@ public class XMLParserException extends Exception {
      */
     int errorNr;
 
-    public XMLParserException(Node node, String sMsg, int nErrorNr) {
-        super(sMsg);
+    public XMLParserException(String msg) {
+    	super(msg);
+    }
+    
+    public XMLParserException(Node node, String msg, int errorNr) {
+        super(msg);
         _node = node;
         msg = "";
-        errorNr = nErrorNr;
+        this.errorNr = errorNr;
     }
 
     // format message and resolve parent
-    public String getMessage() {
-        String sMsg = "\nError " + errorNr + " parsing the xml input file\n\n" + msg + super.getMessage();
+    @Override
+	public String getMessage() {
+        String msg = "\nError " + errorNr + " parsing the xml input file\n\n" + this.msg + super.getMessage();
         if (_node == null) {
-            return "NULL NODE\n" + sMsg;
+            return "NULL NODE\n" + msg;
         }
         String path = "";
         Node node = _node;
         while (node != null && node.getNodeType() == Node.ELEMENT_NODE) {
-            String sID;
-            sID = getAttribute(node, "id");
-            if (sID != null) {
-                sID = " id='" + sID + "'";
+            String id;
+            id = getAttribute(node, "id");
+            if (id != null) {
+                id = " id='" + id + "'";
             } else {
-                sID = "";
+                id = "";
             }
 
-            String sName;
-            sName = getAttribute(node, "name");
-            if (sName != null) {
-                sName = " name='" + sName + "'";
+            String name;
+            name = getAttribute(node, "name");
+            if (name != null) {
+                name = " name='" + name + "'";
             } else {
-                sName = "";
+                name = "";
             }
 
-            String sSpec;
-            sSpec = getAttribute(node, "spec");
-            if (sSpec != null) {
-                sSpec = " spec='" + sSpec + "'";
+            String spec;
+            spec = getAttribute(node, "spec");
+            if (spec != null) {
+                spec = " spec='" + spec + "'";
             } else {
-                sSpec = "";
+                spec = "";
             }
             path = path.replaceAll("  <", "      <");
-            path = "  <" + node.getNodeName() + sID + sName + sSpec + ">\n" + path;
+            path = "  <" + node.getNodeName() + id + name + spec + ">\n" + path;
             node = node.getParentNode();
         }
-        sMsg += "\n\nError detected about here:\n" + path;
-        return sMsg;
+        msg += "\n\nError detected about here:\n" + path;
+        return msg;
     } // getMessage
 
-    String getAttribute(Node node, String sTarget) {
+    String getAttribute(Node node, String target) {
         NamedNodeMap atts = node.getAttributes();
         if (atts == null) {
             return null;
         }
         for (int i = 0; i < atts.getLength(); i++) {
-            String sName = atts.item(i).getNodeName();
-            if (sName.equals(sTarget)) {
-                String sValue = atts.item(i).getNodeValue();
-                return sValue;
+            String name = atts.item(i).getNodeName();
+            if (name.equals(target)) {
+                String valueString = atts.item(i).getNodeValue();
+                return valueString;
             }
         }
         return null;
     } // getID
 
+	public String getOriginalMessage() {
+		return super.getMessage();
+	}
+
 } // XMLParserException
diff --git a/src/beast/util/XMLParserUtils.java b/src/beast/util/XMLParserUtils.java
index 9646e7c..6bd272a 100644
--- a/src/beast/util/XMLParserUtils.java
+++ b/src/beast/util/XMLParserUtils.java
@@ -1,12 +1,10 @@
 package beast.util;
 
-import org.w3c.dom.*;
-
-import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl;
-
-import beast.core.util.Log;
-
 import java.io.File;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -17,6 +15,20 @@ import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.sun.org.apache.xerces.internal.dom.CoreDocumentImpl;
+
+import beast.core.BEASTInterface;
+import beast.core.Input;
+import beast.core.InputForAnnotatedConstructor;
+import beast.core.Param;
+
 /**
  *
  * Provides basic functions for variable substitution and plates.
@@ -25,6 +37,9 @@ import javax.xml.transform.stream.StreamResult;
  * @author Alexei Drummond
  */
 public class XMLParserUtils {
+	
+	final static public List<String> beastObjectNames = AddOnManager.find(beast.core.BEASTInterface.class, AddOnManager.IMPLEMENTATION_DIR);
+
 
     /**
      * Expand plates in XML by duplicating the containing XML and replacing
@@ -38,8 +53,8 @@ public class XMLParserUtils {
         // created when they are nested
         if (nodes.getLength() > 0) {
             Node node = nodes.item(0);
-            final String sVar = node.getAttributes().getNamedItem("var").getNodeValue();
-            final String sRange = node.getAttributes().getNamedItem("range").getNodeValue();
+            final String var = node.getAttributes().getNamedItem("var").getNodeValue();
+            final String rangeString = node.getAttributes().getNamedItem("range").getNodeValue();
             
             if (node.getAttributes().getNamedItem("fragment") != null) {
             	final String fragmentID = node.getAttributes().getNamedItem("fragment").getNodeValue();
@@ -52,30 +67,30 @@ public class XMLParserUtils {
             	node = fragment;
            }
 	
-            final String[] sValues = sRange.split(",");
+            final String[] valuesString = rangeString.split(",");
 
             // interpret values in the range of form x:y as all numbers between x and y inclusive
             List<String> vals = new ArrayList<>();
-            for (final String sValue : sValues) {
-                if (sValue.indexOf(":") > 0) {
-                    String[] range = sValue.split(":");
+            for (final String valueString : valuesString) {
+                if (valueString.indexOf(":") > 0) {
+                    String[] range = valueString.split(":");
                     int min = Integer.parseInt(range[0]);
                     int max = Integer.parseInt(range[1]);
                     for (int i = min; i <= max; i++) {
                         vals.add(String.valueOf(i));
                     }
                 } else {
-                    vals.add(sValue);
+                    vals.add(valueString);
                 }
             }
 
             for (final String val : vals) {
                 // copy children
                 final NodeList children = node.getChildNodes();
-                for (int iChild = 0; iChild < children.getLength(); iChild++) {
-                    final Node child = children.item(iChild);
+                for (int childIndex = 0; childIndex < children.getLength(); childIndex++) {
+                    final Node child = children.item(childIndex);
                     final Node newChild = child.cloneNode(true);
-                    replaceVariable(newChild, sVar, val);
+                    replaceVariable(newChild, var, val);
                     node.getParentNode().insertBefore(newChild, node);
                 }
             }
@@ -119,27 +134,27 @@ public class XMLParserUtils {
     
     /**
      * @param node the node to do variable replacement in
-     * @param sVar the variable name to replace
-     * @param sValue the value to replace the variable name with
+     * @param var the variable name to replace
+     * @param valueString the value to replace the variable name with
      */
-    public static void replaceVariable(final Node node, final String sVar, final String sValue) {
+    public static void replaceVariable(final Node node, final String var, final String valueString) {
         switch (node.getNodeType()) {
 	        case Node.ELEMENT_NODE:  {
 	            final Element element = (Element) node;
 	            final NamedNodeMap atts = element.getAttributes();
 	            for (int i = 0; i < atts.getLength(); i++) {
 	                final Attr attr = (Attr) atts.item(i);
-	                if (attr.getValue().contains("$(" + sVar + ")")) {
-	                    String sAtt = attr.getValue();
-	                    sAtt = sAtt.replaceAll("\\$\\(" + sVar + "\\)", sValue);
-	                    attr.setNodeValue(sAtt);
+	                if (attr.getValue().contains("$(" + var + ")")) {
+	                    String att = attr.getValue();
+	                    att = att.replaceAll("\\$\\(" + var + "\\)", valueString);
+	                    attr.setNodeValue(att);
 	                }
 	            }
 	        }
 	        case Node.CDATA_SECTION_NODE: {
 	        	String content = node.getTextContent();
-	        	if (content.contains("$(" + sVar + ")")) {
-	        		content = content.replaceAll("\\$\\(" + sVar + "\\)", sValue);
+	        	if (content.contains("$(" + var + ")")) {
+	        		content = content.replaceAll("\\$\\(" + var + "\\)", valueString);
 	        		node.setNodeValue(content);
 	        	}
 	        }
@@ -147,12 +162,193 @@ public class XMLParserUtils {
 
         // process children
         final NodeList children = node.getChildNodes();
-        for (int iChild = 0; iChild < children.getLength(); iChild++) {
-            final Node child = children.item(iChild);
-            replaceVariable(child, sVar, sValue);
+        for (int childIndex = 0; childIndex < children.getLength(); childIndex++) {
+            final Node child = children.item(childIndex);
+            replaceVariable(child, var, valueString);
         }
     } // replace
 
+    
+    /** return list of input types specified by Inputs or Param annotations 
+     * @param clazz Class to generate the list for
+     * @param beastObject instantiation of the class, or null if not available
+     * @return
+     * @throws InstantiationException
+     * @throws IllegalAccessException
+     * @throws SecurityException 
+     * @throws NoSuchMethodException 
+     * @throws IllegalArgumentException 
+     */
+	public static List<InputType> listInputs(Class<?> clazz, BEASTInterface beastObject) throws InstantiationException , IllegalAccessException, IllegalArgumentException, NoSuchMethodException, SecurityException {
+		List<InputType> inputTypes = new ArrayList<>();
+
+		// First, collect Input members
+		try {
+			if (beastObject == null) {
+				beastObject = (BEASTInterface) clazz.newInstance();
+			}
+			List<Input<?>> inputs = null;
+			inputs = beastObject.listInputs();
+			for (Input<?> input : inputs) {
+				if (!(input instanceof InputForAnnotatedConstructor)) {
+					try {
+						// force class types to be determined
+						if (input.getType() == null) {
+							input.determineClass(beastObject);
+						}
+						inputTypes.add(new InputType(input.getName(), input.getType(), true, input.defaultValue));
+					} catch (Exception e) {
+						// seems safe to ignore
+						e.printStackTrace();
+					}
+				}
+			}
+		} catch (InstantiationException e) {
+			// this can happen if there is no constructor without arguments, 
+			// e.g. when there are annotated constructors only
+		}
+
+				
+		// Second, collect types of annotated constructor
+	    Constructor<?>[] allConstructors = clazz.getDeclaredConstructors();
+	    for (Constructor<?> ctor : allConstructors) {
+	    	Annotation[][] annotations = ctor.getParameterAnnotations();
+	    	List<Param> paramAnnotations = new ArrayList<>();
+	    	for (Annotation [] a0 : annotations) {
+		    	for (Annotation a : a0) {
+		    		if (a instanceof Param) {
+		    			paramAnnotations.add((Param) a);
+		    		}
+		    	}
+	    	}
+	    	Class<?>[] types  = ctor.getParameterTypes();	    	
+    		Type[] gtypes = ctor.getGenericParameterTypes();
+	    	if (types.length > 0 && paramAnnotations.size() > 0) {
+	    		int offset = 0;
+	    		if (types.length == paramAnnotations.size() + 1) {
+	    			offset = 1;
+	    		}
+	    		for (int i = 0; i < paramAnnotations.size(); i++) {
+	    			Param param = paramAnnotations.get(i);
+	    			Type type = types[i + offset];
+	    			Class<?> clazz2 = null;
+					try {
+						clazz2 = Class.forName(type.getTypeName());
+					} catch (ClassNotFoundException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+	    			if (clazz2.isAssignableFrom(List.class)) {
+                        Type[] genericTypes2 = ((ParameterizedType) gtypes[i + offset]).getActualTypeArguments();
+                        Class<?> theClass = (Class<?>) genericTypes2[0];
+	    				InputType t = new InputType(param.name(), theClass, false, param.defaultValue());
+	    				inputTypes.add(t);
+	    			} else {
+	    				InputType t = new InputType(param.name(), types[i + offset], false, param.defaultValue());
+	    				inputTypes.add(t);
+	    			}
+	    		}
+	    	}
+		}
+		
+		return inputTypes;
+	}
+
+//	/** get value of the input of a beast object with name specified in input **/
+//    static Object getValue(BEASTInterface beastObject, InputType input) {
+//    	if (input.isInput()) {
+//    		// input represents simple Input
+//    		return beastObject.getInput(input.getName()).get();
+//    	} else {
+//    		// input represents Param annotation
+//    		String methodName = "get" + 
+//    		    	input.getName().substring(0, 1).toUpperCase() +
+//    		    	input.getName().substring(1);
+//    		Method method;
+//			try {
+//				method = beastObject.getClass().getMethod(methodName);
+//				return method.invoke(beastObject);
+//			} catch (NoSuchMethodException | SecurityException |IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+//				Log.err.println("Programmer error: when getting here an InputType was identified, but no Input or getter for Param annotation found");
+//				e.printStackTrace();
+//				return null;
+//			}
+//    	}
+//	}
+
 
+    /**
+     * find closest matching class to named class *
+     */
+    static String guessClass(final String classname) {
+        String name = classname;
+        if (classname.contains(".")) {
+            name = classname.substring(classname.lastIndexOf('.') + 1);
+        }
+        int bestDistance = Integer.MAX_VALUE;
+        String closestName = null;
+        for (final String beastObject : beastObjectNames) {
+            final String classname2 = beastObject.substring(beastObject.lastIndexOf('.') + 1);
+            final int distance = getLevenshteinDistance(name, classname2);
+
+
+            if (distance < bestDistance) {
+                bestDistance = distance;
+                closestName = beastObject;
+            }
+        }
+        return closestName;
+    }
+    
+    
+    /**
+     * Compute edit distance between two strings = Levenshtein distance *
+     */
+    public static int getLevenshteinDistance(final String s, final String t) {
+        if (s == null || t == null) {
+            throw new IllegalArgumentException("Strings must not be null");
+        }
+
+        final int n = s.length(); // length of s
+        final int m = t.length(); // length of t
+
+        if (n == 0) {
+            return m;
+        } else if (m == 0) {
+            return n;
+        }
+
+        int p[] = new int[n + 1]; //'previous' cost array, horizontally
+        int d[] = new int[n + 1]; // cost array, horizontally
+        int _d[]; //placeholder to assist in swapping p and d
+
+        // indexes into strings s and t
+        int i; // iterates through s
+        int j; // iterates through t
+        char t_j; // jth character of t
+        int cost; // cost
+        for (i = 0; i <= n; i++) {
+            p[i] = i;
+        }
+        for (j = 1; j <= m; j++) {
+            t_j = t.charAt(j - 1);
+            d[0] = j;
+            for (i = 1; i <= n; i++) {
+                cost = s.charAt(i - 1) == t_j ? 0 : 1;
+                // minimum of cell to the left+1, to the top+1, diagonally left and up +cost
+                d[i] = Math.min(Math.min(d[i - 1] + 1, p[i] + 1), p[i - 1] + cost);
+            }
+            // copy current distance counts to 'previous row' distance counts
+            _d = p;
+            p = d;
+            d = _d;
+        }
+
+        // our last action in the above loop was to switch d and p, so p now
+        // actually has the most recent cost counts
+        return p[n];
+    }
 
 }
+
+
diff --git a/src/beast/util/XMLProducer.java b/src/beast/util/XMLProducer.java
index a3cc5c4..4d77783 100644
--- a/src/beast/util/XMLProducer.java
+++ b/src/beast/util/XMLProducer.java
@@ -27,24 +27,37 @@ package beast.util;
 
 
 
-import beast.core.BEASTInterface;
-import beast.core.Input;
-
-import org.w3c.dom.*;
-import org.xml.sax.InputSource;
+import java.io.IOException;
+import java.io.Reader;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.transform.Transformer;
 import javax.xml.transform.TransformerException;
 import javax.xml.transform.TransformerFactory;
 import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
 
-import java.io.Reader;
-import java.io.StringReader;
-import java.io.StringWriter;
-import java.lang.reflect.Field;
-import java.util.*;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import beast.core.BEASTInterface;
+import beast.core.Input;
 
 /**
  * converts MCMC plug in into XML, i.e. does the reverse of XMLParser
@@ -55,8 +68,8 @@ public class XMLProducer extends XMLParser {
      * list of objects already converted to XML, so an idref suffices
      */
     HashSet<BEASTInterface> isDone;
-    @SuppressWarnings("rawtypes")
-    HashSet<Input> inputsDone;
+    Map<BEASTInterface, Set<String>> isInputsDone;
+
     /**
      * list of IDs of elements produces, used to prevent duplicate ID generation
      */
@@ -76,14 +89,13 @@ public class XMLProducer extends XMLParser {
     /**
      * Main entry point for this class
      * Given a plug-in, produces the XML in BEAST 2.0 format
-     * representing the plug-in. This assumes plugin is Runnable
+     * representing the plug-in. This assumes beast object is Runnable
      */
-    @SuppressWarnings("rawtypes")
-    public String toXML(BEASTInterface plugin) {
-        return toXML(plugin, new ArrayList<BEASTInterface>());
+    public String toXML(BEASTInterface beastObject) {
+        return toXML(beastObject, new ArrayList<>());
     }
 
-    public String toXML(BEASTInterface plugin, Collection<BEASTInterface> others) {
+    public String toXML(BEASTInterface beastObject, Collection<BEASTInterface> others) {
         try {
             StringBuffer buf = new StringBuffer();
             buf.append("<" + XMLParser.BEAST_ELEMENT + " version='2.0' namespace='" + DEFAULT_NAMESPACE + "'>\n");
@@ -93,60 +105,60 @@ public class XMLProducer extends XMLParser {
             	}
             }
             buf.append("\n\n");
-            isDone = new HashSet<BEASTInterface>();
-            inputsDone = new HashSet<Input>();
-            IDs = new HashSet<String>();
+            isDone = new HashSet<>();
+            isInputsDone = new HashMap<>();
+            IDs = new HashSet<>();
             indent = 0;
-            pluginToXML(plugin, buf, null, true);
-            String sEndBeast = "</" + XMLParser.BEAST_ELEMENT + ">";
-            buf.append(sEndBeast);
+            beastObjectToXML(beastObject, buf, null, true);
+            String endBeastString = "</" + XMLParser.BEAST_ELEMENT + ">";
+            buf.append(endBeastString);
             //return buf.toString();
             // beautify XML hierarchy
-            String sXML = cleanUpXML(buf.toString(), m_sXMLBeuatifyXSL);
+            String xml = cleanUpXML(buf.toString(), m_sXMLBeuatifyXSL);
             // TODO: fix m_sIDRefReplacementXSL script to deal with nested taxon sets
-            // String sXML2 = cleanUpXML(sXML, m_sIDRefReplacementXSL);
-            String sXML2 = sXML;
-            sXML = findPlates(sXML2);
+            // String xml2 = cleanUpXML(xml, m_sIDRefReplacementXSL);
+            String xml2 = xml;
+            xml = findPlates(xml2);
             // beatify by applying name spaces to spec attributes
-            String[] sNameSpaces = DEFAULT_NAMESPACE.split(":");
-            for (String sNameSpace : sNameSpaces) {
-                sXML = sXML.replaceAll("spec=\"" + sNameSpace + ".", "spec=\"");
+            String[] nameSpaces = DEFAULT_NAMESPACE.split(":");
+            for (String nameSpace : nameSpaces) {
+                xml = xml.replaceAll("spec=\"" + nameSpace + ".", "spec=\"");
             }
 
 
             buf = new StringBuffer();
             if (others.size() > 0) {
-                for (BEASTInterface plugin2 : others) {
-                    if (!IDs.contains(plugin2.getID())) {
-                        pluginToXML(plugin2, buf, null, false);
+                for (BEASTInterface beastObject2 : others) {
+                    if (!IDs.contains(beastObject2.getID())) {
+                        beastObjectToXML(beastObject2, buf, null, false);
                     }
                 }
             }
-            int iEnd = sXML.indexOf(sEndBeast);
+            int endIndex = xml.indexOf(endBeastString);
             String extras = buf.toString();
             // prevent double -- inside XML comment, this can happen in sequences
             extras = extras.replaceAll("--","- - ");
-            sXML = sXML.substring(0, iEnd) //+ "\n\n<!-- " + DO_NOT_EDIT_WARNING + " \n\n" + 
+            xml = xml.substring(0, endIndex) //+ "\n\n<!-- " + DO_NOT_EDIT_WARNING + " \n\n" + 
             	//extras +  "\n\n-->\n\n" 
-            		+ sEndBeast;
+            		+ endBeastString;
 
-            sXML = sXML.replaceAll("xmlns=\"http://www.w3.org/TR/xhtml1/strict\"", "");
+            xml = xml.replaceAll("xmlns=\"http://www.w3.org/TR/xhtml1/strict\"", "");
             
-            sXML = dedupName(sXML);
-            sXML = sortTags(sXML);
+            xml = dedupName(xml);
+            xml = sortTags(xml);
             
 
             //insert newlines in alignments
-            int k = sXML.indexOf("<data ");
-            StringBuffer buf2 = new StringBuffer(sXML); 
+            int k = xml.indexOf("<data ");
+            StringBuffer buf2 = new StringBuffer(xml); 
             while (k > 0) {
-            	while (sXML.charAt(k) != '>') {
-            		if (sXML.charAt(k) == ' ' && !sXML.startsWith("idref", k+1)) {
+            	while (xml.charAt(k) != '>') {
+            		if (xml.charAt(k) == ' ' && !xml.startsWith("idref", k+1)) {
             			buf2.setCharAt(k, '\n');
             		}
             		k++;
             	}
-            	k = sXML.indexOf("<data ", k + 1);
+            	k = xml.indexOf("<data ", k + 1);
             }
             
 
@@ -158,9 +170,9 @@ public class XMLProducer extends XMLParser {
     } // toXML
 
     // ensure attributes are ordered so that id goes first, then spec, then remainder of attributes
-    private String sortTags(String sXML) {
-    	//if (true) return sXML;
-    	String [] strs = sXML.split("<");
+    private String sortTags(String xml) {
+    	//if (true) return xml;
+    	String [] strs = xml.split("<");
     	StringBuilder bf = new StringBuilder();
     	bf.append(strs[0]);
     	for (int i = 1; i < strs.length; i++) {
@@ -174,27 +186,27 @@ public class XMLProducer extends XMLParser {
     			}
     		}
    			String [] strs2 = split(ss[0]);
-   			int iSpec = 0;
-   			while (iSpec < strs2.length && !strs2[iSpec].startsWith("spec=")) {
-   				iSpec++;
+   			int spec = 0;
+   			while (spec < strs2.length && !strs2[spec].startsWith("spec=")) {
+   				spec++;
    			}
-   			int iID = 0;
-   			while (iID < strs2.length && !strs2[iID].startsWith("id=")) {
-   				iID++;
+   			int iD = 0;
+   			while (iD < strs2.length && !strs2[iD].startsWith("id=")) {
+   				iD++;
    			}
 			bf.append('<');
 			if (strs2[0] != null)
 				bf.append(strs2[0]);
-			if (iID < strs2.length) {
+			if (iD < strs2.length) {
 				bf.append(' ');
-				bf.append(strs2[iID]);
+				bf.append(strs2[iD]);
 			}
-			if (iSpec < strs2.length) {
+			if (spec < strs2.length) {
 				bf.append(' ');
-				bf.append(strs2[iSpec]);
+				bf.append(strs2[spec]);
 			}
 			for (int j = 1; j < strs2.length; j++) {
-				if (j != iID && j != iSpec) {
+				if (j != iD && j != spec) {
 	    			bf.append(' ');
 	    			if (strs2[j] != null)
 	    				bf.append(strs2[j]);
@@ -240,44 +252,44 @@ public class XMLProducer extends XMLParser {
     	return s.toArray(new String []{});
     }
 
-	String dedupName(String sXML) {
+	String dedupName(String xml) {
         // replace <$x name="$y" idref="$z"/> and <$x idref="$z" name="$y"/> 
         // with <$y idref="$z"/>
         StringBuilder sb = new StringBuilder();
         int i = -1;
-        while (++i < sXML.length()) {
-        	char c = sXML.charAt(i);
+        while (++i < xml.length()) {
+        	char c = xml.charAt(i);
         	if (c == '<') {
                 StringBuilder tag = new StringBuilder();
         		tag.append(c);
-        		while (((c = sXML.charAt(++i)) != ' ') && (c != '/') && c != '>') {
+        		while (((c = xml.charAt(++i)) != ' ') && (c != '/') && c != '>') {
         			tag.append(c);
         		}
         		if (c != '/' && c != '>') {
                     StringBuilder tag2 = new StringBuilder();
-            		while ((c = sXML.charAt(++i)) != '=') {
+            		while ((c = xml.charAt(++i)) != '=') {
             			tag2.append(c);
             		}
             		if (tag2.toString().equals("name")) {
                         ++i;
                         StringBuilder value2 = new StringBuilder();
-                		while ((c = sXML.charAt(++i)) != '"') {
+                		while ((c = xml.charAt(++i)) != '"') {
                 			value2.append(c);
                 		}
                         StringBuilder tag3 = new StringBuilder();
-                    	c = sXML.charAt(++i);
+                    	c = xml.charAt(++i);
                         if (c != '>') {
                             if (c == '/') {
                         		tag3.append(c);
                             }
-                        	while (((c = sXML.charAt(++i)) != '=') && (c != '/') && (c != '>')) {
+                        	while (((c = xml.charAt(++i)) != '=') && (c != '/') && (c != '>')) {
                         		tag3.append(c);
                         	}
                         }
                 		if (c != '/' && c != '>' && tag3.toString().equals("idref")) {
                 			tag3.append(c);
-                			tag3.append(sXML.charAt(++i));
-                    		while ((c = sXML.charAt(++i)) != '"') {
+                			tag3.append(xml.charAt(++i));
+                    		while ((c = xml.charAt(++i)) != '"') {
                     			tag3.append(c);
                     		}
                     		sb.append('<');
@@ -285,7 +297,7 @@ public class XMLProducer extends XMLParser {
                     		sb.append('=');
                     		sb.append(tag3);
                     		sb.append("/>");
-                    		while ((c = sXML.charAt(++i)) != '>') {}
+                    		while ((c = xml.charAt(++i)) != '>') {}
                 		} else {
                 			sb.append(tag);
                 			sb.append(' ');
@@ -299,19 +311,19 @@ public class XMLProducer extends XMLParser {
                 		}
             		} else if (tag2.toString().equals("idref")) {
             			tag2.append(c);
-            			tag2.append(sXML.charAt(++i));
-                		while (((c = sXML.charAt(++i)) != ' ') && (c != '/') && c != '>') {
+            			tag2.append(xml.charAt(++i));
+                		while (((c = xml.charAt(++i)) != ' ') && (c != '/') && c != '>') {
                 			tag2.append(c);
                 		}
                 		if (c != '/' && c != '>') {
                             StringBuilder tag3 = new StringBuilder();
-                    		while ((c = sXML.charAt(++i)) != '=') {
+                    		while ((c = xml.charAt(++i)) != '=') {
                     			tag3.append(c);
                     		}
                     		if (tag3.toString().equals("name")) {
                                 ++i;
                                 StringBuilder value2 = new StringBuilder();
-                        		while ((c = sXML.charAt(++i)) != '"') {
+                        		while ((c = xml.charAt(++i)) != '"') {
                         			value2.append(c);
                         		}
                         		sb.append('<');
@@ -319,7 +331,7 @@ public class XMLProducer extends XMLParser {
                         		sb.append(' ');
                         		sb.append(tag2);
                         		sb.append("/>");
-                        		while ((c = sXML.charAt(++i)) != '>') {}
+                        		while ((c = xml.charAt(++i)) != '>') {}
                     		} else {
                     			sb.append(tag);
                     			sb.append(' ');
@@ -352,19 +364,19 @@ public class XMLProducer extends XMLParser {
 	}
 
 	/**
-     * like toXML() but without the assumption that plugin is Runnable *
+     * like toXML() but without the assumption that beast object is Runnable *
      */
-    public String modelToXML(BEASTInterface plugin) {
+    public String modelToXML(BEASTInterface beastObject) {
         try {
-            String sXML0 = toRawXML(plugin);
-            String sXML = cleanUpXML(sXML0, m_sSupressAlignmentXSL);
+            String xML0 = toRawXML(beastObject);
+            String xml = cleanUpXML(xML0, m_sSupressAlignmentXSL);
             // TODO: fix m_sIDRefReplacementXSL script to deal with nested taxon sets
-            //String sXML2 = cleanUpXML(sXML, m_sIDRefReplacementXSL);
-            String sXML2 = sXML;
-            sXML = findPlates(sXML2);
-            sXML = sXML.replaceAll("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>", "");
-            sXML = sXML.replaceAll("\\n\\s*\\n", "\n");
-            return sXML;
+            //String xml2 = cleanUpXML(xml, m_sIDRefReplacementXSL);
+            String xml2 = xml;
+            xml = findPlates(xml2);
+            xml = xml.replaceAll("<\\?xml version=\"1.0\" encoding=\"UTF-8\"\\?>", "");
+            xml = xml.replaceAll("\\n\\s*\\n", "\n");
+            return xml;
         } catch (Exception e) {
             e.printStackTrace();
             return null;
@@ -374,24 +386,22 @@ public class XMLProducer extends XMLParser {
     /**
      * like modelToXML, but without the cleanup *
      */
-    @SuppressWarnings("rawtypes")
-    public String toRawXML(BEASTInterface plugin) {
-        return toRawXML(plugin, null);
+    public String toRawXML(BEASTInterface beastObject) {
+        return toRawXML(beastObject, null);
     } // toRawXML
 
     /**
      * like modelToXML, but without the cleanup *
-     * For plugin without name
+     * For beast object without name
      */
-    @SuppressWarnings("rawtypes")
-    public String toRawXML(BEASTInterface plugin, String sName) {
+    public String toRawXML(BEASTInterface beastObject, String name) {
         try {
             StringBuffer buf = new StringBuffer();
-            isDone = new HashSet<BEASTInterface>();
-            inputsDone = new HashSet<Input>();
-            IDs = new HashSet<String>();
+            isDone = new HashSet<>();
+            isInputsDone = new HashMap<>();
+            IDs = new HashSet<>();
             indent = 0;
-            pluginToXML(plugin, buf, sName, false);
+            beastObjectToXML(beastObject, buf, name, false);
             return buf.toString();
         } catch (Exception e) {
             e.printStackTrace();
@@ -401,14 +411,14 @@ public class XMLProducer extends XMLParser {
 
 
 
-    public String stateNodeToXML(BEASTInterface plugin) {
+    public String stateNodeToXML(BEASTInterface beastObject) {
         try {
             StringBuffer buf = new StringBuffer();
             //buf.append("<" + XMLParser.BEAST_ELEMENT + " version='2.0'>\n");
-            isDone = new HashSet<BEASTInterface>();
-            IDs = new HashSet<String>();
+            isDone = new HashSet<>();
+            IDs = new HashSet<>();
             indent = 0;
-            pluginToXML(plugin, buf, null, false);
+            beastObjectToXML(beastObject, buf, null, false);
             return buf.toString();
         } catch (Exception e) {
             e.printStackTrace();
@@ -422,12 +432,12 @@ public class XMLProducer extends XMLParser {
      * outside MCMC element.
      * Tries to compress common parts into plates.
      */
-    String cleanUpXML(String sXML, String sXSL) throws TransformerException {
+    String cleanUpXML(String xml, String xsl) throws TransformerException {
         StringWriter strWriter = new StringWriter();
-        Reader xmlInput = new StringReader(sXML);
+        Reader xmlInput = new StringReader(xml);
         javax.xml.transform.Source xmlSource =
                 new javax.xml.transform.stream.StreamSource(xmlInput);
-        Reader xslInput = new StringReader(sXSL);
+        Reader xslInput = new StringReader(xsl);
         javax.xml.transform.Source xsltSource =
                 new javax.xml.transform.stream.StreamSource(xslInput);
         javax.xml.transform.Result result =
@@ -437,14 +447,14 @@ public class XMLProducer extends XMLParser {
         javax.xml.transform.Transformer trans = transFact.newTransformer(xsltSource);
         trans.transform(xmlSource, result);
 
-        String sXML2 = strWriter.toString();
-        return sXML2;
+        String xml2 = strWriter.toString();
+        return xml2;
     }
 
     // compress parts into plates
-    String findPlates(String sXML) throws Exception {
+    String findPlates(String xml) throws SAXException, IOException, ParserConfigurationException, TransformerException  {
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
-        doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(sXML)));
+        doc = factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml)));
         doc.normalize();
 
         Node topNode = doc.getElementsByTagName("*").item(0);
@@ -466,80 +476,79 @@ public class XMLProducer extends XMLParser {
      */
     void findPlates(Node node) {
         NodeList children = node.getChildNodes();
-        for (int iChild = 0; iChild < children.getLength(); iChild++) {
-            Node child = children.item(iChild);
+        for (int childIndex = 0; childIndex < children.getLength(); childIndex++) {
+            Node child = children.item(childIndex);
             if (child.getNodeType() == Node.ELEMENT_NODE) {
-                List<Node> comparables = new ArrayList<Node>();
-                for (int iSibling = iChild + 1; iSibling < children.getLength(); iSibling++) {
-                    if (children.item(iSibling).getNodeType() == Node.ELEMENT_NODE) {
-                        Node sibling = children.item(iSibling);
+                List<Node> comparables = new ArrayList<>();
+                for (int siblingNr = childIndex + 1; siblingNr < children.getLength(); siblingNr++) {
+                    if (children.item(siblingNr).getNodeType() == Node.ELEMENT_NODE) {
+                        Node sibling = children.item(siblingNr);
                         if (comparable(child, sibling, ".p1", ".p" + (comparables.size() + 2))) {
                             comparables.add(sibling);
                         } else {
                             // break
-                            iSibling = children.getLength();
+                            siblingNr = children.getLength();
                         }
                     }
                 }
                 if (comparables.size() > 0) {
                 	// TODO: FIX THIS SO THAT NOT AN ARBITRARY `1' is used to generate the plate
                     // we can make a plate now
-//                    String sRange = "1";
+//                    String rangeString = "1";
 //                    int k = 2;
 //                    for (Node sibling : comparables) {
-//                        sRange += "," + k++;
+//                        rangeString += "," + k++;
 //                        sibling.getParentNode().removeChild(sibling);
 //                    }
-//                    makePlate(child, "1", "n", sRange);
+//                    makePlate(child, "1", "n", rangeString);
                 }
             }
         }
         // recurse to lower levels
         children = node.getChildNodes();
-        for (int iChild = 0; iChild < children.getLength(); iChild++) {
-            findPlates(children.item(iChild));
+        for (int childIndex = 0; childIndex < children.getLength(); childIndex++) {
+            findPlates(children.item(childIndex));
         }
     } // findPlates
 
     /**
-     * replace node element by a plate element with variable sVar and range sRange *
+     * replace node element by a plate element with variable var and range rangeString *
      */
-    void makePlate(Node node, String sPattern, String sVar, String sRange) {
+    void makePlate(Node node, String pattern, String var, String rangeString) {
         Element plate = doc.createElement("plate");
-        plate.setAttribute("var", sVar);
-        plate.setAttribute("range", sRange);
-        String sIndent = node.getPreviousSibling().getTextContent();
-        replace(node, sPattern, sVar);
+        plate.setAttribute("var", var);
+        plate.setAttribute("range", rangeString);
+        String indent = node.getPreviousSibling().getTextContent();
+        replace(node, pattern, var);
         node.getParentNode().replaceChild(plate, node);
-        plate.appendChild(doc.createTextNode(sIndent + "  "));
+        plate.appendChild(doc.createTextNode(indent + "  "));
         plate.appendChild(node);
-        plate.appendChild(doc.createTextNode(sIndent));
+        plate.appendChild(doc.createTextNode(indent));
     }
 
     /**
-     * recursively replace all attribute values containing the pattern with variable sVar *
+     * recursively replace all attribute values containing the pattern with variable var *
      */
-    void replace(Node node, String sPattern, String sVar) {
+    void replace(Node node, String pattern, String var) {
         NamedNodeMap atts = node.getAttributes();
         if (atts != null) {
             for (int i = 0; i < atts.getLength(); i++) {
                 Attr attr = (Attr) atts.item(i);
-                String sValue = attr.getValue().replaceAll(sPattern, "\\$\\(" + sVar + "\\)");
-                ;
-                attr.setValue(sValue);
+                String valueString = attr.getValue().replaceAll(pattern, "\\$\\(" + var + "\\)");
+                attr.setValue(valueString);
             }
         }
         NodeList children = node.getChildNodes();
-        for (int iChild = 0; iChild < children.getLength(); iChild++) {
-            Node child = children.item(iChild);
-            replace(child, sPattern, sVar);
+        for (int childIndex = 0; childIndex < children.getLength(); childIndex++) {
+            Node child = children.item(childIndex);
+            replace(child, pattern, var);
         }
     }
 
     /**
-     * check if two XML nodes are the same, when sPattern1 is replaced by sPattothersern2 *
+     * check if two XML nodes are the same, when pattern1 is replaced by pattothersern2 *
      */
-    boolean comparable(Node node1, Node node2, String sPattern1, String sPattern2) {
+    boolean comparable(Node node1, Node node2, String pattern1, String pattern2) {
         // compare name
         if (!node1.getNodeName().equals(node2.getNodeName())) {
             return false;
@@ -556,17 +565,17 @@ public class XMLProducer extends XMLParser {
         }
         for (int i = 0; i < atts.getLength(); i++) {
             Attr attr = (Attr) atts.item(i);
-            String sName = attr.getName();
-            String sValue = attr.getValue();
-            Node att = atts2.getNamedItem(sName);
+            String name = attr.getName();
+            String valueString = attr.getValue();
+            Node att = atts2.getNamedItem(name);
             if (att == null) {
                 return false;
             }
-            String sValue2 = ((Attr) att).getValue();
-            if (!sValue.equals(sValue2)) {
-                sValue = sValue.replaceAll(sPattern1, "\\$\\(n\\)");
-                sValue2 = sValue2.replaceAll(sPattern2, "\\$\\(n\\)");
-                if (!sValue.equals(sValue2)) {
+            String valueString2 = ((Attr) att).getValue();
+            if (!valueString.equals(valueString2)) {
+                valueString = valueString.replaceAll(pattern1, "\\$\\(n\\)");
+                valueString2 = valueString2.replaceAll(pattern2, "\\$\\(n\\)");
+                if (!valueString.equals(valueString2)) {
                     return false;
                 }
             }
@@ -574,18 +583,18 @@ public class XMLProducer extends XMLParser {
         // compare children
         NodeList children = node1.getChildNodes();
         NodeList children2 = node2.getChildNodes();
-        for (int iChild = 0; iChild < children.getLength(); iChild++) {
-            Node child = children.item(iChild);
+        for (int childIndex = 0; childIndex < children.getLength(); childIndex++) {
+            Node child = children.item(childIndex);
             if (child.getNodeType() == Node.ELEMENT_NODE) {
-                String sName = child.getNodeName();
-                boolean bMatch = false;
-                for (int iChild2 = 0; !bMatch && iChild2 < children2.getLength(); iChild2++) {
-                    Node child2 = children2.item(iChild2);
-                    if (child2.getNodeType() == Node.ELEMENT_NODE && sName.equals(child2.getNodeName())) {
-                        bMatch = comparable(child, child2, sPattern1, sPattern2);
+                String name = child.getNodeName();
+                boolean isMatch = false;
+                for (int childIndex2 = 0; !isMatch && childIndex2 < children2.getLength(); childIndex2++) {
+                    Node child2 = children2.item(childIndex2);
+                    if (child2.getNodeType() == Node.ELEMENT_NODE && name.equals(child2.getNodeName())) {
+                        isMatch = comparable(child, child2, pattern1, pattern2);
                     }
                 }
-                if (!bMatch) {
+                if (!isMatch) {
                     return false;
                 }
             }
@@ -765,49 +774,50 @@ public class XMLProducer extends XMLParser {
             "</xsl:stylesheet>\n";
 
     /**
-     * produce elements for a plugin with name sName, putting results in buf.
+     * produce elements for a beast object with name name, putting results in buf.
      * It tries to create XML conforming to the XML transformation rules (see XMLParser)
      * that is moderately readable.
+     * @throws ClassNotFoundException 
      */
     @SuppressWarnings("rawtypes")
-    void pluginToXML(BEASTInterface plugin, StringBuffer buf, String sName, boolean bIsTopLevel) throws Exception {
+    void beastObjectToXML(BEASTInterface beastObject, StringBuffer buf, String name, boolean isTopLevel) throws ClassNotFoundException {
         // determine element name, default is input, otherswise find one of the defaults
-        String sElementName = "input";
+        String elementName = "input";
         for (String key : element2ClassMap.keySet()) {
         	String className = element2ClassMap.get(key);
         	Class _class = Class.forName(className);
-        	if (_class.equals(plugin.getClass())) {
-        		sElementName = key;
+        	if (_class.equals(beastObject.getClass())) {
+        		elementName = key;
         	}
         }
         
-//        if (plugin instanceof Alignment) {
-//            sElementName = XMLParser.DATA_ELEMENT;
+//        if (beastObject instanceof Alignment) {
+//            elementName = XMLParser.DATA_ELEMENT;
 //        }
-//        if (plugin instanceof Sequence) {
-//            sElementName = XMLParser.SEQUENCE_ELEMENT;
+//        if (beastObject instanceof Sequence) {
+//            elementName = XMLParser.SEQUENCE_ELEMENT;
 //        }
-//        if (plugin instanceof State) {
-//            sElementName = XMLParser.STATE_ELEMENT;
+//        if (beastObject instanceof State) {
+//            elementName = XMLParser.STATE_ELEMENT;
 //        }
-//        if (plugin instanceof Distribution) {
-//            sElementName = XMLParser.DISTRIBUTION_ELEMENT;
+//        if (beastObject instanceof Distribution) {
+//            elementName = XMLParser.DISTRIBUTION_ELEMENT;
 //        }
-//        if (plugin instanceof Logger) {
-//            sElementName = XMLParser.LOG_ELEMENT;
+//        if (beastObject instanceof Logger) {
+//            elementName = XMLParser.LOG_ELEMENT;
 //        }
-//        if (plugin instanceof Operator) {
-//            sElementName = XMLParser.OPERATOR_ELEMENT;
+//        if (beastObject instanceof Operator) {
+//            elementName = XMLParser.OPERATOR_ELEMENT;
 //        }
-//        if (plugin instanceof RealParameter) {
-//            sElementName = XMLParser.REAL_PARAMETER_ELEMENT;
+//        if (beastObject instanceof RealParameter) {
+//            elementName = XMLParser.REAL_PARAMETER_ELEMENT;
 //        }
-//        if (plugin instanceof Tree) {
-//            sElementName = XMLParser.TREE_ELEMENT;
+//        if (beastObject instanceof Tree) {
+//            elementName = XMLParser.TREE_ELEMENT;
 //        }
 
-        if (bIsTopLevel) {
-            sElementName = XMLParser.RUN_ELEMENT;
+        if (isTopLevel) {
+            elementName = XMLParser.RUN_ELEMENT;
         }
         for (int i = 0; i < indent; i++) {
             buf.append("    ");
@@ -815,52 +825,54 @@ public class XMLProducer extends XMLParser {
         indent++;
 
         // open element
-        buf.append("<").append(sElementName);
+        buf.append("<").append(elementName);
 
-        boolean bSkipInputs = false;
-        if (isDone.stream().anyMatch(x -> x == plugin)) {
+        boolean skipInputs = false;
+        if (isDone.stream().anyMatch(x -> x == beastObject)) {
             // XML is already produced, we can idref it
-            buf.append(" idref='" + normalise(plugin.getID()) + "'");
-            bSkipInputs = true;
+            buf.append(" idref='" + normalise(beastObject.getID()) + "'");
+            skipInputs = true;
         } else {
             // see whether a reasonable id can be generated
-            if (plugin.getID() != null && !plugin.getID().equals("")) {
-                String sID = plugin.getID();
+            if (beastObject.getID() != null && !beastObject.getID().equals("")) {
+                String id = beastObject.getID();
                 // ensure ID is unique
-                if (IDs.contains(sID)) {
+                if (IDs.contains(id)) {
                     int k = 1;
-                    while (IDs.contains(sID + k)) {
+                    while (IDs.contains(id + k)) {
                         k++;
                     }
-                    sID = sID + k;
+                    id = id + k;
                 }
-                buf.append(" id='" + normalise(sID) + "'");
-                IDs.add(sID);
+                buf.append(" id='" + normalise(id) + "'");
+                IDs.add(id);
             }
-            isDone.add(plugin);
+            isDone.add(beastObject);
         }
-        String sClassName = plugin.getClass().getName();
-        if (bSkipInputs == false && (!element2ClassMap.containsKey(sElementName) ||
-                !element2ClassMap.get(sElementName).equals(sClassName))) {
+        String className = beastObject.getClass().getName();
+        if (skipInputs == false && (!element2ClassMap.containsKey(elementName) ||
+                !element2ClassMap.get(elementName).equals(className))) {
             // only add spec element if it cannot be deduced otherwise (i.e., by idref or default mapping
-            buf.append(" spec='" + sClassName + "'");
+            buf.append(" spec='" + className + "'");
         }
-        if (sName != null && !sName.equals(sElementName)) {
+        if (name != null && !name.equals(elementName)) {
             // only add name element if it differs from element = default name
-            buf.append(" name='" + sName + "'");
+            buf.append(" name='" + name + "'");
         }
 
-        if (!bSkipInputs) {
-            // process inputs of this plugin
+        if (!skipInputs) {
+            // process inputs of this beast object
             // first, collect values as attributes
-            List<Input<?>> sInputs = plugin.listInputs();
-            for (Input sInput : sInputs) {
-                inputToXML(sInput.getName(), plugin, buf, true);
+            List<Input<?>> inputs = beastObject.listInputs();
+            for (Input<?> input : inputs) {
+            	Object value = input.get();
+                inputToXML(input, value, beastObject, buf, true);
             }
             // next, collect values as input elements
             StringBuffer buf2 = new StringBuffer();
-            for (Input sInput : sInputs) {
-                inputToXML(sInput.getName(), plugin, buf2, false);
+            for (Input input : inputs) {
+            	Object value = input.get();
+                inputToXML(input, value, beastObject, buf2, false);
             }
             if (buf2.length() == 0) {
                 // if nothing was added by the inputs, close element
@@ -881,7 +893,7 @@ public class XMLProducer extends XMLParser {
                     indent--;
             	}
                 // add closing element
-                buf.append("</" + sElementName + ">\n");
+                buf.append("</" + elementName + ">\n");
             }
         } else {
             // close element
@@ -895,112 +907,104 @@ public class XMLProducer extends XMLParser {
 
 
     /**
-     * produce XML for an input of a plugin, both as attribute/value pairs for
-     * primitive inputs (if bShort=true) and as individual elements (if bShort=false)
+     * produce XML for an input of a beast object, both as attribute/value pairs for
+     * primitive inputs (if isShort=true) and as individual elements (if isShort=false)
      *
-     * @param sInput: name of the input
-     * @param plugin: plugin to produce this input XML for
+     * @param input: name of the input
+     * @param beastObject: beast object to produce this input XML for
      * @param buf:    gets XML results are appended
      * @param isShort: flag to indicate attribute/value format (true) or element format (false)
-     * @throws Exception
+     * @throws ClassNotFoundException 
      */
-    @SuppressWarnings("rawtypes")
-    void inputToXML(String sInput, BEASTInterface plugin, StringBuffer buf, boolean isShort) throws Exception {
-    	if (sInput.equals("*")) {
+    void inputToXML(Input<?> input, Object value, BEASTInterface beastObject, StringBuffer buf, boolean isShort) throws ClassNotFoundException {
+    	//if (input.getName().equals("*")) {
     		// this can happen with beast.core.parameter.Map
     		// and * is not a valid XML attribute name
-    		return;
-    	}
-    	
-        Field[] fields = plugin.getClass().getFields();
-        for (int i = 0; i < fields.length; i++) {
-            if (fields[i].getType().isAssignableFrom(Input.class)) {
-                Input input = (Input) fields[i].get(plugin);
-                if (input.getName().equals(sInput)) {
-                    // found the input with name sInput
-                    if (input.get() != null) {
-                        if (input.get() instanceof Map) {
-                            // distinguish between List, Plugin and primitive input types
-                        	if (isShort) {
-	                        	Map<String,?> map = (Map<String,?>) input.get();
-	                        	// determine label width
-	                        	int whiteSpaceWidth = 0;
-	                        	List<String> keys = new ArrayList<String>();
-	                        	keys.addAll(map.keySet());
-	                        	Collections.sort(keys);
-	                        	for (String key : keys) {
-	                        		whiteSpaceWidth = Math.max(whiteSpaceWidth, key.length());
-	                        	}
-	                        	for (String key : map.keySet()) {
-                                    //buf.append("        <input name='" + key + "'>");
-                                    buf.append("\n        " + key);
-	                        		for (int k = key.length(); k < whiteSpaceWidth; k++) {
-	                        			buf.append(' ');
-	                        		}
-	                        		buf.append("=\"" + normalise(map.get(key).toString()) + "\"");
-	                        	}
+    		//return;
+    	//}
+        if (value != null) {
+            if (value instanceof Map) {
+                // distinguish between List, Map, BEASTInterface and primitive input types
+            	if (isShort) {
+					@SuppressWarnings("unchecked")
+					Map<String,?> map = (Map<String,?>) value;
+                	// determine label width
+                	int whiteSpaceWidth = 0;
+                	List<String> keys = new ArrayList<>();
+                	keys.addAll(map.keySet());
+                	Collections.sort(keys);
+                	for (String key : keys) {
+                		whiteSpaceWidth = Math.max(whiteSpaceWidth, key.length());
+                	}
+                	for (String key : map.keySet()) {
+                        //buf.append("        <input name='" + key + "'>");
+                        buf.append("\n        " + key);
+                		for (int k = key.length(); k < whiteSpaceWidth; k++) {
+                			buf.append(' ');
+                		}
+                		buf.append("=\"" + normalise(map.get(key).toString()) + "\"");
+                	}
+                }
+            	return;
+            } else if (value instanceof List) {
+                if (!isShort) {
+                	int k = 0;
+                	List<?> list = (List<?>) value;
+                    for (Object o2 : list) {
+                    	if (o2 instanceof BEASTInterface) {
+                    		beastObjectToXML((BEASTInterface) o2, buf, input.getName(), false);
+                    	} else {
+                    		k++;
+                    		buf.append(o2.toString());
+                    		if (k < list.size()) {
+                    			buf.append(' ');
+                    		}
+                    	}
+                    }
+                }
+                return;
+            } else if (value instanceof BEASTInterface) {
+            	if (!value.equals(input.defaultValue)) {
+                    if (isShort && isDone.contains(value)) {
+                        buf.append(" " + input.getName() + "='@" + normalise( ((BEASTInterface) value).getID() ) + "'");
+                        if (!isInputsDone.containsKey(beastObject)) {
+                        	isInputsDone.put(beastObject, new HashSet<>());
+                        }
+                        isInputsDone.get(beastObject).add(input.getName());
+                    }
+                    if (!isShort && (!isInputsDone.containsKey(beastObject) ||
+                    		!isInputsDone.get(beastObject).contains(input.getName()))) {
+                        beastObjectToXML((BEASTInterface) value, buf, input.getName(), false);
+                    }
+            	}
+                return;
+            } else {
+            	if (!value.equals(input.defaultValue)) {
+                    // primitive type
+                    String valueString = value.toString();
+                    if (isShort) {
+                        if (valueString.indexOf('\n') < 0) {
+                            buf.append(" " + input.getName() + "='" + normalise(value.toString()) + "'");
+                        }
+                    } else {
+                        if (valueString.indexOf('\n') >= 0) {
+                            for (int j = 0; j < indent; j++) {
+                                buf.append("    ");
                             }
-                        	return;
-                        } else if (input.get() instanceof List) {
-                            if (!isShort) {
-                            	int k = 0;
-                            	List list = (List) input.get();
-                                for (Object o2 : list) {
-                                	if (o2 instanceof BEASTInterface) {
-                                		pluginToXML((BEASTInterface) o2, buf, sInput, false);
-                                	} else {
-                                		k++;
-                                		buf.append(o2.toString());
-                                		if (k < list.size()) {
-                                			buf.append(' ');
-                                		}
-                                	}
-                                }
+                            if (input.getName().equals("value")) {
+                                buf.append(normalise(value.toString()));
+                            } else {
+                                buf.append("<input name='" + input.getName() + "'>" + normalise(value.toString()) + "</input>\n");
                             }
-                            return;
-                        } else if (input.get() instanceof BEASTInterface) {
-                        	if (!input.get().equals(input.defaultValue)) {
-	                            if (isShort && isDone.contains((BEASTInterface) input.get())) {
-	                                buf.append(" " + sInput + "='@" + normalise( ((BEASTInterface) input.get()).getID() ) + "'");
-	                                inputsDone.add(input);
-	                            }
-	                            if (!isShort && !inputsDone.contains(input)) {
-	                                pluginToXML((BEASTInterface) input.get(), buf, sInput, false);
-	                            }
-                        	}
-                            return;
-                        } else {
-                        	if (!input.get().equals(input.defaultValue)) {
-	                            // primitive type, see if
-	                            String sValue = input.get().toString();
-	                            if (isShort) {
-	                                if (sValue.indexOf('\n') < 0) {
-	                                    buf.append(" " + sInput + "='" + normalise(input.get().toString()) + "'");
-	                                }
-	                            } else {
-	                                if (sValue.indexOf('\n') >= 0) {
-	                                    for (int j = 0; j < indent; j++) {
-	                                        buf.append("    ");
-	                                    }
-	                                    if (sInput.equals("value")) {
-	                                        buf.append(normalise(input.get().toString()));
-	                                    } else {
-	                                        buf.append("<input name='" + sInput + "'>" + normalise(input.get().toString()) + "</input>\n");
-	                                    }
-	                                }
-	                            }
-                        	}
-                            return;
                         }
-                    } else {
-                        // value=null, no XML to produce
-                        return;
                     }
-                }
+            	}
+                return;
             }
+        } else {
+            // value=null, no XML to produce
+            return;
         }
-        // should never get here
-        throw new Exception("Could not find input " + sInput + " in plugin " + plugin.getID() + " " + plugin.getClass().getName());
     } // inputToXML
 
     
diff --git a/src/beast/util/treeparser/Newick.g4 b/src/beast/util/treeparser/Newick.g4
index e14a596..e22a143 100644
--- a/src/beast/util/treeparser/Newick.g4
+++ b/src/beast/util/treeparser/Newick.g4
@@ -30,7 +30,7 @@ fragment NZD : [1-9] ;
 fragment D : [0-9] ;
 
 STRING :
-    [a-zA-Z0-9|*%/.\-+_&]+  // these chars don't need quotes
+    [a-zA-Z0-9|#*%/.\-+_&]+  // these chars don't need quotes
     | '"' .*? '"'
     | '\'' .*? '\''
     ;
diff --git a/src/beast/util/treeparser/NewickBaseVisitor.java b/src/beast/util/treeparser/NewickBaseVisitor.java
index 37739c8..4503959 100644
--- a/src/beast/util/treeparser/NewickBaseVisitor.java
+++ b/src/beast/util/treeparser/NewickBaseVisitor.java
@@ -1,4 +1,4 @@
-// Generated from /home/tvaughan/code/beast_and_friends/beast2/src/beast/util/treeparser/Newick.g4 by ANTLR 4.5.1
+// Generated from Newick.g4 by ANTLR 4.5.1
 package beast.util.treeparser;
 import org.antlr.v4.runtime.tree.AbstractParseTreeVisitor;
 
diff --git a/src/beast/util/treeparser/NewickLexer.java b/src/beast/util/treeparser/NewickLexer.java
index 421a086..de1ed93 100644
--- a/src/beast/util/treeparser/NewickLexer.java
+++ b/src/beast/util/treeparser/NewickLexer.java
@@ -1,4 +1,4 @@
-// Generated from /home/tvaughan/code/beast_and_friends/beast2/src/beast/util/treeparser/Newick.g4 by ANTLR 4.5.1
+// Generated from Newick.g4 by ANTLR 4.5.1
 package beast.util.treeparser;
 import org.antlr.v4.runtime.Lexer;
 import org.antlr.v4.runtime.CharStream;
@@ -102,29 +102,29 @@ public class NewickLexer extends Lexer {
 		"\13\21\3\21\3\21\3\21\7\21s\n\21\f\21\16\21v\13\21\3\21\5\21y\n\21\3\22"+
 		"\6\22|\n\22\r\22\16\22}\3\22\3\22\4lt\2\23\3\3\5\4\7\5\t\6\13\7\r\b\17"+
 		"\t\21\n\23\13\25\f\27\r\31\16\33\2\35\2\37\2!\17#\20\3\2\7\4\2GGgg\3\2"+
-		"\63;\3\2\62;\t\2\'(,-/;C\\aac|~~\5\2\13\f\17\17\"\"\u008b\2\3\3\2\2\2"+
-		"\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3\2"+
-		"\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2\2"+
-		"\2!\3\2\2\2\2#\3\2\2\2\3%\3\2\2\2\5\'\3\2\2\2\7)\3\2\2\2\t+\3\2\2\2\13"+
-		"-\3\2\2\2\r/\3\2\2\2\17\62\3\2\2\2\21\64\3\2\2\2\23\66\3\2\2\2\258\3\2"+
-		"\2\2\27;\3\2\2\2\31Q\3\2\2\2\33]\3\2\2\2\35_\3\2\2\2\37a\3\2\2\2!x\3\2"+
-		"\2\2#{\3\2\2\2%&\7=\2\2&\4\3\2\2\2\'(\7*\2\2(\6\3\2\2\2)*\7.\2\2*\b\3"+
-		"\2\2\2+,\7+\2\2,\n\3\2\2\2-.\7<\2\2.\f\3\2\2\2/\60\7]\2\2\60\61\7(\2\2"+
-		"\61\16\3\2\2\2\62\63\7_\2\2\63\20\3\2\2\2\64\65\7?\2\2\65\22\3\2\2\2\66"+
-		"\67\7}\2\2\67\24\3\2\2\289\7\177\2\29\26\3\2\2\2:<\7/\2\2;:\3\2\2\2;<"+
-		"\3\2\2\2<=\3\2\2\2=>\5\33\16\2>B\7\60\2\2?A\5\37\20\2@?\3\2\2\2AD\3\2"+
-		"\2\2B@\3\2\2\2BC\3\2\2\2CN\3\2\2\2DB\3\2\2\2EG\t\2\2\2FH\7/\2\2GF\3\2"+
-		"\2\2GH\3\2\2\2HJ\3\2\2\2IK\5\37\20\2JI\3\2\2\2KL\3\2\2\2LJ\3\2\2\2LM\3"+
-		"\2\2\2MO\3\2\2\2NE\3\2\2\2NO\3\2\2\2O\30\3\2\2\2PR\7/\2\2QP\3\2\2\2QR"+
-		"\3\2\2\2RS\3\2\2\2ST\5\33\16\2T\32\3\2\2\2U^\7\62\2\2VZ\5\35\17\2WY\5"+
-		"\37\20\2XW\3\2\2\2Y\\\3\2\2\2ZX\3\2\2\2Z[\3\2\2\2[^\3\2\2\2\\Z\3\2\2\2"+
-		"]U\3\2\2\2]V\3\2\2\2^\34\3\2\2\2_`\t\3\2\2`\36\3\2\2\2ab\t\4\2\2b \3\2"+
-		"\2\2ce\t\5\2\2dc\3\2\2\2ef\3\2\2\2fd\3\2\2\2fg\3\2\2\2gy\3\2\2\2hl\7$"+
-		"\2\2ik\13\2\2\2ji\3\2\2\2kn\3\2\2\2lm\3\2\2\2lj\3\2\2\2mo\3\2\2\2nl\3"+
-		"\2\2\2oy\7$\2\2pt\7)\2\2qs\13\2\2\2rq\3\2\2\2sv\3\2\2\2tu\3\2\2\2tr\3"+
-		"\2\2\2uw\3\2\2\2vt\3\2\2\2wy\7)\2\2xd\3\2\2\2xh\3\2\2\2xp\3\2\2\2y\"\3"+
-		"\2\2\2z|\t\6\2\2{z\3\2\2\2|}\3\2\2\2}{\3\2\2\2}~\3\2\2\2~\177\3\2\2\2"+
-		"\177\u0080\b\22\2\2\u0080$\3\2\2\2\20\2;BGLNQZ]fltx}\3\b\2\2";
+		"\63;\3\2\62;\n\2%%\'(,-/;C\\aac|~~\5\2\13\f\17\17\"\"\u008b\2\3\3\2\2"+
+		"\2\2\5\3\2\2\2\2\7\3\2\2\2\2\t\3\2\2\2\2\13\3\2\2\2\2\r\3\2\2\2\2\17\3"+
+		"\2\2\2\2\21\3\2\2\2\2\23\3\2\2\2\2\25\3\2\2\2\2\27\3\2\2\2\2\31\3\2\2"+
+		"\2\2!\3\2\2\2\2#\3\2\2\2\3%\3\2\2\2\5\'\3\2\2\2\7)\3\2\2\2\t+\3\2\2\2"+
+		"\13-\3\2\2\2\r/\3\2\2\2\17\62\3\2\2\2\21\64\3\2\2\2\23\66\3\2\2\2\258"+
+		"\3\2\2\2\27;\3\2\2\2\31Q\3\2\2\2\33]\3\2\2\2\35_\3\2\2\2\37a\3\2\2\2!"+
+		"x\3\2\2\2#{\3\2\2\2%&\7=\2\2&\4\3\2\2\2\'(\7*\2\2(\6\3\2\2\2)*\7.\2\2"+
+		"*\b\3\2\2\2+,\7+\2\2,\n\3\2\2\2-.\7<\2\2.\f\3\2\2\2/\60\7]\2\2\60\61\7"+
+		"(\2\2\61\16\3\2\2\2\62\63\7_\2\2\63\20\3\2\2\2\64\65\7?\2\2\65\22\3\2"+
+		"\2\2\66\67\7}\2\2\67\24\3\2\2\289\7\177\2\29\26\3\2\2\2:<\7/\2\2;:\3\2"+
+		"\2\2;<\3\2\2\2<=\3\2\2\2=>\5\33\16\2>B\7\60\2\2?A\5\37\20\2@?\3\2\2\2"+
+		"AD\3\2\2\2B@\3\2\2\2BC\3\2\2\2CN\3\2\2\2DB\3\2\2\2EG\t\2\2\2FH\7/\2\2"+
+		"GF\3\2\2\2GH\3\2\2\2HJ\3\2\2\2IK\5\37\20\2JI\3\2\2\2KL\3\2\2\2LJ\3\2\2"+
+		"\2LM\3\2\2\2MO\3\2\2\2NE\3\2\2\2NO\3\2\2\2O\30\3\2\2\2PR\7/\2\2QP\3\2"+
+		"\2\2QR\3\2\2\2RS\3\2\2\2ST\5\33\16\2T\32\3\2\2\2U^\7\62\2\2VZ\5\35\17"+
+		"\2WY\5\37\20\2XW\3\2\2\2Y\\\3\2\2\2ZX\3\2\2\2Z[\3\2\2\2[^\3\2\2\2\\Z\3"+
+		"\2\2\2]U\3\2\2\2]V\3\2\2\2^\34\3\2\2\2_`\t\3\2\2`\36\3\2\2\2ab\t\4\2\2"+
+		"b \3\2\2\2ce\t\5\2\2dc\3\2\2\2ef\3\2\2\2fd\3\2\2\2fg\3\2\2\2gy\3\2\2\2"+
+		"hl\7$\2\2ik\13\2\2\2ji\3\2\2\2kn\3\2\2\2lm\3\2\2\2lj\3\2\2\2mo\3\2\2\2"+
+		"nl\3\2\2\2oy\7$\2\2pt\7)\2\2qs\13\2\2\2rq\3\2\2\2sv\3\2\2\2tu\3\2\2\2"+
+		"tr\3\2\2\2uw\3\2\2\2vt\3\2\2\2wy\7)\2\2xd\3\2\2\2xh\3\2\2\2xp\3\2\2\2"+
+		"y\"\3\2\2\2z|\t\6\2\2{z\3\2\2\2|}\3\2\2\2}{\3\2\2\2}~\3\2\2\2~\177\3\2"+
+		"\2\2\177\u0080\b\22\2\2\u0080$\3\2\2\2\20\2;BGLNQZ]fltx}\3\b\2\2";
 	public static final ATN _ATN =
 		new ATNDeserializer().deserialize(_serializedATN.toCharArray());
 	static {
diff --git a/src/beast/util/treeparser/NewickParser.java b/src/beast/util/treeparser/NewickParser.java
index 6816e27..6833af0 100644
--- a/src/beast/util/treeparser/NewickParser.java
+++ b/src/beast/util/treeparser/NewickParser.java
@@ -1,4 +1,4 @@
-// Generated from /home/tvaughan/code/beast_and_friends/beast2/src/beast/util/treeparser/Newick.g4 by ANTLR 4.5.1
+// Generated from Newick.g4 by ANTLR 4.5.1
 package beast.util.treeparser;
 import org.antlr.v4.runtime.atn.*;
 import org.antlr.v4.runtime.dfa.DFA;
diff --git a/src/beast/util/treeparser/NewickVisitor.java b/src/beast/util/treeparser/NewickVisitor.java
index e1cb154..9041257 100644
--- a/src/beast/util/treeparser/NewickVisitor.java
+++ b/src/beast/util/treeparser/NewickVisitor.java
@@ -1,4 +1,4 @@
-// Generated from /home/tvaughan/code/beast_and_friends/beast2/src/beast/util/treeparser/Newick.g4 by ANTLR 4.5.1
+// Generated from Newick.g4 by ANTLR 4.5.1
 package beast.util.treeparser;
 import org.antlr.v4.runtime.tree.ParseTreeVisitor;
 
diff --git a/src/org/apache/commons/math/ConvergingAlgorithmImpl.java b/src/org/apache/commons/math/ConvergingAlgorithmImpl.java
index 23c2c57..c88b1f5 100644
--- a/src/org/apache/commons/math/ConvergingAlgorithmImpl.java
+++ b/src/org/apache/commons/math/ConvergingAlgorithmImpl.java
@@ -85,70 +85,80 @@ public abstract class ConvergingAlgorithmImpl implements ConvergingAlgorithm {
     /**
      * {@inheritDoc}
      */
-    public int getIterationCount() {
+    @Override
+	public int getIterationCount() {
         return iterationCount;
     }
 
     /**
      * {@inheritDoc}
      */
-    public void setAbsoluteAccuracy(double accuracy) {
+    @Override
+	public void setAbsoluteAccuracy(double accuracy) {
         absoluteAccuracy = accuracy;
     }
 
     /**
      * {@inheritDoc}
      */
-    public double getAbsoluteAccuracy() {
+    @Override
+	public double getAbsoluteAccuracy() {
         return absoluteAccuracy;
     }
 
     /**
      * {@inheritDoc}
      */
-    public void resetAbsoluteAccuracy() {
+    @Override
+	public void resetAbsoluteAccuracy() {
         absoluteAccuracy = defaultAbsoluteAccuracy;
     }
 
     /**
      * {@inheritDoc}
      */
-    public void setMaximalIterationCount(int count) {
+    @Override
+	public void setMaximalIterationCount(int count) {
         maximalIterationCount = count;
     }
 
     /**
      * {@inheritDoc}
      */
-    public int getMaximalIterationCount() {
+    @Override
+	public int getMaximalIterationCount() {
         return maximalIterationCount;
     }
 
     /**
      * {@inheritDoc}
      */
-    public void resetMaximalIterationCount() {
+    @Override
+	public void resetMaximalIterationCount() {
         maximalIterationCount = defaultMaximalIterationCount;
     }
 
     /**
      * {@inheritDoc}
      */
-    public void setRelativeAccuracy(double accuracy) {
+    @Override
+	public void setRelativeAccuracy(double accuracy) {
         relativeAccuracy = accuracy;
     }
 
     /**
      * {@inheritDoc}
      */
-    public double getRelativeAccuracy() {
+    @Override
+	public double getRelativeAccuracy() {
         return relativeAccuracy;
     }
 
     /**
      * {@inheritDoc}
      */
-    public void resetRelativeAccuracy() {
+    @Override
+	public void resetRelativeAccuracy() {
         relativeAccuracy = defaultRelativeAccuracy;
     }
 
diff --git a/src/org/apache/commons/math/MaxEvaluationsExceededException.java b/src/org/apache/commons/math/MaxEvaluationsExceededException.java
index accf08a..6f20163 100644
--- a/src/org/apache/commons/math/MaxEvaluationsExceededException.java
+++ b/src/org/apache/commons/math/MaxEvaluationsExceededException.java
@@ -17,8 +17,6 @@
 
 package org.apache.commons.math;
 
-import org.apache.commons.math.ConvergenceException;
-
 /**
  * Error thrown when a numerical computation exceeds its allowed
  * number of functions evaluations.
diff --git a/src/org/apache/commons/math/MaxIterationsExceededException.java b/src/org/apache/commons/math/MaxIterationsExceededException.java
index aa60110..6bb3c6f 100644
--- a/src/org/apache/commons/math/MaxIterationsExceededException.java
+++ b/src/org/apache/commons/math/MaxIterationsExceededException.java
@@ -17,8 +17,6 @@
 
 package org.apache.commons.math;
 
-import org.apache.commons.math.ConvergenceException;
-
 /**
  * Error thrown when a numerical computation exceeds its allowed
  * number of iterations.
diff --git a/src/org/apache/commons/math/analysis/BinaryFunction.java b/src/org/apache/commons/math/analysis/BinaryFunction.java
index 656b22a..1587976 100644
--- a/src/org/apache/commons/math/analysis/BinaryFunction.java
+++ b/src/org/apache/commons/math/analysis/BinaryFunction.java
@@ -97,7 +97,8 @@ public abstract class BinaryFunction implements BivariateRealFunction {
     /**
      * {@inheritDoc}
      */
-    public abstract double value(double x, double y) throws FunctionEvaluationException;
+    @Override
+	public abstract double value(double x, double y) throws FunctionEvaluationException;
 
     /**
      * Get a composable function by fixing the first argument of the instance.
diff --git a/src/org/apache/commons/math/analysis/ComposableFunction.java b/src/org/apache/commons/math/analysis/ComposableFunction.java
index 179f6d9..1936c2e 100644
--- a/src/org/apache/commons/math/analysis/ComposableFunction.java
+++ b/src/org/apache/commons/math/analysis/ComposableFunction.java
@@ -506,7 +506,8 @@ public abstract class ComposableFunction implements UnivariateRealFunction {
                                                 final double initialValue) {
         return new MultivariateRealFunction() {
             /** {@inheritDoc} */
-            public double value(double[] point)
+            @Override
+			public double value(double[] point)
                     throws FunctionEvaluationException, IllegalArgumentException {
                 double result = initialValue;
                 for (final double entry : point) {
@@ -572,6 +573,7 @@ public abstract class ComposableFunction implements UnivariateRealFunction {
     /**
      * {@inheritDoc}
      */
-    public abstract double value(double x) throws FunctionEvaluationException;
+    @Override
+	public abstract double value(double x) throws FunctionEvaluationException;
 
 }
diff --git a/src/org/apache/commons/math/analysis/integration/RombergIntegrator.java b/src/org/apache/commons/math/analysis/integration/RombergIntegrator.java
index e6b5c29..88429b6 100644
--- a/src/org/apache/commons/math/analysis/integration/RombergIntegrator.java
+++ b/src/org/apache/commons/math/analysis/integration/RombergIntegrator.java
@@ -58,7 +58,8 @@ public class RombergIntegrator extends UnivariateRealIntegratorImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double integrate(final double min, final double max)
             throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException {
         return integrate(f, min, max);
@@ -67,7 +68,8 @@ public class RombergIntegrator extends UnivariateRealIntegratorImpl {
     /**
      * {@inheritDoc}
      */
-    public double integrate(final UnivariateRealFunction f,
+    @Override
+	public double integrate(final UnivariateRealFunction f,
                             final double min, final double max)
             throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException {
 
diff --git a/src/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java b/src/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java
index ce780d4..a44824d 100644
--- a/src/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java
+++ b/src/org/apache/commons/math/analysis/integration/TrapezoidIntegrator.java
@@ -100,7 +100,8 @@ public class TrapezoidIntegrator extends UnivariateRealIntegratorImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double integrate(final double min, final double max)
             throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException {
         return integrate(f, min, max);
@@ -109,7 +110,8 @@ public class TrapezoidIntegrator extends UnivariateRealIntegratorImpl {
     /**
      * {@inheritDoc}
      */
-    public double integrate(final UnivariateRealFunction f,
+    @Override
+	public double integrate(final UnivariateRealFunction f,
                             final double min, final double max)
             throws MaxIterationsExceededException, FunctionEvaluationException, IllegalArgumentException {
 
diff --git a/src/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java b/src/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java
index a550bd7..a2985cf 100644
--- a/src/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java
+++ b/src/org/apache/commons/math/analysis/integration/UnivariateRealIntegratorImpl.java
@@ -32,7 +32,7 @@ public abstract class UnivariateRealIntegratorImpl
     /**
      * Serializable version identifier.
      */
-    private static final long serialVersionUID = 6248808456637441533L;
+    //private static final long serialVersionUID = 6248808456637441533L;
 
     /**
      * minimum number of iterations
@@ -117,7 +117,8 @@ public abstract class UnivariateRealIntegratorImpl
      * @return the last computed integral
      * @throws IllegalStateException if no integral has been computed
      */
-    public double getResult() throws IllegalStateException {
+    @Override
+	public double getResult() throws IllegalStateException {
         if (resultComputed) {
             return result;
         } else {
@@ -148,21 +149,24 @@ public abstract class UnivariateRealIntegratorImpl
     /**
      * {@inheritDoc}
      */
-    public void setMinimalIterationCount(int count) {
+    @Override
+	public void setMinimalIterationCount(int count) {
         minimalIterationCount = count;
     }
 
     /**
      * {@inheritDoc}
      */
-    public int getMinimalIterationCount() {
+    @Override
+	public int getMinimalIterationCount() {
         return minimalIterationCount;
     }
 
     /**
      * {@inheritDoc}
      */
-    public void resetMinimalIterationCount() {
+    @Override
+	public void resetMinimalIterationCount() {
         minimalIterationCount = defaultMinimalIterationCount;
     }
 
diff --git a/src/org/apache/commons/math/analysis/solvers/BisectionSolver.java b/src/org/apache/commons/math/analysis/solvers/BisectionSolver.java
index ffd641d..17186aa 100644
--- a/src/org/apache/commons/math/analysis/solvers/BisectionSolver.java
+++ b/src/org/apache/commons/math/analysis/solvers/BisectionSolver.java
@@ -54,7 +54,8 @@ public class BisectionSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(double min, double max, double initial)
             throws MaxIterationsExceededException, FunctionEvaluationException {
         return solve(f, min, max);
@@ -63,7 +64,8 @@ public class BisectionSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(double min, double max)
             throws MaxIterationsExceededException, FunctionEvaluationException {
         return solve(f, min, max);
@@ -72,7 +74,8 @@ public class BisectionSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    public double solve(final UnivariateRealFunction f, double min, double max, double initial)
+    @Override
+	public double solve(final UnivariateRealFunction f, double min, double max, double initial)
             throws MaxIterationsExceededException, FunctionEvaluationException {
         return solve(min, max);
     }
@@ -80,7 +83,8 @@ public class BisectionSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    public double solve(final UnivariateRealFunction f, double min, double max)
+    @Override
+	public double solve(final UnivariateRealFunction f, double min, double max)
             throws MaxIterationsExceededException, FunctionEvaluationException {
 
         clearResult();
diff --git a/src/org/apache/commons/math/analysis/solvers/BrentSolver.java b/src/org/apache/commons/math/analysis/solvers/BrentSolver.java
index 1a7cb7f..2586988 100644
--- a/src/org/apache/commons/math/analysis/solvers/BrentSolver.java
+++ b/src/org/apache/commons/math/analysis/solvers/BrentSolver.java
@@ -56,7 +56,7 @@ public class BrentSolver extends UnivariateRealSolverImpl {
     /**
      * Serializable version identifier
      */
-    private static final long serialVersionUID = 7694577816772532779L;
+    //private static final long serialVersionUID = 7694577816772532779L;
 
     /**
      * Construct a solver for the given function.
@@ -103,7 +103,8 @@ public class BrentSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(double min, double max)
             throws MaxIterationsExceededException, FunctionEvaluationException {
         return solve(f, min, max);
@@ -112,7 +113,8 @@ public class BrentSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(double min, double max, double initial)
             throws MaxIterationsExceededException, FunctionEvaluationException {
         return solve(f, min, max, initial);
@@ -138,7 +140,8 @@ public class BrentSolver extends UnivariateRealSolverImpl {
      * @throws IllegalArgumentException       if initial is not between min and max
      *                                        (even if it <em>is</em> a root)
      */
-    public double solve(final UnivariateRealFunction f,
+    @Override
+	public double solve(final UnivariateRealFunction f,
                         final double min, final double max, final double initial)
             throws MaxIterationsExceededException, FunctionEvaluationException {
 
@@ -202,7 +205,8 @@ public class BrentSolver extends UnivariateRealSolverImpl {
      * @throws IllegalArgumentException       if min is not less than max or the
      *                                        signs of the values of the function at the endpoints are not opposites
      */
-    public double solve(final UnivariateRealFunction f,
+    @Override
+	public double solve(final UnivariateRealFunction f,
                         final double min, final double max)
             throws MaxIterationsExceededException,
             FunctionEvaluationException {
diff --git a/src/org/apache/commons/math/analysis/solvers/MullerSolver.java b/src/org/apache/commons/math/analysis/solvers/MullerSolver.java
index f0c8a82..ad5a598 100644
--- a/src/org/apache/commons/math/analysis/solvers/MullerSolver.java
+++ b/src/org/apache/commons/math/analysis/solvers/MullerSolver.java
@@ -61,7 +61,8 @@ public class MullerSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(final double min, final double max)
             throws ConvergenceException, FunctionEvaluationException {
         return solve(f, min, max);
@@ -70,7 +71,8 @@ public class MullerSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(final double min, final double max, final double initial)
             throws ConvergenceException, FunctionEvaluationException {
         return solve(f, min, max, initial);
@@ -92,7 +94,8 @@ public class MullerSolver extends UnivariateRealSolverImpl {
      *                                        function
      * @throws IllegalArgumentException       if any parameters are invalid
      */
-    public double solve(final UnivariateRealFunction f,
+    @Override
+	public double solve(final UnivariateRealFunction f,
                         final double min, final double max, final double initial)
             throws MaxIterationsExceededException, FunctionEvaluationException {
 
@@ -141,7 +144,8 @@ public class MullerSolver extends UnivariateRealSolverImpl {
      *                                        function
      * @throws IllegalArgumentException       if any parameters are invalid
      */
-    public double solve(final UnivariateRealFunction f,
+    @Override
+	public double solve(final UnivariateRealFunction f,
                         final double min, final double max)
             throws MaxIterationsExceededException, FunctionEvaluationException {
 
diff --git a/src/org/apache/commons/math/analysis/solvers/NewtonSolver.java b/src/org/apache/commons/math/analysis/solvers/NewtonSolver.java
index 6c7fdf2..46fb4c3 100644
--- a/src/org/apache/commons/math/analysis/solvers/NewtonSolver.java
+++ b/src/org/apache/commons/math/analysis/solvers/NewtonSolver.java
@@ -57,7 +57,8 @@ public class NewtonSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(final double min, final double max)
             throws MaxIterationsExceededException,
             FunctionEvaluationException {
@@ -67,7 +68,8 @@ public class NewtonSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(final double min, final double max, final double startValue)
             throws MaxIterationsExceededException, FunctionEvaluationException {
         return solve(f, min, max, startValue);
@@ -85,7 +87,8 @@ public class NewtonSolver extends UnivariateRealSolverImpl {
      *                                        function or derivative
      * @throws IllegalArgumentException       if min is not less than max
      */
-    public double solve(final UnivariateRealFunction f,
+    @Override
+	public double solve(final UnivariateRealFunction f,
                         final double min, final double max)
             throws MaxIterationsExceededException, FunctionEvaluationException {
         return solve(f, min, max, UnivariateRealSolverUtils.midpoint(min, max));
@@ -105,7 +108,8 @@ public class NewtonSolver extends UnivariateRealSolverImpl {
      * @throws IllegalArgumentException       if startValue is not between min and max or
      *                                        if function is not a {@link DifferentiableUnivariateRealFunction} instance
      */
-    public double solve(final UnivariateRealFunction f,
+    @Override
+	public double solve(final UnivariateRealFunction f,
                         final double min, final double max, final double startValue)
             throws MaxIterationsExceededException, FunctionEvaluationException {
 
diff --git a/src/org/apache/commons/math/analysis/solvers/RiddersSolver.java b/src/org/apache/commons/math/analysis/solvers/RiddersSolver.java
index a1c5afe..e8b6754 100644
--- a/src/org/apache/commons/math/analysis/solvers/RiddersSolver.java
+++ b/src/org/apache/commons/math/analysis/solvers/RiddersSolver.java
@@ -60,7 +60,8 @@ public class RiddersSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(final double min, final double max)
             throws ConvergenceException, FunctionEvaluationException {
         return solve(f, min, max);
@@ -69,7 +70,8 @@ public class RiddersSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(final double min, final double max, final double initial)
             throws ConvergenceException, FunctionEvaluationException {
         return solve(f, min, max, initial);
@@ -90,7 +92,8 @@ public class RiddersSolver extends UnivariateRealSolverImpl {
      *                                        function
      * @throws IllegalArgumentException       if any parameters are invalid
      */
-    public double solve(final UnivariateRealFunction f,
+    @Override
+	public double solve(final UnivariateRealFunction f,
                         final double min, final double max, final double initial)
             throws MaxIterationsExceededException, FunctionEvaluationException {
 
@@ -128,7 +131,8 @@ public class RiddersSolver extends UnivariateRealSolverImpl {
      *                                        function
      * @throws IllegalArgumentException       if any parameters are invalid
      */
-    public double solve(final UnivariateRealFunction f,
+    @Override
+	public double solve(final UnivariateRealFunction f,
                         final double min, final double max)
             throws MaxIterationsExceededException, FunctionEvaluationException {
 
diff --git a/src/org/apache/commons/math/analysis/solvers/SecantSolver.java b/src/org/apache/commons/math/analysis/solvers/SecantSolver.java
index 76fd8d9..5d044b3 100644
--- a/src/org/apache/commons/math/analysis/solvers/SecantSolver.java
+++ b/src/org/apache/commons/math/analysis/solvers/SecantSolver.java
@@ -65,7 +65,8 @@ public class SecantSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(final double min, final double max)
             throws ConvergenceException, FunctionEvaluationException {
         return solve(f, min, max);
@@ -74,7 +75,8 @@ public class SecantSolver extends UnivariateRealSolverImpl {
     /**
      * {@inheritDoc}
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public double solve(final double min, final double max, final double initial)
             throws ConvergenceException, FunctionEvaluationException {
         return solve(f, min, max, initial);
@@ -94,7 +96,8 @@ public class SecantSolver extends UnivariateRealSolverImpl {
      * @throws IllegalArgumentException       if min is not less than max or the
      *                                        signs of the values of the function at the endpoints are not opposites
      */
-    public double solve(final UnivariateRealFunction f,
+    @Override
+	public double solve(final UnivariateRealFunction f,
                         final double min, final double max, final double initial)
             throws MaxIterationsExceededException, FunctionEvaluationException {
         return solve(f, min, max);
@@ -113,7 +116,8 @@ public class SecantSolver extends UnivariateRealSolverImpl {
      * @throws IllegalArgumentException       if min is not less than max or the
      *                                        signs of the values of the function at the endpoints are not opposites
      */
-    public double solve(final UnivariateRealFunction f,
+    @Override
+	public double solve(final UnivariateRealFunction f,
                         final double min, final double max)
             throws MaxIterationsExceededException, FunctionEvaluationException {
 
diff --git a/src/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java b/src/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java
index fae775f..ca1301e 100644
--- a/src/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java
+++ b/src/org/apache/commons/math/analysis/solvers/UnivariateRealSolverImpl.java
@@ -122,7 +122,8 @@ public abstract class UnivariateRealSolverImpl
     /**
      * {@inheritDoc}
      */
-    public double getResult() {
+    @Override
+	public double getResult() {
         checkResultComputed();
         return result;
     }
@@ -130,7 +131,8 @@ public abstract class UnivariateRealSolverImpl
     /**
      * {@inheritDoc}
      */
-    public double getFunctionValue() {
+    @Override
+	public double getFunctionValue() {
         checkResultComputed();
         return functionValue;
     }
@@ -138,21 +140,24 @@ public abstract class UnivariateRealSolverImpl
     /**
      * {@inheritDoc}
      */
-    public void setFunctionValueAccuracy(final double accuracy) {
+    @Override
+	public void setFunctionValueAccuracy(final double accuracy) {
         functionValueAccuracy = accuracy;
     }
 
     /**
      * {@inheritDoc}
      */
-    public double getFunctionValueAccuracy() {
+    @Override
+	public double getFunctionValueAccuracy() {
         return functionValueAccuracy;
     }
 
     /**
      * {@inheritDoc}
      */
-    public void resetFunctionValueAccuracy() {
+    @Override
+	public void resetFunctionValueAccuracy() {
         functionValueAccuracy = defaultFunctionValueAccuracy;
     }
 
diff --git a/src/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java b/src/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java
index db55aaf..f491551 100644
--- a/src/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java
+++ b/src/org/apache/commons/math/analysis/solvers/UnivariateRealSolverUtils.java
@@ -16,8 +16,8 @@
  */
 package org.apache.commons.math.analysis.solvers;
 
-import org.apache.commons.math.FunctionEvaluationException;
 import org.apache.commons.math.ConvergenceException;
+import org.apache.commons.math.FunctionEvaluationException;
 import org.apache.commons.math.MathRuntimeException;
 import org.apache.commons.math.analysis.UnivariateRealFunction;
 
diff --git a/src/org/apache/commons/math/distribution/AbstractContinuousDistribution.java b/src/org/apache/commons/math/distribution/AbstractContinuousDistribution.java
index 22c62c5..0a0c4ad 100644
--- a/src/org/apache/commons/math/distribution/AbstractContinuousDistribution.java
+++ b/src/org/apache/commons/math/distribution/AbstractContinuousDistribution.java
@@ -23,7 +23,6 @@ import org.apache.commons.math.FunctionEvaluationException;
 import org.apache.commons.math.MathException;
 import org.apache.commons.math.MathRuntimeException;
 import org.apache.commons.math.analysis.UnivariateRealFunction;
-import org.apache.commons.math.analysis.solvers.BrentSolver;
 import org.apache.commons.math.analysis.solvers.UnivariateRealSolverUtils;
 
 /**
@@ -64,7 +63,8 @@ public abstract class AbstractContinuousDistribution
      * @throws MathRuntimeException if the specialized class hasn't implemented this function
      * @since 2.1
      */
-    public double density(double x) throws MathRuntimeException {
+    @Override
+	public double density(double x) throws MathRuntimeException {
         throw new MathRuntimeException(new UnsupportedOperationException(),
                 "This distribution does not have a density function implemented");
     }
@@ -85,7 +85,8 @@ public abstract class AbstractContinuousDistribution
      * @throws IllegalArgumentException if <code>p</code> is not a valid
      *                                  probability.
      */
-    public double inverseCumulativeProbability(final double p)
+    @Override
+	public double inverseCumulativeProbability(final double p)
             throws MathException {
         if (p < 0.0 || p > 1.0) {
             throw MathRuntimeException.createIllegalArgumentException(
@@ -96,7 +97,8 @@ public abstract class AbstractContinuousDistribution
         // subclasses can override if there is a better method.
         UnivariateRealFunction rootFindingFunction =
                 new UnivariateRealFunction() {
-                    public double value(double x) throws FunctionEvaluationException {
+                    @Override
+					public double value(double x) throws FunctionEvaluationException {
                         double ret = Double.NaN;
                         try {
                             ret = cumulativeProbability(x) - p;
diff --git a/src/org/apache/commons/math/distribution/AbstractDistribution.java b/src/org/apache/commons/math/distribution/AbstractDistribution.java
index 5cbec8e..066c319 100644
--- a/src/org/apache/commons/math/distribution/AbstractDistribution.java
+++ b/src/org/apache/commons/math/distribution/AbstractDistribution.java
@@ -58,7 +58,8 @@ public abstract class AbstractDistribution
      *                                  computed due to convergence or other numerical errors.
      * @throws IllegalArgumentException if <code>x0 > x1</code>
      */
-    public double cumulativeProbability(double x0, double x1)
+    @Override
+	public double cumulativeProbability(double x0, double x1)
             throws MathException {
         if (x0 > x1) {
             throw MathRuntimeException.createIllegalArgumentException(
diff --git a/src/org/apache/commons/math/distribution/AbstractIntegerDistribution.java b/src/org/apache/commons/math/distribution/AbstractIntegerDistribution.java
index 79fc871..faafdb4 100644
--- a/src/org/apache/commons/math/distribution/AbstractIntegerDistribution.java
+++ b/src/org/apache/commons/math/distribution/AbstractIntegerDistribution.java
@@ -72,7 +72,8 @@ public abstract class AbstractIntegerDistribution extends AbstractDistribution
      * @throws MathException if the cumulative probability can not be
      *                       computed due to convergence or other numerical errors.
      */
-    public double cumulativeProbability(double x) throws MathException {
+    @Override
+	public double cumulativeProbability(double x) throws MathException {
         return cumulativeProbability((int) Math.floor(x));
     }
 
@@ -116,7 +117,8 @@ public abstract class AbstractIntegerDistribution extends AbstractDistribution
      * @throws MathException if the cumulative probability can not be
      *                       computed due to convergence or other numerical errors.
      */
-    public abstract double cumulativeProbability(int x) throws MathException;
+    @Override
+	public abstract double cumulativeProbability(int x) throws MathException;
 
     /**
      * For a random variable X whose values are distributed according
@@ -128,7 +130,8 @@ public abstract class AbstractIntegerDistribution extends AbstractDistribution
      * @param x the value at which the probability density function is evaluated
      * @return the value of the probability density function at x
      */
-    public double probability(double x) {
+    @Override
+	public double probability(double x) {
         double fl = Math.floor(x);
         if (fl == x) {
             return this.probability((int) x);
@@ -148,7 +151,8 @@ public abstract class AbstractIntegerDistribution extends AbstractDistribution
      *                                  computed due to convergence or other numerical errors.
      * @throws IllegalArgumentException if x0 > x1
      */
-    public double cumulativeProbability(int x0, int x1) throws MathException {
+    @Override
+	public double cumulativeProbability(int x0, int x1) throws MathException {
         if (x0 > x1) {
             throw MathRuntimeException.createIllegalArgumentException(
                     WRONG_ORDER_ENDPOINTS_MESSAGE, x0, x1);
@@ -167,7 +171,8 @@ public abstract class AbstractIntegerDistribution extends AbstractDistribution
      *                                  computed due to convergence or other numerical errors.
      * @throws IllegalArgumentException if p < 0 or p > 1
      */
-    public int inverseCumulativeProbability(final double p) throws MathException {
+    @Override
+	public int inverseCumulativeProbability(final double p) throws MathException {
         if (p < 0.0 || p > 1.0) {
             throw MathRuntimeException.createIllegalArgumentException(
                     OUT_OF_RANGE_POINT, p, 0.0, 1.0);
diff --git a/src/org/apache/commons/math/distribution/BetaDistribution.java b/src/org/apache/commons/math/distribution/BetaDistribution.java
index 569682b..3cef8a0 100644
--- a/src/org/apache/commons/math/distribution/BetaDistribution.java
+++ b/src/org/apache/commons/math/distribution/BetaDistribution.java
@@ -25,7 +25,7 @@ import org.apache.commons.math.MathException;
  * @see <a href="http://en.wikipedia.org/wiki/Beta_distribution">Beta_distribution</a>
  * @since 2.0
  */
-public interface BetaDistribution extends ContinuousDistribution, HasDensity<Double> {
+public interface BetaDistribution extends ContinuousDistribution /*, HasDensity<Double>*/ {
     /**
      * Modify the shape parameter, alpha.
      *
diff --git a/src/org/apache/commons/math/distribution/BetaDistributionImpl.java b/src/org/apache/commons/math/distribution/BetaDistributionImpl.java
index b896692..3bc27df 100644
--- a/src/org/apache/commons/math/distribution/BetaDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/BetaDistributionImpl.java
@@ -18,8 +18,8 @@ package org.apache.commons.math.distribution;
 
 import org.apache.commons.math.MathException;
 import org.apache.commons.math.MathRuntimeException;
-import org.apache.commons.math.special.Gamma;
 import org.apache.commons.math.special.Beta;
+import org.apache.commons.math.special.Gamma;
 
 /**
  * Implements the Beta distribution.
@@ -101,7 +101,8 @@ public class BetaDistributionImpl
      *
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setAlpha(double alpha) {
         this.alpha = alpha;
         z = Double.NaN;
@@ -110,7 +111,8 @@ public class BetaDistributionImpl
     /**
      * {@inheritDoc}
      */
-    public double getAlpha() {
+    @Override
+	public double getAlpha() {
         return alpha;
     }
 
@@ -119,7 +121,8 @@ public class BetaDistributionImpl
      *
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setBeta(double beta) {
         this.beta = beta;
         z = Double.NaN;
@@ -128,7 +131,8 @@ public class BetaDistributionImpl
     /**
      * {@inheritDoc}
      */
-    public double getBeta() {
+    @Override
+	public double getBeta() {
         return beta;
     }
 
@@ -148,7 +152,9 @@ public class BetaDistributionImpl
      * @return The pdf at point x.
      * @deprecated
      */
-    public double density(Double x) {
+    @Deprecated
+	@Override
+	public double density(Double x) {
         return density(x.doubleValue());
     }
 
@@ -159,7 +165,8 @@ public class BetaDistributionImpl
      * @return The pdf at point x.
      * @since 2.1
      */
-    public double density(double x) {
+    @Override
+	public double density(double x) {
         recomputeZ();
         if (x < 0 || x > 1) {
             return 0;
@@ -223,7 +230,8 @@ public class BetaDistributionImpl
     /**
      * {@inheritDoc}
      */
-    public double cumulativeProbability(double x) throws MathException {
+    @Override
+	public double cumulativeProbability(double x) throws MathException {
         if (x <= 0) {
             return 0;
         } else if (x >= 1) {
diff --git a/src/org/apache/commons/math/distribution/BinomialDistributionImpl.java b/src/org/apache/commons/math/distribution/BinomialDistributionImpl.java
index 7ad65c7..17e4d0e 100644
--- a/src/org/apache/commons/math/distribution/BinomialDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/BinomialDistributionImpl.java
@@ -63,7 +63,8 @@ public class BinomialDistributionImpl extends AbstractIntegerDistribution
      *
      * @return the number of trials.
      */
-    public int getNumberOfTrials() {
+    @Override
+	public int getNumberOfTrials() {
         return numberOfTrials;
     }
 
@@ -72,7 +73,8 @@ public class BinomialDistributionImpl extends AbstractIntegerDistribution
      *
      * @return the probability of success.
      */
-    public double getProbabilityOfSuccess() {
+    @Override
+	public double getProbabilityOfSuccess() {
         return probabilityOfSuccess;
     }
 
@@ -84,7 +86,8 @@ public class BinomialDistributionImpl extends AbstractIntegerDistribution
      *                                  number of trials.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setNumberOfTrials(int trials) {
         setNumberOfTrialsInternal(trials);
     }
@@ -112,7 +115,8 @@ public class BinomialDistributionImpl extends AbstractIntegerDistribution
      *                                  probability.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setProbabilityOfSuccess(double p) {
         setProbabilityOfSuccessInternal(p);
     }
@@ -186,7 +190,8 @@ public class BinomialDistributionImpl extends AbstractIntegerDistribution
      * @param x the value at which the PMF is evaluated.
      * @return PMF for this distribution.
      */
-    public double probability(int x) {
+    @Override
+	public double probability(int x) {
         double ret;
         if (x < 0 || x > numberOfTrials) {
             ret = 0.0;
diff --git a/src/org/apache/commons/math/distribution/CauchyDistributionImpl.java b/src/org/apache/commons/math/distribution/CauchyDistributionImpl.java
index 7686815..06f2f7e 100644
--- a/src/org/apache/commons/math/distribution/CauchyDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/CauchyDistributionImpl.java
@@ -98,7 +98,8 @@ public class CauchyDistributionImpl extends AbstractContinuousDistribution
      * @param x the value at which the CDF is evaluated.
      * @return CDF evaluted at <code>x</code>.
      */
-    public double cumulativeProbability(double x) {
+    @Override
+	public double cumulativeProbability(double x) {
         return 0.5 + (Math.atan((x - median) / scale) / Math.PI);
     }
 
@@ -107,7 +108,8 @@ public class CauchyDistributionImpl extends AbstractContinuousDistribution
      *
      * @return median for this distribution
      */
-    public double getMedian() {
+    @Override
+	public double getMedian() {
         return median;
     }
 
@@ -116,7 +118,8 @@ public class CauchyDistributionImpl extends AbstractContinuousDistribution
      *
      * @return scale parameter for this distribution
      */
-    public double getScale() {
+    @Override
+	public double getScale() {
         return scale;
     }
 
@@ -167,7 +170,8 @@ public class CauchyDistributionImpl extends AbstractContinuousDistribution
      * @param median for this distribution
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setMedian(double median) {
         setMedianInternal(median);
     }
@@ -188,7 +192,8 @@ public class CauchyDistributionImpl extends AbstractContinuousDistribution
      * @throws IllegalArgumentException if <code>sd</code> is not positive.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setScale(double s) {
         setScaleInternal(s);
     }
diff --git a/src/org/apache/commons/math/distribution/ChiSquaredDistribution.java b/src/org/apache/commons/math/distribution/ChiSquaredDistribution.java
index e44d54a..9a62b13 100644
--- a/src/org/apache/commons/math/distribution/ChiSquaredDistribution.java
+++ b/src/org/apache/commons/math/distribution/ChiSquaredDistribution.java
@@ -29,7 +29,7 @@ package org.apache.commons.math.distribution;
  *
  * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $
  */
-public interface ChiSquaredDistribution extends ContinuousDistribution, HasDensity<Double> {
+public interface ChiSquaredDistribution extends ContinuousDistribution /*, HasDensity<Double>*/ {
     /**
      * Modify the degrees of freedom.
      *
diff --git a/src/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java b/src/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java
index 53ffe12..d25410a 100644
--- a/src/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/ChiSquaredDistributionImpl.java
@@ -99,7 +99,8 @@ public class ChiSquaredDistributionImpl
      * @param degreesOfFreedom the new degrees of freedom.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setDegreesOfFreedom(double degreesOfFreedom) {
         setDegreesOfFreedomInternal(degreesOfFreedom);
     }
@@ -109,7 +110,8 @@ public class ChiSquaredDistributionImpl
      *
      * @param degreesOfFreedom the new degrees of freedom.
      */
-    private void setDegreesOfFreedomInternal(double degreesOfFreedom) {
+    @SuppressWarnings("deprecation")
+	private void setDegreesOfFreedomInternal(double degreesOfFreedom) {
         gamma.setAlpha(degreesOfFreedom / 2.0);
     }
 
@@ -118,7 +120,8 @@ public class ChiSquaredDistributionImpl
      *
      * @return the degrees of freedom.
      */
-    public double getDegreesOfFreedom() {
+    @Override
+	public double getDegreesOfFreedom() {
         return gamma.getAlpha() * 2.0;
     }
 
@@ -129,7 +132,9 @@ public class ChiSquaredDistributionImpl
      * @return The pdf at point x.
      * @deprecated
      */
-    public double density(Double x) {
+    @Deprecated
+	@Override
+	public double density(Double x) {
         return density(x.doubleValue());
     }
 
@@ -153,7 +158,8 @@ public class ChiSquaredDistributionImpl
      * @throws MathException if the cumulative probability can not be
      *                       computed due to convergence or other numerical errors.
      */
-    public double cumulativeProbability(double x) throws MathException {
+    @Override
+	public double cumulativeProbability(double x) throws MathException {
         return gamma.cumulativeProbability(x);
     }
 
diff --git a/src/org/apache/commons/math/distribution/ExponentialDistribution.java b/src/org/apache/commons/math/distribution/ExponentialDistribution.java
index 22fb7cb..be06a91 100644
--- a/src/org/apache/commons/math/distribution/ExponentialDistribution.java
+++ b/src/org/apache/commons/math/distribution/ExponentialDistribution.java
@@ -29,7 +29,7 @@ package org.apache.commons.math.distribution;
  *
  * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $
  */
-public interface ExponentialDistribution extends ContinuousDistribution, HasDensity<Double> {
+public interface ExponentialDistribution extends ContinuousDistribution /*, HasDensity<Double>*/ {
     /**
      * Modify the mean.
      *
diff --git a/src/org/apache/commons/math/distribution/ExponentialDistributionImpl.java b/src/org/apache/commons/math/distribution/ExponentialDistributionImpl.java
index 5227afa..7157cb3 100644
--- a/src/org/apache/commons/math/distribution/ExponentialDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/ExponentialDistributionImpl.java
@@ -81,7 +81,8 @@ public class ExponentialDistributionImpl extends AbstractContinuousDistribution
      * @throws IllegalArgumentException if <code>mean</code> is not positive.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setMean(double mean) {
         setMeanInternal(mean);
     }
@@ -105,7 +106,8 @@ public class ExponentialDistributionImpl extends AbstractContinuousDistribution
      *
      * @return the mean.
      */
-    public double getMean() {
+    @Override
+	public double getMean() {
         return mean;
     }
 
@@ -116,7 +118,9 @@ public class ExponentialDistributionImpl extends AbstractContinuousDistribution
      * @return The pdf at point x.
      * @deprecated - use density(double)
      */
-    public double density(Double x) {
+    @Deprecated
+	@Override
+	public double density(Double x) {
         return density(x.doubleValue());
     }
 
@@ -150,7 +154,8 @@ public class ExponentialDistributionImpl extends AbstractContinuousDistribution
      * @throws MathException if the cumulative probability can not be
      *                       computed due to convergence or other numerical errors.
      */
-    public double cumulativeProbability(double x) throws MathException {
+    @Override
+	public double cumulativeProbability(double x) throws MathException {
         double ret;
         if (x <= 0.0) {
             ret = 0.0;
diff --git a/src/org/apache/commons/math/distribution/FDistributionImpl.java b/src/org/apache/commons/math/distribution/FDistributionImpl.java
index 5c959dd..ecc5f0f 100644
--- a/src/org/apache/commons/math/distribution/FDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/FDistributionImpl.java
@@ -127,7 +127,8 @@ public class FDistributionImpl
      * @throws MathException if the cumulative probability can not be
      *                       computed due to convergence or other numerical errors.
      */
-    public double cumulativeProbability(double x) throws MathException {
+    @Override
+	public double cumulativeProbability(double x) throws MathException {
         double ret;
         if (x <= 0.0) {
             ret = 0.0;
@@ -222,7 +223,8 @@ public class FDistributionImpl
      *                                  positive.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setNumeratorDegreesOfFreedom(double degreesOfFreedom) {
         setNumeratorDegreesOfFreedomInternal(degreesOfFreedom);
     }
@@ -247,7 +249,8 @@ public class FDistributionImpl
      *
      * @return the numerator degrees of freedom.
      */
-    public double getNumeratorDegreesOfFreedom() {
+    @Override
+	public double getNumeratorDegreesOfFreedom() {
         return numeratorDegreesOfFreedom;
     }
 
@@ -259,7 +262,8 @@ public class FDistributionImpl
      *                                  positive.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setDenominatorDegreesOfFreedom(double degreesOfFreedom) {
         setDenominatorDegreesOfFreedomInternal(degreesOfFreedom);
     }
@@ -284,7 +288,8 @@ public class FDistributionImpl
      *
      * @return the denominator degrees of freedom.
      */
-    public double getDenominatorDegreesOfFreedom() {
+    @Override
+	public double getDenominatorDegreesOfFreedom() {
         return denominatorDegreesOfFreedom;
     }
 
diff --git a/src/org/apache/commons/math/distribution/GammaDistribution.java b/src/org/apache/commons/math/distribution/GammaDistribution.java
index 42a21a8..cc60f3d 100644
--- a/src/org/apache/commons/math/distribution/GammaDistribution.java
+++ b/src/org/apache/commons/math/distribution/GammaDistribution.java
@@ -29,7 +29,7 @@ package org.apache.commons.math.distribution;
  *
  * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $
  */
-public interface GammaDistribution extends ContinuousDistribution, HasDensity<Double> {
+public interface GammaDistribution extends ContinuousDistribution /*, HasDensity<Double>*/ {
     /**
      * Modify the shape parameter, alpha.
      *
diff --git a/src/org/apache/commons/math/distribution/GammaDistributionImpl.java b/src/org/apache/commons/math/distribution/GammaDistributionImpl.java
index defc265..3418aea 100644
--- a/src/org/apache/commons/math/distribution/GammaDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/GammaDistributionImpl.java
@@ -100,7 +100,8 @@ public class GammaDistributionImpl extends AbstractContinuousDistribution
      * @throws MathException if the cumulative probability can not be
      *                       computed due to convergence or other numerical errors.
      */
-    public double cumulativeProbability(double x) throws MathException {
+    @Override
+	public double cumulativeProbability(double x) throws MathException {
         double ret;
 
         if (x <= 0.0) {
@@ -144,7 +145,8 @@ public class GammaDistributionImpl extends AbstractContinuousDistribution
      * @throws IllegalArgumentException if <code>alpha</code> is not positive.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setAlpha(double alpha) {
         setAlphaInternal(alpha);
     }
@@ -169,7 +171,8 @@ public class GammaDistributionImpl extends AbstractContinuousDistribution
      *
      * @return alpha.
      */
-    public double getAlpha() {
+    @Override
+	public double getAlpha() {
         return alpha;
     }
 
@@ -180,7 +183,8 @@ public class GammaDistributionImpl extends AbstractContinuousDistribution
      * @throws IllegalArgumentException if <code>newBeta</code> is not positive.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setBeta(double newBeta) {
         setBetaInternal(newBeta);
     }
@@ -205,7 +209,8 @@ public class GammaDistributionImpl extends AbstractContinuousDistribution
      *
      * @return beta.
      */
-    public double getBeta() {
+    @Override
+	public double getBeta() {
         return beta;
     }
 
@@ -228,7 +233,9 @@ public class GammaDistributionImpl extends AbstractContinuousDistribution
      * @return The pdf at point x.
      * @deprecated
      */
-    public double density(Double x) {
+    @Deprecated
+	@Override
+	public double density(Double x) {
         return density(x.doubleValue());
     }
 
diff --git a/src/org/apache/commons/math/distribution/HasDensity.java b/src/org/apache/commons/math/distribution/HasDensity.java
index 9044374..ca95d77 100644
--- a/src/org/apache/commons/math/distribution/HasDensity.java
+++ b/src/org/apache/commons/math/distribution/HasDensity.java
@@ -31,6 +31,7 @@ import org.apache.commons.math.MathException;
  * @version $Revision: 924362 $ $Date: 2010-03-17 12:45:31 -0400 (Wed, 17 Mar 2010) $
  * @deprecated to be removed in math 3.0
  */
+ at Deprecated
 public interface HasDensity<P> {
 
     /**
diff --git a/src/org/apache/commons/math/distribution/HypergeometricDistributionImpl.java b/src/org/apache/commons/math/distribution/HypergeometricDistributionImpl.java
index 42f3cf2..71b5624 100644
--- a/src/org/apache/commons/math/distribution/HypergeometricDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/HypergeometricDistributionImpl.java
@@ -159,7 +159,8 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
      *
      * @return the number of successes.
      */
-    public int getNumberOfSuccesses() {
+    @Override
+	public int getNumberOfSuccesses() {
         return numberOfSuccesses;
     }
 
@@ -168,7 +169,8 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
      *
      * @return the population size.
      */
-    public int getPopulationSize() {
+    @Override
+	public int getPopulationSize() {
         return populationSize;
     }
 
@@ -177,7 +179,8 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
      *
      * @return the sample size.
      */
-    public int getSampleSize() {
+    @Override
+	public int getSampleSize() {
         return sampleSize;
     }
 
@@ -199,7 +202,8 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
      * @param x the value at which the PMF is evaluated.
      * @return PMF for this distribution.
      */
-    public double probability(int x) {
+    @Override
+	public double probability(int x) {
         double ret;
 
         int[] domain = getDomain(populationSize, numberOfSuccesses, sampleSize);
@@ -244,7 +248,8 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
      * @throws IllegalArgumentException if <code>num</code> is negative.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setNumberOfSuccesses(int num) {
         setNumberOfSuccessesInternal(num);
     }
@@ -270,7 +275,8 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
      * @throws IllegalArgumentException if <code>size</code> is not positive.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setPopulationSize(int size) {
         setPopulationSizeInternal(size);
     }
@@ -296,7 +302,8 @@ public class HypergeometricDistributionImpl extends AbstractIntegerDistribution
      * @throws IllegalArgumentException if <code>size</code> is negative.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setSampleSize(int size) {
         setSampleSizeInternal(size);
     }
diff --git a/src/org/apache/commons/math/distribution/NormalDistribution.java b/src/org/apache/commons/math/distribution/NormalDistribution.java
index adafe4e..706658d 100644
--- a/src/org/apache/commons/math/distribution/NormalDistribution.java
+++ b/src/org/apache/commons/math/distribution/NormalDistribution.java
@@ -30,7 +30,7 @@ package org.apache.commons.math.distribution;
  *
  * @version $Revision: 920852 $ $Date: 2010-03-09 07:53:44 -0500 (Tue, 09 Mar 2010) $
  */
-public interface NormalDistribution extends ContinuousDistribution, HasDensity<Double> {
+public interface NormalDistribution extends ContinuousDistribution /*, HasDensity<Double>*/ {
     /**
      * Access the mean.
      *
diff --git a/src/org/apache/commons/math/distribution/NormalDistributionImpl.java b/src/org/apache/commons/math/distribution/NormalDistributionImpl.java
index 913dbdc..0eceaec 100644
--- a/src/org/apache/commons/math/distribution/NormalDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/NormalDistributionImpl.java
@@ -104,7 +104,8 @@ public class NormalDistributionImpl extends AbstractContinuousDistribution
      *
      * @return mean for this distribution
      */
-    public double getMean() {
+    @Override
+	public double getMean() {
         return mean;
     }
 
@@ -114,7 +115,8 @@ public class NormalDistributionImpl extends AbstractContinuousDistribution
      * @param mean for this distribution
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setMean(double mean) {
         setMeanInternal(mean);
     }
@@ -133,7 +135,8 @@ public class NormalDistributionImpl extends AbstractContinuousDistribution
      *
      * @return standard deviation for this distribution
      */
-    public double getStandardDeviation() {
+    @Override
+	public double getStandardDeviation() {
         return standardDeviation;
     }
 
@@ -144,7 +147,8 @@ public class NormalDistributionImpl extends AbstractContinuousDistribution
      * @throws IllegalArgumentException if <code>sd</code> is not positive.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setStandardDeviation(double sd) {
         setStandardDeviationInternal(sd);
     }
@@ -171,7 +175,9 @@ public class NormalDistributionImpl extends AbstractContinuousDistribution
      * @return The pdf at point x.
      * @deprecated
      */
-    public double density(Double x) {
+    @Deprecated
+	@Override
+	public double density(Double x) {
         return density(x.doubleValue());
     }
 
@@ -205,7 +211,8 @@ public class NormalDistributionImpl extends AbstractContinuousDistribution
      *                       x is more than 20 standard deviations from the mean, in which case the
      *                       convergence exception is caught and 0 or 1 is returned.
      */
-    public double cumulativeProbability(double x) throws MathException {
+    @Override
+	public double cumulativeProbability(double x) throws MathException {
         try {
             return 0.5 * (1.0 + Erf.erf((x - mean) /
                     (standardDeviation * Math.sqrt(2.0))));
diff --git a/src/org/apache/commons/math/distribution/PascalDistributionImpl.java b/src/org/apache/commons/math/distribution/PascalDistributionImpl.java
index 6a4de7a..a5d6116 100644
--- a/src/org/apache/commons/math/distribution/PascalDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/PascalDistributionImpl.java
@@ -65,7 +65,8 @@ public class PascalDistributionImpl extends AbstractIntegerDistribution
      *
      * @return the number of successes
      */
-    public int getNumberOfSuccesses() {
+    @Override
+	public int getNumberOfSuccesses() {
         return numberOfSuccesses;
     }
 
@@ -74,7 +75,8 @@ public class PascalDistributionImpl extends AbstractIntegerDistribution
      *
      * @return the probability of success
      */
-    public double getProbabilityOfSuccess() {
+    @Override
+	public double getProbabilityOfSuccess() {
         return probabilityOfSuccess;
     }
 
@@ -86,7 +88,8 @@ public class PascalDistributionImpl extends AbstractIntegerDistribution
      *                                  positive.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setNumberOfSuccesses(int successes) {
         setNumberOfSuccessesInternal(successes);
     }
@@ -115,7 +118,8 @@ public class PascalDistributionImpl extends AbstractIntegerDistribution
      *                                  probability.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setProbabilityOfSuccess(double p) {
         setProbabilityOfSuccessInternal(p);
     }
@@ -188,7 +192,8 @@ public class PascalDistributionImpl extends AbstractIntegerDistribution
      * @param x the value at which the PMF is evaluated
      * @return PMF for this distribution
      */
-    public double probability(int x) {
+    @Override
+	public double probability(int x) {
         double ret;
         if (x < 0) {
             ret = 0.0;
diff --git a/src/org/apache/commons/math/distribution/PoissonDistributionImpl.java b/src/org/apache/commons/math/distribution/PoissonDistributionImpl.java
index af1b0c6..78c36fd 100644
--- a/src/org/apache/commons/math/distribution/PoissonDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/PoissonDistributionImpl.java
@@ -146,7 +146,8 @@ public class PoissonDistributionImpl extends AbstractIntegerDistribution
      *
      * @return the Poisson mean for the distribution.
      */
-    public double getMean() {
+    @Override
+	public double getMean() {
         return mean;
     }
 
@@ -158,7 +159,8 @@ public class PoissonDistributionImpl extends AbstractIntegerDistribution
      * @throws IllegalArgumentException if p ≤ 0
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setMean(double p) {
         setNormalAndMeanInternal(normal, p);
     }
@@ -171,7 +173,8 @@ public class PoissonDistributionImpl extends AbstractIntegerDistribution
      * @param p the Poisson mean value
      * @throws IllegalArgumentException if p ≤ 0
      */
-    private void setNormalAndMeanInternal(NormalDistribution z,
+    @SuppressWarnings("deprecation")
+	private void setNormalAndMeanInternal(NormalDistribution z,
                                           double p) {
         if (p <= 0) {
             throw MathRuntimeException.createIllegalArgumentException(
@@ -190,7 +193,8 @@ public class PoissonDistributionImpl extends AbstractIntegerDistribution
      *          evaluated.
      * @return the value of the probability mass function at x
      */
-    public double probability(int x) {
+    @Override
+	public double probability(int x) {
         double ret;
         if (x < 0 || x == Integer.MAX_VALUE) {
             ret = 0.0;
@@ -239,7 +243,8 @@ public class PoissonDistributionImpl extends AbstractIntegerDistribution
      * @throws MathException if an error occurs computing the normal
      *                       approximation
      */
-    public double normalApproximateProbability(int x) throws MathException {
+    @Override
+	public double normalApproximateProbability(int x) throws MathException {
         // calculate the probability using half-correction
         return normal.cumulativeProbability(x + 0.5);
     }
diff --git a/src/org/apache/commons/math/distribution/TDistributionImpl.java b/src/org/apache/commons/math/distribution/TDistributionImpl.java
index e4f97a4..928dff5 100644
--- a/src/org/apache/commons/math/distribution/TDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/TDistributionImpl.java
@@ -85,7 +85,8 @@ public class TDistributionImpl
      * @param degreesOfFreedom the new degrees of freedom.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setDegreesOfFreedom(double degreesOfFreedom) {
         setDegreesOfFreedomInternal(degreesOfFreedom);
     }
@@ -109,7 +110,8 @@ public class TDistributionImpl
      *
      * @return the degrees of freedom.
      */
-    public double getDegreesOfFreedom() {
+    @Override
+	public double getDegreesOfFreedom() {
         return degreesOfFreedom;
     }
 
@@ -123,9 +125,9 @@ public class TDistributionImpl
     @Override
     public double density(double x) {
         final double n = degreesOfFreedom;
-        final double nPlus1Over2 = (n + 1) / 2;
-        return Math.exp(Gamma.logGamma(nPlus1Over2) - 0.5 * (Math.log(Math.PI) + Math.log(n)) -
-                Gamma.logGamma(n / 2) - nPlus1Over2 * Math.log(1 + x * x / n));
+        final double plus1Over2 = (n + 1) / 2;
+        return Math.exp(Gamma.logGamma(plus1Over2) - 0.5 * (Math.log(Math.PI) + Math.log(n)) -
+                Gamma.logGamma(n / 2) - plus1Over2 * Math.log(1 + x * x / n));
     }
 
     /**
@@ -136,7 +138,8 @@ public class TDistributionImpl
      * @throws MathException if the cumulative probability can not be
      *                       computed due to convergence or other numerical errors.
      */
-    public double cumulativeProbability(double x) throws MathException {
+    @Override
+	public double cumulativeProbability(double x) throws MathException {
         double ret;
         if (x == 0.0) {
             ret = 0.5;
diff --git a/src/org/apache/commons/math/distribution/WeibullDistributionImpl.java b/src/org/apache/commons/math/distribution/WeibullDistributionImpl.java
index 4d9f1da..2a96606 100644
--- a/src/org/apache/commons/math/distribution/WeibullDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/WeibullDistributionImpl.java
@@ -92,7 +92,8 @@ public class WeibullDistributionImpl extends AbstractContinuousDistribution
      * @param x the value at which the CDF is evaluated.
      * @return CDF evaluted at <code>x</code>.
      */
-    public double cumulativeProbability(double x) {
+    @Override
+	public double cumulativeProbability(double x) {
         double ret;
         if (x <= 0.0) {
             ret = 0.0;
@@ -107,7 +108,8 @@ public class WeibullDistributionImpl extends AbstractContinuousDistribution
      *
      * @return the shape parameter.
      */
-    public double getShape() {
+    @Override
+	public double getShape() {
         return shape;
     }
 
@@ -116,7 +118,8 @@ public class WeibullDistributionImpl extends AbstractContinuousDistribution
      *
      * @return the scale parameter.
      */
-    public double getScale() {
+    @Override
+	public double getScale() {
         return scale;
     }
 
@@ -180,7 +183,8 @@ public class WeibullDistributionImpl extends AbstractContinuousDistribution
      * @param alpha the new shape parameter value.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setShape(double alpha) {
         setShapeInternal(alpha);
     }
@@ -205,7 +209,8 @@ public class WeibullDistributionImpl extends AbstractContinuousDistribution
      * @param beta the new scale parameter value.
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setScale(double beta) {
         setScaleInternal(beta);
     }
diff --git a/src/org/apache/commons/math/distribution/ZipfDistributionImpl.java b/src/org/apache/commons/math/distribution/ZipfDistributionImpl.java
index ff1dec3..c3127e0 100644
--- a/src/org/apache/commons/math/distribution/ZipfDistributionImpl.java
+++ b/src/org/apache/commons/math/distribution/ZipfDistributionImpl.java
@@ -64,7 +64,8 @@ public class ZipfDistributionImpl extends AbstractIntegerDistribution
      *
      * @return the number of elements
      */
-    public int getNumberOfElements() {
+    @Override
+	public int getNumberOfElements() {
         return numberOfElements;
     }
 
@@ -77,7 +78,8 @@ public class ZipfDistributionImpl extends AbstractIntegerDistribution
      * @throws IllegalArgumentException if n ≤ 0
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setNumberOfElements(final int n) {
         setNumberOfElementsInternal(n);
     }
@@ -105,7 +107,8 @@ public class ZipfDistributionImpl extends AbstractIntegerDistribution
      *
      * @return the exponent
      */
-    public double getExponent() {
+    @Override
+	public double getExponent() {
         return exponent;
     }
 
@@ -118,7 +121,8 @@ public class ZipfDistributionImpl extends AbstractIntegerDistribution
      * @throws IllegalArgumentException if s ≤ 0.0
      * @deprecated as of 2.1 (class will become immutable in 3.0)
      */
-    @Deprecated
+    @Override
+	@Deprecated
     public void setExponent(final double s) {
         setExponentInternal(s);
     }
@@ -147,7 +151,8 @@ public class ZipfDistributionImpl extends AbstractIntegerDistribution
      * @param x the value at which the probability density function is evaluated.
      * @return the value of the probability mass function at x
      */
-    public double probability(final int x) {
+    @Override
+	public double probability(final int x) {
         if (x <= 0 || x > numberOfElements) {
             return 0.0;
         }
diff --git a/src/org/json/CDL.java b/src/org/json/CDL.java
deleted file mode 100755
index 0fc3cf8..0000000
--- a/src/org/json/CDL.java
+++ /dev/null
@@ -1,279 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/**
- * This provides static methods to convert comma delimited text into a
- * JSONArray, and to covert a JSONArray into comma delimited text. Comma
- * delimited text is a very popular format for data interchange. It is
- * understood by most database, spreadsheet, and organizer programs.
- * <p>
- * Each row of text represents a row in a table or a data record. Each row
- * ends with a NEWLINE character. Each row contains one or more values.
- * Values are separated by commas. A value can contain any character except
- * for comma, unless is is wrapped in single quotes or double quotes.
- * <p>
- * The first row usually contains the names of the columns.
- * <p>
- * A comma delimited list can be converted into a JSONArray of JSONObjects.
- * The names for the elements in the JSONObjects can be taken from the names
- * in the first row.
- * @author JSON.org
- * @version 2012-11-13
- */
-public class CDL {
-
-    /**
-     * Get the next value. The value can be wrapped in quotes. The value can
-     * be empty.
-     * @param x A JSONTokener of the source text.
-     * @return The value string, or null if empty.
-     * @throws JSONException if the quoted string is badly formed.
-     */
-    private static String getValue(JSONTokener x) throws JSONException {
-        char c;
-        char q;
-        StringBuffer sb;
-        do {
-            c = x.next();
-        } while (c == ' ' || c == '\t');
-        switch (c) {
-        case 0:
-            return null;
-        case '"':
-        case '\'':
-            q = c;
-            sb = new StringBuffer();
-            for (;;) {
-                c = x.next();
-                if (c == q) {
-                    break;
-                }
-                if (c == 0 || c == '\n' || c == '\r') {
-                    throw x.syntaxError("Missing close quote '" + q + "'.");
-                }
-                sb.append(c);
-            }
-            return sb.toString();
-        case ',':
-            x.back();
-            return "";
-        default:
-            x.back();
-            return x.nextTo(',');
-        }
-    }
-
-    /**
-     * Produce a JSONArray of strings from a row of comma delimited values.
-     * @param x A JSONTokener of the source text.
-     * @return A JSONArray of strings.
-     * @throws JSONException
-     */
-    public static JSONArray rowToJSONArray(JSONTokener x) throws JSONException {
-        JSONArray ja = new JSONArray();
-        for (;;) {
-            String value = getValue(x);
-            char c = x.next();
-            if (value == null ||
-                    (ja.length() == 0 && value.length() == 0 && c != ',')) {
-                return null;
-            }
-            ja.put(value);
-            for (;;) {
-                if (c == ',') {
-                    break;
-                }
-                if (c != ' ') {
-                    if (c == '\n' || c == '\r' || c == 0) {
-                        return ja;
-                    }
-                    throw x.syntaxError("Bad character '" + c + "' (" +
-                            (int)c + ").");
-                }
-                c = x.next();
-            }
-        }
-    }
-
-    /**
-     * Produce a JSONObject from a row of comma delimited text, using a
-     * parallel JSONArray of strings to provides the names of the elements.
-     * @param names A JSONArray of names. This is commonly obtained from the
-     *  first row of a comma delimited text file using the rowToJSONArray
-     *  method.
-     * @param x A JSONTokener of the source text.
-     * @return A JSONObject combining the names and values.
-     * @throws JSONException
-     */
-    public static JSONObject rowToJSONObject(JSONArray names, JSONTokener x)
-            throws JSONException {
-        JSONArray ja = rowToJSONArray(x);
-        return ja != null ? ja.toJSONObject(names) :  null;
-    }
-
-    /**
-     * Produce a comma delimited text row from a JSONArray. Values containing
-     * the comma character will be quoted. Troublesome characters may be
-     * removed.
-     * @param ja A JSONArray of strings.
-     * @return A string ending in NEWLINE.
-     */
-    public static String rowToString(JSONArray ja) {
-        StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < ja.length(); i += 1) {
-            if (i > 0) {
-                sb.append(',');
-            }
-            Object object = ja.opt(i);
-            if (object != null) {
-                String string = object.toString();
-                if (string.length() > 0 && (string.indexOf(',') >= 0 ||
-                        string.indexOf('\n') >= 0 || string.indexOf('\r') >= 0 ||
-                        string.indexOf(0) >= 0 || string.charAt(0) == '"')) {
-                    sb.append('"');
-                    int length = string.length();
-                    for (int j = 0; j < length; j += 1) {
-                        char c = string.charAt(j);
-                        if (c >= ' ' && c != '"') {
-                            sb.append(c);
-                        }
-                    }
-                    sb.append('"');
-                } else {
-                    sb.append(string);
-                }
-            }
-        }
-        sb.append('\n');
-        return sb.toString();
-    }
-
-    /**
-     * Produce a JSONArray of JSONObjects from a comma delimited text string,
-     * using the first row as a source of names.
-     * @param string The comma delimited text.
-     * @return A JSONArray of JSONObjects.
-     * @throws JSONException
-     */
-    public static JSONArray toJSONArray(String string) throws JSONException {
-        return toJSONArray(new JSONTokener(string));
-    }
-
-    /**
-     * Produce a JSONArray of JSONObjects from a comma delimited text string,
-     * using the first row as a source of names.
-     * @param x The JSONTokener containing the comma delimited text.
-     * @return A JSONArray of JSONObjects.
-     * @throws JSONException
-     */
-    public static JSONArray toJSONArray(JSONTokener x) throws JSONException {
-        return toJSONArray(rowToJSONArray(x), x);
-    }
-
-    /**
-     * Produce a JSONArray of JSONObjects from a comma delimited text string
-     * using a supplied JSONArray as the source of element names.
-     * @param names A JSONArray of strings.
-     * @param string The comma delimited text.
-     * @return A JSONArray of JSONObjects.
-     * @throws JSONException
-     */
-    public static JSONArray toJSONArray(JSONArray names, String string)
-            throws JSONException {
-        return toJSONArray(names, new JSONTokener(string));
-    }
-
-    /**
-     * Produce a JSONArray of JSONObjects from a comma delimited text string
-     * using a supplied JSONArray as the source of element names.
-     * @param names A JSONArray of strings.
-     * @param x A JSONTokener of the source text.
-     * @return A JSONArray of JSONObjects.
-     * @throws JSONException
-     */
-    public static JSONArray toJSONArray(JSONArray names, JSONTokener x)
-            throws JSONException {
-        if (names == null || names.length() == 0) {
-            return null;
-        }
-        JSONArray ja = new JSONArray();
-        for (;;) {
-            JSONObject jo = rowToJSONObject(names, x);
-            if (jo == null) {
-                break;
-            }
-            ja.put(jo);
-        }
-        if (ja.length() == 0) {
-            return null;
-        }
-        return ja;
-    }
-
-
-    /**
-     * Produce a comma delimited text from a JSONArray of JSONObjects. The
-     * first row will be a list of names obtained by inspecting the first
-     * JSONObject.
-     * @param ja A JSONArray of JSONObjects.
-     * @return A comma delimited text.
-     * @throws JSONException
-     */
-    public static String toString(JSONArray ja) throws JSONException {
-        JSONObject jo = ja.optJSONObject(0);
-        if (jo != null) {
-            JSONArray names = jo.names();
-            if (names != null) {
-                return rowToString(names) + toString(names, ja);
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Produce a comma delimited text from a JSONArray of JSONObjects using
-     * a provided list of names. The list of names is not included in the
-     * output.
-     * @param names A JSONArray of strings.
-     * @param ja A JSONArray of JSONObjects.
-     * @return A comma delimited text.
-     * @throws JSONException
-     */
-    public static String toString(JSONArray names, JSONArray ja)
-            throws JSONException {
-        if (names == null || names.length() == 0) {
-            return null;
-        }
-        StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < ja.length(); i += 1) {
-            JSONObject jo = ja.optJSONObject(i);
-            if (jo != null) {
-                sb.append(rowToString(jo.toJSONArray(names)));
-            }
-        }
-        return sb.toString();
-    }
-}
diff --git a/src/org/json/Cookie.java b/src/org/json/Cookie.java
deleted file mode 100755
index 9cf5ce2..0000000
--- a/src/org/json/Cookie.java
+++ /dev/null
@@ -1,169 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/**
- * Convert a web browser cookie specification to a JSONObject and back.
- * JSON and Cookies are both notations for name/value pairs.
- * @author JSON.org
- * @version 2010-12-24
- */
-public class Cookie {
-
-    /**
-     * Produce a copy of a string in which the characters '+', '%', '=', ';'
-     * and control characters are replaced with "%hh". This is a gentle form
-     * of URL encoding, attempting to cause as little distortion to the
-     * string as possible. The characters '=' and ';' are meta characters in
-     * cookies. By convention, they are escaped using the URL-encoding. This is
-     * only a convention, not a standard. Often, cookies are expected to have
-     * encoded values. We encode '=' and ';' because we must. We encode '%' and
-     * '+' because they are meta characters in URL encoding.
-     * @param string The source string.
-     * @return       The escaped result.
-     */
-    public static String escape(String string) {
-        char         c;
-        String       s = string.trim();
-        StringBuffer sb = new StringBuffer();
-        int          length = s.length();
-        for (int i = 0; i < length; i += 1) {
-            c = s.charAt(i);
-            if (c < ' ' || c == '+' || c == '%' || c == '=' || c == ';') {
-                sb.append('%');
-                sb.append(Character.forDigit((char)((c >>> 4) & 0x0f), 16));
-                sb.append(Character.forDigit((char)(c & 0x0f), 16));
-            } else {
-                sb.append(c);
-            }
-        }
-        return sb.toString();
-    }
-
-
-    /**
-     * Convert a cookie specification string into a JSONObject. The string
-     * will contain a name value pair separated by '='. The name and the value
-     * will be unescaped, possibly converting '+' and '%' sequences. The
-     * cookie properties may follow, separated by ';', also represented as
-     * name=value (except the secure property, which does not have a value).
-     * The name will be stored under the key "name", and the value will be
-     * stored under the key "value". This method does not do checking or
-     * validation of the parameters. It only converts the cookie string into
-     * a JSONObject.
-     * @param string The cookie specification string.
-     * @return A JSONObject containing "name", "value", and possibly other
-     *  members.
-     * @throws JSONException
-     */
-    public static JSONObject toJSONObject(String string) throws JSONException {
-        String         name;
-        JSONObject     jo = new JSONObject();
-        Object         value;
-        JSONTokener x = new JSONTokener(string);
-        jo.put("name", x.nextTo('='));
-        x.next('=');
-        jo.put("value", x.nextTo(';'));
-        x.next();
-        while (x.more()) {
-            name = unescape(x.nextTo("=;"));
-            if (x.next() != '=') {
-                if (name.equals("secure")) {
-                    value = Boolean.TRUE;
-                } else {
-                    throw x.syntaxError("Missing '=' in cookie parameter.");
-                }
-            } else {
-                value = unescape(x.nextTo(';'));
-                x.next();
-            }
-            jo.put(name, value);
-        }
-        return jo;
-    }
-
-
-    /**
-     * Convert a JSONObject into a cookie specification string. The JSONObject
-     * must contain "name" and "value" members.
-     * If the JSONObject contains "expires", "domain", "path", or "secure"
-     * members, they will be appended to the cookie specification string.
-     * All other members are ignored.
-     * @param jo A JSONObject
-     * @return A cookie specification string
-     * @throws JSONException
-     */
-    public static String toString(JSONObject jo) throws JSONException {
-        StringBuffer sb = new StringBuffer();
-
-        sb.append(escape(jo.getString("name")));
-        sb.append("=");
-        sb.append(escape(jo.getString("value")));
-        if (jo.has("expires")) {
-            sb.append(";expires=");
-            sb.append(jo.getString("expires"));
-        }
-        if (jo.has("domain")) {
-            sb.append(";domain=");
-            sb.append(escape(jo.getString("domain")));
-        }
-        if (jo.has("path")) {
-            sb.append(";path=");
-            sb.append(escape(jo.getString("path")));
-        }
-        if (jo.optBoolean("secure")) {
-            sb.append(";secure");
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Convert <code>%</code><i>hh</i> sequences to single characters, and
-     * convert plus to space.
-     * @param string A string that may contain
-     *      <code>+</code> <small>(plus)</small> and
-     *      <code>%</code><i>hh</i> sequences.
-     * @return The unescaped string.
-     */
-    public static String unescape(String string) {
-        int length = string.length();
-        StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < length; ++i) {
-            char c = string.charAt(i);
-            if (c == '+') {
-                c = ' ';
-            } else if (c == '%' && i + 2 < length) {
-                int d = JSONTokener.dehexchar(string.charAt(i + 1));
-                int e = JSONTokener.dehexchar(string.charAt(i + 2));
-                if (d >= 0 && e >= 0) {
-                    c = (char)(d * 16 + e);
-                    i += 2;
-                }
-            }
-            sb.append(c);
-        }
-        return sb.toString();
-    }
-}
diff --git a/src/org/json/CookieList.java b/src/org/json/CookieList.java
deleted file mode 100755
index 7f4fe07..0000000
--- a/src/org/json/CookieList.java
+++ /dev/null
@@ -1,90 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-import java.util.Iterator;
-
-/**
- * Convert a web browser cookie list string to a JSONObject and back.
- * @author JSON.org
- * @version 2010-12-24
- */
-public class CookieList {
-
-    /**
-     * Convert a cookie list into a JSONObject. A cookie list is a sequence
-     * of name/value pairs. The names are separated from the values by '='.
-     * The pairs are separated by ';'. The names and the values
-     * will be unescaped, possibly converting '+' and '%' sequences.
-     *
-     * To add a cookie to a cooklist,
-     * cookielistJSONObject.put(cookieJSONObject.getString("name"),
-     *     cookieJSONObject.getString("value"));
-     * @param string  A cookie list string
-     * @return A JSONObject
-     * @throws JSONException
-     */
-    public static JSONObject toJSONObject(String string) throws JSONException {
-        JSONObject jo = new JSONObject();
-        JSONTokener x = new JSONTokener(string);
-        while (x.more()) {
-            String name = Cookie.unescape(x.nextTo('='));
-            x.next('=');
-            jo.put(name, Cookie.unescape(x.nextTo(';')));
-            x.next();
-        }
-        return jo;
-    }
-
-
-    /**
-     * Convert a JSONObject into a cookie list. A cookie list is a sequence
-     * of name/value pairs. The names are separated from the values by '='.
-     * The pairs are separated by ';'. The characters '%', '+', '=', and ';'
-     * in the names and values are replaced by "%hh".
-     * @param jo A JSONObject
-     * @return A cookie list string
-     * @throws JSONException
-     */
-    public static String toString(JSONObject jo) throws JSONException {
-        boolean      b = false;
-        Iterator     keys = jo.keys();
-        String       string;
-        StringBuffer sb = new StringBuffer();
-        while (keys.hasNext()) {
-            string = keys.next().toString();
-            if (!jo.isNull(string)) {
-                if (b) {
-                    sb.append(';');
-                }
-                sb.append(Cookie.escape(string));
-                sb.append("=");
-                sb.append(Cookie.escape(jo.getString(string)));
-                b = true;
-            }
-        }
-        return sb.toString();
-    }
-}
diff --git a/src/org/json/HTTP.java b/src/org/json/HTTP.java
deleted file mode 100755
index 43d04a8..0000000
--- a/src/org/json/HTTP.java
+++ /dev/null
@@ -1,163 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-import java.util.Iterator;
-
-/**
- * Convert an HTTP header to a JSONObject and back.
- * @author JSON.org
- * @version 2010-12-24
- */
-public class HTTP {
-
-    /** Carriage return/line feed. */
-    public static final String CRLF = "\r\n";
-
-    /**
-     * Convert an HTTP header string into a JSONObject. It can be a request
-     * header or a response header. A request header will contain
-     * <pre>{
-     *    Method: "POST" (for example),
-     *    "Request-URI": "/" (for example),
-     *    "HTTP-Version": "HTTP/1.1" (for example)
-     * }</pre>
-     * A response header will contain
-     * <pre>{
-     *    "HTTP-Version": "HTTP/1.1" (for example),
-     *    "Status-Code": "200" (for example),
-     *    "Reason-Phrase": "OK" (for example)
-     * }</pre>
-     * In addition, the other parameters in the header will be captured, using
-     * the HTTP field names as JSON names, so that <pre>
-     *    Date: Sun, 26 May 2002 18:06:04 GMT
-     *    Cookie: Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s
-     *    Cache-Control: no-cache</pre>
-     * become
-     * <pre>{...
-     *    Date: "Sun, 26 May 2002 18:06:04 GMT",
-     *    Cookie: "Q=q2=PPEAsg--; B=677gi6ouf29bn&b=2&f=s",
-     *    "Cache-Control": "no-cache",
-     * ...}</pre>
-     * It does no further checking or conversion. It does not parse dates.
-     * It does not do '%' transforms on URLs.
-     * @param string An HTTP header string.
-     * @return A JSONObject containing the elements and attributes
-     * of the XML string.
-     * @throws JSONException
-     */
-    public static JSONObject toJSONObject(String string) throws JSONException {
-        JSONObject     jo = new JSONObject();
-        HTTPTokener    x = new HTTPTokener(string);
-        String         token;
-
-        token = x.nextToken();
-        if (token.toUpperCase().startsWith("HTTP")) {
-
-// Response
-
-            jo.put("HTTP-Version", token);
-            jo.put("Status-Code", x.nextToken());
-            jo.put("Reason-Phrase", x.nextTo('\0'));
-            x.next();
-
-        } else {
-
-// Request
-
-            jo.put("Method", token);
-            jo.put("Request-URI", x.nextToken());
-            jo.put("HTTP-Version", x.nextToken());
-        }
-
-// Fields
-
-        while (x.more()) {
-            String name = x.nextTo(':');
-            x.next(':');
-            jo.put(name, x.nextTo('\0'));
-            x.next();
-        }
-        return jo;
-    }
-
-
-    /**
-     * Convert a JSONObject into an HTTP header. A request header must contain
-     * <pre>{
-     *    Method: "POST" (for example),
-     *    "Request-URI": "/" (for example),
-     *    "HTTP-Version": "HTTP/1.1" (for example)
-     * }</pre>
-     * A response header must contain
-     * <pre>{
-     *    "HTTP-Version": "HTTP/1.1" (for example),
-     *    "Status-Code": "200" (for example),
-     *    "Reason-Phrase": "OK" (for example)
-     * }</pre>
-     * Any other members of the JSONObject will be output as HTTP fields.
-     * The result will end with two CRLF pairs.
-     * @param jo A JSONObject
-     * @return An HTTP header string.
-     * @throws JSONException if the object does not contain enough
-     *  information.
-     */
-    public static String toString(JSONObject jo) throws JSONException {
-        Iterator     keys = jo.keys();
-        String       string;
-        StringBuffer sb = new StringBuffer();
-        if (jo.has("Status-Code") && jo.has("Reason-Phrase")) {
-            sb.append(jo.getString("HTTP-Version"));
-            sb.append(' ');
-            sb.append(jo.getString("Status-Code"));
-            sb.append(' ');
-            sb.append(jo.getString("Reason-Phrase"));
-        } else if (jo.has("Method") && jo.has("Request-URI")) {
-            sb.append(jo.getString("Method"));
-            sb.append(' ');
-            sb.append('"');
-            sb.append(jo.getString("Request-URI"));
-            sb.append('"');
-            sb.append(' ');
-            sb.append(jo.getString("HTTP-Version"));
-        } else {
-            throw new JSONException("Not enough material for an HTTP header.");
-        }
-        sb.append(CRLF);
-        while (keys.hasNext()) {
-            string = keys.next().toString();
-            if (!"HTTP-Version".equals(string)      && !"Status-Code".equals(string) &&
-                    !"Reason-Phrase".equals(string) && !"Method".equals(string) &&
-                    !"Request-URI".equals(string)   && !jo.isNull(string)) {
-                sb.append(string);
-                sb.append(": ");
-                sb.append(jo.getString(string));
-                sb.append(CRLF);
-            }
-        }
-        sb.append(CRLF);
-        return sb.toString();
-    }
-}
diff --git a/src/org/json/HTTPTokener.java b/src/org/json/HTTPTokener.java
deleted file mode 100755
index ed41744..0000000
--- a/src/org/json/HTTPTokener.java
+++ /dev/null
@@ -1,77 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/**
- * The HTTPTokener extends the JSONTokener to provide additional methods
- * for the parsing of HTTP headers.
- * @author JSON.org
- * @version 2012-11-13
- */
-public class HTTPTokener extends JSONTokener {
-
-    /**
-     * Construct an HTTPTokener from a string.
-     * @param string A source string.
-     */
-    public HTTPTokener(String string) {
-        super(string);
-    }
-
-
-    /**
-     * Get the next token or string. This is used in parsing HTTP headers.
-     * @throws JSONException
-     * @return A String.
-     */
-    public String nextToken() throws JSONException {
-        char c;
-        char q;
-        StringBuffer sb = new StringBuffer();
-        do {
-            c = next();
-        } while (Character.isWhitespace(c));
-        if (c == '"' || c == '\'') {
-            q = c;
-            for (;;) {
-                c = next();
-                if (c < ' ') {
-                    throw syntaxError("Unterminated string.");
-                }
-                if (c == q) {
-                    return sb.toString();
-                }
-                sb.append(c);
-            }
-        }
-        for (;;) {
-            if (c == 0 || Character.isWhitespace(c)) {
-                return sb.toString();
-            }
-            sb.append(c);
-            c = next();
-        }
-    }
-}
diff --git a/src/org/json/JSON.java b/src/org/json/JSON.java
new file mode 100644
index 0000000..e3b10e4
--- /dev/null
+++ b/src/org/json/JSON.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+class JSON {
+    /**
+     * Returns the input if it is a JSON-permissible value; throws otherwise.
+     */
+    static double checkDouble(double d) throws JSONException {
+    	// For BEAST, we allow non-standard values
+//        if (Double.isInfinite(d) || Double.isNaN(d)) {
+//            throw new JSONException("Forbidden numeric value: " + d);
+//        }
+        return d;
+    }
+
+    static Boolean toBoolean(Object value) {
+        if (value instanceof Boolean) {
+            return (Boolean) value;
+        } else if (value instanceof String) {
+            String stringValue = (String) value;
+            if ("true".equalsIgnoreCase(stringValue)) {
+                return true;
+            } else if ("false".equalsIgnoreCase(stringValue)) {
+                return false;
+            }
+        }
+        return null;
+    }
+
+    static Double toDouble(Object value) {
+        if (value instanceof Double) {
+            return (Double) value;
+        } else if (value instanceof Number) {
+            return ((Number) value).doubleValue();
+        } else if (value instanceof String) {
+            try {
+                return Double.valueOf((String) value);
+            } catch (NumberFormatException ignored) {
+            }
+        }
+        return null;
+    }
+
+    static Integer toInteger(Object value) {
+        if (value instanceof Integer) {
+            return (Integer) value;
+        } else if (value instanceof Number) {
+            return ((Number) value).intValue();
+        } else if (value instanceof String) {
+            try {
+                return (int) Double.parseDouble((String) value);
+            } catch (NumberFormatException ignored) {
+            }
+        }
+        return null;
+    }
+
+    static Long toLong(Object value) {
+        if (value instanceof Long) {
+            return (Long) value;
+        } else if (value instanceof Number) {
+            return ((Number) value).longValue();
+        } else if (value instanceof String) {
+            try {
+                return (long) Double.parseDouble((String) value);
+            } catch (NumberFormatException ignored) {
+            }
+        }
+        return null;
+    }
+
+    static String toString(Object value) {
+        if (value instanceof String) {
+            return (String) value;
+        } else if (value != null) {
+            return String.valueOf(value);
+        }
+        return null;
+    }
+
+    public static JSONException typeMismatch(Object indexOrName, Object actual,
+            String requiredType) throws JSONException {
+        if (actual == null) {
+            throw new JSONException("Value at " + indexOrName + " is null.");
+        } else {
+            throw new JSONException("Value " + actual + " at " + indexOrName
+                    + " of type " + actual.getClass().getName()
+                    + " cannot be converted to " + requiredType);
+        }
+    }
+
+    public static JSONException typeMismatch(Object actual, String requiredType)
+            throws JSONException {
+        if (actual == null) {
+            throw new JSONException("Value is null.");
+        } else {
+            throw new JSONException("Value " + actual
+                    + " of type " + actual.getClass().getName()
+                    + " cannot be converted to " + requiredType);
+        }
+    }
+}
diff --git a/src/org/json/JSONArray.java b/src/org/json/JSONArray.java
index f8a8a72..7a84243 100644
--- a/src/org/json/JSONArray.java
+++ b/src/org/json/JSONArray.java
@@ -1,987 +1,657 @@
-package org.json;
-
 /*
- Copyright (c) 2002 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
+package org.json;
+
 import java.lang.reflect.Array;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
-import java.util.Map;
+import java.util.List;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
 
 /**
- * A JSONArray is an ordered sequence of values. Its external text form is a
- * string wrapped in square brackets with commas separating the values. The
- * internal form is an object having <code>get</code> and <code>opt</code>
- * methods for accessing the values by index, and <code>put</code> methods for
- * adding or replacing values. The values can be any of these types:
- * <code>Boolean</code>, <code>JSONArray</code>, <code>JSONObject</code>,
- * <code>Number</code>, <code>String</code>, or the
- * <code>JSONObject.NULL object</code>.
- * <p>
- * The constructor can convert a JSON text into a Java object. The
- * <code>toString</code> method converts to JSON text.
- * <p>
- * A <code>get</code> method returns a value if one can be found, and throws an
- * exception if one cannot be found. An <code>opt</code> method returns a
- * default value instead of throwing an exception, and so is useful for
- * obtaining optional values.
- * <p>
- * The generic <code>get()</code> and <code>opt()</code> methods return an
- * object which you can cast or query for type. There are also typed
- * <code>get</code> and <code>opt</code> methods that do type checking and type
- * coercion for you.
- * <p>
- * The texts produced by the <code>toString</code> methods strictly conform to
- * JSON syntax rules. The constructors are more forgiving in the texts they will
- * accept:
- * <ul>
- * <li>An extra <code>,</code> <small>(comma)</small> may appear just
- * before the closing bracket.</li>
- * <li>The <code>null</code> value will be inserted when there is <code>,</code>
- *  <small>(comma)</small> elision.</li>
- * <li>Strings may be quoted with <code>'</code> <small>(single
- * quote)</small>.</li>
- * <li>Strings do not need to be quoted at all if they do not begin with a quote
- * or single quote, and if they do not contain leading or trailing spaces, and
- * if they do not contain any of these characters:
- * <code>{ } [ ] / \ : , #</code> and if they do not look like numbers and
- * if they are not the reserved words <code>true</code>, <code>false</code>, or
- * <code>null</code>.</li>
- * </ul>
+ * A dense indexed sequence of values. Values may be any mix of
+ * {@link JSONObject JSONObjects}, other {@link JSONArray JSONArrays}, Strings,
+ * Booleans, Integers, Longs, Doubles, {@code null} or {@link JSONObject#NULL}.
+ * Values may not be {@link Double#isNaN() NaNs}, {@link Double#isInfinite()
+ * infinities}, or of any type not listed here.
+ *
+ * <p>{@code JSONArray} has the same type coercion behavior and
+ * optional/mandatory accessors as {@link JSONObject}. See that class'
+ * documentation for details.
  *
- * @author JSON.org
- * @version 2013-04-18
+ * <p><strong>Warning:</strong> this class represents null in two incompatible
+ * ways: the standard Java {@code null} reference, and the sentinel value {@link
+ * JSONObject#NULL}. In particular, {@code get} fails if the requested index
+ * holds the null reference, but succeeds if it holds {@code JSONObject.NULL}.
+ *
+ * <p>Instances of this class are not thread safe. Although this class is
+ * nonfinal, it was not designed for inheritance and should not be subclassed.
+ * In particular, self-use by overridable methods is not specified. See
+ * <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
+ * prohibit it" for further information.
  */
 public class JSONArray {
 
-    /**
-     * The arrayList where the JSONArray's properties are kept.
-     */
-    private final ArrayList myArrayList;
-
-    protected Object parent = null;
+    private final List<Object> values;
     
-    public Object getParent() {
-    	return parent;
-    }
+    private Object parent = null;
 
     /**
-     * Construct an empty JSONArray.
+     * Creates a {@code JSONArray} with no values.
      */
     public JSONArray() {
-        this.myArrayList = new ArrayList();
+        values = new ArrayList<Object>();
     }
 
     /**
-     * Construct a JSONArray from a JSONTokener.
+     * Creates a new {@code JSONArray} by copying all values from the given
+     * collection.
      *
-     * @param x
-     *            A JSONTokener
-     * @throws JSONException
-     *             If there is a syntax error.
+     * @param copyFrom a collection whose values are of supported types.
+     *     Unsupported values are not permitted and will yield an array in an
+     *     inconsistent state.
      */
-    public JSONArray(JSONTokener x) throws JSONException {
+    /* Accept a raw type for API compatibility */
+    public JSONArray(@SuppressWarnings("rawtypes") Collection copyFrom) {
         this();
-        if (x.nextClean() != '[') {
-            throw x.syntaxError("A JSONArray text must start with '['");
-        }
-        if (x.nextClean() != ']') {
-            x.back();
-            for (;;) {
-                if (x.nextClean() == ',') {
-                    x.back();
-                    this.myArrayList.add(JSONObject.NULL);
-                } else {
-                    x.back();
-                    add(x.nextValue());
-                }
-                switch (x.nextClean()) {
-                case ',':
-                    if (x.nextClean() == ']') {
-                        return;
-                    }
-                    x.back();
-                    break;
-                case ']':
-                    return;
-                default:
-                    throw x.syntaxError("Expected a ',' or ']'");
-                }
+        if (copyFrom != null) {
+            for (@SuppressWarnings("rawtypes")
+			Iterator it = copyFrom.iterator(); it.hasNext();) {
+                put(JSONObject.wrap(it.next()));
             }
         }
     }
 
-    public void add(Object o) {
-    	this.myArrayList.add(o);
-    	if (o instanceof JSONObject) {
-    		((JSONObject)o).parent = this;
-    	}
-    	if (o instanceof JSONArray) {
-    		((JSONArray)o).parent = this;
-    	}
-    }
-
-    public void insert(int index, Object o) {
-    	this.myArrayList.add(index, o);
-    	if (o instanceof JSONObject) {
-    		((JSONObject)o).parent = this;
-    	}
-    	if (o instanceof JSONArray) {
-    		((JSONArray)o).parent = this;
-    	}
-    }
-
-    public int indexOf(Object o) {
-    	return this.myArrayList.indexOf(o);
-    }
-
     /**
-     * Construct a JSONArray from a source JSON text.
+     * Creates a new {@code JSONArray} with values from the next array in the
+     * tokener.
      *
-     * @param source
-     *            A string that begins with <code>[</code> <small>(left
-     *            bracket)</small> and ends with <code>]</code>
-     *             <small>(right bracket)</small>.
-     * @throws JSONException
-     *             If there is a syntax error.
+     * @param readFrom a tokener whose nextValue() method will yield a
+     *     {@code JSONArray}.
+     * @throws JSONException if the parse fails or doesn't yield a
+     *     {@code JSONArray}.
      */
-    public JSONArray(String source) throws JSONException {
-        this(new JSONTokener(source));
-    }
-
-    /**
-     * Construct a JSONArray from a Collection.
-     *
-     * @param collection
-     *            A Collection.
-     */
-    public JSONArray(Collection collection) {
-        this.myArrayList = new ArrayList();
-        if (collection != null) {
-            Iterator iter = collection.iterator();
-            while (iter.hasNext()) {
-                add(JSONObject.wrap(iter.next()));
-            }
+    public JSONArray(JSONTokener readFrom) throws JSONException {
+        /*
+         * Getting the parser to populate this could get tricky. Instead, just
+         * parse to temporary JSONArray and then steal the data from that.
+         */
+        Object object = readFrom.nextValue();
+        if (object instanceof JSONArray) {
+            values = ((JSONArray) object).values;
+        } else {
+            throw JSON.typeMismatch(object, "JSONArray");
         }
     }
 
     /**
-     * Construct a JSONArray from an array
+     * Creates a new {@code JSONArray} with values from the JSON string.
      *
-     * @throws JSONException
-     *             If not an array.
+     * @param json a JSON-encoded string containing an array.
+     * @throws JSONException if the parse fails or doesn't yield a {@code
+     *     JSONArray}.
      */
-    public JSONArray(Object array) throws JSONException {
-        this();
-        if (array.getClass().isArray()) {
-            int length = Array.getLength(array);
-            for (int i = 0; i < length; i += 1) {
-                this.put(JSONObject.wrap(Array.get(array, i)));
-            }
-        } else {
-            throw new JSONException(
-                    "JSONArray initial value should be a string or collection or array.");
-        }
+    public JSONArray(String json) throws JSONException {
+        this(new JSONTokener(json));
     }
 
     /**
-     * Get the object value associated with an index.
-     *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return An object value.
-     * @throws JSONException
-     *             If there is no value for the index.
+     * Creates a new {@code JSONArray} with values from the given primitive array.
      */
-    public Object get(int index) throws JSONException {
-        Object object = this.opt(index);
-        if (object == null) {
-            throw new JSONException("JSONArray[" + index + "] not found.");
+    public JSONArray(Object array) throws JSONException {
+        if (!array.getClass().isArray()) {
+            throw new JSONException("Not a primitive array: " + array.getClass());
+        }
+        final int length = Array.getLength(array);
+        values = new ArrayList<Object>(length);
+        for (int i = 0; i < length; ++i) {
+            put(JSONObject.wrap(Array.get(array, i)));
         }
-        return object;
     }
 
     /**
-     * Get the boolean value associated with an index. The string values "true"
-     * and "false" are converted to boolean.
-     *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return The truth.
-     * @throws JSONException
-     *             If there is no value for the index or if the value is not
-     *             convertible to boolean.
+     * Returns the number of values in this array.
      */
-    public boolean getBoolean(int index) throws JSONException {
-        Object object = this.get(index);
-        if (object.equals(Boolean.FALSE)
-                || (object instanceof String && ((String) object)
-                        .equalsIgnoreCase("false"))) {
-            return false;
-        } else if (object.equals(Boolean.TRUE)
-                || (object instanceof String && ((String) object)
-                        .equalsIgnoreCase("true"))) {
-            return true;
-        }
-        throw new JSONException("JSONArray[" + index + "] is not a boolean.");
+    public int length() {
+        return values.size();
     }
 
     /**
-     * Get the double value associated with an index.
+     * Appends {@code value} to the end of this array.
      *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return The value.
-     * @throws JSONException
-     *             If the key is not found or if the value cannot be converted
-     *             to a number.
+     * @return this array.
      */
-    public double getDouble(int index) throws JSONException {
-        Object object = this.get(index);
-        try {
-            return object instanceof Number ? ((Number) object).doubleValue()
-                    : Double.parseDouble((String) object);
-        } catch (Exception e) {
-            throw new JSONException("JSONArray[" + index + "] is not a number.");
-        }
+    public JSONArray put(boolean value) {
+        values.add(value);
+        return this;
     }
 
     /**
-     * Get the int value associated with an index.
+     * Appends {@code value} to the end of this array.
      *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return The value.
-     * @throws JSONException
-     *             If the key is not found or if the value is not a number.
+     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+     *     {@link Double#isInfinite() infinities}.
+     * @return this array.
      */
-    public int getInt(int index) throws JSONException {
-        Object object = this.get(index);
-        try {
-            return object instanceof Number ? ((Number) object).intValue()
-                    : Integer.parseInt((String) object);
-        } catch (Exception e) {
-            throw new JSONException("JSONArray[" + index + "] is not a number.");
-        }
+    public JSONArray put(double value) throws JSONException {
+        values.add(JSON.checkDouble(value));
+        return this;
     }
 
     /**
-     * Get the JSONArray associated with an index.
+     * Appends {@code value} to the end of this array.
      *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return A JSONArray value.
-     * @throws JSONException
-     *             If there is no value for the index. or if the value is not a
-     *             JSONArray
+     * @return this array.
      */
-    public JSONArray getJSONArray(int index) throws JSONException {
-        Object object = this.get(index);
-        if (object instanceof JSONArray) {
-            return (JSONArray) object;
-        }
-        throw new JSONException("JSONArray[" + index + "] is not a JSONArray.");
+    public JSONArray put(int value) {
+        values.add(value);
+        return this;
     }
 
     /**
-     * Get the JSONObject associated with an index.
+     * Appends {@code value} to the end of this array.
      *
-     * @param index
-     *            subscript
-     * @return A JSONObject value.
-     * @throws JSONException
-     *             If there is no value for the index or if the value is not a
-     *             JSONObject
+     * @return this array.
      */
-    public JSONObject getJSONObject(int index) throws JSONException {
-        Object object = this.get(index);
-        if (object instanceof JSONObject) {
-            return (JSONObject) object;
-        }
-        throw new JSONException("JSONArray[" + index + "] is not a JSONObject.");
+    public JSONArray put(long value) {
+        values.add(value);
+        return this;
     }
 
     /**
-     * Get the long value associated with an index.
+     * Appends {@code value} to the end of this array.
      *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return The value.
-     * @throws JSONException
-     *             If the key is not found or if the value cannot be converted
-     *             to a number.
+     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     *     Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
+     *     not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
+     *     infinities}. Unsupported values are not permitted and will cause the
+     *     array to be in an inconsistent state.
+     * @return this array.
      */
-    public long getLong(int index) throws JSONException {
-        Object object = this.get(index);
-        try {
-            return object instanceof Number ? ((Number) object).longValue()
-                    : Long.parseLong((String) object);
-        } catch (Exception e) {
-            throw new JSONException("JSONArray[" + index + "] is not a number.");
-        }
+    public JSONArray put(Object value) {
+        values.add(value);
+        return this;
     }
+    
+    /** alias for put **/
+    public JSONArray add(Object value) {return put(value);}
 
     /**
-     * Get the string associated with an index.
-     *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return A string value.
-     * @throws JSONException
-     *             If there is no string value for the index.
+     * Same as {@link #put}, with added validity checks.
      */
-    public String getString(int index) throws JSONException {
-        Object object = this.get(index);
-        if (object instanceof String) {
-            return (String) object;
+    void checkedPut(Object value) throws JSONException {
+        if (value instanceof Number) {
+            JSON.checkDouble(((Number) value).doubleValue());
         }
-        throw new JSONException("JSONArray[" + index + "] not a string.");
+
+        put(value);
     }
 
     /**
-     * Determine if the value is null.
+     * Sets the value at {@code index} to {@code value}, null padding this array
+     * to the required length if necessary. If a value already exists at {@code
+     * index}, it will be replaced.
      *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return true if the value at the index is null, or if there is no value.
+     * @return this array.
      */
-    public boolean isNull(int index) {
-        return JSONObject.NULL.equals(this.opt(index));
+    public JSONArray put(int index, boolean value) throws JSONException {
+        return put(index, (Boolean) value);
     }
 
     /**
-     * Make a string from the contents of this JSONArray. The
-     * <code>separator</code> string is inserted between each element. Warning:
-     * This method assumes that the data structure is acyclical.
+     * Sets the value at {@code index} to {@code value}, null padding this array
+     * to the required length if necessary. If a value already exists at {@code
+     * index}, it will be replaced.
      *
-     * @param separator
-     *            A string that will be inserted between the elements.
-     * @return a string.
-     * @throws JSONException
-     *             If the array contains an invalid number.
+     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+     *     {@link Double#isInfinite() infinities}.
+     * @return this array.
      */
-    public String join(String separator) throws JSONException {
-        int len = this.length();
-        StringBuffer sb = new StringBuffer();
-
-        for (int i = 0; i < len; i += 1) {
-            if (i > 0) {
-                sb.append(separator);
-            }
-            sb.append(JSONObject.valueToString(this.myArrayList.get(i)));
-        }
-        return sb.toString();
+    public JSONArray put(int index, double value) throws JSONException {
+        return put(index, (Double) value);
     }
 
     /**
-     * Get the number of elements in the JSONArray, included nulls.
+     * Sets the value at {@code index} to {@code value}, null padding this array
+     * to the required length if necessary. If a value already exists at {@code
+     * index}, it will be replaced.
      *
-     * @return The length (or size).
+     * @return this array.
      */
-    public int length() {
-        return this.myArrayList.size();
+    public JSONArray put(int index, int value) throws JSONException {
+        return put(index, (Integer) value);
     }
 
     /**
-     * Get the optional object value associated with an index.
+     * Sets the value at {@code index} to {@code value}, null padding this array
+     * to the required length if necessary. If a value already exists at {@code
+     * index}, it will be replaced.
      *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return An object value, or null if there is no object at that index.
+     * @return this array.
      */
-    public Object opt(int index) {
-        return (index < 0 || index >= this.length()) ? null : this.myArrayList
-                .get(index);
+    public JSONArray put(int index, long value) throws JSONException {
+        return put(index, (Long) value);
     }
 
     /**
-     * Get the optional boolean value associated with an index. It returns false
-     * if there is no value at that index, or if the value is not Boolean.TRUE
-     * or the String "true".
+     * Sets the value at {@code index} to {@code value}, null padding this array
+     * to the required length if necessary. If a value already exists at {@code
+     * index}, it will be replaced.
      *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return The truth.
+     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     *     Integer, Long, Double, {@link JSONObject#NULL}, or {@code null}. May
+     *     not be {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
+     *     infinities}.
+     * @return this array.
      */
-    public boolean optBoolean(int index) {
-        return this.optBoolean(index, false);
+    public JSONArray put(int index, Object value) throws JSONException {
+        if (value instanceof Number) {
+            // deviate from the original by checking all Numbers, not just floats & doubles
+            JSON.checkDouble(((Number) value).doubleValue());
+        }
+        while (values.size() <= index) {
+            values.add(null);
+        }
+        values.set(index, value);
+        return this;
     }
 
-    /**
-     * Get the optional boolean value associated with an index. It returns the
-     * defaultValue if there is no value at that index or if it is not a Boolean
-     * or the String "true" or "false" (case insensitive).
-     *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @param defaultValue
-     *            A boolean default.
-     * @return The truth.
-     */
-    public boolean optBoolean(int index, boolean defaultValue) {
-        try {
-            return this.getBoolean(index);
-        } catch (Exception e) {
-            return defaultValue;
+    public JSONArray insert(int index, Object value) throws JSONException {
+        if (value instanceof Number) {
+            // deviate from the original by checking all Numbers, not just floats & doubles
+            JSON.checkDouble(((Number) value).doubleValue());
         }
+        while (values.size() <= index) {
+            values.add(null);
+        }
+        values.add(index, value);
+        return this;
     }
 
     /**
-     * Get the optional double value associated with an index. NaN is returned
-     * if there is no value for the index, or if the value is not a number and
-     * cannot be converted to a number.
-     *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return The value.
+     * Returns true if this array has no value at {@code index}, or if its value
+     * is the {@code null} reference or {@link JSONObject#NULL}.
      */
-    public double optDouble(int index) {
-        return this.optDouble(index, Double.NaN);
+    public boolean isNull(int index) {
+        Object value = opt(index);
+        return value == null || value == JSONObject.NULL;
     }
 
     /**
-     * Get the optional double value associated with an index. The defaultValue
-     * is returned if there is no value for the index, or if the value is not a
-     * number and cannot be converted to a number.
+     * Returns the value at {@code index}.
      *
-     * @param index
-     *            subscript
-     * @param defaultValue
-     *            The default value.
-     * @return The value.
+     * @throws JSONException if this array has no value at {@code index}, or if
+     *     that value is the {@code null} reference. This method returns
+     *     normally if the value is {@code JSONObject#NULL}.
      */
-    public double optDouble(int index, double defaultValue) {
+    public Object get(int index) throws JSONException {
         try {
-            return this.getDouble(index);
-        } catch (Exception e) {
-            return defaultValue;
+            Object value = values.get(index);
+            if (value == null) {
+                throw new JSONException("Value at " + index + " is null.");
+            }
+            return value;
+        } catch (IndexOutOfBoundsException e) {
+            throw new JSONException("Index " + index + " out of range [0.." + values.size() + ")");
         }
     }
 
     /**
-     * Get the optional int value associated with an index. Zero is returned if
-     * there is no value for the index, or if the value is not a number and
-     * cannot be converted to a number.
-     *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return The value.
+     * Returns the value at {@code index}, or null if the array has no value
+     * at {@code index}.
      */
-    public int optInt(int index) {
-        return this.optInt(index, 0);
+    public Object opt(int index) {
+        if (index < 0 || index >= values.size()) {
+            return null;
+        }
+        return values.get(index);
     }
 
     /**
-     * Get the optional int value associated with an index. The defaultValue is
-     * returned if there is no value for the index, or if the value is not a
-     * number and cannot be converted to a number.
-     *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @param defaultValue
-     *            The default value.
-     * @return The value.
+     * Removes and returns the value at {@code index}, or null if the array has no value
+     * at {@code index}.
      */
-    public int optInt(int index, int defaultValue) {
-        try {
-            return this.getInt(index);
-        } catch (Exception e) {
-            return defaultValue;
+    public Object remove(int index) {
+        if (index < 0 || index >= values.size()) {
+            return null;
         }
+        return values.remove(index);
     }
 
     /**
-     * Get the optional JSONArray associated with an index.
+     * Returns the value at {@code index} if it exists and is a boolean or can
+     * be coerced to a boolean.
      *
-     * @param index
-     *            subscript
-     * @return A JSONArray value, or null if the index has no value, or if the
-     *         value is not a JSONArray.
+     * @throws JSONException if the value at {@code index} doesn't exist or
+     *     cannot be coerced to a boolean.
      */
-    public JSONArray optJSONArray(int index) {
-        Object o = this.opt(index);
-        return o instanceof JSONArray ? (JSONArray) o : null;
+    public boolean getBoolean(int index) throws JSONException {
+        Object object = get(index);
+        Boolean result = JSON.toBoolean(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "boolean");
+        }
+        return result;
     }
 
     /**
-     * Get the optional JSONObject associated with an index. Null is returned if
-     * the key is not found, or null if the index has no value, or if the value
-     * is not a JSONObject.
-     *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return A JSONObject value.
+     * Returns the value at {@code index} if it exists and is a boolean or can
+     * be coerced to a boolean. Returns false otherwise.
      */
-    public JSONObject optJSONObject(int index) {
-        Object o = this.opt(index);
-        return o instanceof JSONObject ? (JSONObject) o : null;
+    public boolean optBoolean(int index) {
+        return optBoolean(index, false);
     }
 
     /**
-     * Get the optional long value associated with an index. Zero is returned if
-     * there is no value for the index, or if the value is not a number and
-     * cannot be converted to a number.
-     *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return The value.
+     * Returns the value at {@code index} if it exists and is a boolean or can
+     * be coerced to a boolean. Returns {@code fallback} otherwise.
      */
-    public long optLong(int index) {
-        return this.optLong(index, 0);
+    public boolean optBoolean(int index, boolean fallback) {
+        Object object = opt(index);
+        Boolean result = JSON.toBoolean(object);
+        return result != null ? result : fallback;
     }
 
     /**
-     * Get the optional long value associated with an index. The defaultValue is
-     * returned if there is no value for the index, or if the value is not a
-     * number and cannot be converted to a number.
+     * Returns the value at {@code index} if it exists and is a double or can
+     * be coerced to a double.
      *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @param defaultValue
-     *            The default value.
-     * @return The value.
+     * @throws JSONException if the value at {@code index} doesn't exist or
+     *     cannot be coerced to a double.
      */
-    public long optLong(int index, long defaultValue) {
-        try {
-            return this.getLong(index);
-        } catch (Exception e) {
-            return defaultValue;
+    public double getDouble(int index) throws JSONException {
+        Object object = get(index);
+        Double result = JSON.toDouble(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "double");
         }
+        return result;
     }
 
     /**
-     * Get the optional string value associated with an index. It returns an
-     * empty string if there is no value at that index. If the value is not a
-     * string and is not null, then it is coverted to a string.
-     *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @return A String value.
+     * Returns the value at {@code index} if it exists and is a double or can
+     * be coerced to a double. Returns {@code NaN} otherwise.
      */
-    public String optString(int index) {
-        return this.optString(index, "");
+    public double optDouble(int index) {
+        return optDouble(index, Double.NaN);
     }
 
     /**
-     * Get the optional string associated with an index. The defaultValue is
-     * returned if the key is not found.
-     *
-     * @param index
-     *            The index must be between 0 and length() - 1.
-     * @param defaultValue
-     *            The default value.
-     * @return A String value.
+     * Returns the value at {@code index} if it exists and is a double or can
+     * be coerced to a double. Returns {@code fallback} otherwise.
      */
-    public String optString(int index, String defaultValue) {
-        Object object = this.opt(index);
-        return JSONObject.NULL.equals(object) ? defaultValue : object
-                .toString();
+    public double optDouble(int index, double fallback) {
+        Object object = opt(index);
+        Double result = JSON.toDouble(object);
+        return result != null ? result : fallback;
     }
 
     /**
-     * Append a boolean value. This increases the array's length by one.
+     * Returns the value at {@code index} if it exists and is an int or
+     * can be coerced to an int.
      *
-     * @param value
-     *            A boolean value.
-     * @return this.
+     * @throws JSONException if the value at {@code index} doesn't exist or
+     *     cannot be coerced to a int.
      */
-    public JSONArray put(boolean value) {
-        this.put(value ? Boolean.TRUE : Boolean.FALSE);
-        return this;
+    public int getInt(int index) throws JSONException {
+        Object object = get(index);
+        Integer result = JSON.toInteger(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "int");
+        }
+        return result;
     }
 
     /**
-     * Put a value in the JSONArray, where the value will be a JSONArray which
-     * is produced from a Collection.
-     *
-     * @param value
-     *            A Collection value.
-     * @return this.
+     * Returns the value at {@code index} if it exists and is an int or
+     * can be coerced to an int. Returns 0 otherwise.
      */
-    public JSONArray put(Collection value) {
-        this.put(new JSONArray(value));
-        return this;
+    public int optInt(int index) {
+        return optInt(index, 0);
     }
 
     /**
-     * Append a double value. This increases the array's length by one.
-     *
-     * @param value
-     *            A double value.
-     * @throws JSONException
-     *             if the value is not finite.
-     * @return this.
+     * Returns the value at {@code index} if it exists and is an int or
+     * can be coerced to an int. Returns {@code fallback} otherwise.
      */
-    public JSONArray put(double value) throws JSONException {
-        Double d = new Double(value);
-        JSONObject.testValidity(d);
-        this.put(d);
-        return this;
+    public int optInt(int index, int fallback) {
+        Object object = opt(index);
+        Integer result = JSON.toInteger(object);
+        return result != null ? result : fallback;
     }
 
     /**
-     * Append an int value. This increases the array's length by one.
+     * Returns the value at {@code index} if it exists and is a long or
+     * can be coerced to a long.
      *
-     * @param value
-     *            An int value.
-     * @return this.
+     * @throws JSONException if the value at {@code index} doesn't exist or
+     *     cannot be coerced to a long.
      */
-    public JSONArray put(int value) {
-        this.put(new Integer(value));
-        return this;
+    public long getLong(int index) throws JSONException {
+        Object object = get(index);
+        Long result = JSON.toLong(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "long");
+        }
+        return result;
     }
 
     /**
-     * Append an long value. This increases the array's length by one.
-     *
-     * @param value
-     *            A long value.
-     * @return this.
+     * Returns the value at {@code index} if it exists and is a long or
+     * can be coerced to a long. Returns 0 otherwise.
      */
-    public JSONArray put(long value) {
-        this.put(new Long(value));
-        return this;
+    public long optLong(int index) {
+        return optLong(index, 0L);
     }
 
     /**
-     * Put a value in the JSONArray, where the value will be a JSONObject which
-     * is produced from a Map.
-     *
-     * @param value
-     *            A Map value.
-     * @return this.
+     * Returns the value at {@code index} if it exists and is a long or
+     * can be coerced to a long. Returns {@code fallback} otherwise.
      */
-    public JSONArray put(Map value) {
-        this.put(new JSONObject(value));
-        return this;
+    public long optLong(int index, long fallback) {
+        Object object = opt(index);
+        Long result = JSON.toLong(object);
+        return result != null ? result : fallback;
     }
 
     /**
-     * Append an object value. This increases the array's length by one.
+     * Returns the value at {@code index} if it exists, coercing it if
+     * necessary.
      *
-     * @param value
-     *            An object value. The value should be a Boolean, Double,
-     *            Integer, JSONArray, JSONObject, Long, or String, or the
-     *            JSONObject.NULL object.
-     * @return this.
+     * @throws JSONException if no such value exists.
      */
-    public JSONArray put(Object value) {
-        add(value);
-        return this;
+    public String getString(int index) throws JSONException {
+        Object object = get(index);
+        String result = JSON.toString(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "String");
+        }
+        return result;
     }
 
     /**
-     * Put or replace a boolean value in the JSONArray. If the index is greater
-     * than the length of the JSONArray, then null elements will be added as
-     * necessary to pad it out.
-     *
-     * @param index
-     *            The subscript.
-     * @param value
-     *            A boolean value.
-     * @return this.
-     * @throws JSONException
-     *             If the index is negative.
+     * Returns the value at {@code index} if it exists, coercing it if
+     * necessary. Returns the empty string if no such value exists.
      */
-    public JSONArray put(int index, boolean value) throws JSONException {
-        this.put(index, value ? Boolean.TRUE : Boolean.FALSE);
-        return this;
-    }
-
-    /**
-     * Put a value in the JSONArray, where the value will be a JSONArray which
-     * is produced from a Collection.
-     *
-     * @param index
-     *            The subscript.
-     * @param value
-     *            A Collection value.
-     * @return this.
-     * @throws JSONException
-     *             If the index is negative or if the value is not finite.
-     */
-    public JSONArray put(int index, Collection value) throws JSONException {
-        this.put(index, new JSONArray(value));
-        return this;
+    public String optString(int index) {
+        return optString(index, "");
     }
 
     /**
-     * Put or replace a double value. If the index is greater than the length of
-     * the JSONArray, then null elements will be added as necessary to pad it
-     * out.
-     *
-     * @param index
-     *            The subscript.
-     * @param value
-     *            A double value.
-     * @return this.
-     * @throws JSONException
-     *             If the index is negative or if the value is not finite.
+     * Returns the value at {@code index} if it exists, coercing it if
+     * necessary. Returns {@code fallback} if no such value exists.
      */
-    public JSONArray put(int index, double value) throws JSONException {
-        this.put(index, new Double(value));
-        return this;
+    public String optString(int index, String fallback) {
+        Object object = opt(index);
+        String result = JSON.toString(object);
+        return result != null ? result : fallback;
     }
 
     /**
-     * Put or replace an int value. If the index is greater than the length of
-     * the JSONArray, then null elements will be added as necessary to pad it
-     * out.
+     * Returns the value at {@code index} if it exists and is a {@code
+     * JSONArray}.
      *
-     * @param index
-     *            The subscript.
-     * @param value
-     *            An int value.
-     * @return this.
-     * @throws JSONException
-     *             If the index is negative.
+     * @throws JSONException if the value doesn't exist or is not a {@code
+     *     JSONArray}.
      */
-    public JSONArray put(int index, int value) throws JSONException {
-        this.put(index, new Integer(value));
-        return this;
+    public JSONArray getJSONArray(int index) throws JSONException {
+        Object object = get(index);
+        if (object instanceof JSONArray) {
+            return (JSONArray) object;
+        } else {
+            throw JSON.typeMismatch(index, object, "JSONArray");
+        }
     }
 
     /**
-     * Put or replace a long value. If the index is greater than the length of
-     * the JSONArray, then null elements will be added as necessary to pad it
-     * out.
-     *
-     * @param index
-     *            The subscript.
-     * @param value
-     *            A long value.
-     * @return this.
-     * @throws JSONException
-     *             If the index is negative.
+     * Returns the value at {@code index} if it exists and is a {@code
+     * JSONArray}. Returns null otherwise.
      */
-    public JSONArray put(int index, long value) throws JSONException {
-        this.put(index, new Long(value));
-        return this;
-    }
-
-    /**
-     * Put a value in the JSONArray, where the value will be a JSONObject that
-     * is produced from a Map.
-     *
-     * @param index
-     *            The subscript.
-     * @param value
-     *            The Map value.
-     * @return this.
-     * @throws JSONException
-     *             If the index is negative or if the the value is an invalid
-     *             number.
-     */
-    public JSONArray put(int index, Map value) throws JSONException {
-        this.put(index, new JSONObject(value));
-        return this;
+    public JSONArray optJSONArray(int index) {
+        Object object = opt(index);
+        return object instanceof JSONArray ? (JSONArray) object : null;
     }
 
     /**
-     * Put or replace an object value in the JSONArray. If the index is greater
-     * than the length of the JSONArray, then null elements will be added as
-     * necessary to pad it out.
+     * Returns the value at {@code index} if it exists and is a {@code
+     * JSONObject}.
      *
-     * @param index
-     *            The subscript.
-     * @param value
-     *            The value to put into the array. The value should be a
-     *            Boolean, Double, Integer, JSONArray, JSONObject, Long, or
-     *            String, or the JSONObject.NULL object.
-     * @return this.
-     * @throws JSONException
-     *             If the index is negative or if the the value is an invalid
-     *             number.
+     * @throws JSONException if the value doesn't exist or is not a {@code
+     *     JSONObject}.
      */
-    public JSONArray put(int index, Object value) throws JSONException {
-        JSONObject.testValidity(value);
-        if (index < 0) {
-            throw new JSONException("JSONArray[" + index + "] not found.");
-        }
-        if (index < this.length()) {
-            this.myArrayList.set(index, value);
-        	if (value instanceof JSONObject) {
-        		((JSONObject)value).parent = null;
-        	}
-        	if (value instanceof JSONArray) {
-        		((JSONArray)value).parent = null;
-        	}
-
+    public JSONObject getJSONObject(int index) throws JSONException {
+        Object object = get(index);
+        if (object instanceof JSONObject) {
+            return (JSONObject) object;
         } else {
-            while (index != this.length()) {
-                this.put(JSONObject.NULL);
-            }
-            this.put(value);
+            throw JSON.typeMismatch(index, object, "JSONObject");
         }
-        return this;
     }
 
     /**
-     * Remove an index and close the hole.
-     *
-     * @param index
-     *            The index of the element to be removed.
-     * @return The value that was associated with the index, or null if there
-     *         was no value.
+     * Returns the value at {@code index} if it exists and is a {@code
+     * JSONObject}. Returns null otherwise.
      */
-    public Object remove(int index) {
-        Object o = this.opt(index);
-        this.myArrayList.remove(index);
-    	if (o instanceof JSONObject) {
-    		((JSONObject)o).parent = null;
-    	}
-    	if (o instanceof JSONArray) {
-    		((JSONArray)o).parent = null;
-    	}
-        return o;
+    public JSONObject optJSONObject(int index) {
+        Object object = opt(index);
+        return object instanceof JSONObject ? (JSONObject) object : null;
     }
 
     /**
-     * Produce a JSONObject by combining a JSONArray of names with the values of
-     * this JSONArray.
-     *
-     * @param names
-     *            A JSONArray containing a list of key strings. These will be
-     *            paired with the values.
-     * @return A JSONObject, or null if there are no names or if this JSONArray
-     *         has no values.
-     * @throws JSONException
-     *             If any of the names are null.
+     * Returns a new object whose values are the values in this array, and whose
+     * names are the values in {@code names}. Names and values are paired up by
+     * index from 0 through to the shorter array's length. Names that are not
+     * strings will be coerced to strings. This method returns null if either
+     * array is empty.
      */
     public JSONObject toJSONObject(JSONArray names) throws JSONException {
-        if (names == null || names.length() == 0 || this.length() == 0) {
+        JSONObject result = new JSONObject();
+        int length = Math.min(names.length(), values.size());
+        if (length == 0) {
             return null;
         }
-        JSONObject jo = new JSONObject();
-        for (int i = 0; i < names.length(); i += 1) {
-            jo.put(names.getString(i), this.opt(i));
+        for (int i = 0; i < length; i++) {
+            String name = JSON.toString(names.opt(i));
+            result.put(name, opt(i));
         }
-        return jo;
+        return result;
     }
 
     /**
-     * Make a JSON text of this JSONArray. For compactness, no unnecessary
-     * whitespace is added. If it is not possible to produce a syntactically
-     * correct JSON text then null will be returned instead. This could occur if
-     * the array contains an invalid number.
-     * <p>
-     * Warning: This method assumes that the data structure is acyclical.
-     *
-     * @return a printable, displayable, transmittable representation of the
-     *         array.
+     * Returns a new string by alternating this array's values with {@code
+     * separator}. This array's string values are quoted and have their special
+     * characters escaped. For example, the array containing the strings '12"
+     * pizza', 'taco' and 'soda' joined on '+' returns this:
+     * <pre>"12\" pizza"+"taco"+"soda"</pre>
      */
-    public String toString() {
-        try {
-            return this.toString(0);
-        } catch (Exception e) {
-            return null;
+    public String join(String separator) throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.open(JSONStringer.Scope.NULL, "");
+        for (int i = 0, size = values.size(); i < size; i++) {
+            if (i > 0) {
+                stringer.out.append(separator);
+            }
+            stringer.value(values.get(i));
         }
+        stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
+        return stringer.out.toString();
     }
 
     /**
-     * Make a prettyprinted JSON text of this JSONArray. Warning: This method
-     * assumes that the data structure is acyclical.
-     *
-     * @param indentFactor
-     *            The number of spaces to add to each level of indentation.
-     * @return a printable, displayable, transmittable representation of the
-     *         object, beginning with <code>[</code> <small>(left
-     *         bracket)</small> and ending with <code>]</code>
-     *          <small>(right bracket)</small>.
-     * @throws JSONException
-     */
-    public String toString(int indentFactor) throws JSONException {
-        StringWriter sw = new StringWriter();
-        synchronized (sw.getBuffer()) {
-            return this.write(sw, indentFactor, 0).toString();
+     * Encodes this array as a compact JSON string, such as:
+     * <pre>[94043,90210]</pre>
+     */
+    @Override public String toString() {
+        try {
+            JSONStringer stringer = new JSONStringer();
+            writeTo(stringer);
+            return stringer.toString();
+        } catch (JSONException e) {
+            return null;
         }
     }
 
     /**
-     * Write the contents of the JSONArray as JSON text to a writer. For
-     * compactness, no whitespace is added.
-     * <p>
-     * Warning: This method assumes that the data structure is acyclical.
+     * Encodes this array as a human readable JSON string for debugging, such
+     * as:
+     * <pre>
+     * [
+     *     94043,
+     *     90210
+     * ]</pre>
      *
-     * @return The writer.
-     * @throws JSONException
+     * @param indentSpaces the number of spaces to indent for each level of
+     *     nesting.
      */
-    public Writer write(Writer writer) throws JSONException {
-        return this.write(writer, 0, 0);
+    public String toString(int indentSpaces) throws JSONException {
+        JSONStringer stringer = new JSONStringer(indentSpaces);
+        writeTo(stringer);
+        return stringer.toString();
     }
 
-    /**
-     * Write the contents of the JSONArray as JSON text to a writer. For
-     * compactness, no whitespace is added.
-     * <p>
-     * Warning: This method assumes that the data structure is acyclical.
-     *
-     * @param indentFactor
-     *            The number of spaces to add to each level of indentation.
-     * @param indent
-     *            The indention of the top level.
-     * @return The writer.
-     * @throws JSONException
-     */
-    Writer write(Writer writer, int indentFactor, int indent)
-            throws JSONException {
-        try {
-            boolean commanate = false;
-            int length = this.length();
-            writer.write('[');
-
-            if (length == 1) {
-                JSONObject.writeValue(writer, this.myArrayList.get(0),
-                        indentFactor, indent);
-            } else if (length != 0) {
-                final int newindent = indent + indentFactor;
-
-                for (int i = 0; i < length; i += 1) {
-                    if (commanate) {
-                        writer.write(',');
-                    }
-                    if (indentFactor > 0) {
-                        writer.write('\n');
-                    }
-                    JSONObject.indent(writer, newindent);
-                    JSONObject.writeValue(writer, this.myArrayList.get(i),
-                            indentFactor, newindent);
-                    commanate = true;
-                }
-                if (indentFactor > 0) {
-                    writer.write('\n');
-                }
-                JSONObject.indent(writer, indent);
-            }
-            writer.write(']');
-            return writer;
-        } catch (IOException e) {
-            throw new JSONException(e);
+    void writeTo(JSONStringer stringer) throws JSONException {
+        stringer.array();
+        for (Object value : values) {
+            stringer.value(value);
         }
+        stringer.endArray();
     }
+
+    @Override public boolean equals(Object o) {
+        return o instanceof JSONArray && ((JSONArray) o).values.equals(values);
+    }
+
+    @Override public int hashCode() {
+        // diverge from the original, which doesn't implement hashCode
+        return values.hashCode();
+    }
+    
+    public int indexOf(Object o) {
+    	return values.indexOf(o);
+    }
+    
+    public Object getParent() {
+    	return parent;
+    }
+
+	public void setParent(Object parent) {
+		this.parent = parent;
+	}
+
 }
diff --git a/src/org/json/JSONException.java b/src/org/json/JSONException.java
old mode 100755
new mode 100644
index 971547e..53871dc
--- a/src/org/json/JSONException.java
+++ b/src/org/json/JSONException.java
@@ -1,41 +1,51 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package org.json;
 
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
 /**
- * The JSONException is thrown by the JSON.org classes when things are amiss.
+ * Thrown to indicate a problem with the JSON API. Such problems include:
+ * <ul>
+ *   <li>Attempts to parse or construct malformed documents
+ *   <li>Use of null as a name
+ *   <li>Use of numeric types not available to JSON, such as {@link
+ *       Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
+ *   <li>Lookups using an out of range index or nonexistent name
+ *   <li>Type mismatches on lookups
+ * </ul>
  *
- * @author JSON.org
- * @version 2013-02-10
+ * <p>Although this is a checked exception, it is rarely recoverable. Most
+ * callers should simply wrap this exception in an unchecked exception and
+ * rethrow:
+ * <pre>  public JSONArray toJSONObject() {
+ *     try {
+ *         JSONObject result = new JSONObject();
+ *         ...
+ *     } catch (JSONException e) {
+ *         throw new RuntimeException(e);
+ *     }
+ * }</pre>
  */
-public class JSONException extends RuntimeException {
-    private static final long serialVersionUID = 0;
-    private Throwable cause;
-
-    /**
-     * Constructs a JSONException with an explanatory message.
-     *
-     * @param message
-     *            Detail about the reason for the exception.
-     */
-    public JSONException(String message) {
-        super(message);
-    }
+public class JSONException extends Exception {
 
-    /**
-     * Constructs a new JSONException with the specified cause.
-     */
-    public JSONException(Throwable cause) {
-        super(cause.getMessage());
-        this.cause = cause;
-    }
+	private static final long serialVersionUID = 1L;
 
-    /**
-     * Returns the cause of this exception or null if the cause is nonexistent
-     * or unknown.
-     *
-     * @returns the cause of this exception or null if the cause is nonexistent
-     *          or unknown.
-     */
-    public Throwable getCause() {
-        return this.cause;
+	public JSONException(String s) {
+        super(s);
     }
 }
diff --git a/src/org/json/JSONML.java b/src/org/json/JSONML.java
deleted file mode 100755
index 4be6863..0000000
--- a/src/org/json/JSONML.java
+++ /dev/null
@@ -1,467 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2008 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-import java.util.Iterator;
-
-
-/**
- * This provides static methods to convert an XML text into a JSONArray or
- * JSONObject, and to covert a JSONArray or JSONObject into an XML text using
- * the JsonML transform.
- *
- * @author JSON.org
- * @version 2012-03-28
- */
-public class JSONML {
-
-    /**
-     * Parse XML values and store them in a JSONArray.
-     * @param x       The XMLTokener containing the source string.
-     * @param arrayForm true if array form, false if object form.
-     * @param ja      The JSONArray that is containing the current tag or null
-     *     if we are at the outermost level.
-     * @return A JSONArray if the value is the outermost tag, otherwise null.
-     * @throws JSONException
-     */
-    private static Object parse(
-        XMLTokener x,
-        boolean    arrayForm,
-        JSONArray  ja
-    ) throws JSONException {
-        String     attribute;
-        char       c;
-        String       closeTag = null;
-        int        i;
-        JSONArray  newja = null;
-        JSONObject newjo = null;
-        Object     token;
-        String       tagName = null;
-
-// Test for and skip past these forms:
-//      <!-- ... -->
-//      <![  ... ]]>
-//      <!   ...   >
-//      <?   ...  ?>
-
-        while (true) {
-            if (!x.more()) {
-                throw x.syntaxError("Bad XML");
-            }
-            token = x.nextContent();
-            if (token == XML.LT) {
-                token = x.nextToken();
-                if (token instanceof Character) {
-                    if (token == XML.SLASH) {
-
-// Close tag </
-
-                        token = x.nextToken();
-                        if (!(token instanceof String)) {
-                            throw new JSONException(
-                                    "Expected a closing name instead of '" +
-                                    token + "'.");
-                        }
-                        if (x.nextToken() != XML.GT) {
-                            throw x.syntaxError("Misshaped close tag");
-                        }
-                        return token;
-                    } else if (token == XML.BANG) {
-
-// <!
-
-                        c = x.next();
-                        if (c == '-') {
-                            if (x.next() == '-') {
-                                x.skipPast("-->");
-                            } else {
-                                x.back();
-                            }
-                        } else if (c == '[') {
-                            token = x.nextToken();
-                            if (token.equals("CDATA") && x.next() == '[') {
-                                if (ja != null) {
-                                    ja.put(x.nextCDATA());
-                                }
-                            } else {
-                                throw x.syntaxError("Expected 'CDATA['");
-                            }
-                        } else {
-                            i = 1;
-                            do {
-                                token = x.nextMeta();
-                                if (token == null) {
-                                    throw x.syntaxError("Missing '>' after '<!'.");
-                                } else if (token == XML.LT) {
-                                    i += 1;
-                                } else if (token == XML.GT) {
-                                    i -= 1;
-                                }
-                            } while (i > 0);
-                        }
-                    } else if (token == XML.QUEST) {
-
-// <?
-
-                        x.skipPast("?>");
-                    } else {
-                        throw x.syntaxError("Misshaped tag");
-                    }
-
-// Open tag <
-
-                } else {
-                    if (!(token instanceof String)) {
-                        throw x.syntaxError("Bad tagName '" + token + "'.");
-                    }
-                    tagName = (String)token;
-                    newja = new JSONArray();
-                    newjo = new JSONObject();
-                    if (arrayForm) {
-                        newja.put(tagName);
-                        if (ja != null) {
-                            ja.put(newja);
-                        }
-                    } else {
-                        newjo.put("tagName", tagName);
-                        if (ja != null) {
-                            ja.put(newjo);
-                        }
-                    }
-                    token = null;
-                    for (;;) {
-                        if (token == null) {
-                            token = x.nextToken();
-                        }
-                        if (token == null) {
-                            throw x.syntaxError("Misshaped tag");
-                        }
-                        if (!(token instanceof String)) {
-                            break;
-                        }
-
-// attribute = value
-
-                        attribute = (String)token;
-                        if (!arrayForm && ("tagName".equals(attribute) || "childNode".equals(attribute))) {
-                            throw x.syntaxError("Reserved attribute.");
-                        }
-                        token = x.nextToken();
-                        if (token == XML.EQ) {
-                            token = x.nextToken();
-                            if (!(token instanceof String)) {
-                                throw x.syntaxError("Missing value");
-                            }
-                            newjo.accumulate(attribute, XML.stringToValue((String)token));
-                            token = null;
-                        } else {
-                            newjo.accumulate(attribute, "");
-                        }
-                    }
-                    if (arrayForm && newjo.length() > 0) {
-                        newja.put(newjo);
-                    }
-
-// Empty tag <.../>
-
-                    if (token == XML.SLASH) {
-                        if (x.nextToken() != XML.GT) {
-                            throw x.syntaxError("Misshaped tag");
-                        }
-                        if (ja == null) {
-                            if (arrayForm) {
-                                return newja;
-                            } else {
-                                return newjo;
-                            }
-                        }
-
-// Content, between <...> and </...>
-
-                    } else {
-                        if (token != XML.GT) {
-                            throw x.syntaxError("Misshaped tag");
-                        }
-                        closeTag = (String)parse(x, arrayForm, newja);
-                        if (closeTag != null) {
-                            if (!closeTag.equals(tagName)) {
-                                throw x.syntaxError("Mismatched '" + tagName +
-                                        "' and '" + closeTag + "'");
-                            }
-                            tagName = null;
-                            if (!arrayForm && newja.length() > 0) {
-                                newjo.put("childNodes", newja);
-                            }
-                            if (ja == null) {
-                                if (arrayForm) {
-                                    return newja;
-                                } else {
-                                    return newjo;
-                                }
-                            }
-                        }
-                    }
-                }
-            } else {
-                if (ja != null) {
-                    ja.put(token instanceof String
-                        ? XML.stringToValue((String)token)
-                        : token);
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Convert a well-formed (but not necessarily valid) XML string into a
-     * JSONArray using the JsonML transform. Each XML tag is represented as
-     * a JSONArray in which the first element is the tag name. If the tag has
-     * attributes, then the second element will be JSONObject containing the
-     * name/value pairs. If the tag contains children, then strings and
-     * JSONArrays will represent the child tags.
-     * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
-     * @param string The source string.
-     * @return A JSONArray containing the structured data from the XML string.
-     * @throws JSONException
-     */
-    public static JSONArray toJSONArray(String string) throws JSONException {
-        return toJSONArray(new XMLTokener(string));
-    }
-
-
-    /**
-     * Convert a well-formed (but not necessarily valid) XML string into a
-     * JSONArray using the JsonML transform. Each XML tag is represented as
-     * a JSONArray in which the first element is the tag name. If the tag has
-     * attributes, then the second element will be JSONObject containing the
-     * name/value pairs. If the tag contains children, then strings and
-     * JSONArrays will represent the child content and tags.
-     * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
-     * @param x An XMLTokener.
-     * @return A JSONArray containing the structured data from the XML string.
-     * @throws JSONException
-     */
-    public static JSONArray toJSONArray(XMLTokener x) throws JSONException {
-        return (JSONArray)parse(x, true, null);
-    }
-
-
-    /**
-     * Convert a well-formed (but not necessarily valid) XML string into a
-     * JSONObject using the JsonML transform. Each XML tag is represented as
-     * a JSONObject with a "tagName" property. If the tag has attributes, then
-     * the attributes will be in the JSONObject as properties. If the tag
-     * contains children, the object will have a "childNodes" property which
-     * will be an array of strings and JsonML JSONObjects.
-
-     * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
-     * @param x An XMLTokener of the XML source text.
-     * @return A JSONObject containing the structured data from the XML string.
-     * @throws JSONException
-     */
-    public static JSONObject toJSONObject(XMLTokener x) throws JSONException {
-           return (JSONObject)parse(x, false, null);
-    }
-
-
-    /**
-     * Convert a well-formed (but not necessarily valid) XML string into a
-     * JSONObject using the JsonML transform. Each XML tag is represented as
-     * a JSONObject with a "tagName" property. If the tag has attributes, then
-     * the attributes will be in the JSONObject as properties. If the tag
-     * contains children, the object will have a "childNodes" property which
-     * will be an array of strings and JsonML JSONObjects.
-
-     * Comments, prologs, DTDs, and <code><[ [ ]]></code> are ignored.
-     * @param string The XML source text.
-     * @return A JSONObject containing the structured data from the XML string.
-     * @throws JSONException
-     */
-    public static JSONObject toJSONObject(String string) throws JSONException {
-        return toJSONObject(new XMLTokener(string));
-    }
-
-
-    /**
-     * Reverse the JSONML transformation, making an XML text from a JSONArray.
-     * @param ja A JSONArray.
-     * @return An XML string.
-     * @throws JSONException
-     */
-    public static String toString(JSONArray ja) throws JSONException {
-        int             i;
-        JSONObject   jo;
-        String       key;
-        Iterator     keys;
-        int             length;
-        Object         object;
-        StringBuffer sb = new StringBuffer();
-        String       tagName;
-        String       value;
-
-// Emit <tagName
-
-        tagName = ja.getString(0);
-        XML.noSpace(tagName);
-        tagName = XML.escape(tagName);
-        sb.append('<');
-        sb.append(tagName);
-
-        object = ja.opt(1);
-        if (object instanceof JSONObject) {
-            i = 2;
-            jo = (JSONObject)object;
-
-// Emit the attributes
-
-            keys = jo.keys();
-            while (keys.hasNext()) {
-                key = keys.next().toString();
-                XML.noSpace(key);
-                value = jo.optString(key);
-                if (value != null) {
-                    sb.append(' ');
-                    sb.append(XML.escape(key));
-                    sb.append('=');
-                    sb.append('"');
-                    sb.append(XML.escape(value));
-                    sb.append('"');
-                }
-            }
-        } else {
-            i = 1;
-        }
-
-//Emit content in body
-
-        length = ja.length();
-        if (i >= length) {
-            sb.append('/');
-            sb.append('>');
-        } else {
-            sb.append('>');
-            do {
-                object = ja.get(i);
-                i += 1;
-                if (object != null) {
-                    if (object instanceof String) {
-                        sb.append(XML.escape(object.toString()));
-                    } else if (object instanceof JSONObject) {
-                        sb.append(toString((JSONObject)object));
-                    } else if (object instanceof JSONArray) {
-                        sb.append(toString((JSONArray)object));
-                    }
-                }
-            } while (i < length);
-            sb.append('<');
-            sb.append('/');
-            sb.append(tagName);
-            sb.append('>');
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Reverse the JSONML transformation, making an XML text from a JSONObject.
-     * The JSONObject must contain a "tagName" property. If it has children,
-     * then it must have a "childNodes" property containing an array of objects.
-     * The other properties are attributes with string values.
-     * @param jo A JSONObject.
-     * @return An XML string.
-     * @throws JSONException
-     */
-    public static String toString(JSONObject jo) throws JSONException {
-        StringBuffer sb = new StringBuffer();
-        int          i;
-        JSONArray    ja;
-        String       key;
-        Iterator     keys;
-        int          length;
-        Object         object;
-        String       tagName;
-        String       value;
-
-//Emit <tagName
-
-        tagName = jo.optString("tagName");
-        if (tagName == null) {
-            return XML.escape(jo.toString());
-        }
-        XML.noSpace(tagName);
-        tagName = XML.escape(tagName);
-        sb.append('<');
-        sb.append(tagName);
-
-//Emit the attributes
-
-        keys = jo.keys();
-        while (keys.hasNext()) {
-            key = keys.next().toString();
-            if (!"tagName".equals(key) && !"childNodes".equals(key)) {
-                XML.noSpace(key);
-                value = jo.optString(key);
-                if (value != null) {
-                    sb.append(' ');
-                    sb.append(XML.escape(key));
-                    sb.append('=');
-                    sb.append('"');
-                    sb.append(XML.escape(value));
-                    sb.append('"');
-                }
-            }
-        }
-
-//Emit content in body
-
-        ja = jo.optJSONArray("childNodes");
-        if (ja == null) {
-            sb.append('/');
-            sb.append('>');
-        } else {
-            sb.append('>');
-            length = ja.length();
-            for (i = 0; i < length; i += 1) {
-                object = ja.get(i);
-                if (object != null) {
-                    if (object instanceof String) {
-                        sb.append(XML.escape(object.toString()));
-                    } else if (object instanceof JSONObject) {
-                        sb.append(toString((JSONObject)object));
-                    } else if (object instanceof JSONArray) {
-                        sb.append(toString((JSONArray)object));
-                    } else {
-                        sb.append(object.toString());
-                    }
-                }
-            }
-            sb.append('<');
-            sb.append('/');
-            sb.append(tagName);
-            sb.append('>');
-        }
-        return sb.toString();
-    }
-}
diff --git a/src/org/json/JSONObject.java b/src/org/json/JSONObject.java
old mode 100755
new mode 100644
index 929a34d..eedce64
--- a/src/org/json/JSONObject.java
+++ b/src/org/json/JSONObject.java
@@ -1,1665 +1,835 @@
-package org.json;
-
 /*
- Copyright (c) 2002 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
-import java.io.IOException;
-import java.io.StringWriter;
-import java.io.Writer;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
+package org.json;
+
+import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Enumeration;
-import java.util.HashMap;
 import java.util.Iterator;
-import java.util.Locale;
+import java.util.LinkedHashMap;
 import java.util.Map;
-import java.util.Map.Entry;
-import java.util.ResourceBundle;
 import java.util.Set;
 
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
 /**
- * A JSONObject is an unordered collection of name/value pairs. Its external
- * form is a string wrapped in curly braces with colons between the names and
- * values, and commas between the values and names. The internal form is an
- * object having <code>get</code> and <code>opt</code> methods for accessing
- * the values by name, and <code>put</code> methods for adding or replacing
- * values by name. The values can be any of these types: <code>Boolean</code>,
- * <code>JSONArray</code>, <code>JSONObject</code>, <code>Number</code>,
- * <code>String</code>, or the <code>JSONObject.NULL</code> object. A
- * JSONObject constructor can be used to convert an external form JSON text
- * into an internal form whose values can be retrieved with the
- * <code>get</code> and <code>opt</code> methods, or to convert values into a
- * JSON text using the <code>put</code> and <code>toString</code> methods. A
- * <code>get</code> method returns a value if one can be found, and throws an
- * exception if one cannot be found. An <code>opt</code> method returns a
- * default value instead of throwing an exception, and so is useful for
- * obtaining optional values.
- * <p>
- * The generic <code>get()</code> and <code>opt()</code> methods return an
- * object, which you can cast or query for type. There are also typed
- * <code>get</code> and <code>opt</code> methods that do type checking and type
- * coercion for you. The opt methods differ from the get methods in that they
- * do not throw. Instead, they return a specified value, such as null.
- * <p>
- * The <code>put</code> methods add or replace values in an object. For
- * example,
+ * A modifiable set of name/value mappings. Names are unique, non-null strings.
+ * Values may be any mix of {@link JSONObject JSONObjects}, {@link JSONArray
+ * JSONArrays}, Strings, Booleans, Integers, Longs, Doubles or {@link #NULL}.
+ * Values may not be {@code null}, {@link Double#isNaN() NaNs}, {@link
+ * Double#isInfinite() infinities}, or of any type not listed here.
  *
- * <pre>
- * myString = new JSONObject()
- *         .put("JSON", "Hello, World!").toString();
- * </pre>
+ * <p>This class can coerce values to another type when requested.
+ * <ul>
+ *   <li>When the requested type is a boolean, strings will be coerced using a
+ *       case-insensitive comparison to "true" and "false".
+ *   <li>When the requested type is a double, other {@link Number} types will
+ *       be coerced using {@link Number#doubleValue() doubleValue}. Strings
+ *       that can be coerced using {@link Double#valueOf(String)} will be.
+ *   <li>When the requested type is an int, other {@link Number} types will
+ *       be coerced using {@link Number#intValue() intValue}. Strings
+ *       that can be coerced using {@link Double#valueOf(String)} will be,
+ *       and then cast to int.
+ *   <li><a name="lossy">When the requested type is a long, other {@link Number} types will
+ *       be coerced using {@link Number#longValue() longValue}. Strings
+ *       that can be coerced using {@link Double#valueOf(String)} will be,
+ *       and then cast to long. This two-step conversion is lossy for very
+ *       large values. For example, the string "9223372036854775806" yields the
+ *       long 9223372036854775807.</a>
+ *   <li>When the requested type is a String, other non-null values will be
+ *       coerced using {@link String#valueOf(Object)}. Although null cannot be
+ *       coerced, the sentinel value {@link JSONObject#NULL} is coerced to the
+ *       string "null".
+ * </ul>
  *
- * produces the string <code>{"JSON": "Hello, World"}</code>.
- * <p>
- * The texts produced by the <code>toString</code> methods strictly conform to
- * the JSON syntax rules. The constructors are more forgiving in the texts they
- * will accept:
+ * <p>This class can look up both mandatory and optional values:
  * <ul>
- * <li>An extra <code>,</code> <small>(comma)</small> may appear just
- * before the closing brace.</li>
- * <li>Strings may be quoted with <code>'</code> <small>(single
- * quote)</small>.</li>
- * <li>Strings do not need to be quoted at all if they do not begin with a
- * quote or single quote, and if they do not contain leading or trailing
- * spaces, and if they do not contain any of these characters:
- * <code>{ } [ ] / \ : , #</code> and if they do not look like numbers and
- * if they are not the reserved words <code>true</code>, <code>false</code>,
- * or <code>null</code>.</li>
+ *   <li>Use <code>get<i>Type</i>()</code> to retrieve a mandatory value. This
+ *       fails with a {@code JSONException} if the requested name has no value
+ *       or if the value cannot be coerced to the requested type.
+ *   <li>Use <code>opt<i>Type</i>()</code> to retrieve an optional value. This
+ *       returns a system- or user-supplied default if the requested name has no
+ *       value or if the value cannot be coerced to the requested type.
  * </ul>
  *
- * @author JSON.org
- * @version 2013-06-17
+ * <p><strong>Warning:</strong> this class represents null in two incompatible
+ * ways: the standard Java {@code null} reference, and the sentinel value {@link
+ * JSONObject#NULL}. In particular, calling {@code put(name, null)} removes the
+ * named entry from the object but {@code put(name, JSONObject.NULL)} stores an
+ * entry whose value is {@code JSONObject.NULL}.
+ *
+ * <p>Instances of this class are not thread safe. Although this class is
+ * nonfinal, it was not designed for inheritance and should not be subclassed.
+ * In particular, self-use by overrideable methods is not specified. See
+ * <i>Effective Java</i> Item 17, "Design and Document or inheritance or else
+ * prohibit it" for further information.
  */
 public class JSONObject {
-    /**
-     * JSONObject.NULL is equivalent to the value that JavaScript calls null,
-     * whilst Java's null is equivalent to the value that JavaScript calls
-     * undefined.
-     */
-    private static final class Null {
 
-        /**
-         * There is only intended to be a single instance of the NULL object,
-         * so the clone method returns itself.
-         *
-         * @return NULL.
-         */
-        protected final Object clone() {
-            return this;
-        }
+    private static final Double NEGATIVE_ZERO = -0d;
 
-        /**
-         * A Null object is equal to the null value and to itself.
-         *
-         * @param object
-         *            An object to test for nullness.
-         * @return true if the object parameter is the JSONObject.NULL object or
-         *         null.
-         */
-        public boolean equals(Object object) {
-            return object == null || object == this;
-        }
-
-        /**
-         * Get the "null" string value.
-         *
-         * @return The string "null".
-         */
-        public String toString() {
-            return "null";
-        }
-    }
+    private Object parent = null;
 
     /**
-     * The map where the JSONObject's properties are kept.
+     * A sentinel value used to explicitly define a name with no value. Unlike
+     * {@code null}, names with this value:
+     * <ul>
+     *   <li>show up in the {@link #names} array
+     *   <li>show up in the {@link #keys} iterator
+     *   <li>return {@code true} for {@link #has(String)}
+     *   <li>do not throw on {@link #get(String)}
+     *   <li>are included in the encoded JSON string.
+     * </ul>
+     *
+     * <p>This value violates the general contract of {@link Object#equals} by
+     * returning true when compared to {@code null}. Its {@link #toString}
+     * method returns "null".
      */
-    private final Map<String, Object> map;
-    
-    protected Object parent = null;
-    
-    public Object getParent() {
-    	return parent;
-    }
+    public static final Object NULL = new Object() {
+        @Override public boolean equals(Object o) {
+            return o == this || o == null; // API specifies this broken equals implementation
+        }
+        @Override public String toString() {
+            return "null";
+        }
+    };
 
-    /**
-     * It is sometimes more convenient and less ambiguous to have a
-     * <code>NULL</code> object than to use Java's <code>null</code> value.
-     * <code>JSONObject.NULL.equals(null)</code> returns <code>true</code>.
-     * <code>JSONObject.NULL.toString()</code> returns <code>"null"</code>.
-     */
-    public static final Object NULL = new Null();
+    private final LinkedHashMap<String, Object> nameValuePairs;
 
     /**
-     * Construct an empty JSONObject.
+     * Creates a {@code JSONObject} with no name/value mappings.
      */
     public JSONObject() {
-        this.map = new HashMap<String, Object>();
-    }
-
-    /**
-     * Construct a JSONObject from a subset of another JSONObject. An array of
-     * strings is used to identify the keys that should be copied. Missing keys
-     * are ignored.
-     *
-     * @param jo
-     *            A JSONObject.
-     * @param names
-     *            An array of strings.
-     * @throws JSONException
-     * @exception JSONException
-     *                If a value is a non-finite number or if a name is
-     *                duplicated.
-     */
-    public JSONObject(JSONObject jo, String[] names) {
-        this();
-        for (int i = 0; i < names.length; i += 1) {
-            try {
-                this.putOnce(names[i], jo.opt(names[i]));
-            } catch (Exception ignore) {
-            }
-        }
+        nameValuePairs = new LinkedHashMap<String, Object>();
     }
 
     /**
-     * Construct a JSONObject from a JSONTokener.
+     * Creates a new {@code JSONObject} by copying all name/value mappings from
+     * the given map.
      *
-     * @param x
-     *            A JSONTokener object containing the source string.
-     * @throws JSONException
-     *             If there is a syntax error in the source string or a
-     *             duplicated key.
+     * @param copyFrom a map whose keys are of type {@link String} and whose
+     *     values are of supported types.
+     * @throws NullPointerException if any of the map's keys are null.
      */
-    public JSONObject(JSONTokener x) throws JSONException {
+    /* (accept a raw type for API compatibility) */
+    @SuppressWarnings("rawtypes")
+	public JSONObject(Map copyFrom) {
         this();
-        char c;
-        String key;
-
-        if (x.nextClean() != '{') {
-            throw x.syntaxError("A JSONObject text must begin with '{'");
-        }
-        for (;;) {
-            c = x.nextClean();
-            switch (c) {
-            case 0:
-                throw x.syntaxError("A JSONObject text must end with '}'");
-            case '}':
-                return;
-            default:
-                x.back();
-                key = x.nextValue().toString();
-            }
-
-// The key is followed by ':'.
-
-            c = x.nextClean();
-            if (c != ':') {
-                throw x.syntaxError("Expected a ':' after a key");
-            }
-            this.putOnce(key, x.nextValue());
-
-// Pairs are separated by ','.
-
-            switch (x.nextClean()) {
-            case ';':
-            case ',':
-                if (x.nextClean() == '}') {
-                    return;
-                }
-                x.back();
-                break;
-            case '}':
-                return;
-            default:
-                throw x.syntaxError("Expected a ',' or '}'");
+        Map<?, ?> contentsTyped = copyFrom;
+        for (Map.Entry<?, ?> entry : contentsTyped.entrySet()) {
+            /*
+             * Deviate from the original by checking that keys are non-null and
+             * of the proper type. (We still defer validating the values).
+             */
+            String key = (String) entry.getKey();
+            if (key == null) {
+                throw new NullPointerException("key == null");
             }
+            nameValuePairs.put(key, wrap(entry.getValue()));
         }
     }
 
     /**
-     * Construct a JSONObject from a Map.
+     * Creates a new {@code JSONObject} with name/value mappings from the next
+     * object in the tokener.
      *
-     * @param map
-     *            A map object that can be used to initialize the contents of
-     *            the JSONObject.
-     * @throws JSONException
+     * @param readFrom a tokener whose nextValue() method will yield a
+     *     {@code JSONObject}.
+     * @throws JSONException if the parse fails or doesn't yield a
+     *     {@code JSONObject}.
      */
-    public JSONObject(Map<String, Object> map) {
-        this.map = new HashMap<String, Object>();
-        if (map != null) {
-            Iterator<Entry<String, Object>> i = map.entrySet().iterator();
-            while (i.hasNext()) {
-                Map.Entry<String,Object> e = (Map.Entry<String,Object>) i.next();
-                Object value = e.getValue();
-                if (value != null) {
-                    _put((String) e.getKey(), wrap(value));
-                }
-            }
+    public JSONObject(JSONTokener readFrom) throws JSONException {
+        /*
+         * Getting the parser to populate this could get tricky. Instead, just
+         * parse to temporary JSONObject and then steal the data from that.
+         */
+        Object object = readFrom.nextValue();
+        if (object instanceof JSONObject) {
+            this.nameValuePairs = ((JSONObject) object).nameValuePairs;
+        } else {
+            throw JSON.typeMismatch(object, "JSONObject");
         }
     }
 
-    private void _put(String key, Object o) {
-        this.map.put(key, o);
-        if (o instanceof JSONObject) {
-        	((JSONObject) o).parent = this;
-        }
-        if (o instanceof JSONArray) {
-        	((JSONArray) o).parent = this;
-        }
-    }
-    
     /**
-     * Construct a JSONObject from an Object using bean getters. It reflects on
-     * all of the public methods of the object. For each of the methods with no
-     * parameters and a name starting with <code>"get"</code> or
-     * <code>"is"</code> followed by an uppercase letter, the method is invoked,
-     * and a key and the value returned from the getter method are put into the
-     * new JSONObject.
-     *
-     * The key is formed by removing the <code>"get"</code> or <code>"is"</code>
-     * prefix. If the second remaining character is not upper case, then the
-     * first character is converted to lower case.
-     *
-     * For example, if an object has a method named <code>"getName"</code>, and
-     * if the result of calling <code>object.getName()</code> is
-     * <code>"Larry Fine"</code>, then the JSONObject will contain
-     * <code>"name": "Larry Fine"</code>.
+     * Creates a new {@code JSONObject} with name/value mappings from the JSON
+     * string.
      *
-     * @param bean
-     *            An object that has getter methods that should be used to make
-     *            a JSONObject.
+     * @param json a JSON-encoded string containing an object.
+     * @throws JSONException if the parse fails or doesn't yield a {@code
+     *     JSONObject}.
      */
-    public JSONObject(Object bean) {
-        this();
-        this.populateMap(bean);
+    public JSONObject(String json) throws JSONException {
+        this(new JSONTokener(json));
     }
 
     /**
-     * Construct a JSONObject from an Object, using reflection to find the
-     * public members. The resulting JSONObject's keys will be the strings from
-     * the names array, and the values will be the field values associated with
-     * those keys in the object. If a key is not found or not visible, then it
-     * will not be copied into the new JSONObject.
-     *
-     * @param object
-     *            An object that has fields that should be used to make a
-     *            JSONObject.
-     * @param names
-     *            An array of strings, the names of the fields to be obtained
-     *            from the object.
+     * Creates a new {@code JSONObject} by copying mappings for the listed names
+     * from the given object. Names that aren't present in {@code copyFrom} will
+     * be skipped.
      */
-    public JSONObject(Object object, String names[]) {
+    public JSONObject(JSONObject copyFrom, String[] names) throws JSONException {
         this();
-        Class c = object.getClass();
-        for (int i = 0; i < names.length; i += 1) {
-            String name = names[i];
-            try {
-                this.putOpt(name, c.getField(name).get(object));
-            } catch (Exception ignore) {
+        for (String name : names) {
+            Object value = copyFrom.opt(name);
+            if (value != null) {
+                nameValuePairs.put(name, value);
             }
         }
     }
 
     /**
-     * Construct a JSONObject from a source JSON text string. This is the most
-     * commonly used JSONObject constructor.
-     *
-     * @param source
-     *            A string beginning with <code>{</code> <small>(left
-     *            brace)</small> and ending with <code>}</code>
-     *             <small>(right brace)</small>.
-     * @exception JSONException
-     *                If there is a syntax error in the source string or a
-     *                duplicated key.
+     * Returns the number of name/value mappings in this object.
      */
-    public JSONObject(String source) throws JSONException {
-        this(new JSONTokener(source));
+    public int length() {
+        return nameValuePairs.size();
     }
 
     /**
-     * Construct a JSONObject from a ResourceBundle.
+     * Maps {@code name} to {@code value}, clobbering any existing name/value
+     * mapping with the same name.
      *
-     * @param baseName
-     *            The ResourceBundle base name.
-     * @param locale
-     *            The Locale to load the ResourceBundle for.
-     * @throws JSONException
-     *             If any JSONExceptions are detected.
+     * @return this object.
      */
-    public JSONObject(String baseName, Locale locale) throws JSONException {
-        this();
-        ResourceBundle bundle = ResourceBundle.getBundle(baseName, locale,
-                Thread.currentThread().getContextClassLoader());
-
-// Iterate through the keys in the bundle.
-
-        Enumeration keys = bundle.getKeys();
-        while (keys.hasMoreElements()) {
-            Object key = keys.nextElement();
-            if (key instanceof String) {
-
-// Go through the path, ensuring that there is a nested JSONObject for each
-// segment except the last. Add the value using the last segment's name into
-// the deepest nested JSONObject.
-
-                String[] path = ((String) key).split("\\.");
-                int last = path.length - 1;
-                JSONObject target = this;
-                for (int i = 0; i < last; i += 1) {
-                    String segment = path[i];
-                    JSONObject nextTarget = target.optJSONObject(segment);
-                    if (nextTarget == null) {
-                        nextTarget = new JSONObject();
-                        target.put(segment, nextTarget);
-                    }
-                    target = nextTarget;
-                }
-                target.put(path[last], bundle.getString((String) key));
-            }
-        }
+    public JSONObject put(String name, boolean value) throws JSONException {
+        nameValuePairs.put(checkName(name), value);
+        return this;
     }
 
     /**
-     * Accumulate values under a key. It is similar to the put method except
-     * that if there is already an object stored under the key then a JSONArray
-     * is stored under the key to hold all of the accumulated values. If there
-     * is already a JSONArray, then the new value is appended to it. In
-     * contrast, the put method replaces the previous value.
-     *
-     * If only one value is accumulated that is not a JSONArray, then the result
-     * will be the same as using put. But if multiple values are accumulated,
-     * then the result will be like append.
+     * Maps {@code name} to {@code value}, clobbering any existing name/value
+     * mapping with the same name.
      *
-     * @param key
-     *            A key string.
-     * @param value
-     *            An object to be accumulated under the key.
-     * @return this.
-     * @throws JSONException
-     *             If the value is an invalid number or if the key is null.
+     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+     *     {@link Double#isInfinite() infinities}.
+     * @return this object.
      */
-    public JSONObject accumulate(String key, Object value) throws JSONException {
-        testValidity(value);
-        Object object = this.opt(key);
-        if (object == null) {
-            this.put(key,
-                    value instanceof JSONArray ? new JSONArray().put(value)
-                            : value);
-        } else if (object instanceof JSONArray) {
-            ((JSONArray) object).put(value);
-        } else {
-            this.put(key, new JSONArray().put(object).put(value));
-        }
+    public JSONObject put(String name, double value) throws JSONException {
+        nameValuePairs.put(checkName(name), JSON.checkDouble(value));
         return this;
     }
 
     /**
-     * Append values to the array under a key. If the key does not exist in the
-     * JSONObject, then the key is put in the JSONObject with its value being a
-     * JSONArray containing the value parameter. If the key was already
-     * associated with a JSONArray, then the value parameter is appended to it.
+     * Maps {@code name} to {@code value}, clobbering any existing name/value
+     * mapping with the same name.
      *
-     * @param key
-     *            A key string.
-     * @param value
-     *            An object to be accumulated under the key.
-     * @return this.
-     * @throws JSONException
-     *             If the key is null or if the current value associated with
-     *             the key is not a JSONArray.
+     * @return this object.
      */
-    public JSONObject append(String key, Object value) throws JSONException {
-        testValidity(value);
-        Object object = this.opt(key);
-        if (object == null) {
-            this.put(key, new JSONArray().put(value));
-        } else if (object instanceof JSONArray) {
-            this.put(key, ((JSONArray) object).put(value));
-        } else {
-            throw new JSONException("JSONObject[" + key
-                    + "] is not a JSONArray.");
-        }
+    public JSONObject put(String name, int value) throws JSONException {
+        nameValuePairs.put(checkName(name), value);
         return this;
     }
 
     /**
-     * Produce a string from a double. The string "null" will be returned if the
-     * number is not finite.
+     * Maps {@code name} to {@code value}, clobbering any existing name/value
+     * mapping with the same name.
      *
-     * @param d
-     *            A double.
-     * @return A String.
+     * @return this object.
      */
-    public static String doubleToString(double d) {
-        if (Double.isInfinite(d) || Double.isNaN(d)) {
-            return "null";
-        }
-
-// Shave off trailing zeros and decimal point, if possible.
-
-        String string = Double.toString(d);
-        if (string.indexOf('.') > 0 && string.indexOf('e') < 0
-                && string.indexOf('E') < 0) {
-            while (string.endsWith("0")) {
-                string = string.substring(0, string.length() - 1);
-            }
-            if (string.endsWith(".")) {
-                string = string.substring(0, string.length() - 1);
-            }
-        }
-        return string;
+    public JSONObject put(String name, long value) throws JSONException {
+        nameValuePairs.put(checkName(name), value);
+        return this;
     }
 
     /**
-     * Get the value object associated with a key.
+     * Maps {@code name} to {@code value}, clobbering any existing name/value
+     * mapping with the same name. If the value is {@code null}, any existing
+     * mapping for {@code name} is removed.
      *
-     * @param key
-     *            A key string.
-     * @return The object associated with the key.
-     * @throws JSONException
-     *             if the key is not found.
+     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     *     Integer, Long, Double, {@link #NULL}, or {@code null}. May not be
+     *     {@link Double#isNaN() NaNs} or {@link Double#isInfinite()
+     *     infinities}.
+     * @return this object.
      */
-    public Object get(String key) throws JSONException {
-        if (key == null) {
-            throw new JSONException("Null key.");
+    public JSONObject put(String name, Object value) throws JSONException {
+        if (value == null) {
+            nameValuePairs.remove(name);
+            return this;
         }
-        Object object = this.opt(key);
-        if (object == null) {
-            throw new JSONException("JSONObject[" + quote(key) + "] not found.");
+        if (value instanceof Number) {
+            // deviate from the original by checking all Numbers, not just floats & doubles
+            JSON.checkDouble(((Number) value).doubleValue());
         }
-        return object;
+        nameValuePairs.put(checkName(name), value);
+        return this;
     }
 
     /**
-     * Get the boolean value associated with a key.
-     *
-     * @param key
-     *            A key string.
-     * @return The truth.
-     * @throws JSONException
-     *             if the value is not a Boolean or the String "true" or
-     *             "false".
+     * Equivalent to {@code put(name, value)} when both parameters are non-null;
+     * does nothing otherwise.
      */
-    public boolean getBoolean(String key) throws JSONException {
-        Object object = this.get(key);
-        if (object.equals(Boolean.FALSE)
-                || (object instanceof String && ((String) object)
-                        .equalsIgnoreCase("false"))) {
-            return false;
-        } else if (object.equals(Boolean.TRUE)
-                || (object instanceof String && ((String) object)
-                        .equalsIgnoreCase("true"))) {
-            return true;
+    public JSONObject putOpt(String name, Object value) throws JSONException {
+        if (name == null || value == null) {
+            return this;
         }
-        throw new JSONException("JSONObject[" + quote(key)
-                + "] is not a Boolean.");
+        return put(name, value);
     }
 
     /**
-     * Get the double value associated with a key.
+     * Appends {@code value} to the array already mapped to {@code name}. If
+     * this object has no mapping for {@code name}, this inserts a new mapping.
+     * If the mapping exists but its value is not an array, the existing
+     * and new values are inserted in order into a new array which is itself
+     * mapped to {@code name}. In aggregate, this allows values to be added to a
+     * mapping one at a time.
      *
-     * @param key
-     *            A key string.
-     * @return The numeric value.
-     * @throws JSONException
-     *             if the key is not found or if the value is not a Number
-     *             object and cannot be converted to a number.
-     */
-    public double getDouble(String key) throws JSONException {
-        Object object = this.get(key);
-        try {
-            return object instanceof Number ? ((Number) object).doubleValue()
-                    : Double.parseDouble((String) object);
-        } catch (Exception e) {
-            throw new JSONException("JSONObject[" + quote(key)
-                    + "] is not a number.");
-        }
-    }
-
-    /**
-     * Get the int value associated with a key.
+     * <p> Note that {@code append(String, Object)} provides better semantics.
+     * In particular, the mapping for {@code name} will <b>always</b> be a
+     * {@link JSONArray}. Using {@code accumulate} will result in either a
+     * {@link JSONArray} or a mapping whose type is the type of {@code value}
+     * depending on the number of calls to it.
      *
-     * @param key
-     *            A key string.
-     * @return The integer value.
-     * @throws JSONException
-     *             if the key is not found or if the value cannot be converted
-     *             to an integer.
+     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     *     Integer, Long, Double, {@link #NULL} or null. May not be {@link
+     *     Double#isNaN() NaNs} or {@link Double#isInfinite() infinities}.
      */
-    public int getInt(String key) throws JSONException {
-        Object object = this.get(key);
-        try {
-            return object instanceof Number ? ((Number) object).intValue()
-                    : Integer.parseInt((String) object);
-        } catch (Exception e) {
-            throw new JSONException("JSONObject[" + quote(key)
-                    + "] is not an int.");
+    // TODO: Change {@code append) to {@link #append} when append is
+    // unhidden.
+    public JSONObject accumulate(String name, Object value) throws JSONException {
+        Object current = nameValuePairs.get(checkName(name));
+        if (current == null) {
+            return put(name, value);
         }
-    }
 
-    /**
-     * Get the JSONArray value associated with a key.
-     *
-     * @param key
-     *            A key string.
-     * @return A JSONArray which is the value.
-     * @throws JSONException
-     *             if the key is not found or if the value is not a JSONArray.
-     */
-    public JSONArray getJSONArray(String key) throws JSONException {
-        Object object = this.get(key);
-        if (object instanceof JSONArray) {
-            return (JSONArray) object;
+        if (current instanceof JSONArray) {
+            JSONArray array = (JSONArray) current;
+            array.checkedPut(value);
+        } else {
+            JSONArray array = new JSONArray();
+            array.checkedPut(current);
+            array.checkedPut(value);
+            nameValuePairs.put(name, array);
         }
-        throw new JSONException("JSONObject[" + quote(key)
-                + "] is not a JSONArray.");
+        return this;
     }
 
     /**
-     * Get the JSONObject value associated with a key.
+     * Appends values to the array mapped to {@code name}. A new {@link JSONArray}
+     * mapping for {@code name} will be inserted if no mapping exists. If the existing
+     * mapping for {@code name} is not a {@link JSONArray}, a {@link JSONException}
+     * will be thrown.
      *
-     * @param key
-     *            A key string.
-     * @return A JSONObject which is the value.
-     * @throws JSONException
-     *             if the key is not found or if the value is not a JSONObject.
-     */
-    public JSONObject getJSONObject(String key) throws JSONException {
-        Object object = this.get(key);
-        if (object instanceof JSONObject) {
-            return (JSONObject) object;
-        }
-        throw new JSONException("JSONObject[" + quote(key)
-                + "] is not a JSONObject.");
-    }
-
-    /**
-     * Get the long value associated with a key.
+     * @throws JSONException if {@code name} is {@code null} or if the mapping for
+     *         {@code name} is non-null and is not a {@link JSONArray}.
      *
-     * @param key
-     *            A key string.
-     * @return The long value.
-     * @throws JSONException
-     *             if the key is not found or if the value cannot be converted
-     *             to a long.
+     * @hide
      */
-    public long getLong(String key) throws JSONException {
-        Object object = this.get(key);
-        try {
-            return object instanceof Number ? ((Number) object).longValue()
-                    : Long.parseLong((String) object);
-        } catch (Exception e) {
-            throw new JSONException("JSONObject[" + quote(key)
-                    + "] is not a long.");
+    public JSONObject append(String name, Object value) throws JSONException {
+        Object current = nameValuePairs.get(checkName(name));
+
+        final JSONArray array;
+        if (current instanceof JSONArray) {
+            array = (JSONArray) current;
+        } else if (current == null) {
+            JSONArray newArray = new JSONArray();
+            nameValuePairs.put(name, newArray);
+            array = newArray;
+        } else {
+            throw new JSONException("Key " + name + " is not a JSONArray");
         }
+
+        array.checkedPut(value);
+
+        return this;
     }
 
-    /**
-     * Get an array of field names from a JSONObject.
-     *
-     * @return An array of field names, or null if there are no names.
-     */
-    public static String[] getNames(JSONObject jo) {
-        int length = jo.length();
-        if (length == 0) {
-            return null;
+    String checkName(String name) throws JSONException {
+        if (name == null) {
+            throw new JSONException("Names must be non-null");
         }
-        Iterator iterator = jo.keys();
-        String[] names = new String[length];
-        int i = 0;
-        while (iterator.hasNext()) {
-            names[i] = (String) iterator.next();
-            i += 1;
-        }
-        return names;
+        return name;
     }
 
     /**
-     * Get an array of field names from an Object.
+     * Removes the named mapping if it exists; does nothing otherwise.
      *
-     * @return An array of field names, or null if there are no names.
+     * @return the value previously mapped by {@code name}, or null if there was
+     *     no such mapping.
      */
-    public static String[] getNames(Object object) {
-        if (object == null) {
-            return null;
-        }
-        Class klass = object.getClass();
-        Field[] fields = klass.getFields();
-        int length = fields.length;
-        if (length == 0) {
-            return null;
-        }
-        String[] names = new String[length];
-        for (int i = 0; i < length; i += 1) {
-            names[i] = fields[i].getName();
-        }
-        return names;
+    public Object remove(String name) {
+        return nameValuePairs.remove(name);
     }
 
     /**
-     * Get the string associated with a key.
-     *
-     * @param key
-     *            A key string.
-     * @return A string which is the value.
-     * @throws JSONException
-     *             if there is no string value for the key.
+     * Returns true if this object has no mapping for {@code name} or if it has
+     * a mapping whose value is {@link #NULL}.
      */
-    public String getString(String key) throws JSONException {
-        Object object = this.get(key);
-        if (object instanceof String) {
-            return (String) object;
-        }
-        throw new JSONException("JSONObject[" + quote(key) + "] not a string.");
+    public boolean isNull(String name) {
+        Object value = nameValuePairs.get(name);
+        return value == null || value == NULL;
     }
 
     /**
-     * Determine if the JSONObject contains a specific key.
-     *
-     * @param key
-     *            A key string.
-     * @return true if the key exists in the JSONObject.
+     * Returns true if this object has a mapping for {@code name}. The mapping
+     * may be {@link #NULL}.
      */
-    public boolean has(String key) {
-        return this.map.containsKey(key);
+    public boolean has(String name) {
+        return nameValuePairs.containsKey(name);
     }
 
     /**
-     * Increment a property of a JSONObject. If there is no such property,
-     * create one with a value of 1. If there is such a property, and if it is
-     * an Integer, Long, Double, or Float, then add one to it.
+     * Returns the value mapped by {@code name}, or throws if no such mapping exists.
      *
-     * @param key
-     *            A key string.
-     * @return this.
-     * @throws JSONException
-     *             If there is already a property with this name that is not an
-     *             Integer, Long, Double, or Float.
+     * @throws JSONException if no such mapping exists.
      */
-    public JSONObject increment(String key) throws JSONException {
-        Object value = this.opt(key);
-        if (value == null) {
-            this.put(key, 1);
-        } else if (value instanceof Integer) {
-            this.put(key, ((Integer) value).intValue() + 1);
-        } else if (value instanceof Long) {
-            this.put(key, ((Long) value).longValue() + 1);
-        } else if (value instanceof Double) {
-            this.put(key, ((Double) value).doubleValue() + 1);
-        } else if (value instanceof Float) {
-            this.put(key, ((Float) value).floatValue() + 1);
-        } else {
-            throw new JSONException("Unable to increment [" + quote(key) + "].");
+    public Object get(String name) throws JSONException {
+        Object result = nameValuePairs.get(name);
+        if (result == null) {
+            throw new JSONException("No value for " + name);
         }
-        return this;
+        return result;
     }
 
     /**
-     * Determine if the value associated with the key is null or if there is no
-     * value.
-     *
-     * @param key
-     *            A key string.
-     * @return true if there is no value associated with the key or if the value
-     *         is the JSONObject.NULL object.
+     * Returns the value mapped by {@code name}, or null if no such mapping
+     * exists.
      */
-    public boolean isNull(String key) {
-        return JSONObject.NULL.equals(this.opt(key));
+    public Object opt(String name) {
+        return nameValuePairs.get(name);
     }
 
     /**
-     * Get an enumeration of the keys of the JSONObject.
+     * Returns the value mapped by {@code name} if it exists and is a boolean or
+     * can be coerced to a boolean, or throws otherwise.
      *
-     * @return An iterator of the keys.
+     * @throws JSONException if the mapping doesn't exist or cannot be coerced
+     *     to a boolean.
      */
-    public Iterator keys() {
-        return this.keySet().iterator();
+    public boolean getBoolean(String name) throws JSONException {
+        Object object = get(name);
+        Boolean result = JSON.toBoolean(object);
+        if (result == null) {
+            throw JSON.typeMismatch(name, object, "boolean");
+        }
+        return result;
     }
 
     /**
-     * Get a set of keys of the JSONObject.
-     *
-     * @return A keySet.
+     * Returns the value mapped by {@code name} if it exists and is a boolean or
+     * can be coerced to a boolean, or false otherwise.
      */
-    public Set<String> keySet() {
-        return this.map.keySet();
+    public boolean optBoolean(String name) {
+        return optBoolean(name, false);
     }
 
     /**
-     * Get the number of keys stored in the JSONObject.
-     *
-     * @return The number of keys in the JSONObject.
+     * Returns the value mapped by {@code name} if it exists and is a boolean or
+     * can be coerced to a boolean, or {@code fallback} otherwise.
      */
-    public int length() {
-        return this.map.size();
+    public boolean optBoolean(String name, boolean fallback) {
+        Object object = opt(name);
+        Boolean result = JSON.toBoolean(object);
+        return result != null ? result : fallback;
     }
 
     /**
-     * Produce a JSONArray containing the names of the elements of this
-     * JSONObject.
+     * Returns the value mapped by {@code name} if it exists and is a double or
+     * can be coerced to a double, or throws otherwise.
      *
-     * @return A JSONArray containing the key strings, or null if the JSONObject
-     *         is empty.
+     * @throws JSONException if the mapping doesn't exist or cannot be coerced
+     *     to a double.
      */
-    public JSONArray names() {
-        JSONArray ja = new JSONArray();
-        Iterator keys = this.keys();
-        while (keys.hasNext()) {
-            ja.put(keys.next());
+    public double getDouble(String name) throws JSONException {
+        Object object = get(name);
+        Double result = JSON.toDouble(object);
+        if (result == null) {
+            throw JSON.typeMismatch(name, object, "double");
         }
-        return ja.length() == 0 ? null : ja;
+        return result;
     }
 
     /**
-     * Produce a string from a Number.
-     *
-     * @param number
-     *            A Number
-     * @return A String.
-     * @throws JSONException
-     *             If n is a non-finite number.
+     * Returns the value mapped by {@code name} if it exists and is a double or
+     * can be coerced to a double, or {@code NaN} otherwise.
      */
-    public static String numberToString(Number number) throws JSONException {
-        if (number == null) {
-            throw new JSONException("Null pointer");
-        }
-        testValidity(number);
-
-// Shave off trailing zeros and decimal point, if possible.
-
-        String string = number.toString();
-        if (string.indexOf('.') > 0 && string.indexOf('e') < 0
-                && string.indexOf('E') < 0) {
-            while (string.endsWith("0")) {
-                string = string.substring(0, string.length() - 1);
-            }
-            if (string.endsWith(".")) {
-                string = string.substring(0, string.length() - 1);
-            }
-        }
-        return string;
+    public double optDouble(String name) {
+        return optDouble(name, Double.NaN);
     }
 
     /**
-     * Get an optional value associated with a key.
-     *
-     * @param key
-     *            A key string.
-     * @return An object which is the value, or null if there is no value.
+     * Returns the value mapped by {@code name} if it exists and is a double or
+     * can be coerced to a double, or {@code fallback} otherwise.
      */
-    public Object opt(String key) {
-        return key == null ? null : this.map.get(key);
+    public double optDouble(String name, double fallback) {
+        Object object = opt(name);
+        Double result = JSON.toDouble(object);
+        return result != null ? result : fallback;
     }
 
     /**
-     * Get an optional boolean associated with a key. It returns false if there
-     * is no such key, or if the value is not Boolean.TRUE or the String "true".
+     * Returns the value mapped by {@code name} if it exists and is an int or
+     * can be coerced to an int, or throws otherwise.
      *
-     * @param key
-     *            A key string.
-     * @return The truth.
+     * @throws JSONException if the mapping doesn't exist or cannot be coerced
+     *     to an int.
      */
-    public boolean optBoolean(String key) {
-        return this.optBoolean(key, false);
+    public int getInt(String name) throws JSONException {
+        Object object = get(name);
+        Integer result = JSON.toInteger(object);
+        if (result == null) {
+            throw JSON.typeMismatch(name, object, "int");
+        }
+        return result;
     }
 
     /**
-     * Get an optional boolean associated with a key. It returns the
-     * defaultValue if there is no such key, or if it is not a Boolean or the
-     * String "true" or "false" (case insensitive).
-     *
-     * @param key
-     *            A key string.
-     * @param defaultValue
-     *            The default.
-     * @return The truth.
+     * Returns the value mapped by {@code name} if it exists and is an int or
+     * can be coerced to an int, or 0 otherwise.
      */
-    public boolean optBoolean(String key, boolean defaultValue) {
-        try {
-            return this.getBoolean(key);
-        } catch (Exception e) {
-            return defaultValue;
-        }
+    public int optInt(String name) {
+        return optInt(name, 0);
     }
 
     /**
-     * Get an optional double associated with a key, or NaN if there is no such
-     * key or if its value is not a number. If the value is a string, an attempt
-     * will be made to evaluate it as a number.
-     *
-     * @param key
-     *            A string which is the key.
-     * @return An object which is the value.
+     * Returns the value mapped by {@code name} if it exists and is an int or
+     * can be coerced to an int, or {@code fallback} otherwise.
      */
-    public double optDouble(String key) {
-        return this.optDouble(key, Double.NaN);
+    public int optInt(String name, int fallback) {
+        Object object = opt(name);
+        Integer result = JSON.toInteger(object);
+        return result != null ? result : fallback;
     }
 
     /**
-     * Get an optional double associated with a key, or the defaultValue if
-     * there is no such key or if its value is not a number. If the value is a
-     * string, an attempt will be made to evaluate it as a number.
+     * Returns the value mapped by {@code name} if it exists and is a long or
+     * can be coerced to a long, or throws otherwise.
+     * Note that JSON represents numbers as doubles,
+     * so this is <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
      *
-     * @param key
-     *            A key string.
-     * @param defaultValue
-     *            The default.
-     * @return An object which is the value.
+     * @throws JSONException if the mapping doesn't exist or cannot be coerced
+     *     to a long.
      */
-    public double optDouble(String key, double defaultValue) {
-        try {
-            return this.getDouble(key);
-        } catch (Exception e) {
-            return defaultValue;
+    public long getLong(String name) throws JSONException {
+        Object object = get(name);
+        Long result = JSON.toLong(object);
+        if (result == null) {
+            throw JSON.typeMismatch(name, object, "long");
         }
+        return result;
     }
 
     /**
-     * Get an optional int value associated with a key, or zero if there is no
-     * such key or if the value is not a number. If the value is a string, an
-     * attempt will be made to evaluate it as a number.
-     *
-     * @param key
-     *            A key string.
-     * @return An object which is the value.
+     * Returns the value mapped by {@code name} if it exists and is a long or
+     * can be coerced to a long, or 0 otherwise. Note that JSON represents numbers as doubles,
+     * so this is <a href="#lossy">lossy</a>; use strings to transfer numbers via JSON.
      */
-    public int optInt(String key) {
-        return this.optInt(key, 0);
+    public long optLong(String name) {
+        return optLong(name, 0L);
     }
 
     /**
-     * Get an optional int value associated with a key, or the default if there
-     * is no such key or if the value is not a number. If the value is a string,
-     * an attempt will be made to evaluate it as a number.
-     *
-     * @param key
-     *            A key string.
-     * @param defaultValue
-     *            The default.
-     * @return An object which is the value.
+     * Returns the value mapped by {@code name} if it exists and is a long or
+     * can be coerced to a long, or {@code fallback} otherwise. Note that JSON represents
+     * numbers as doubles, so this is <a href="#lossy">lossy</a>; use strings to transfer
+     * numbers via JSON.
      */
-    public int optInt(String key, int defaultValue) {
-        try {
-            return this.getInt(key);
-        } catch (Exception e) {
-            return defaultValue;
-        }
+    public long optLong(String name, long fallback) {
+        Object object = opt(name);
+        Long result = JSON.toLong(object);
+        return result != null ? result : fallback;
     }
 
     /**
-     * Get an optional JSONArray associated with a key. It returns null if there
-     * is no such key, or if its value is not a JSONArray.
+     * Returns the value mapped by {@code name} if it exists, coercing it if
+     * necessary, or throws if no such mapping exists.
      *
-     * @param key
-     *            A key string.
-     * @return A JSONArray which is the value.
+     * @throws JSONException if no such mapping exists.
      */
-    public JSONArray optJSONArray(String key) {
-        Object o = this.opt(key);
-        return o instanceof JSONArray ? (JSONArray) o : null;
+    public String getString(String name) throws JSONException {
+        Object object = get(name);
+        String result = JSON.toString(object);
+        if (result == null) {
+            throw JSON.typeMismatch(name, object, "String");
+        }
+        return result;
     }
 
     /**
-     * Get an optional JSONObject associated with a key. It returns null if
-     * there is no such key, or if its value is not a JSONObject.
-     *
-     * @param key
-     *            A key string.
-     * @return A JSONObject which is the value.
+     * Returns the value mapped by {@code name} if it exists, coercing it if
+     * necessary, or the empty string if no such mapping exists.
      */
-    public JSONObject optJSONObject(String key) {
-        Object object = this.opt(key);
-        return object instanceof JSONObject ? (JSONObject) object : null;
+    public String optString(String name) {
+        return optString(name, "");
     }
 
     /**
-     * Get an optional long value associated with a key, or zero if there is no
-     * such key or if the value is not a number. If the value is a string, an
-     * attempt will be made to evaluate it as a number.
-     *
-     * @param key
-     *            A key string.
-     * @return An object which is the value.
+     * Returns the value mapped by {@code name} if it exists, coercing it if
+     * necessary, or {@code fallback} if no such mapping exists.
      */
-    public long optLong(String key) {
-        return this.optLong(key, 0);
+    public String optString(String name, String fallback) {
+        Object object = opt(name);
+        String result = JSON.toString(object);
+        return result != null ? result : fallback;
     }
 
     /**
-     * Get an optional long value associated with a key, or the default if there
-     * is no such key or if the value is not a number. If the value is a string,
-     * an attempt will be made to evaluate it as a number.
+     * Returns the value mapped by {@code name} if it exists and is a {@code
+     * JSONArray}, or throws otherwise.
      *
-     * @param key
-     *            A key string.
-     * @param defaultValue
-     *            The default.
-     * @return An object which is the value.
+     * @throws JSONException if the mapping doesn't exist or is not a {@code
+     *     JSONArray}.
      */
-    public long optLong(String key, long defaultValue) {
-        try {
-            return this.getLong(key);
-        } catch (Exception e) {
-            return defaultValue;
+    public JSONArray getJSONArray(String name) throws JSONException {
+        Object object = get(name);
+        if (object instanceof JSONArray) {
+            return (JSONArray) object;
+        } else {
+            throw JSON.typeMismatch(name, object, "JSONArray");
         }
     }
 
     /**
-     * Get an optional string associated with a key. It returns an empty string
-     * if there is no such key. If the value is not a string and is not null,
-     * then it is converted to a string.
-     *
-     * @param key
-     *            A key string.
-     * @return A string which is the value.
+     * Returns the value mapped by {@code name} if it exists and is a {@code
+     * JSONArray}, or null otherwise.
      */
-    public String optString(String key) {
-        return this.optString(key, "");
+    public JSONArray optJSONArray(String name) {
+        Object object = opt(name);
+        return object instanceof JSONArray ? (JSONArray) object : null;
     }
 
     /**
-     * Get an optional string associated with a key. It returns the defaultValue
-     * if there is no such key.
+     * Returns the value mapped by {@code name} if it exists and is a {@code
+     * JSONObject}, or throws otherwise.
      *
-     * @param key
-     *            A key string.
-     * @param defaultValue
-     *            The default.
-     * @return A string which is the value.
+     * @throws JSONException if the mapping doesn't exist or is not a {@code
+     *     JSONObject}.
      */
-    public String optString(String key, String defaultValue) {
-        Object object = this.opt(key);
-        return NULL.equals(object) ? defaultValue : object.toString();
-    }
-
-    private void populateMap(Object bean) {
-        Class klass = bean.getClass();
-
-// If klass is a System class then set includeSuperClass to false.
-
-        boolean includeSuperClass = klass.getClassLoader() != null;
-
-        Method[] methods = includeSuperClass ? klass.getMethods() : klass
-                .getDeclaredMethods();
-        for (int i = 0; i < methods.length; i += 1) {
-            try {
-                Method method = methods[i];
-                if (Modifier.isPublic(method.getModifiers())) {
-                    String name = method.getName();
-                    String key = "";
-                    if (name.startsWith("get")) {
-                        if ("getClass".equals(name)
-                                || "getDeclaringClass".equals(name)) {
-                            key = "";
-                        } else {
-                            key = name.substring(3);
-                        }
-                    } else if (name.startsWith("is")) {
-                        key = name.substring(2);
-                    }
-                    if (key.length() > 0
-                            && Character.isUpperCase(key.charAt(0))
-                            && method.getParameterTypes().length == 0) {
-                        if (key.length() == 1) {
-                            key = key.toLowerCase();
-                        } else if (!Character.isUpperCase(key.charAt(1))) {
-                            key = key.substring(0, 1).toLowerCase()
-                                    + key.substring(1);
-                        }
-
-                        Object result = method.invoke(bean, (Object[]) null);
-                        if (result != null) {
-                            _put(key, wrap(result));
-                        }
-                    }
-                }
-            } catch (Exception ignore) {
-            }
+    public JSONObject getJSONObject(String name) throws JSONException {
+        Object object = get(name);
+        if (object instanceof JSONObject) {
+            return (JSONObject) object;
+        } else {
+            throw JSON.typeMismatch(name, object, "JSONObject");
         }
     }
 
     /**
-     * Put a key/boolean pair in the JSONObject.
-     *
-     * @param key
-     *            A key string.
-     * @param value
-     *            A boolean which is the value.
-     * @return this.
-     * @throws JSONException
-     *             If the key is null.
+     * Returns the value mapped by {@code name} if it exists and is a {@code
+     * JSONObject}, or null otherwise.
      */
-    public JSONObject put(String key, boolean value) throws JSONException {
-        this.put(key, value ? Boolean.TRUE : Boolean.FALSE);
-        return this;
+    public JSONObject optJSONObject(String name) {
+        Object object = opt(name);
+        return object instanceof JSONObject ? (JSONObject) object : null;
     }
 
     /**
-     * Put a key/value pair in the JSONObject, where the value will be a
-     * JSONArray which is produced from a Collection.
-     *
-     * @param key
-     *            A key string.
-     * @param value
-     *            A Collection value.
-     * @return this.
-     * @throws JSONException
+     * Returns an array with the values corresponding to {@code names}. The
+     * array contains null for names that aren't mapped. This method returns
+     * null if {@code names} is either null or empty.
      */
-    public JSONObject put(String key, Collection value) throws JSONException {
-        this.put(key, new JSONArray(value));
-        return this;
+    public JSONArray toJSONArray(JSONArray names) throws JSONException {
+        JSONArray result = new JSONArray();
+        if (names == null) {
+            return null;
+        }
+        int length = names.length();
+        if (length == 0) {
+            return null;
+        }
+        for (int i = 0; i < length; i++) {
+            String name = JSON.toString(names.opt(i));
+            result.put(opt(name));
+        }
+        return result;
     }
 
     /**
-     * Put a key/double pair in the JSONObject.
-     *
-     * @param key
-     *            A key string.
-     * @param value
-     *            A double which is the value.
-     * @return this.
-     * @throws JSONException
-     *             If the key is null or if the number is invalid.
+     * Returns an iterator of the {@code String} names in this object. The
+     * returned iterator supports {@link Iterator#remove() remove}, which will
+     * remove the corresponding mapping from this object. If this object is
+     * modified after the iterator is returned, the iterator's behavior is
+     * undefined. The order of the keys is undefined.
      */
-    public JSONObject put(String key, double value) throws JSONException {
-        this.put(key, new Double(value));
-        return this;
+    public Iterator<String> keys() {
+        return nameValuePairs.keySet().iterator();
     }
 
     /**
-     * Put a key/int pair in the JSONObject.
+     * Returns the set of {@code String} names in this object. The returned set
+     * is a view of the keys in this object. {@link Set#remove(Object)} will remove
+     * the corresponding mapping from this object and set iterator behaviour
+     * is undefined if this object is modified after it is returned.
      *
-     * @param key
-     *            A key string.
-     * @param value
-     *            An int which is the value.
-     * @return this.
-     * @throws JSONException
-     *             If the key is null.
-     */
-    public JSONObject put(String key, int value) throws JSONException {
-        this.put(key, new Integer(value));
-        return this;
-    }
-
-    /**
-     * Put a key/long pair in the JSONObject.
+     * See {@link #keys()}.
      *
-     * @param key
-     *            A key string.
-     * @param value
-     *            A long which is the value.
-     * @return this.
-     * @throws JSONException
-     *             If the key is null.
+     * @hide.
      */
-    public JSONObject put(String key, long value) throws JSONException {
-        this.put(key, new Long(value));
-        return this;
+    public Set<String> keySet() {
+        return nameValuePairs.keySet();
     }
 
     /**
-     * Put a key/value pair in the JSONObject, where the value will be a
-     * JSONObject which is produced from a Map.
-     *
-     * @param key
-     *            A key string.
-     * @param value
-     *            A Map value.
-     * @return this.
-     * @throws JSONException
+     * Returns an array containing the string names in this object. This method
+     * returns null if this object contains no mappings.
      */
-    public JSONObject put(String key, Map value) throws JSONException {
-        this.put(key, new JSONObject(value));
-        return this;
+    public JSONArray names() {
+        return nameValuePairs.isEmpty()
+                ? null
+                : new JSONArray(new ArrayList<String>(nameValuePairs.keySet()));
     }
 
     /**
-     * Put a key/value pair in the JSONObject. If the value is null, then the
-     * key will be removed from the JSONObject if it is present.
-     *
-     * @param key
-     *            A key string.
-     * @param value
-     *            An object which is the value. It should be of one of these
-     *            types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
-     *            String, or the JSONObject.NULL object.
-     * @return this.
-     * @throws JSONException
-     *             If the value is non-finite number or if the key is null.
+     * Encodes this object as a compact JSON string, such as:
+     * <pre>{"query":"Pizza","locations":[94043,90210]}</pre>
      */
-    public JSONObject put(String key, Object value) throws JSONException {
-        if (key == null) {
-            throw new NullPointerException("Null key.");
-        }
-        if (value != null) {
-            testValidity(value);
-            _put(key, value);
-        } else {
-            this.remove(key);
+    @Override public String toString() {
+        try {
+            JSONStringer stringer = new JSONStringer();
+            writeTo(stringer);
+            return stringer.toString();
+        } catch (JSONException e) {
+            return null;
         }
-        return this;
     }
 
     /**
-     * Put a key/value pair in the JSONObject, but only if the key and the value
-     * are both non-null, and only if there is not already a member with that
-     * name.
+     * Encodes this object as a human readable JSON string for debugging, such
+     * as:
+     * <pre>
+     * {
+     *     "query": "Pizza",
+     *     "locations": [
+     *         94043,
+     *         90210
+     *     ]
+     * }</pre>
      *
-     * @param key
-     * @param value
-     * @return his.
-     * @throws JSONException
-     *             if the key is a duplicate
+     * @param indentSpaces the number of spaces to indent for each level of
+     *     nesting.
      */
-    public JSONObject putOnce(String key, Object value) throws JSONException {
-        if (key != null && value != null) {
-            if (this.opt(key) != null) {
-                throw new JSONException("Duplicate key \"" + key + "\"");
-            }
-            this.put(key, value);
-        }
-        return this;
+    public String toString(int indentSpaces) throws JSONException {
+        JSONStringer stringer = new JSONStringer(indentSpaces);
+        writeTo(stringer);
+        return stringer.toString();
     }
 
-    /**
-     * Put a key/value pair in the JSONObject, but only if the key and the value
-     * are both non-null.
-     *
-     * @param key
-     *            A key string.
-     * @param value
-     *            An object which is the value. It should be of one of these
-     *            types: Boolean, Double, Integer, JSONArray, JSONObject, Long,
-     *            String, or the JSONObject.NULL object.
-     * @return this.
-     * @throws JSONException
-     *             If the value is a non-finite number.
-     */
-    public JSONObject putOpt(String key, Object value) throws JSONException {
-        if (key != null && value != null) {
-            this.put(key, value);
+    void writeTo(JSONStringer stringer) throws JSONException {
+        stringer.object();
+        for (Map.Entry<String, Object> entry : nameValuePairs.entrySet()) {
+            stringer.key(entry.getKey()).value(entry.getValue());
         }
-        return this;
+        stringer.endObject();
     }
 
     /**
-     * Produce a string in double quotes with backslash sequences in all the
-     * right places. A backslash will be inserted within </, producing <\/,
-     * allowing JSON text to be delivered in HTML. In JSON text, a string cannot
-     * contain a control character or an unescaped quote or backslash.
+     * Encodes the number as a JSON string.
      *
-     * @param string
-     *            A String
-     * @return A String correctly formatted for insertion in a JSON text.
+     * @param number a finite value. May not be {@link Double#isNaN() NaNs} or
+     *     {@link Double#isInfinite() infinities}.
      */
-    public static String quote(String string) {
-        StringWriter sw = new StringWriter();
-        synchronized (sw.getBuffer()) {
-            try {
-                return quote(string, sw).toString();
-            } catch (IOException ignored) {
-                // will never happen - we are writing to a string writer
-                return "";
-            }
-        }
-    }
-
-    public static Writer quote(String string, Writer w) throws IOException {
-        if (string == null || string.length() == 0) {
-            w.write("\"\"");
-            return w;
-        }
-
-        char b;
-        char c = 0;
-        String hhhh;
-        int i;
-        int len = string.length();
-
-        w.write('"');
-        for (i = 0; i < len; i += 1) {
-            b = c;
-            c = string.charAt(i);
-            switch (c) {
-            case '\\':
-            case '"':
-                w.write('\\');
-                w.write(c);
-                break;
-            case '/':
-                if (b == '<') {
-                    w.write('\\');
-                }
-                w.write(c);
-                break;
-            case '\b':
-                w.write("\\b");
-                break;
-            case '\t':
-                w.write("\\t");
-                break;
-            case '\n':
-                w.write("\\n");
-                break;
-            case '\f':
-                w.write("\\f");
-                break;
-            case '\r':
-                w.write("\\r");
-                break;
-            default:
-                if (c < ' ' || (c >= '\u0080' && c < '\u00a0')
-                        || (c >= '\u2000' && c < '\u2100')) {
-                    w.write("\\u");
-                    hhhh = Integer.toHexString(c);
-                    w.write("0000", 0, 4 - hhhh.length());
-                    w.write(hhhh);
-                } else {
-                    w.write(c);
-                }
-            }
+    public static String numberToString(Number number) throws JSONException {
+        if (number == null) {
+            throw new JSONException("Number must be non-null");
         }
-        w.write('"');
-        return w;
-    }
 
-    /**
-     * Remove a name and its value, if present.
-     *
-     * @param key
-     *            The name to be removed.
-     * @return The value that was associated with the name, or null if there was
-     *         no value.
-     */
-    public Object remove(String key) {
-    	Object value = this.map.remove(key);
-        if (value instanceof JSONObject) {
-        	((JSONObject) value).parent = null;
-        }
-        if (value instanceof JSONArray) {
-        	((JSONArray) value).parent = null;
-        }
-        return value;
-    }
+        double doubleValue = number.doubleValue();
+        JSON.checkDouble(doubleValue);
 
-    /**
-     * Try to convert a string into a number, boolean, or null. If the string
-     * can't be converted, return the string.
-     *
-     * @param string
-     *            A String.
-     * @return A simple JSON value.
-     */
-    public static Object stringToValue(String string) {
-        Double d;
-        if (string.equals("")) {
-            return string;
-        }
-        if (string.equalsIgnoreCase("true")) {
-            return Boolean.TRUE;
-        }
-        if (string.equalsIgnoreCase("false")) {
-            return Boolean.FALSE;
-        }
-        if (string.equalsIgnoreCase("null")) {
-            return JSONObject.NULL;
+        // the original returns "-0" instead of "-0.0" for negative zero
+        if (number.equals(NEGATIVE_ZERO)) {
+            return "-0";
         }
 
-        /*
-         * If it might be a number, try converting it. If a number cannot be
-         * produced, then the value will just be a string.
-         */
-
-        char b = string.charAt(0);
-        if ((b >= '0' && b <= '9') || b == '-') {
-            try {
-                if (string.indexOf('.') > -1 || string.indexOf('e') > -1
-                        || string.indexOf('E') > -1) {
-                    d = Double.valueOf(string);
-                    if (!d.isInfinite() && !d.isNaN()) {
-                        return d;
-                    }
-                } else {
-                    Long myLong = new Long(string);
-                    if (string.equals(myLong.toString())) {
-                        if (myLong.longValue() == myLong.intValue()) {
-                            return new Integer(myLong.intValue());
-                        } else {
-                            return myLong;
-                        }
-                    }
-                }
-            } catch (Exception ignore) {
-            }
+        long longValue = number.longValue();
+        if (doubleValue == longValue) {
+            return Long.toString(longValue);
         }
-        return string;
-    }
 
-    /**
-     * Throw an exception if the object is a NaN or infinite number.
-     *
-     * @param o
-     *            The object to test.
-     * @throws JSONException
-     *             If o is a non-finite number.
-     */
-    public static void testValidity(Object o) throws JSONException {
-        if (o != null) {
-            if (o instanceof Double) {
-                if (((Double) o).isInfinite() || ((Double) o).isNaN()) {
-                    throw new JSONException(
-                            "JSON does not allow non-finite numbers.");
-                }
-            } else if (o instanceof Float) {
-                if (((Float) o).isInfinite() || ((Float) o).isNaN()) {
-                    throw new JSONException(
-                            "JSON does not allow non-finite numbers.");
-                }
-            }
-        }
+        return number.toString();
     }
 
     /**
-     * Produce a JSONArray containing the values of the members of this
-     * JSONObject.
+     * Encodes {@code data} as a JSON string. This applies quotes and any
+     * necessary character escaping.
      *
-     * @param names
-     *            A JSONArray containing a list of key strings. This determines
-     *            the sequence of the values in the result.
-     * @return A JSONArray of values.
-     * @throws JSONException
-     *             If any of the values are non-finite numbers.
+     * @param data the string to encode. Null will be interpreted as an empty
+     *     string.
      */
-    public JSONArray toJSONArray(JSONArray names) throws JSONException {
-        if (names == null || names.length() == 0) {
-            return null;
+    public static String quote(String data) {
+        if (data == null) {
+            return "\"\"";
         }
-        JSONArray ja = new JSONArray();
-        for (int i = 0; i < names.length(); i += 1) {
-            ja.put(this.opt(names.getString(i)));
-        }
-        return ja;
-    }
-
-    /**
-     * Make a JSON text of this JSONObject. For compactness, no whitespace is
-     * added. If this would not result in a syntactically correct JSON text,
-     * then null will be returned instead.
-     * <p>
-     * Warning: This method assumes that the data structure is acyclical.
-     *
-     * @return a printable, displayable, portable, transmittable representation
-     *         of the object, beginning with <code>{</code> <small>(left
-     *         brace)</small> and ending with <code>}</code> <small>(right
-     *         brace)</small>.
-     */
-    public String toString() {
         try {
-            return this.toString(0);
-        } catch (Exception e) {
-            return null;
+            JSONStringer stringer = new JSONStringer();
+            stringer.open(JSONStringer.Scope.NULL, "");
+            stringer.value(data);
+            stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
+            return stringer.toString();
+        } catch (JSONException e) {
+            throw new AssertionError();
         }
     }
 
     /**
-     * Make a prettyprinted JSON text of this JSONObject.
-     * <p>
-     * Warning: This method assumes that the data structure is acyclical.
+     * Wraps the given object if necessary.
      *
-     * @param indentFactor
-     *            The number of spaces to add to each level of indentation.
-     * @return a printable, displayable, portable, transmittable representation
-     *         of the object, beginning with <code>{</code> <small>(left
-     *         brace)</small> and ending with <code>}</code> <small>(right
-     *         brace)</small>.
-     * @throws JSONException
-     *             If the object contains an invalid number.
+     * <p>If the object is null or , returns {@link #NULL}.
+     * If the object is a {@code JSONArray} or {@code JSONObject}, no wrapping is necessary.
+     * If the object is {@code NULL}, no wrapping is necessary.
+     * If the object is an array or {@code Collection}, returns an equivalent {@code JSONArray}.
+     * If the object is a {@code Map}, returns an equivalent {@code JSONObject}.
+     * If the object is a primitive wrapper type or {@code String}, returns the object.
+     * Otherwise if the object is from a {@code java} package, returns the result of {@code toString}.
+     * If wrapping fails, returns null.
      */
-    public String toString(int indentFactor) throws JSONException {
-        StringWriter w = new StringWriter();
-        synchronized (w.getBuffer()) {
-            return this.write(w, indentFactor, 0).toString();
+    @SuppressWarnings("rawtypes")
+	public static Object wrap(Object o) {
+        if (o == null) {
+            return NULL;
         }
-    }
-
-    /**
-     * Make a JSON text of an Object value. If the object has an
-     * value.toJSONString() method, then that method will be used to produce the
-     * JSON text. The method is required to produce a strictly conforming text.
-     * If the object does not contain a toJSONString method (which is the most
-     * common case), then a text will be produced by other means. If the value
-     * is an array or Collection, then a JSONArray will be made from it and its
-     * toJSONString method will be called. If the value is a MAP, then a
-     * JSONObject will be made from it and its toJSONString method will be
-     * called. Otherwise, the value's toString method will be called, and the
-     * result will be quoted.
-     *
-     * <p>
-     * Warning: This method assumes that the data structure is acyclical.
-     *
-     * @param value
-     *            The value to be serialized.
-     * @return a printable, displayable, transmittable representation of the
-     *         object, beginning with <code>{</code> <small>(left
-     *         brace)</small> and ending with <code>}</code> <small>(right
-     *         brace)</small>.
-     * @throws JSONException
-     *             If the value is or contains an invalid number.
-     */
-    public static String valueToString(Object value) throws JSONException {
-        if (value == null || value.equals(null)) {
-            return "null";
+        if (o instanceof JSONArray || o instanceof JSONObject) {
+            return o;
         }
-        if (value instanceof JSONString) {
-            Object object;
-            try {
-                object = ((JSONString) value).toJSONString();
-            } catch (Exception e) {
-                throw new JSONException(e);
-            }
-            if (object instanceof String) {
-                return (String) object;
-            }
-            throw new JSONException("Bad value from toJSONString: " + object);
-        }
-        if (value instanceof Number) {
-            return numberToString((Number) value);
-        }
-        if (value instanceof Boolean || value instanceof JSONObject
-                || value instanceof JSONArray) {
-            return value.toString();
-        }
-        if (value instanceof Map) {
-            return new JSONObject((Map) value).toString();
+        if (o.equals(NULL)) {
+            return o;
         }
-        if (value instanceof Collection) {
-            return new JSONArray((Collection) value).toString();
-        }
-        if (value.getClass().isArray()) {
-            return new JSONArray(value).toString();
-        }
-        return quote(value.toString());
-    }
-
-    /**
-     * Wrap an object, if necessary. If the object is null, return the NULL
-     * object. If it is an array or collection, wrap it in a JSONArray. If it is
-     * a map, wrap it in a JSONObject. If it is a standard property (Double,
-     * String, et al) then it is already wrapped. Otherwise, if it comes from
-     * one of the java packages, turn it into a string. And if it doesn't, try
-     * to wrap it in a JSONObject. If the wrapping fails, then null is returned.
-     *
-     * @param object
-     *            The object to wrap
-     * @return The wrapped value
-     */
-    public static Object wrap(Object object) {
         try {
-            if (object == null) {
-                return NULL;
+            if (o instanceof Collection) {
+                return new JSONArray((Collection) o);
+            } else if (o.getClass().isArray()) {
+                return new JSONArray(o);
             }
-            if (object instanceof JSONObject || object instanceof JSONArray
-                    || NULL.equals(object) || object instanceof JSONString
-                    || object instanceof Byte || object instanceof Character
-                    || object instanceof Short || object instanceof Integer
-                    || object instanceof Long || object instanceof Boolean
-                    || object instanceof Float || object instanceof Double
-                    || object instanceof String) {
-                return object;
-            }
-
-            if (object instanceof Collection) {
-                return new JSONArray((Collection) object);
+            if (o instanceof Map) {
+                return new JSONObject((Map) o);
             }
-            if (object.getClass().isArray()) {
-                return new JSONArray(object);
+            if (o instanceof Boolean ||
+                o instanceof Byte ||
+                o instanceof Character ||
+                o instanceof Double ||
+                o instanceof Float ||
+                o instanceof Integer ||
+                o instanceof Long ||
+                o instanceof Short ||
+                o instanceof String) {
+                return o;
             }
-            if (object instanceof Map) {
-                return new JSONObject((Map) object);
-            }
-            Package objectPackage = object.getClass().getPackage();
-            String objectPackageName = objectPackage != null ? objectPackage
-                    .getName() : "";
-            if (objectPackageName.startsWith("java.")
-                    || objectPackageName.startsWith("javax.")
-                    || object.getClass().getClassLoader() == null) {
-                return object.toString();
-            }
-            return new JSONObject(object);
-        } catch (Exception exception) {
-            return null;
-        }
-    }
-
-    /**
-     * Write the contents of the JSONObject as JSON text to a writer. For
-     * compactness, no whitespace is added.
-     * <p>
-     * Warning: This method assumes that the data structure is acyclical.
-     *
-     * @return The writer.
-     * @throws JSONException
-     */
-    public Writer write(Writer writer) throws JSONException {
-        return this.write(writer, 0, 0);
-    }
-
-    static final Writer writeValue(Writer writer, Object value,
-            int indentFactor, int indent) throws JSONException, IOException {
-        if (value == null || value.equals(null)) {
-            writer.write("null");
-        } else if (value instanceof JSONObject) {
-            ((JSONObject) value).write(writer, indentFactor, indent);
-        } else if (value instanceof JSONArray) {
-            ((JSONArray) value).write(writer, indentFactor, indent);
-        } else if (value instanceof Map) {
-            new JSONObject((Map) value).write(writer, indentFactor, indent);
-        } else if (value instanceof Collection) {
-            new JSONArray((Collection) value).write(writer, indentFactor,
-                    indent);
-        } else if (value.getClass().isArray()) {
-            new JSONArray(value).write(writer, indentFactor, indent);
-        } else if (value instanceof Number) {
-            writer.write(numberToString((Number) value));
-        } else if (value instanceof Boolean) {
-            writer.write(value.toString());
-        } else if (value instanceof JSONString) {
-            Object o;
-            try {
-                o = ((JSONString) value).toJSONString();
-            } catch (Exception e) {
-                throw new JSONException(e);
+            if (o.getClass().getPackage().getName().startsWith("java.")) {
+                return o.toString();
             }
-            writer.write(o != null ? o.toString() : quote(value.toString()));
-        } else {
-            quote(value.toString(), writer);
+        } catch (Exception ignored) {
         }
-        return writer;
+        return null;
     }
 
-    static final void indent(Writer writer, int indent) throws IOException {
-        for (int i = 0; i < indent; i += 1) {
-            writer.write(' ');
-        }
+    public Object getParent() {
+    	return parent;
     }
 
-    /**
-     * Write the contents of the JSONObject as JSON text to a writer. For
-     * compactness, no whitespace is added.
-     * <p>
-     * Warning: This method assumes that the data structure is acyclical.
-     *
-     * @return The writer.
-     * @throws JSONException
-     */
-    Writer write(Writer writer, int indentFactor, int indent)
-            throws JSONException {
-        try {
-            boolean commanate = false;
-            final int length = this.length();
-            Iterator keys = this.keys();
-            writer.write('{');
-
-            if (length == 1) {
-                Object key = keys.next();
-                writer.write(quote(key.toString()));
-                writer.write(':');
-                if (indentFactor > 0) {
-                    writer.write(' ');
-                }
-                writeValue(writer, this.map.get(key), indentFactor, indent);
-            } else if (length != 0) {
-                final int newindent = indent + indentFactor;
-                while (keys.hasNext()) {
-                    Object key = keys.next();
-                    if (commanate) {
-                        writer.write(',');
-                    }
-                    if (indentFactor > 0) {
-                        writer.write('\n');
-                    }
-                    indent(writer, newindent);
-                    writer.write(quote(key.toString()));
-                    writer.write(':');
-                    if (indentFactor > 0) {
-                        writer.write(' ');
-                    }
-                    writeValue(writer, this.map.get(key), indentFactor,
-                            newindent);
-                    commanate = true;
-                }
-                if (indentFactor > 0) {
-                    writer.write('\n');
-                }
-                indent(writer, indent);
-            }
-            writer.write('}');
-            return writer;
-        } catch (IOException exception) {
-            throw new JSONException(exception);
-        }
-    }
+    public void setParent(Object parent) {
+		this.parent = parent;
+	}
 }
diff --git a/src/org/json/JSONString.java b/src/org/json/JSONString.java
deleted file mode 100755
index 1f2d77d..0000000
--- a/src/org/json/JSONString.java
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.json;
-/**
- * The <code>JSONString</code> interface allows a <code>toJSONString()</code>
- * method so that a class can change the behavior of
- * <code>JSONObject.toString()</code>, <code>JSONArray.toString()</code>,
- * and <code>JSONWriter.value(</code>Object<code>)</code>. The
- * <code>toJSONString</code> method will be used instead of the default behavior
- * of using the Object's <code>toString()</code> method and quoting the result.
- */
-public interface JSONString {
-    /**
-     * The <code>toJSONString</code> method allows a class to produce its own JSON
-     * serialization.
-     *
-     * @return A strictly syntactically correct JSON text.
-     */
-    public String toJSONString();
-}
diff --git a/src/org/json/JSONStringer.java b/src/org/json/JSONStringer.java
old mode 100755
new mode 100644
index 25c2e5d..dd3b2a7
--- a/src/org/json/JSONStringer.java
+++ b/src/org/json/JSONStringer.java
@@ -1,78 +1,432 @@
-package org.json;
-
-/*
-Copyright (c) 2006 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-import java.io.StringWriter;
-
-/**
- * JSONStringer provides a quick and convenient way of producing JSON text.
- * The texts produced strictly conform to JSON syntax rules. No whitespace is
- * added, so the results are ready for transmission or storage. Each instance of
- * JSONStringer can produce one JSON text.
- * <p>
- * A JSONStringer instance provides a <code>value</code> method for appending
- * values to the
- * text, and a <code>key</code>
- * method for adding keys before values in objects. There are <code>array</code>
- * and <code>endArray</code> methods that make and bound array values, and
- * <code>object</code> and <code>endObject</code> methods which make and bound
- * object values. All of these methods return the JSONWriter instance,
- * permitting cascade style. For example, <pre>
- * myString = new JSONStringer()
- *     .object()
- *         .key("JSON")
- *         .value("Hello, World!")
- *     .endObject()
- *     .toString();</pre> which produces the string <pre>
- * {"JSON":"Hello, World!"}</pre>
- * <p>
- * The first method called must be <code>array</code> or <code>object</code>.
- * There are no methods for adding commas or colons. JSONStringer adds them for
- * you. Objects and arrays can be nested up to 20 levels deep.
- * <p>
- * This can sometimes be easier than using a JSONObject to build a string.
- * @author JSON.org
- * @version 2008-09-18
- */
-public class JSONStringer extends JSONWriter {
-    /**
-     * Make a fresh JSONStringer. It can be used to build one JSON text.
-     */
-    public JSONStringer() {
-        super(new StringWriter());
-    }
-
-    /**
-     * Return the JSON text. This method is used to obtain the product of the
-     * JSONStringer instance. It will return <code>null</code> if there was a
-     * problem in the construction of the JSON text (such as the calls to
-     * <code>array</code> were not properly balanced with calls to
-     * <code>endArray</code>).
-     * @return The JSON text.
-     */
-    public String toString() {
-        return this.mode == 'd' ? this.writer.toString() : null;
-    }
-}
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
+/**
+ * Implements {@link JSONObject#toString} and {@link JSONArray#toString}. Most
+ * application developers should use those methods directly and disregard this
+ * API. For example:<pre>
+ * JSONObject object = ...
+ * String json = object.toString();</pre>
+ *
+ * <p>Stringers only encode well-formed JSON strings. In particular:
+ * <ul>
+ *   <li>The stringer must have exactly one top-level array or object.
+ *   <li>Lexical scopes must be balanced: every call to {@link #array} must
+ *       have a matching call to {@link #endArray} and every call to {@link
+ *       #object} must have a matching call to {@link #endObject}.
+ *   <li>Arrays may not contain keys (property names).
+ *   <li>Objects must alternate keys (property names) and values.
+ *   <li>Values are inserted with either literal {@link #value(Object) value}
+ *       calls, or by nesting arrays or objects.
+ * </ul>
+ * Calls that would result in a malformed JSON string will fail with a
+ * {@link JSONException}.
+ *
+ * <p>This class provides no facility for pretty-printing (ie. indenting)
+ * output. To encode indented output, use {@link JSONObject#toString(int)} or
+ * {@link JSONArray#toString(int)}.
+ *
+ * <p>Some implementations of the API support at most 20 levels of nesting.
+ * Attempts to create more than 20 levels of nesting may fail with a {@link
+ * JSONException}.
+ *
+ * <p>Each stringer may be used to encode a single top level value. Instances of
+ * this class are not thread safe. Although this class is nonfinal, it was not
+ * designed for inheritance and should not be subclassed. In particular,
+ * self-use by overrideable methods is not specified. See <i>Effective Java</i>
+ * Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * information.
+ */
+public class JSONStringer {
+
+    /** The output data, containing at most one top-level array or object. */
+    final StringBuilder out = new StringBuilder();
+
+    /**
+     * Lexical scoping elements within this stringer, necessary to insert the
+     * appropriate separator characters (ie. commas and colons) and to detect
+     * nesting errors.
+     */
+    enum Scope {
+
+        /**
+         * An array with no elements requires no separators or newlines before
+         * it is closed.
+         */
+        EMPTY_ARRAY,
+
+        /**
+         * A array with at least one value requires a comma and newline before
+         * the next element.
+         */
+        NONEMPTY_ARRAY,
+
+        /**
+         * An object with no keys or values requires no separators or newlines
+         * before it is closed.
+         */
+        EMPTY_OBJECT,
+
+        /**
+         * An object whose most recent element is a key. The next element must
+         * be a value.
+         */
+        DANGLING_KEY,
+
+        /**
+         * An object with at least one name/value pair requires a comma and
+         * newline before the next element.
+         */
+        NONEMPTY_OBJECT,
+
+        /**
+         * A special bracketless array needed by JSONStringer.join() and
+         * JSONObject.quote() only. Not used for JSON encoding.
+         */
+        NULL,
+    }
+
+    /**
+     * Unlike the original implementation, this stack isn't limited to 20
+     * levels of nesting.
+     */
+    private final List<Scope> stack = new ArrayList<Scope>();
+
+    /**
+     * A string containing a full set of spaces for a single level of
+     * indentation, or null for no pretty printing.
+     */
+    private final String indent;
+
+    public JSONStringer() {
+        indent = null;
+    }
+
+    JSONStringer(int indentSpaces) {
+        char[] indentChars = new char[indentSpaces];
+        Arrays.fill(indentChars, ' ');
+        indent = new String(indentChars);
+    }
+
+    /**
+     * Begins encoding a new array. Each call to this method must be paired with
+     * a call to {@link #endArray}.
+     *
+     * @return this stringer.
+     */
+    public JSONStringer array() throws JSONException {
+        return open(Scope.EMPTY_ARRAY, "[");
+    }
+
+    /**
+     * Ends encoding the current array.
+     *
+     * @return this stringer.
+     */
+    public JSONStringer endArray() throws JSONException {
+        return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]");
+    }
+
+    /**
+     * Begins encoding a new object. Each call to this method must be paired
+     * with a call to {@link #endObject}.
+     *
+     * @return this stringer.
+     */
+    public JSONStringer object() throws JSONException {
+        return open(Scope.EMPTY_OBJECT, "{");
+    }
+
+    /**
+     * Ends encoding the current object.
+     *
+     * @return this stringer.
+     */
+    public JSONStringer endObject() throws JSONException {
+        return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}");
+    }
+
+    /**
+     * Enters a new scope by appending any necessary whitespace and the given
+     * bracket.
+     */
+    JSONStringer open(Scope empty, String openBracket) throws JSONException {
+        if (stack.isEmpty() && out.length() > 0) {
+            throw new JSONException("Nesting problem: multiple top-level roots");
+        }
+        beforeValue();
+        stack.add(empty);
+        out.append(openBracket);
+        return this;
+    }
+
+    /**
+     * Closes the current scope by appending any necessary whitespace and the
+     * given bracket.
+     */
+    JSONStringer close(Scope empty, Scope nonempty, String closeBracket) throws JSONException {
+        Scope context = peek();
+        if (context != nonempty && context != empty) {
+            throw new JSONException("Nesting problem");
+        }
+
+        stack.remove(stack.size() - 1);
+        if (context == nonempty) {
+            newline();
+        }
+        out.append(closeBracket);
+        return this;
+    }
+
+    /**
+     * Returns the value on the top of the stack.
+     */
+    private Scope peek() throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        return stack.get(stack.size() - 1);
+    }
+
+    /**
+     * Replace the value on the top of the stack with the given value.
+     */
+    private void replaceTop(Scope topOfStack) {
+        stack.set(stack.size() - 1, topOfStack);
+    }
+
+    /**
+     * Encodes {@code value}.
+     *
+     * @param value a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     *     Integer, Long, Double or null. May not be {@link Double#isNaN() NaNs}
+     *     or {@link Double#isInfinite() infinities}.
+     * @return this stringer.
+     */
+    public JSONStringer value(Object value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+
+        if (value instanceof JSONArray) {
+            ((JSONArray) value).writeTo(this);
+            return this;
+
+        } else if (value instanceof JSONObject) {
+            ((JSONObject) value).writeTo(this);
+            return this;
+        }
+
+        beforeValue();
+
+        if (value == null
+                || value instanceof Boolean
+                || value == JSONObject.NULL) {
+            out.append(value);
+
+        } else if (value instanceof Number) {
+            out.append(JSONObject.numberToString((Number) value));
+
+        } else {
+            string(value.toString());
+        }
+
+        return this;
+    }
+
+    /**
+     * Encodes {@code value} to this stringer.
+     *
+     * @return this stringer.
+     */
+    public JSONStringer value(boolean value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        beforeValue();
+        out.append(value);
+        return this;
+    }
+
+    /**
+     * Encodes {@code value} to this stringer.
+     *
+     * @param value a finite value. May not be {@link Double#isNaN() NaNs} or
+     *     {@link Double#isInfinite() infinities}.
+     * @return this stringer.
+     */
+    public JSONStringer value(double value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        beforeValue();
+        out.append(JSONObject.numberToString(value));
+        return this;
+    }
+
+    /**
+     * Encodes {@code value} to this stringer.
+     *
+     * @return this stringer.
+     */
+    public JSONStringer value(long value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        beforeValue();
+        out.append(value);
+        return this;
+    }
+
+    private void string(String value) {
+        out.append("\"");
+        for (int i = 0, length = value.length(); i < length; i++) {
+            char c = value.charAt(i);
+
+            /*
+             * From RFC 4627, "All Unicode characters may be placed within the
+             * quotation marks except for the characters that must be escaped:
+             * quotation mark, reverse solidus, and the control characters
+             * (U+0000 through U+001F)."
+             */
+            switch (c) {
+                case '"':
+                case '\\':
+                case '/':
+                    out.append('\\').append(c);
+                    break;
+
+                case '\t':
+                    out.append("\\t");
+                    break;
+
+                case '\b':
+                    out.append("\\b");
+                    break;
+
+                case '\n':
+                    out.append("\\n");
+                    break;
+
+                case '\r':
+                    out.append("\\r");
+                    break;
+
+                case '\f':
+                    out.append("\\f");
+                    break;
+
+                default:
+                    if (c <= 0x1F) {
+                        out.append(String.format("\\u%04x", (int) c));
+                    } else {
+                        out.append(c);
+                    }
+                    break;
+            }
+
+        }
+        out.append("\"");
+    }
+
+    private void newline() {
+        if (indent == null) {
+            return;
+        }
+
+        out.append("\n");
+        for (int i = 0; i < stack.size(); i++) {
+            out.append(indent);
+        }
+    }
+
+    /**
+     * Encodes the key (property name) to this stringer.
+     *
+     * @param name the name of the forthcoming value. May not be null.
+     * @return this stringer.
+     */
+    public JSONStringer key(String name) throws JSONException {
+        if (name == null) {
+            throw new JSONException("Names must be non-null");
+        }
+        beforeKey();
+        string(name);
+        return this;
+    }
+
+    /**
+     * Inserts any necessary separators and whitespace before a name. Also
+     * adjusts the stack to expect the key's value.
+     */
+    private void beforeKey() throws JSONException {
+        Scope context = peek();
+        if (context == Scope.NONEMPTY_OBJECT) { // first in object
+            out.append(',');
+        } else if (context != Scope.EMPTY_OBJECT) { // not in an object!
+            throw new JSONException("Nesting problem");
+        }
+        newline();
+        replaceTop(Scope.DANGLING_KEY);
+    }
+
+    /**
+     * Inserts any necessary separators and whitespace before a literal value,
+     * inline array, or inline object. Also adjusts the stack to expect either a
+     * closing bracket or another element.
+     */
+    private void beforeValue() throws JSONException {
+        if (stack.isEmpty()) {
+            return;
+        }
+
+        Scope context = peek();
+        if (context == Scope.EMPTY_ARRAY) { // first in array
+            replaceTop(Scope.NONEMPTY_ARRAY);
+            newline();
+        } else if (context == Scope.NONEMPTY_ARRAY) { // another in array
+            out.append(',');
+            newline();
+        } else if (context == Scope.DANGLING_KEY) { // value for key
+            out.append(indent == null ? ":" : ": ");
+            replaceTop(Scope.NONEMPTY_OBJECT);
+        } else if (context != Scope.NULL) {
+            throw new JSONException("Nesting problem");
+        }
+    }
+
+    /**
+     * Returns the encoded JSON string.
+     *
+     * <p>If invoked with unterminated arrays or unclosed objects, this method's
+     * return value is undefined.
+     *
+     * <p><strong>Warning:</strong> although it contradicts the general contract
+     * of {@link Object#toString}, this method returns null if the stringer
+     * contains no data.
+     */
+    @Override public String toString() {
+        return out.length() == 0 ? null : out.toString();
+    }
+}
diff --git a/src/org/json/JSONTokener.java b/src/org/json/JSONTokener.java
index 13c84f1..b6b944c 100644
--- a/src/org/json/JSONTokener.java
+++ b/src/org/json/JSONTokener.java
@@ -1,446 +1,615 @@
-package org.json;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.io.StringReader;
-
 /*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
 
-The Software shall be used for Good, not Evil.
+package org.json;
 
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
+// Note: this class was written without inspecting the non-free org.json sourcecode.
 
 /**
- * A JSONTokener takes a source string and extracts characters and tokens from
- * it. It is used by the JSONObject and JSONArray constructors to parse
- * JSON source strings.
- * @author JSON.org
- * @version 2012-02-16
+ * Parses a JSON (<a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>)
+ * encoded string into the corresponding object. Most clients of
+ * this class will use only need the {@link #JSONTokener(String) constructor}
+ * and {@link #nextValue} method. Example usage: <pre>
+ * String json = "{"
+ *         + "  \"query\": \"Pizza\", "
+ *         + "  \"locations\": [ 94043, 90210 ] "
+ *         + "}";
+ *
+ * JSONObject object = (JSONObject) new JSONTokener(json).nextValue();
+ * String query = object.getString("query");
+ * JSONArray locations = object.getJSONArray("locations");</pre>
+ *
+ * <p>For best interoperability and performance use JSON that complies with
+ * RFC 4627, such as that generated by {@link JSONStringer}. For legacy reasons
+ * this parser is lenient, so a successful parse does not indicate that the
+ * input string was valid JSON. All of the following syntax errors will be
+ * ignored:
+ * <ul>
+ *   <li>End of line comments starting with {@code //} or {@code #} and ending
+ *       with a newline character.
+ *   <li>C-style comments starting with {@code /*} and ending with
+ *       {@code *}{@code /}. Such comments may not be nested.
+ *   <li>Strings that are unquoted or {@code 'single quoted'}.
+ *   <li>Hexadecimal integers prefixed with {@code 0x} or {@code 0X}.
+ *   <li>Octal integers prefixed with {@code 0}.
+ *   <li>Array elements separated by {@code ;}.
+ *   <li>Unnecessary array separators. These are interpreted as if null was the
+ *       omitted value.
+ *   <li>Key-value pairs separated by {@code =} or {@code =>}.
+ *   <li>Key-value pairs separated by {@code ;}.
+ * </ul>
+ *
+ * <p>Each tokener may be used to parse a single JSON string. Instances of this
+ * class are not thread safe. Although this class is nonfinal, it was not
+ * designed for inheritance and should not be subclassed. In particular,
+ * self-use by overrideable methods is not specified. See <i>Effective Java</i>
+ * Item 17, "Design and Document or inheritance or else prohibit it" for further
+ * information.
  */
 public class JSONTokener {
 
-    private long    character;
-    private boolean eof;
-    private long    index;
-    private long    line;
-    private char    previous;
-    private Reader  reader;
-    private boolean usePrevious;
-
+    /** The input JSON. */
+    private final String in;
 
     /**
-     * Construct a JSONTokener from a Reader.
-     *
-     * @param reader     A reader.
+     * The index of the next character to be returned by {@link #next}. When
+     * the input is exhausted, this equals the input's length.
      */
-    public JSONTokener(Reader reader) {
-        this.reader = reader.markSupported()
-            ? reader
-            : new BufferedReader(reader);
-        this.eof = false;
-        this.usePrevious = false;
-        this.previous = 0;
-        this.index = 0;
-        this.character = 1;
-        this.line = 1;
-    }
-
+    private int pos;
 
     /**
-     * Construct a JSONTokener from an InputStream.
+     * @param in JSON encoded string. Null is not permitted and will yield a
+     *     tokener that throws {@code NullPointerExceptions} when methods are
+     *     called.
      */
-    public JSONTokener(InputStream inputStream) throws JSONException {
-        this(new InputStreamReader(inputStream));
+    public JSONTokener(String in) {
+        // consume an optional byte order mark (BOM) if it exists
+        if (in != null && in.startsWith("\ufeff")) {
+            in = in.substring(1);
+        }
+        this.in = in;
     }
 
-
     /**
-     * Construct a JSONTokener from a string.
+     * Returns the next value from the input.
      *
-     * @param s     A source string.
+     * @return a {@link JSONObject}, {@link JSONArray}, String, Boolean,
+     *     Integer, Long, Double or {@link JSONObject#NULL}.
+     * @throws JSONException if the input is malformed.
      */
-    public JSONTokener(String s) {
-        this(new StringReader(s));
+    public Object nextValue() throws JSONException {
+    	return nextValue(null);
     }
+    private Object nextValue(Object parent) throws JSONException {
+        int c = nextCleanInternal();
+        switch (c) {
+            case -1:
+                throw syntaxError("End of input");
+
+            case '{':
+                return readObject(parent);
 
+            case '[':
+                return readArray(parent);
 
-    /**
-     * Back up one character. This provides a sort of lookahead capability,
-     * so that you can test for a digit or letter before attempting to parse
-     * the next number or identifier.
-     */
-    public void back() throws JSONException {
-        if (this.usePrevious || this.index <= 0) {
-            throw new JSONException("Stepping back two steps is not supported");
+            case '\'':
+            case '"':
+                return nextString((char) c);
+
+            default:
+                pos--;
+                return readLiteral();
         }
-        this.index -= 1;
-        this.character -= 1;
-        this.usePrevious = true;
-        this.eof = false;
     }
 
+    private int nextCleanInternal() throws JSONException {
+        while (pos < in.length()) {
+            int c = in.charAt(pos++);
+            switch (c) {
+                case '\t':
+                case ' ':
+                case '\n':
+                case '\r':
+                    continue;
 
-    /**
-     * Get the hex value of a character (base16).
-     * @param c A character between '0' and '9' or between 'A' and 'F' or
-     * between 'a' and 'f'.
-     * @return  An int between 0 and 15, or -1 if c was not a hex digit.
-     */
-    public static int dehexchar(char c) {
-        if (c >= '0' && c <= '9') {
-            return c - '0';
-        }
-        if (c >= 'A' && c <= 'F') {
-            return c - ('A' - 10);
-        }
-        if (c >= 'a' && c <= 'f') {
-            return c - ('a' - 10);
+                case '/':
+                    if (pos == in.length()) {
+                        return c;
+                    }
+
+                    char peek = in.charAt(pos);
+                    switch (peek) {
+                        case '*':
+                            // skip a /* c-style comment */
+                            pos++;
+                            int commentEnd = in.indexOf("*/", pos);
+                            if (commentEnd == -1) {
+                                throw syntaxError("Unterminated comment");
+                            }
+                            pos = commentEnd + 2;
+                            continue;
+
+                        case '/':
+                            // skip a // end-of-line comment
+                            pos++;
+                            skipToEndOfLine();
+                            continue;
+
+                        default:
+                            return c;
+                    }
+
+                case '#':
+                    /*
+                     * Skip a # hash end-of-line comment. The JSON RFC doesn't
+                     * specify this behavior, but it's required to parse
+                     * existing documents. See http://b/2571423.
+                     */
+                    skipToEndOfLine();
+                    continue;
+
+                default:
+                    return c;
+            }
         }
-        return -1;
-    }
 
-    public boolean end() {
-        return this.eof && !this.usePrevious;
+        return -1;
     }
 
-
     /**
-     * Determine if the source string still contains characters that next()
-     * can consume.
-     * @return true if not yet at the end of the source.
+     * Advances the position until after the next newline character. If the line
+     * is terminated by "\r\n", the '\n' must be consumed as whitespace by the
+     * caller.
      */
-    public boolean more() throws JSONException {
-        this.next();
-        if (this.end()) {
-            return false;
+    private void skipToEndOfLine() {
+        for (; pos < in.length(); pos++) {
+            char c = in.charAt(pos);
+            if (c == '\r' || c == '\n') {
+                pos++;
+                break;
+            }
         }
-        this.back();
-        return true;
     }
 
-
     /**
-     * Get the next character in the source string.
+     * Returns the string up to but not including {@code quote}, unescaping any
+     * character escape sequences encountered along the way. The opening quote
+     * should have already been read. This consumes the closing quote, but does
+     * not include it in the returned string.
      *
-     * @return The next character, or 0 if past the end of the source string.
+     * @param quote either ' or ".
      */
-    public char next() throws JSONException {
-        int c;
-        if (this.usePrevious) {
-            this.usePrevious = false;
-            c = this.previous;
-        } else {
-            try {
-                c = this.reader.read();
-            } catch (IOException exception) {
-                throw new JSONException(exception);
+    public String nextString(char quote) throws JSONException {
+        /*
+         * For strings that are free of escape sequences, we can just extract
+         * the result as a substring of the input. But if we encounter an escape
+         * sequence, we need to use a StringBuilder to compose the result.
+         */
+        StringBuilder builder = null;
+
+        /* the index of the first character not yet appended to the builder. */
+        int start = pos;
+
+        while (pos < in.length()) {
+            int c = in.charAt(pos++);
+            if (c == quote) {
+                if (builder == null) {
+                    // a new string avoids leaking memory
+                    return new String(in.substring(start, pos - 1));
+                } else {
+                    builder.append(in, start, pos - 1);
+                    return builder.toString();
+                }
             }
 
-            if (c <= 0) { // End of stream
-                this.eof = true;
-                c = 0;
+            if (c == '\\') {
+                if (pos == in.length()) {
+                    throw syntaxError("Unterminated escape sequence");
+                }
+                if (builder == null) {
+                    builder = new StringBuilder();
+                }
+                builder.append(in, start, pos - 1);
+                builder.append(readEscapeCharacter());
+                start = pos;
             }
         }
-        this.index += 1;
-        if (this.previous == '\r') {
-            this.line += 1;
-            this.character = c == '\n' ? 0 : 1;
-        } else if (c == '\n') {
-            this.line += 1;
-            this.character = 0;
-        } else {
-            this.character += 1;
-        }
-        this.previous = (char) c;
-        return this.previous;
-    }
 
+        throw syntaxError("Unterminated string");
+    }
 
     /**
-     * Consume the next character, and check that it matches a specified
-     * character.
-     * @param c The character to match.
-     * @return The character.
-     * @throws JSONException if the character does not match.
+     * Unescapes the character identified by the character or characters that
+     * immediately follow a backslash. The backslash '\' should have already
+     * been read. This supports both unicode escapes "u000A" and two-character
+     * escapes "\n".
      */
-    public char next(char c) throws JSONException {
-        char n = this.next();
-        if (n != c) {
-            throw this.syntaxError("Expected '" + c + "' and instead saw '" +
-                    n + "'");
-        }
-        return n;
-    }
+    private char readEscapeCharacter() throws JSONException {
+        char escaped = in.charAt(pos++);
+        switch (escaped) {
+            case 'u':
+                if (pos + 4 > in.length()) {
+                    throw syntaxError("Unterminated escape sequence");
+                }
+                String hex = in.substring(pos, pos + 4);
+                pos += 4;
+                try {
+                    return (char) Integer.parseInt(hex, 16);
+                } catch (NumberFormatException nfe) {
+                    throw syntaxError("Invalid escape sequence: " + hex);
+                }
 
+            case 't':
+                return '\t';
 
-    /**
-     * Get the next n characters.
-     *
-     * @param n     The number of characters to take.
-     * @return      A string of n characters.
-     * @throws JSONException
-     *   Substring bounds error if there are not
-     *   n characters remaining in the source string.
-     */
-     public String next(int n) throws JSONException {
-         if (n == 0) {
-             return "";
-         }
+            case 'b':
+                return '\b';
 
-         char[] chars = new char[n];
-         int pos = 0;
+            case 'n':
+                return '\n';
 
-         while (pos < n) {
-             chars[pos] = this.next();
-             if (this.end()) {
-                 throw this.syntaxError("Substring bounds error");
-             }
-             pos += 1;
-         }
-         return new String(chars);
-     }
+            case 'r':
+                return '\r';
 
+            case 'f':
+                return '\f';
+
+            case '\'':
+            case '"':
+            case '\\':
+            default:
+                return escaped;
+        }
+    }
 
     /**
-     * Get the next char in the string, skipping whitespace.
-     * @throws JSONException
-     * @return  A character, or 0 if there are no more characters.
+     * Reads a null, boolean, numeric or unquoted string literal value. Numeric
+     * values will be returned as an Integer, Long, or Double, in that order of
+     * preference.
      */
-    public char nextClean() throws JSONException {
-        for (;;) {
-            char c = this.next();
-            if (c == 0 || c > ' ') {
-                return c;
+    private Object readLiteral() throws JSONException {
+        String literal = nextToInternal("{}[]/\\:,=;# \t\f");
+
+        if (literal.length() == 0) {
+            throw syntaxError("Expected literal value");
+        } else if ("null".equalsIgnoreCase(literal)) {
+            return JSONObject.NULL;
+        } else if ("true".equalsIgnoreCase(literal)) {
+            return Boolean.TRUE;
+        } else if ("false".equalsIgnoreCase(literal)) {
+            return Boolean.FALSE;
+        }
+
+        /* try to parse as an integral type... */
+        if (literal.indexOf('.') == -1) {
+            int base = 10;
+            String number = literal;
+            if (number.startsWith("0x") || number.startsWith("0X")) {
+                number = number.substring(2);
+                base = 16;
+            } else if (number.startsWith("0") && number.length() > 1) {
+                number = number.substring(1);
+                base = 8;
+            }
+            try {
+                long longValue = Long.parseLong(number, base);
+                if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
+                    return (int) longValue;
+                } else {
+                    return longValue;
+                }
+            } catch (NumberFormatException e) {
+                /*
+                 * This only happens for integral numbers greater than
+                 * Long.MAX_VALUE, numbers in exponential form (5e-10) and
+                 * unquoted strings. Fall through to try floating point.
+                 */
             }
         }
-    }
 
+        /* ...next try to parse as a floating point... */
+        try {
+            return Double.valueOf(literal);
+        } catch (NumberFormatException ignored) {
+        }
+
+        /* ... finally give up. We have an unquoted string */
+        return new String(literal); // a new string avoids leaking memory
+    }
 
     /**
-     * Return the characters up to the next close quote character.
-     * Backslash processing is done. The formal JSON format does not
-     * allow strings in single quotes, but an implementation is allowed to
-     * accept them.
-     * @param quote The quoting character, either
-     *      <code>"</code> <small>(double quote)</small> or
-     *      <code>'</code> <small>(single quote)</small>.
-     * @return      A String.
-     * @throws JSONException Unterminated string.
+     * Returns the string up to but not including any of the given characters or
+     * a newline character. This does not consume the excluded character.
      */
-    public String nextString(char quote) throws JSONException {
-        char c;
-        StringBuffer sb = new StringBuffer();
-        for (;;) {
-            c = this.next();
-            switch (c) {
-            case 0:
-            case '\n':
-            case '\r':
-                throw this.syntaxError("Unterminated string");
-            case '\\':
-                c = this.next();
-                switch (c) {
-                case 'b':
-                    sb.append('\b');
-                    break;
-                case 't':
-                    sb.append('\t');
-                    break;
-                case 'n':
-                    sb.append('\n');
-                    break;
-                case 'f':
-                    sb.append('\f');
-                    break;
-                case 'r':
-                    sb.append('\r');
-                    break;
-                case 'u':
-                    sb.append((char)Integer.parseInt(this.next(4), 16));
-                    break;
-                case '"':
-                case '\'':
-                case '\\':
-                case '/':
-                    sb.append(c);
-                    break;
-                default:
-                    throw this.syntaxError("Illegal escape.");
-                }
-                break;
-            default:
-                if (c == quote) {
-                    return sb.toString();
-                }
-                sb.append(c);
+    private String nextToInternal(String excluded) {
+        int start = pos;
+        for (; pos < in.length(); pos++) {
+            char c = in.charAt(pos);
+            if (c == '\r' || c == '\n' || excluded.indexOf(c) != -1) {
+                return in.substring(start, pos);
             }
         }
+        return in.substring(start);
     }
 
-
     /**
-     * Get the text up but not including the specified character or the
-     * end of line, whichever comes first.
-     * @param  delimiter A delimiter character.
-     * @return   A string.
+     * Reads a sequence of key/value pairs and the trailing closing brace '}' of
+     * an object. The opening brace '{' should have already been read.
      */
-    public String nextTo(char delimiter) throws JSONException {
-        StringBuffer sb = new StringBuffer();
-        for (;;) {
-            char c = this.next();
-            if (c == delimiter || c == 0 || c == '\n' || c == '\r') {
-                if (c != 0) {
-                    this.back();
+    private JSONObject readObject(Object parent) throws JSONException {
+        JSONObject result = new JSONObject();
+        result.setParent(parent);
+
+        /* Peek to see if this is the empty object. */
+        int first = nextCleanInternal();
+        if (first == '}') {
+            return result;
+        } else if (first != -1) {
+            pos--;
+        }
+
+        while (true) {
+            Object name = nextValue(result);
+            if (!(name instanceof String)) {
+                if (name == null) {
+                    throw syntaxError("Names cannot be null");
+                } else {
+                    throw syntaxError("Names must be strings, but " + name
+                            + " is of type " + name.getClass().getName());
                 }
-                return sb.toString().trim();
             }
-            sb.append(c);
+
+            /*
+             * Expect the name/value separator to be either a colon ':', an
+             * equals sign '=', or an arrow "=>". The last two are bogus but we
+             * include them because that's what the original implementation did.
+             */
+            int separator = nextCleanInternal();
+            if (separator != ':' && separator != '=') {
+                throw syntaxError("Expected ':' after " + name);
+            }
+            if (pos < in.length() && in.charAt(pos) == '>') {
+                pos++;
+            }
+
+            result.put((String) name, nextValue(result));
+
+            switch (nextCleanInternal()) {
+                case '}':
+                    return result;
+                case ';':
+                case ',':
+                    continue;
+                default:
+                    throw syntaxError("Unterminated object");
+            }
         }
     }
 
-
     /**
-     * Get the text up but not including one of the specified delimiter
-     * characters or the end of line, whichever comes first.
-     * @param delimiters A set of delimiter characters.
-     * @return A string, trimmed.
+     * Reads a sequence of values and the trailing closing brace ']' of an
+     * array. The opening brace '[' should have already been read. Note that
+     * "[]" yields an empty array, but "[,]" returns a two-element array
+     * equivalent to "[null,null]".
      */
-    public String nextTo(String delimiters) throws JSONException {
-        char c;
-        StringBuffer sb = new StringBuffer();
-        for (;;) {
-            c = this.next();
-            if (delimiters.indexOf(c) >= 0 || c == 0 ||
-                    c == '\n' || c == '\r') {
-                if (c != 0) {
-                    this.back();
-                }
-                return sb.toString().trim();
+    private JSONArray readArray(Object parent) throws JSONException {
+        JSONArray result = new JSONArray();
+        result.setParent(parent);
+
+        /* to cover input that ends with ",]". */
+        boolean hasTrailingSeparator = false;
+
+        while (true) {
+            switch (nextCleanInternal()) {
+                case -1:
+                    throw syntaxError("Unterminated array");
+                case ']':
+                    if (hasTrailingSeparator) {
+                        result.put(null);
+                    }
+                    return result;
+                case ',':
+                case ';':
+                    /* A separator without a value first means "null". */
+                    result.put(null);
+                    hasTrailingSeparator = true;
+                    continue;
+                default:
+                    pos--;
+            }
+
+            result.put(nextValue(result));
+
+            switch (nextCleanInternal()) {
+                case ']':
+                    return result;
+                case ',':
+                case ';':
+                    hasTrailingSeparator = true;
+                    continue;
+                default:
+                    throw syntaxError("Unterminated array");
             }
-            sb.append(c);
         }
     }
 
+    /**
+     * Returns an exception containing the given message plus the current
+     * position and the entire input string.
+     */
+    public JSONException syntaxError(String message) {
+        return new JSONException(message + this);
+    }
 
     /**
-     * Get the next value. The value can be a Boolean, Double, Integer,
-     * JSONArray, JSONObject, Long, or String, or the JSONObject.NULL object.
-     * @throws JSONException If syntax error.
+     * Returns the current position and the entire input string.
+     */
+    @Override public String toString() {
+        // consistent with the original implementation
+        return " at character " + pos + " of " + in;
+    }
+
+    /*
+     * Legacy APIs.
      *
-     * @return An object.
+     * None of the methods below are on the critical path of parsing JSON
+     * documents. They exist only because they were exposed by the original
+     * implementation and may be used by some clients.
      */
-    public Object nextValue() throws JSONException {
-        char c = this.nextClean();
-        String string;
 
-        switch (c) {
-            case '"':
-            case '\'':
-                return this.nextString(c);
-            case '{':
-                this.back();
-                return new JSONObject(this);
-            case '[':
-                this.back();
-                return new JSONArray(this);
-        }
+    /**
+     * Returns true until the input has been exhausted.
+     */
+    public boolean more() {
+        return pos < in.length();
+    }
 
-        /*
-         * Handle unquoted text. This could be the values true, false, or
-         * null, or it can be a number. An implementation (such as this one)
-         * is allowed to also accept non-standard forms.
-         *
-         * Accumulate characters until we reach the end of the text or a
-         * formatting character.
-         */
+    /**
+     * Returns the next available character, or the null character '\0' if all
+     * input has been exhausted. The return value of this method is ambiguous
+     * for JSON strings that contain the character '\0'.
+     */
+    public char next() {
+        return pos < in.length() ? in.charAt(pos++) : '\0';
+    }
 
-        StringBuffer sb = new StringBuffer();
-        while (c >= ' ' && ",:]}/\\\"[{;=#".indexOf(c) < 0) {
-            sb.append(c);
-            c = this.next();
+    /**
+     * Returns the next available character if it equals {@code c}. Otherwise an
+     * exception is thrown.
+     */
+    public char next(char c) throws JSONException {
+        char result = next();
+        if (result != c) {
+            throw syntaxError("Expected " + c + " but was " + result);
         }
-        this.back();
+        return result;
+    }
 
-        string = sb.toString().trim();
-        if ("".equals(string)) {
-            throw this.syntaxError("Missing value");
-        }
-        return JSONObject.stringToValue(string);
+    /**
+     * Returns the next character that is not whitespace and does not belong to
+     * a comment. If the input is exhausted before such a character can be
+     * found, the null character '\0' is returned. The return value of this
+     * method is ambiguous for JSON strings that contain the character '\0'.
+     */
+    public char nextClean() throws JSONException {
+        int nextCleanInt = nextCleanInternal();
+        return nextCleanInt == -1 ? '\0' : (char) nextCleanInt;
     }
 
+    /**
+     * Returns the next {@code length} characters of the input.
+     *
+     * <p>The returned string shares its backing character array with this
+     * tokener's input string. If a reference to the returned string may be held
+     * indefinitely, you should use {@code new String(result)} to copy it first
+     * to avoid memory leaks.
+     *
+     * @throws JSONException if the remaining input is not long enough to
+     *     satisfy this request.
+     */
+    public String next(int length) throws JSONException {
+        if (pos + length > in.length()) {
+            throw syntaxError(length + " is out of bounds");
+        }
+        String result = in.substring(pos, pos + length);
+        pos += length;
+        return result;
+    }
 
     /**
-     * Skip characters until the next character is the requested character.
-     * If the requested character is not found, no characters are skipped.
-     * @param to A character to skip to.
-     * @return The requested character, or zero if the requested character
-     * is not found.
+     * Returns the {@link String#trim trimmed} string holding the characters up
+     * to but not including the first of:
+     * <ul>
+     *   <li>any character in {@code excluded}
+     *   <li>a newline character '\n'
+     *   <li>a carriage return '\r'
+     * </ul>
+     *
+     * <p>The returned string shares its backing character array with this
+     * tokener's input string. If a reference to the returned string may be held
+     * indefinitely, you should use {@code new String(result)} to copy it first
+     * to avoid memory leaks.
+     *
+     * @return a possibly-empty string
      */
-    public char skipTo(char to) throws JSONException {
-        char c;
-        try {
-            long startIndex = this.index;
-            long startCharacter = this.character;
-            long startLine = this.line;
-            this.reader.mark(1000000);
-            do {
-                c = this.next();
-                if (c == 0) {
-                    this.reader.reset();
-                    this.index = startIndex;
-                    this.character = startCharacter;
-                    this.line = startLine;
-                    return c;
-                }
-            } while (c != to);
-        } catch (IOException exc) {
-            throw new JSONException(exc);
+    public String nextTo(String excluded) {
+        if (excluded == null) {
+            throw new NullPointerException("excluded == null");
         }
+        return nextToInternal(excluded).trim();
+    }
 
-        this.back();
-        return c;
+    /**
+     * Equivalent to {@code nextTo(String.valueOf(excluded))}.
+     */
+    public String nextTo(char excluded) {
+        return nextToInternal(String.valueOf(excluded)).trim();
     }
 
+    /**
+     * Advances past all input up to and including the next occurrence of
+     * {@code thru}. If the remaining input doesn't contain {@code thru}, the
+     * input is exhausted.
+     */
+    public void skipPast(String thru) {
+        int thruStart = in.indexOf(thru, pos);
+        pos = thruStart == -1 ? in.length() : (thruStart + thru.length());
+    }
 
     /**
-     * Make a JSONException to signal a syntax error.
-     *
-     * @param message The error message.
-     * @return  A JSONException object, suitable for throwing
+     * Advances past all input up to but not including the next occurrence of
+     * {@code to}. If the remaining input doesn't contain {@code to}, the input
+     * is unchanged.
      */
-    public JSONException syntaxError(String message) {
-        return new JSONException(message + this.toString());
+    public char skipTo(char to) {
+        int index = in.indexOf(to, pos);
+        if (index != -1) {
+            pos = index;
+            return to;
+        } else {
+            return '\0';
+        }
     }
 
+    /**
+     * Unreads the most recent character of input. If no input characters have
+     * been read, the input is unchanged.
+     */
+    public void back() {
+        if (--pos == -1) {
+            pos = 0;
+        }
+    }
 
     /**
-     * Make a printable string of this JSONTokener.
+     * Returns the integer [0..15] value for the given hex character, or -1
+     * for non-hex input.
      *
-     * @return " at {index} [character {character} line {line}]"
+     * @param hex a character in the ranges [0-9], [A-F] or [a-f]. Any other
+     *     character will yield a -1 result.
      */
-    public String toString() {
-        return " at " + this.index + " [character " + this.character + " line " +
-            this.line + "]";
+    public static int dehexchar(char hex) {
+        if (hex >= '0' && hex <= '9') {
+            return hex - '0';
+        } else if (hex >= 'A' && hex <= 'F') {
+            return hex - 'A' + 10;
+        } else if (hex >= 'a' && hex <= 'f') {
+            return hex - 'a' + 10;
+        } else {
+            return -1;
+        }
     }
 }
diff --git a/src/org/json/JSONWriter.java b/src/org/json/JSONWriter.java
deleted file mode 100755
index 855b2bd..0000000
--- a/src/org/json/JSONWriter.java
+++ /dev/null
@@ -1,327 +0,0 @@
-package org.json;
-
-import java.io.IOException;
-import java.io.Writer;
-
-/*
-Copyright (c) 2006 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/**
- * JSONWriter provides a quick and convenient way of producing JSON text.
- * The texts produced strictly conform to JSON syntax rules. No whitespace is
- * added, so the results are ready for transmission or storage. Each instance of
- * JSONWriter can produce one JSON text.
- * <p>
- * A JSONWriter instance provides a <code>value</code> method for appending
- * values to the
- * text, and a <code>key</code>
- * method for adding keys before values in objects. There are <code>array</code>
- * and <code>endArray</code> methods that make and bound array values, and
- * <code>object</code> and <code>endObject</code> methods which make and bound
- * object values. All of these methods return the JSONWriter instance,
- * permitting a cascade style. For example, <pre>
- * new JSONWriter(myWriter)
- *     .object()
- *         .key("JSON")
- *         .value("Hello, World!")
- *     .endObject();</pre> which writes <pre>
- * {"JSON":"Hello, World!"}</pre>
- * <p>
- * The first method called must be <code>array</code> or <code>object</code>.
- * There are no methods for adding commas or colons. JSONWriter adds them for
- * you. Objects and arrays can be nested up to 20 levels deep.
- * <p>
- * This can sometimes be easier than using a JSONObject to build a string.
- * @author JSON.org
- * @version 2011-11-24
- */
-public class JSONWriter {
-    private static final int maxdepth = 200;
-
-    /**
-     * The comma flag determines if a comma should be output before the next
-     * value.
-     */
-    private boolean comma;
-
-    /**
-     * The current mode. Values:
-     * 'a' (array),
-     * 'd' (done),
-     * 'i' (initial),
-     * 'k' (key),
-     * 'o' (object).
-     */
-    protected char mode;
-
-    /**
-     * The object/array stack.
-     */
-    private final JSONObject stack[];
-
-    /**
-     * The stack top index. A value of 0 indicates that the stack is empty.
-     */
-    private int top;
-
-    /**
-     * The writer that will receive the output.
-     */
-    protected Writer writer;
-
-    /**
-     * Make a fresh JSONWriter. It can be used to build one JSON text.
-     */
-    public JSONWriter(Writer w) {
-        this.comma = false;
-        this.mode = 'i';
-        this.stack = new JSONObject[maxdepth];
-        this.top = 0;
-        this.writer = w;
-    }
-
-    /**
-     * Append a value.
-     * @param string A string value.
-     * @return this
-     * @throws JSONException If the value is out of sequence.
-     */
-    private JSONWriter append(String string) throws JSONException {
-        if (string == null) {
-            throw new JSONException("Null pointer");
-        }
-        if (this.mode == 'o' || this.mode == 'a') {
-            try {
-                if (this.comma && this.mode == 'a') {
-                    this.writer.write(',');
-                }
-                this.writer.write(string);
-            } catch (IOException e) {
-                throw new JSONException(e);
-            }
-            if (this.mode == 'o') {
-                this.mode = 'k';
-            }
-            this.comma = true;
-            return this;
-        }
-        throw new JSONException("Value out of sequence.");
-    }
-
-    /**
-     * Begin appending a new array. All values until the balancing
-     * <code>endArray</code> will be appended to this array. The
-     * <code>endArray</code> method must be called to mark the array's end.
-     * @return this
-     * @throws JSONException If the nesting is too deep, or if the object is
-     * started in the wrong place (for example as a key or after the end of the
-     * outermost array or object).
-     */
-    public JSONWriter array() throws JSONException {
-        if (this.mode == 'i' || this.mode == 'o' || this.mode == 'a') {
-            this.push(null);
-            this.append("[");
-            this.comma = false;
-            return this;
-        }
-        throw new JSONException("Misplaced array.");
-    }
-
-    /**
-     * End something.
-     * @param mode Mode
-     * @param c Closing character
-     * @return this
-     * @throws JSONException If unbalanced.
-     */
-    private JSONWriter end(char mode, char c) throws JSONException {
-        if (this.mode != mode) {
-            throw new JSONException(mode == 'a'
-                ? "Misplaced endArray."
-                : "Misplaced endObject.");
-        }
-        this.pop(mode);
-        try {
-            this.writer.write(c);
-        } catch (IOException e) {
-            throw new JSONException(e);
-        }
-        this.comma = true;
-        return this;
-    }
-
-    /**
-     * End an array. This method most be called to balance calls to
-     * <code>array</code>.
-     * @return this
-     * @throws JSONException If incorrectly nested.
-     */
-    public JSONWriter endArray() throws JSONException {
-        return this.end('a', ']');
-    }
-
-    /**
-     * End an object. This method most be called to balance calls to
-     * <code>object</code>.
-     * @return this
-     * @throws JSONException If incorrectly nested.
-     */
-    public JSONWriter endObject() throws JSONException {
-        return this.end('k', '}');
-    }
-
-    /**
-     * Append a key. The key will be associated with the next value. In an
-     * object, every value must be preceded by a key.
-     * @param string A key string.
-     * @return this
-     * @throws JSONException If the key is out of place. For example, keys
-     *  do not belong in arrays or if the key is null.
-     */
-    public JSONWriter key(String string) throws JSONException {
-        if (string == null) {
-            throw new JSONException("Null key.");
-        }
-        if (this.mode == 'k') {
-            try {
-                this.stack[this.top - 1].putOnce(string, Boolean.TRUE);
-                if (this.comma) {
-                    this.writer.write(',');
-                }
-                this.writer.write(JSONObject.quote(string));
-                this.writer.write(':');
-                this.comma = false;
-                this.mode = 'o';
-                return this;
-            } catch (IOException e) {
-                throw new JSONException(e);
-            }
-        }
-        throw new JSONException("Misplaced key.");
-    }
-
-
-    /**
-     * Begin appending a new object. All keys and values until the balancing
-     * <code>endObject</code> will be appended to this object. The
-     * <code>endObject</code> method must be called to mark the object's end.
-     * @return this
-     * @throws JSONException If the nesting is too deep, or if the object is
-     * started in the wrong place (for example as a key or after the end of the
-     * outermost array or object).
-     */
-    public JSONWriter object() throws JSONException {
-        if (this.mode == 'i') {
-            this.mode = 'o';
-        }
-        if (this.mode == 'o' || this.mode == 'a') {
-            this.append("{");
-            this.push(new JSONObject());
-            this.comma = false;
-            return this;
-        }
-        throw new JSONException("Misplaced object.");
-
-    }
-
-
-    /**
-     * Pop an array or object scope.
-     * @param c The scope to close.
-     * @throws JSONException If nesting is wrong.
-     */
-    private void pop(char c) throws JSONException {
-        if (this.top <= 0) {
-            throw new JSONException("Nesting error.");
-        }
-        char m = this.stack[this.top - 1] == null ? 'a' : 'k';
-        if (m != c) {
-            throw new JSONException("Nesting error.");
-        }
-        this.top -= 1;
-        this.mode = this.top == 0
-            ? 'd'
-            : this.stack[this.top - 1] == null
-            ? 'a'
-            : 'k';
-    }
-
-    /**
-     * Push an array or object scope.
-     * @param c The scope to open.
-     * @throws JSONException If nesting is too deep.
-     */
-    private void push(JSONObject jo) throws JSONException {
-        if (this.top >= maxdepth) {
-            throw new JSONException("Nesting too deep.");
-        }
-        this.stack[this.top] = jo;
-        this.mode = jo == null ? 'a' : 'k';
-        this.top += 1;
-    }
-
-
-    /**
-     * Append either the value <code>true</code> or the value
-     * <code>false</code>.
-     * @param b A boolean.
-     * @return this
-     * @throws JSONException
-     */
-    public JSONWriter value(boolean b) throws JSONException {
-        return this.append(b ? "true" : "false");
-    }
-
-    /**
-     * Append a double value.
-     * @param d A double.
-     * @return this
-     * @throws JSONException If the number is not finite.
-     */
-    public JSONWriter value(double d) throws JSONException {
-        return this.value(new Double(d));
-    }
-
-    /**
-     * Append a long value.
-     * @param l A long.
-     * @return this
-     * @throws JSONException
-     */
-    public JSONWriter value(long l) throws JSONException {
-        return this.append(Long.toString(l));
-    }
-
-
-    /**
-     * Append an object value.
-     * @param object The object to append. It can be null, or a Boolean, Number,
-     *   String, JSONObject, or JSONArray, or an object that implements JSONString.
-     * @return this
-     * @throws JSONException If the value is out of sequence.
-     */
-    public JSONWriter value(Object object) throws JSONException {
-        return this.append(JSONObject.valueToString(object));
-    }
-}
diff --git a/src/org/json/Kim.java b/src/org/json/Kim.java
deleted file mode 100644
index d4770b5..0000000
--- a/src/org/json/Kim.java
+++ /dev/null
@@ -1,373 +0,0 @@
-package org.json;
-
-
-/*
- Copyright (c) 2013 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * Kim makes immutable eight bit Unicode strings. If the MSB of a byte is set,
- * then the next byte is a continuation byte. The last byte of a character
- * never has the MSB reset. Every byte that is not the last byte has the MSB
- * set. Kim stands for "Keep it minimal". A Unicode character is never longer
- * than 3 bytes. Every byte contributes 7 bits to the character. ASCII is
- * unmodified.
- *
- *                  Kim             UTF-8
- * one byte         U+007F          U+007F
- * two bytes        U+3FFF          U+07FF
- * three bytes      U+10FFF         U+FFFF
- * four bytes                       U+10FFFF
- *
- * Characters in the ranges U+0800..U+3FFF and U+10000..U+10FFFF will be one
- * byte smaller when encoded in Kim compared to UTF-8.
- *
- * Kim is beneficial when using scripts such as Old South Arabian, Aramaic,
- * Avestan, Balinese, Batak, Bopomofo, Buginese, Buhid, Carian, Cherokee,
- * Coptic, Cyrillic, Deseret, Egyptian Hieroglyphs, Ethiopic, Georgian,
- * Glagolitic, Gothic, Hangul Jamo, Hanunoo, Hiragana, Kanbun, Kaithi,
- * Kannada, Katakana, Kharoshthi, Khmer, Lao, Lepcha, Limbu, Lycian, Lydian,
- * Malayalam, Mandaic, Meroitic, Miao, Mongolian, Myanmar, New Tai Lue,
- * Ol Chiki, Old Turkic, Oriya, Osmanya, Pahlavi, Parthian, Phags-Pa,
- * Phoenician, Samaritan, Sharada, Sinhala, Sora Sompeng, Tagalog, Tagbanwa,
- * Takri, Tai Le, Tai Tham, Tamil, Telugu, Thai, Tibetan, Tifinagh, UCAS.
- *
- * A kim object can be constructed from an ordinary UTF-16 string, or from a
- * byte array. A kim object can produce a UTF-16 string.
- *
- * As with UTF-8, it is possible to detect character boundaries within a byte
- * sequence. UTF-8 is one of the world's great inventions. While Kim is more
- * efficient, it is not clear that it is worth the expense of transition.
- *
- * @version 2013-04-18
- */
-public class Kim {
-
-    /**
-     * The byte array containing the kim's content.
-     */
-    private byte[] bytes = null;
-
-    /**
-     * The kim's hashcode, conforming to Java's hashcode conventions.
-     */
-    private int hashcode = 0;
-
-    /**
-     * The number of bytes in the kim. The number of bytes can be as much as
-     * three times the number of characters.
-     */
-    public int length = 0;
-
-    /**
-     * The memoization of toString().
-     */
-    private String string = null;
-
-    /**
-     * Make a kim from a portion of a byte array.
-     *
-     * @param bytes
-     *            A byte array.
-     * @param from
-     *            The index of the first byte.
-     * @param thru
-     *            The index of the last byte plus one.
-     */
-    public Kim(byte[] bytes, int from, int thru) {
-
-// As the bytes are copied into the new kim, a hashcode is computed using a
-// modified Fletcher code.
-
-        int sum = 1;
-        int value;
-        this.hashcode = 0;
-        this.length = thru - from;
-        if (this.length > 0) {
-            this.bytes = new byte[this.length];
-            for (int at = 0; at < this.length; at += 1) {
-                value = (int) bytes[at + from] & 0xFF;
-                sum += value;
-                this.hashcode += sum;
-                this.bytes[at] = (byte) value;
-            }
-            this.hashcode += sum << 16;
-        }
-    }
-
-    /**
-     * Make a kim from a byte array.
-     *
-     * @param bytes
-     *            The byte array.
-     * @param length
-     *            The number of bytes.
-     */
-    public Kim(byte[] bytes, int length) {
-        this(bytes, 0, length);
-    }
-
-    /**
-     * Make a new kim from a substring of an existing kim. The coordinates are
-     * in byte units, not character units.
-     *
-     * @param kim
-     *            The source of bytes.
-     * @param from
-     *            The point at which to take bytes.
-     * @param thru
-     *            The point at which to stop taking bytes.
-     * @return the substring
-     */
-    public Kim(Kim kim, int from, int thru) {
-        this(kim.bytes, from, thru);
-    }
-
-    /**
-     * Make a kim from a string.
-     *
-     * @param string
-     *            The string.
-     * @throws JSONException
-     *             if surrogate pair mismatch.
-     */
-    public Kim(String string) throws JSONException {
-        int stringLength = string.length();
-        this.hashcode = 0;
-        this.length = 0;
-
-// First pass: Determine the length of the kim, allowing for the UTF-16
-// to UTF-32 conversion, and then the UTF-32 to Kim conversion.
-
-        if (stringLength > 0) {
-            for (int i = 0; i < stringLength; i += 1) {
-                int c = string.charAt(i);
-                if (c <= 0x7F) {
-                    this.length += 1;
-                } else if (c <= 0x3FFF) {
-                    this.length += 2;
-                } else {
-                    if (c >= 0xD800 && c <= 0xDFFF) {
-                        i += 1;
-                        int d = string.charAt(i);
-                        if (c > 0xDBFF || d < 0xDC00 || d > 0xDFFF) {
-                            throw new JSONException("Bad UTF16");
-                        }
-                    }
-                    this.length += 3;
-                }
-            }
-
-// Second pass: Allocate a byte array and fill that array with the conversion
-// while computing the hashcode.
-
-            this.bytes = new byte[length];
-            int at = 0;
-            int b;
-            int sum = 1;
-            for (int i = 0; i < stringLength; i += 1) {
-                int character = string.charAt(i);
-                if (character <= 0x7F) {
-                    bytes[at] = (byte) character;
-                    sum += character;
-                    this.hashcode += sum;
-                    at += 1;
-                } else if (character <= 0x3FFF) {
-                    b = 0x80 | (character >>> 7);
-                    bytes[at] = (byte) b;
-                    sum += b;
-                    this.hashcode += sum;
-                    at += 1;
-                    b = character & 0x7F;
-                    bytes[at] = (byte) b;
-                    sum += b;
-                    this.hashcode += sum;
-                    at += 1;
-                } else {
-                    if (character >= 0xD800 && character <= 0xDBFF) {
-                        i += 1;
-                        character = (((character & 0x3FF) << 10) | (string
-                                .charAt(i) & 0x3FF)) + 65536;
-                    }
-                    b = 0x80 | (character >>> 14);
-                    bytes[at] = (byte) b;
-                    sum += b;
-                    this.hashcode += sum;
-                    at += 1;
-                    b = 0x80 | ((character >>> 7) & 0xFF);
-                    bytes[at] = (byte) b;
-                    sum += b;
-                    this.hashcode += sum;
-                    at += 1;
-                    b = character & 0x7F;
-                    bytes[at] = (byte) b;
-                    sum += b;
-                    this.hashcode += sum;
-                    at += 1;
-                }
-            }
-            this.hashcode += sum << 16;
-        }
-    }
-
-    /**
-     * Returns the character at the specified index. The index refers to byte
-     * values and ranges from 0 to length - 1. The index of the next character
-     * is at index + Kim.characterSize(kim.characterAt(index)).
-     *
-     * @param at
-     *            the index of the char value. The first character is at 0.
-     * @returns a Unicode character between 0 and 0x10FFFF.
-     * @throws JSONException
-     *             if at does not point to a valid character.
-     */
-    public int characterAt(int at) throws JSONException {
-        int c = get(at);
-        if ((c & 0x80) == 0) {
-            return c;
-        }
-        int character;
-        int c1 = get(at + 1);
-        if ((c1 & 0x80) == 0) {
-            character = ((c & 0x7F) << 7) | c1;
-            if (character > 0x7F) {
-                return character;
-            }
-        } else {
-            int c2 = get(at + 2);
-            character = ((c & 0x7F) << 14) | ((c1 & 0x7F) << 7) | c2;
-            if ((c2 & 0x80) == 0 && character > 0x3FFF && character <= 0x10FFFF
-                    && (character < 0xD800 || character > 0xDFFF)) {
-                return character;
-            }
-        }
-        throw new JSONException("Bad character at " + at);
-    }
-
-    /**
-     * Returns the number of bytes needed to contain the character in Kim
-     * format.
-     *
-     * @param character
-     *            a Unicode character between 0 and 0x10FFFF.
-     * @return 1, 2, or 3
-     * @throws JSONException
-     *             if the character is not representable in a kim.
-     */
-    public static int characterSize(int character) throws JSONException {
-        if (character < 0 || character > 0x10FFFF) {
-            throw new JSONException("Bad character " + character);
-        }
-        return character <= 0x7F ? 1 : character <= 0x3FFF ? 2 : 3;
-    }
-
-    /**
-     * Copy the contents of this kim to a byte array.
-     *
-     * @param bytes
-     *            A byte array of sufficient size.
-     * @param at
-     *            The position within the byte array to take the byes.
-     * @return The position immediately after the copy.
-     */
-    public int copy(byte[] bytes, int at) {
-        System.arraycopy(this.bytes, 0, bytes, at, this.length);
-        return at + this.length;
-    }
-
-    /**
-     * Two kim objects containing exactly the same bytes in the same order are
-     * equal to each other.
-     *
-     * @param obj
-     *            the other kim with which to compare.
-     * @returns true if this and obj are both kim objects containing identical
-     *          byte sequences.
-     */
-    public boolean equals(Object obj) {
-        if (!(obj instanceof Kim)) {
-            return false;
-        }
-        Kim that = (Kim) obj;
-        if (this == that) {
-            return true;
-        }
-        if (this.hashcode != that.hashcode) {
-            return false;
-        }
-        return java.util.Arrays.equals(this.bytes, that.bytes);
-    }
-
-    /**
-     * Get a byte from a kim.
-     * @param at
-     *            The position of the byte. The first byte is at 0.
-     * @return The byte.
-     * @throws JSONException
-     *             if there is no byte at that position.
-     */
-    public int get(int at) throws JSONException {
-        if (at < 0 || at > this.length) {
-            throw new JSONException("Bad character at " + at);
-        }
-        return ((int) this.bytes[at]) & 0xFF;
-    }
-
-    /**
-     * Returns a hash code value for the kim.
-     */
-    public int hashCode() {
-        return this.hashcode;
-    }
-
-    /**
-     * Produce a UTF-16 String from this kim. The number of codepoints in the
-     * string will not be greater than the number of bytes in the kim, although
-     * it could be less.
-     *
-     * @return The string. A kim memoizes its string representation.
-     * @throws JSONException
-     *             if the kim is not valid.
-     */
-    public String toString() throws JSONException {
-        if (this.string == null) {
-            int c;
-            int length = 0;
-            char chars[] = new char[this.length];
-            for (int at = 0; at < this.length; at += characterSize(c)) {
-                c = this.characterAt(at);
-                if (c < 0x10000) {
-                    chars[length] = (char) c;
-                    length += 1;
-                } else {
-                    chars[length] = (char) (0xD800 | ((c - 0x10000) >>> 10));
-                    length += 1;
-                    chars[length] = (char) (0xDC00 | (c & 0x03FF));
-                    length += 1;
-                }
-            }
-            this.string = new String(chars, 0, length);
-        }
-        return this.string;
-    }
-}
diff --git a/src/org/json/Property.java b/src/org/json/Property.java
deleted file mode 100644
index dbbd7ef..0000000
--- a/src/org/json/Property.java
+++ /dev/null
@@ -1,74 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Properties;
-
-/**
- * Converts a Property file data into JSONObject and back.
- * @author JSON.org
- * @version 2013-05-23
- */
-public class Property {
-    /**
-     * Converts a property file object into a JSONObject. The property file object is a table of name value pairs.
-     * @param properties java.util.Properties
-     * @return JSONObject
-     * @throws JSONException
-     */
-    public static JSONObject toJSONObject(java.util.Properties properties) throws JSONException {
-        JSONObject jo = new JSONObject();
-        if (properties != null && !properties.isEmpty()) {
-            Enumeration enumProperties = properties.propertyNames();
-            while(enumProperties.hasMoreElements()) {
-                String name = (String)enumProperties.nextElement();
-                jo.put(name, properties.getProperty(name));
-            }
-        }
-        return jo;
-
-    }
-
-    /**
-     * Converts the JSONObject into a property file object.
-     * @param jo JSONObject
-     * @return java.util.Properties
-     * @throws JSONException
-     */
-    public static Properties toProperties(JSONObject jo)  throws JSONException {
-        Properties  properties = new Properties();
-        if (jo != null) {
-            Iterator keys = jo.keys();
-
-            while (keys.hasNext()) {
-                String name = keys.next().toString();
-                properties.put(name, jo.getString(name));
-            }
-        }
-        return properties;
-    }
-}
\ No newline at end of file
diff --git a/src/org/json/README b/src/org/json/README
deleted file mode 100755
index b77c71a..0000000
--- a/src/org/json/README
+++ /dev/null
@@ -1,68 +0,0 @@
-JSON in Java [package org.json]
-
-Douglas Crockford
-douglas at crockford.com
-
-2011-02-02
-
-
-JSON is a light-weight, language independent, data interchange format.
-See http://www.JSON.org/
-
-The files in this package implement JSON encoders/decoders in Java.
-It also includes the capability to convert between JSON and XML, HTTP
-headers, Cookies, and CDL.
-
-This is a reference implementation. There is a large number of JSON packages
-in Java. Perhaps someday the Java community will standardize on one. Until
-then, choose carefully.
-
-The license includes this restriction: "The software shall be used for good,
-not evil." If your conscience cannot live with that, then choose a different
-package.
-
-The package compiles on Java 1.2 thru Java 1.4.
-
-
-JSONObject.java: The JSONObject can parse text from a String or a JSONTokener
-to produce a map-like object. The object provides methods for manipulating its
-contents, and for producing a JSON compliant object serialization.
-
-JSONArray.java: The JSONObject can parse text from a String or a JSONTokener
-to produce a vector-like object. The object provides methods for manipulating
-its contents, and for producing a JSON compliant array serialization.
-
-JSONTokener.java: The JSONTokener breaks a text into a sequence of individual
-tokens. It can be constructed from a String, Reader, or InputStream.
-
-JSONException.java: The JSONException is the standard exception type thrown
-by this package.
-
-
-JSONString.java: The JSONString interface requires a toJSONString method,
-allowing an object to provide its own serialization.
-
-JSONStringer.java: The JSONStringer provides a convenient facility for
-building JSON strings.
-
-JSONWriter.java: The JSONWriter provides a convenient facility for building
-JSON text through a writer.
-
-
-CDL.java: CDL provides support for converting between JSON and comma
-delimited lists.
-
-Cookie.java: Cookie provides support for converting between JSON and cookies.
-
-CookieList.java: CookieList provides support for converting between JSON and
-cookie lists.
-
-HTTP.java: HTTP provides support for converting between JSON and HTTP headers.
-
-HTTPTokener.java: HTTPTokener extends JSONTokener for parsing HTTP headers.
-
-XML.java: XML provides support for converting between JSON and XML.
-
-JSONML.java: JSONML provides support for converting between JSONML and XML.
-
-XMLTokener.java: XMLTokener extends JSONTokener for parsing XML text.
diff --git a/src/org/json/XML.java b/src/org/json/XML.java
deleted file mode 100755
index d49784d..0000000
--- a/src/org/json/XML.java
+++ /dev/null
@@ -1,508 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-import java.util.Iterator;
-
-
-/**
- * This provides static methods to convert an XML text into a JSONObject,
- * and to covert a JSONObject into an XML text.
- * @author JSON.org
- * @version 2012-10-26
- */
-public class XML {
-
-    /** The Character '&'. */
-    public static final Character AMP   = new Character('&');
-
-    /** The Character '''. */
-    public static final Character APOS  = new Character('\'');
-
-    /** The Character '!'. */
-    public static final Character BANG  = new Character('!');
-
-    /** The Character '='. */
-    public static final Character EQ    = new Character('=');
-
-    /** The Character '>'. */
-    public static final Character GT    = new Character('>');
-
-    /** The Character '<'. */
-    public static final Character LT    = new Character('<');
-
-    /** The Character '?'. */
-    public static final Character QUEST = new Character('?');
-
-    /** The Character '"'. */
-    public static final Character QUOT  = new Character('"');
-
-    /** The Character '/'. */
-    public static final Character SLASH = new Character('/');
-
-    /**
-     * Replace special characters with XML escapes:
-     * <pre>
-     * & <small>(ampersand)</small> is replaced by &amp;
-     * < <small>(less than)</small> is replaced by &lt;
-     * > <small>(greater than)</small> is replaced by &gt;
-     * " <small>(double quote)</small> is replaced by &quot;
-     * </pre>
-     * @param string The string to be escaped.
-     * @return The escaped string.
-     */
-    public static String escape(String string) {
-        StringBuffer sb = new StringBuffer();
-        for (int i = 0, length = string.length(); i < length; i++) {
-            char c = string.charAt(i);
-            switch (c) {
-            case '&':
-                sb.append("&");
-                break;
-            case '<':
-                sb.append("<");
-                break;
-            case '>':
-                sb.append(">");
-                break;
-            case '"':
-                sb.append(""");
-                break;
-            case '\'':
-                sb.append("'");
-                break;
-            default:
-                sb.append(c);
-            }
-        }
-        return sb.toString();
-    }
-
-    /**
-     * Throw an exception if the string contains whitespace.
-     * Whitespace is not allowed in tagNames and attributes.
-     * @param string
-     * @throws JSONException
-     */
-    public static void noSpace(String string) throws JSONException {
-        int i, length = string.length();
-        if (length == 0) {
-            throw new JSONException("Empty string.");
-        }
-        for (i = 0; i < length; i += 1) {
-            if (Character.isWhitespace(string.charAt(i))) {
-                throw new JSONException("'" + string +
-                        "' contains a space character.");
-            }
-        }
-    }
-
-    /**
-     * Scan the content following the named tag, attaching it to the context.
-     * @param x       The XMLTokener containing the source string.
-     * @param context The JSONObject that will include the new material.
-     * @param name    The tag name.
-     * @return true if the close tag is processed.
-     * @throws JSONException
-     */
-    private static boolean parse(XMLTokener x, JSONObject context,
-                                 String name) throws JSONException {
-        char       c;
-        int        i;
-        JSONObject jsonobject = null;
-        String     string;
-        String     tagName;
-        Object     token;
-
-// Test for and skip past these forms:
-//      <!-- ... -->
-//      <!   ...   >
-//      <![  ... ]]>
-//      <?   ...  ?>
-// Report errors for these forms:
-//      <>
-//      <=
-//      <<
-
-        token = x.nextToken();
-
-// <!
-
-        if (token == BANG) {
-            c = x.next();
-            if (c == '-') {
-                if (x.next() == '-') {
-                    x.skipPast("-->");
-                    return false;
-                }
-                x.back();
-            } else if (c == '[') {
-                token = x.nextToken();
-                if ("CDATA".equals(token)) {
-                    if (x.next() == '[') {
-                        string = x.nextCDATA();
-                        if (string.length() > 0) {
-                            context.accumulate("content", string);
-                        }
-                        return false;
-                    }
-                }
-                throw x.syntaxError("Expected 'CDATA['");
-            }
-            i = 1;
-            do {
-                token = x.nextMeta();
-                if (token == null) {
-                    throw x.syntaxError("Missing '>' after '<!'.");
-                } else if (token == LT) {
-                    i += 1;
-                } else if (token == GT) {
-                    i -= 1;
-                }
-            } while (i > 0);
-            return false;
-        } else if (token == QUEST) {
-
-// <?
-
-            x.skipPast("?>");
-            return false;
-        } else if (token == SLASH) {
-
-// Close tag </
-
-            token = x.nextToken();
-            if (name == null) {
-                throw x.syntaxError("Mismatched close tag " + token);
-            }
-            if (!token.equals(name)) {
-                throw x.syntaxError("Mismatched " + name + " and " + token);
-            }
-            if (x.nextToken() != GT) {
-                throw x.syntaxError("Misshaped close tag");
-            }
-            return true;
-
-        } else if (token instanceof Character) {
-            throw x.syntaxError("Misshaped tag");
-
-// Open tag <
-
-        } else {
-            tagName = (String)token;
-            token = null;
-            jsonobject = new JSONObject();
-            for (;;) {
-                if (token == null) {
-                    token = x.nextToken();
-                }
-
-// attribute = value
-
-                if (token instanceof String) {
-                    string = (String)token;
-                    token = x.nextToken();
-                    if (token == EQ) {
-                        token = x.nextToken();
-                        if (!(token instanceof String)) {
-                            throw x.syntaxError("Missing value");
-                        }
-                        jsonobject.accumulate(string,
-                                XML.stringToValue((String)token));
-                        token = null;
-                    } else {
-                        jsonobject.accumulate(string, "");
-                    }
-
-// Empty tag <.../>
-
-                } else if (token == SLASH) {
-                    if (x.nextToken() != GT) {
-                        throw x.syntaxError("Misshaped tag");
-                    }
-                    if (jsonobject.length() > 0) {
-                        context.accumulate(tagName, jsonobject);
-                    } else {
-                        context.accumulate(tagName, "");
-                    }
-                    return false;
-
-// Content, between <...> and </...>
-
-                } else if (token == GT) {
-                    for (;;) {
-                        token = x.nextContent();
-                        if (token == null) {
-                            if (tagName != null) {
-                                throw x.syntaxError("Unclosed tag " + tagName);
-                            }
-                            return false;
-                        } else if (token instanceof String) {
-                            string = (String)token;
-                            if (string.length() > 0) {
-                                jsonobject.accumulate("content",
-                                        XML.stringToValue(string));
-                            }
-
-// Nested element
-
-                        } else if (token == LT) {
-                            if (parse(x, jsonobject, tagName)) {
-                                if (jsonobject.length() == 0) {
-                                    context.accumulate(tagName, "");
-                                } else if (jsonobject.length() == 1 &&
-                                       jsonobject.opt("content") != null) {
-                                    context.accumulate(tagName,
-                                            jsonobject.opt("content"));
-                                } else {
-                                    context.accumulate(tagName, jsonobject);
-                                }
-                                return false;
-                            }
-                        }
-                    }
-                } else {
-                    throw x.syntaxError("Misshaped tag");
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Try to convert a string into a number, boolean, or null. If the string
-     * can't be converted, return the string. This is much less ambitious than
-     * JSONObject.stringToValue, especially because it does not attempt to
-     * convert plus forms, octal forms, hex forms, or E forms lacking decimal
-     * points.
-     * @param string A String.
-     * @return A simple JSON value.
-     */
-    public static Object stringToValue(String string) {
-        if ("".equals(string)) {
-            return string;
-        }
-        if ("true".equalsIgnoreCase(string)) {
-            return Boolean.TRUE;
-        }
-        if ("false".equalsIgnoreCase(string)) {
-            return Boolean.FALSE;
-        }
-        if ("null".equalsIgnoreCase(string)) {
-            return JSONObject.NULL;
-        }
-        if ("0".equals(string)) {
-            return new Integer(0);
-        }
-
-// If it might be a number, try converting it. If that doesn't work,
-// return the string.
-
-        try {
-            char initial = string.charAt(0);
-            boolean negative = false;
-            if (initial == '-') {
-                initial = string.charAt(1);
-                negative = true;
-            }
-            if (initial == '0' && string.charAt(negative ? 2 : 1) == '0') {
-                return string;
-            }
-            if ((initial >= '0' && initial <= '9')) {
-                if (string.indexOf('.') >= 0) {
-                    return Double.valueOf(string);
-                } else if (string.indexOf('e') < 0 && string.indexOf('E') < 0) {
-                    Long myLong = new Long(string);
-                    if (myLong.longValue() == myLong.intValue()) {
-                        return new Integer(myLong.intValue());
-                    } else {
-                        return myLong;
-                    }
-                }
-            }
-        }  catch (Exception ignore) {
-        }
-        return string;
-    }
-
-
-    /**
-     * Convert a well-formed (but not necessarily valid) XML string into a
-     * JSONObject. Some information may be lost in this transformation
-     * because JSON is a data format and XML is a document format. XML uses
-     * elements, attributes, and content text, while JSON uses unordered
-     * collections of name/value pairs and arrays of values. JSON does not
-     * does not like to distinguish between elements and attributes.
-     * Sequences of similar elements are represented as JSONArrays. Content
-     * text may be placed in a "content" member. Comments, prologs, DTDs, and
-     * <code><[ [ ]]></code> are ignored.
-     * @param string The source string.
-     * @return A JSONObject containing the structured data from the XML string.
-     * @throws JSONException
-     */
-    public static JSONObject toJSONObject(String string) throws JSONException {
-        JSONObject jo = new JSONObject();
-        XMLTokener x = new XMLTokener(string);
-        while (x.more() && x.skipPast("<")) {
-            parse(x, jo, null);
-        }
-        return jo;
-    }
-
-
-    /**
-     * Convert a JSONObject into a well-formed, element-normal XML string.
-     * @param object A JSONObject.
-     * @return  A string.
-     * @throws  JSONException
-     */
-    public static String toString(Object object) throws JSONException {
-        return toString(object, null);
-    }
-
-
-    /**
-     * Convert a JSONObject into a well-formed, element-normal XML string.
-     * @param object A JSONObject.
-     * @param tagName The optional name of the enclosing tag.
-     * @return A string.
-     * @throws JSONException
-     */
-    public static String toString(Object object, String tagName)
-            throws JSONException {
-        StringBuffer sb = new StringBuffer();
-        int          i;
-        JSONArray    ja;
-        JSONObject   jo;
-        String       key;
-        Iterator     keys;
-        int          length;
-        String       string;
-        Object       value;
-        if (object instanceof JSONObject) {
-
-// Emit <tagName>
-
-            if (tagName != null) {
-                sb.append('<');
-                sb.append(tagName);
-                sb.append('>');
-            }
-
-// Loop thru the keys.
-
-            jo = (JSONObject)object;
-            keys = jo.keys();
-            while (keys.hasNext()) {
-                key = keys.next().toString();
-                value = jo.opt(key);
-                if (value == null) {
-                    value = "";
-                }
-                if (value instanceof String) {
-                    string = (String)value;
-                } else {
-                    string = null;
-                }
-
-// Emit content in body
-
-                if ("content".equals(key)) {
-                    if (value instanceof JSONArray) {
-                        ja = (JSONArray)value;
-                        length = ja.length();
-                        for (i = 0; i < length; i += 1) {
-                            if (i > 0) {
-                                sb.append('\n');
-                            }
-                            sb.append(escape(ja.get(i).toString()));
-                        }
-                    } else {
-                        sb.append(escape(value.toString()));
-                    }
-
-// Emit an array of similar keys
-
-                } else if (value instanceof JSONArray) {
-                    ja = (JSONArray)value;
-                    length = ja.length();
-                    for (i = 0; i < length; i += 1) {
-                        value = ja.get(i);
-                        if (value instanceof JSONArray) {
-                            sb.append('<');
-                            sb.append(key);
-                            sb.append('>');
-                            sb.append(toString(value));
-                            sb.append("</");
-                            sb.append(key);
-                            sb.append('>');
-                        } else {
-                            sb.append(toString(value, key));
-                        }
-                    }
-                } else if ("".equals(value)) {
-                    sb.append('<');
-                    sb.append(key);
-                    sb.append("/>");
-
-// Emit a new tag <k>
-
-                } else {
-                    sb.append(toString(value, key));
-                }
-            }
-            if (tagName != null) {
-
-// Emit the </tagname> close tag
-
-                sb.append("</");
-                sb.append(tagName);
-                sb.append('>');
-            }
-            return sb.toString();
-
-// XML does not have good support for arrays. If an array appears in a place
-// where XML is lacking, synthesize an <array> element.
-
-        } else {
-            if (object.getClass().isArray()) {
-                object = new JSONArray(object);
-            }
-            if (object instanceof JSONArray) {
-                ja = (JSONArray)object;
-                length = ja.length();
-                for (i = 0; i < length; i += 1) {
-                    sb.append(toString(ja.opt(i), tagName == null ? "array" : tagName));
-                }
-                return sb.toString();
-            } else {
-                string = (object == null) ? "null" : escape(object.toString());
-                return (tagName == null) ? "\"" + string + "\"" :
-                    (string.length() == 0) ? "<" + tagName + "/>" :
-                    "<" + tagName + ">" + string + "</" + tagName + ">";
-            }
-        }
-    }
-}
diff --git a/src/org/json/XMLTokener.java b/src/org/json/XMLTokener.java
deleted file mode 100755
index be15ebe..0000000
--- a/src/org/json/XMLTokener.java
+++ /dev/null
@@ -1,365 +0,0 @@
-package org.json;
-
-/*
-Copyright (c) 2002 JSON.org
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-The Software shall be used for Good, not Evil.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
-*/
-
-/**
- * The XMLTokener extends the JSONTokener to provide additional methods
- * for the parsing of XML texts.
- * @author JSON.org
- * @version 2012-11-13
- */
-public class XMLTokener extends JSONTokener {
-
-
-   /** The table of entity values. It initially contains Character values for
-    * amp, apos, gt, lt, quot.
-    */
-   public static final java.util.HashMap entity;
-
-   static {
-       entity = new java.util.HashMap(8);
-       entity.put("amp",  XML.AMP);
-       entity.put("apos", XML.APOS);
-       entity.put("gt",   XML.GT);
-       entity.put("lt",   XML.LT);
-       entity.put("quot", XML.QUOT);
-   }
-
-    /**
-     * Construct an XMLTokener from a string.
-     * @param s A source string.
-     */
-    public XMLTokener(String s) {
-        super(s);
-    }
-
-    /**
-     * Get the text in the CDATA block.
-     * @return The string up to the <code>]]></code>.
-     * @throws JSONException If the <code>]]></code> is not found.
-     */
-    public String nextCDATA() throws JSONException {
-        char         c;
-        int          i;
-        StringBuffer sb = new StringBuffer();
-        for (;;) {
-            c = next();
-            if (end()) {
-                throw syntaxError("Unclosed CDATA");
-            }
-            sb.append(c);
-            i = sb.length() - 3;
-            if (i >= 0 && sb.charAt(i) == ']' &&
-                          sb.charAt(i + 1) == ']' && sb.charAt(i + 2) == '>') {
-                sb.setLength(i);
-                return sb.toString();
-            }
-        }
-    }
-
-
-    /**
-     * Get the next XML outer token, trimming whitespace. There are two kinds
-     * of tokens: the '<' character which begins a markup tag, and the content
-     * text between markup tags.
-     *
-     * @return  A string, or a '<' Character, or null if there is no more
-     * source text.
-     * @throws JSONException
-     */
-    public Object nextContent() throws JSONException {
-        char         c;
-        StringBuffer sb;
-        do {
-            c = next();
-        } while (Character.isWhitespace(c));
-        if (c == 0) {
-            return null;
-        }
-        if (c == '<') {
-            return XML.LT;
-        }
-        sb = new StringBuffer();
-        for (;;) {
-            if (c == '<' || c == 0) {
-                back();
-                return sb.toString().trim();
-            }
-            if (c == '&') {
-                sb.append(nextEntity(c));
-            } else {
-                sb.append(c);
-            }
-            c = next();
-        }
-    }
-
-
-    /**
-     * Return the next entity. These entities are translated to Characters:
-     *     <code>&  '  >  <  "</code>.
-     * @param ampersand An ampersand character.
-     * @return  A Character or an entity String if the entity is not recognized.
-     * @throws JSONException If missing ';' in XML entity.
-     */
-    public Object nextEntity(char ampersand) throws JSONException {
-        StringBuffer sb = new StringBuffer();
-        for (;;) {
-            char c = next();
-            if (Character.isLetterOrDigit(c) || c == '#') {
-                sb.append(Character.toLowerCase(c));
-            } else if (c == ';') {
-                break;
-            } else {
-                throw syntaxError("Missing ';' in XML entity: &" + sb);
-            }
-        }
-        String string = sb.toString();
-        Object object = entity.get(string);
-        return object != null ? object : ampersand + string + ";";
-    }
-
-
-    /**
-     * Returns the next XML meta token. This is used for skipping over <!...>
-     * and <?...?> structures.
-     * @return Syntax characters (<code>< > / = ! ?</code>) are returned as
-     *  Character, and strings and names are returned as Boolean. We don't care
-     *  what the values actually are.
-     * @throws JSONException If a string is not properly closed or if the XML
-     *  is badly structured.
-     */
-    public Object nextMeta() throws JSONException {
-        char c;
-        char q;
-        do {
-            c = next();
-        } while (Character.isWhitespace(c));
-        switch (c) {
-        case 0:
-            throw syntaxError("Misshaped meta tag");
-        case '<':
-            return XML.LT;
-        case '>':
-            return XML.GT;
-        case '/':
-            return XML.SLASH;
-        case '=':
-            return XML.EQ;
-        case '!':
-            return XML.BANG;
-        case '?':
-            return XML.QUEST;
-        case '"':
-        case '\'':
-            q = c;
-            for (;;) {
-                c = next();
-                if (c == 0) {
-                    throw syntaxError("Unterminated string");
-                }
-                if (c == q) {
-                    return Boolean.TRUE;
-                }
-            }
-        default:
-            for (;;) {
-                c = next();
-                if (Character.isWhitespace(c)) {
-                    return Boolean.TRUE;
-                }
-                switch (c) {
-                case 0:
-                case '<':
-                case '>':
-                case '/':
-                case '=':
-                case '!':
-                case '?':
-                case '"':
-                case '\'':
-                    back();
-                    return Boolean.TRUE;
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Get the next XML Token. These tokens are found inside of angle
-     * brackets. It may be one of these characters: <code>/ > = ! ?</code> or it
-     * may be a string wrapped in single quotes or double quotes, or it may be a
-     * name.
-     * @return a String or a Character.
-     * @throws JSONException If the XML is not well formed.
-     */
-    public Object nextToken() throws JSONException {
-        char c;
-        char q;
-        StringBuffer sb;
-        do {
-            c = next();
-        } while (Character.isWhitespace(c));
-        switch (c) {
-        case 0:
-            throw syntaxError("Misshaped element");
-        case '<':
-            throw syntaxError("Misplaced '<'");
-        case '>':
-            return XML.GT;
-        case '/':
-            return XML.SLASH;
-        case '=':
-            return XML.EQ;
-        case '!':
-            return XML.BANG;
-        case '?':
-            return XML.QUEST;
-
-// Quoted string
-
-        case '"':
-        case '\'':
-            q = c;
-            sb = new StringBuffer();
-            for (;;) {
-                c = next();
-                if (c == 0) {
-                    throw syntaxError("Unterminated string");
-                }
-                if (c == q) {
-                    return sb.toString();
-                }
-                if (c == '&') {
-                    sb.append(nextEntity(c));
-                } else {
-                    sb.append(c);
-                }
-            }
-        default:
-
-// Name
-
-            sb = new StringBuffer();
-            for (;;) {
-                sb.append(c);
-                c = next();
-                if (Character.isWhitespace(c)) {
-                    return sb.toString();
-                }
-                switch (c) {
-                case 0:
-                    return sb.toString();
-                case '>':
-                case '/':
-                case '=':
-                case '!':
-                case '?':
-                case '[':
-                case ']':
-                    back();
-                    return sb.toString();
-                case '<':
-                case '"':
-                case '\'':
-                    throw syntaxError("Bad character in a name");
-                }
-            }
-        }
-    }
-
-
-    /**
-     * Skip characters until past the requested string.
-     * If it is not found, we are left at the end of the source with a result of false.
-     * @param to A string to skip past.
-     * @throws JSONException
-     */
-    public boolean skipPast(String to) throws JSONException {
-        boolean b;
-        char c;
-        int i;
-        int j;
-        int offset = 0;
-        int length = to.length();
-        char[] circle = new char[length];
-
-        /*
-         * First fill the circle buffer with as many characters as are in the
-         * to string. If we reach an early end, bail.
-         */
-
-        for (i = 0; i < length; i += 1) {
-            c = next();
-            if (c == 0) {
-                return false;
-            }
-            circle[i] = c;
-        }
-
-        /* We will loop, possibly for all of the remaining characters. */
-
-        for (;;) {
-            j = offset;
-            b = true;
-
-            /* Compare the circle buffer with the to string. */
-
-            for (i = 0; i < length; i += 1) {
-                if (circle[j] != to.charAt(i)) {
-                    b = false;
-                    break;
-                }
-                j += 1;
-                if (j >= length) {
-                    j -= length;
-                }
-            }
-
-            /* If we exit the loop with b intact, then victory is ours. */
-
-            if (b) {
-                return true;
-            }
-
-            /* Get the next character. If there isn't one, then defeat is ours. */
-
-            c = next();
-            if (c == 0) {
-                return false;
-            }
-            /*
-             * Shove the character in the circle buffer and advance the
-             * circle offset. The offset is mod n.
-             */
-            circle[offset] = c;
-            offset += 1;
-            if (offset >= length) {
-                offset -= length;
-            }
-        }
-    }
-}
diff --git a/src/org/json/zip/BitInputStream.java b/src/org/json/zip/BitInputStream.java
deleted file mode 100644
index 7864ce1..0000000
--- a/src/org/json/zip/BitInputStream.java
+++ /dev/null
@@ -1,169 +0,0 @@
-package org.json.zip;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/*
- Copyright (c) 2013 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * This is a big endian bit reader. It reads its bits from an InputStream.
- *
- * @version 2013-04-18
- *
- */
-public class BitInputStream implements BitReader {
-    /**
-     * 2^n - 1
-     */
-    static final int[] mask = { 0, 1, 3, 7, 15, 31, 63, 127, 255 };
-
-    /**
-     * The number of bits remaining in the current byte.
-     */
-    private int available = 0;
-
-    /**
-     * Up to a byte's worth of unread bits.
-     */
-    private int unread = 0;
-
-    /**
-     * The source of the bits.
-     */
-    private InputStream in;
-
-    /**
-     * The number of bits read so far. This is used in padding.
-     */
-    private long nrBits = 0;
-
-    /**
-     * Make a BitReader from an InputStream. The BitReader will take bytes from
-     * the InputStream and unpack them into bits.
-     *
-     * @param in
-     *            An InputStream.
-     */
-    public BitInputStream(InputStream in) {
-        this.in = in;
-    }
-
-    /**
-     * Make a BitReader. The first byte is passed in explicitly, the remaining
-     * bytes are obtained from the InputStream. This makes it possible to look
-     * at the first byte of a stream before deciding that it should be read as
-     * bits.
-     *
-     * @param in
-     *            An InputStream
-     * @param firstByte
-     *            The first byte, which was probably read from in.
-     */
-    public BitInputStream(InputStream in, int firstByte) {
-        this.in = in;
-        this.unread = firstByte;
-        this.available = 8;
-    }
-
-    /**
-     * Read one bit.
-     *
-     * @return true if it is a 1 bit.
-     */
-    public boolean bit() throws IOException {
-        return read(1) != 0;
-    }
-
-    /**
-     * Get the number of bits that have been read from this BitInputStream.
-     * This includes pad bits that have been skipped, but might not include
-     * bytes that have been read from the underlying InputStream that have not
-     * yet been delivered as bits.
-     *
-     * @return The number of bits read so far.
-     */
-    public long nrBits() {
-        return this.nrBits;
-    }
-
-    /**
-     * Check that the rest of the block has been padded with zeroes.
-     *
-     * @param factor
-     *            The size of the block to pad. This will typically be 8, 16,
-     *            32, 64, 128, 256, etc.
-     * @return true if the block was zero padded, or false if the the padding
-     *         contains any one bits.
-     * @throws IOException
-     */
-    public boolean pad(int factor) throws IOException {
-        int padding = factor - (int) (this.nrBits % factor);
-        boolean result = true;
-
-        for (int i = 0; i < padding; i += 1) {
-            if (bit()) {
-                result = false;
-            }
-        }
-        return result;
-    }
-
-    /**
-     * Read some bits.
-     *
-     * @param width
-     *            The number of bits to read. (0..32)
-     * @throws IOException
-     * @return the bits
-     */
-    public int read(int width) throws IOException {
-        if (width == 0) {
-            return 0;
-        }
-        if (width < 0 || width > 32) {
-            throw new IOException("Bad read width.");
-        }
-        int result = 0;
-        while (width > 0) {
-            if (this.available == 0) {
-                this.unread = this.in.read();
-                if (this.unread < 0) {
-                    throw new IOException("Attempt to read past end.");
-                }
-                this.available = 8;
-            }
-            int take = width;
-            if (take > this.available) {
-                take = this.available;
-            }
-            result |= ((this.unread >>> (this.available - take)) & mask[take])
-                    << (width - take);
-            this.nrBits += take;
-            this.available -= take;
-            width -= take;
-        }
-        return result;
-    }
-}
diff --git a/src/org/json/zip/BitOutputStream.java b/src/org/json/zip/BitOutputStream.java
deleted file mode 100644
index 526ad61..0000000
--- a/src/org/json/zip/BitOutputStream.java
+++ /dev/null
@@ -1,154 +0,0 @@
-package org.json.zip;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/*
- Copyright (c) 2013 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * This is a big endian bit writer. It writes its bits to an OutputStream.
- *
- * @version 2013-04-18
- *
- */
-public class BitOutputStream implements BitWriter {
-
-    /**
-     * The number of bits written.
-     */
-    private long nrBits = 0;
-
-    /**
-     * The destination of the bits.
-     */
-    private OutputStream out;
-
-    /**
-     * Holder of bits not yet written.
-     */
-    private int unwritten;
-
-    /**
-     * The number of unused bits in this.unwritten.
-     */
-    private int vacant = 8;
-
-    /**
-     * Use an OutputStream to produce a BitWriter. The BitWriter will send its
-     * bits to the OutputStream as each byte is filled.
-     *
-     * @param out
-     *            An Output Stream
-     */
-    public BitOutputStream(OutputStream out) {
-        this.out = out;
-    }
-
-    /**
-     * Returns the number of bits that have been written to this
-     * bitOutputStream. This may include bits that have not yet been written
-     * to the underlying outputStream.
-     */
-    public long nrBits() {
-        return this.nrBits;
-    }
-
-    /**
-     * Write a 1 bit.
-     *
-     * @throws IOException
-     */
-    public void one() throws IOException {
-        write(1, 1);
-    }
-
-    /**
-     * Pad the rest of the block with zeroes and flush. pad(8) flushes the last
-     * unfinished byte. The underlying OutputStream will be flushed.
-     *
-     * @param factor
-     *            The size of the block to pad. This will typically be 8, 16,
-     *            32, 64, 128, 256, etc.
-     * @return this
-     * @throws IOException
-     */
-    public void pad(int factor) throws IOException {
-        int padding = factor - (int) (nrBits % factor);
-        int excess = padding & 7;
-        if (excess > 0) {
-            this.write(0, excess);
-            padding -= excess;
-        }
-        while (padding > 0) {
-            this.write(0, 8);
-            padding -= 8;
-        }
-        this.out.flush();
-    }
-
-    /**
-     * Write some bits. Up to 32 bits can be written at a time.
-     *
-     * @param bits
-     *            The bits to be written.
-     * @param width
-     *            The number of bits to write. (0..32)
-     * @throws IOException
-     */
-    public void write(int bits, int width) throws IOException {
-        if (bits == 0 && width == 0) {
-            return;
-        }
-        if (width <= 0 || width > 32) {
-            throw new IOException("Bad write width.");
-        }
-        while (width > 0) {
-            int actual = width;
-            if (actual > this.vacant) {
-                actual = this.vacant;
-            }
-            this.unwritten |= ((bits >>> (width - actual)) &
-                    BitInputStream.mask[actual]) << (this.vacant - actual);
-            width -= actual;
-            nrBits += actual;
-            this.vacant -= actual;
-            if (this.vacant == 0) {
-                this.out.write(this.unwritten);
-                this.unwritten = 0;
-                this.vacant = 8;
-            }
-        }
-    }
-
-    /**
-     * Write a 0 bit.
-     *
-     * @throws IOException
-     */
-    public void zero() throws IOException {
-        write(0, 1);
-
-    }
-}
diff --git a/src/org/json/zip/BitReader.java b/src/org/json/zip/BitReader.java
deleted file mode 100644
index 1987729..0000000
--- a/src/org/json/zip/BitReader.java
+++ /dev/null
@@ -1,41 +0,0 @@
-package org.json.zip;
-
-import java.io.IOException;
-
-public interface BitReader {
-    /**
-     * Read one bit.
-     *
-     * @return true if it is a 1 bit.
-     */
-    public boolean bit() throws IOException;
-
-    /**
-     * Returns the number of bits that have been read from this bitreader.
-     *
-     * @return The number of bits read so far.
-     */
-    public long nrBits();
-
-    /**
-     * Check that the rest of the block has been padded with zeroes.
-     *
-     * @param factor
-     *            The size in bits of the block to pad. This will typically be
-     *            8, 16, 32, 64, 128, 256, etc.
-     * @return true if the block was zero padded, or false if the the padding
-     *         contained any one bits.
-     * @throws IOException
-     */
-    public boolean pad(int factor) throws IOException;
-
-    /**
-     * Read some bits.
-     *
-     * @param width
-     *            The number of bits to read. (0..32)
-     * @throws IOException
-     * @return the bits
-     */
-    public int read(int width) throws IOException;
-}
diff --git a/src/org/json/zip/BitWriter.java b/src/org/json/zip/BitWriter.java
deleted file mode 100644
index 83eb7e3..0000000
--- a/src/org/json/zip/BitWriter.java
+++ /dev/null
@@ -1,51 +0,0 @@
-package org.json.zip;
-
-import java.io.IOException;
-
-/**
- * A bitwriter is a an interface that allows for doing output at the bit level.
- * Most IO interfaces only allow for writing at the byte level or higher.
- */
-public interface BitWriter {
-    /**
-     * Returns the number of bits that have been written to this bitwriter.
-     */
-    public long nrBits();
-
-    /**
-     * Write a 1 bit.
-     *
-     * @throws IOException
-     */
-    public void one() throws IOException;
-
-    /**
-     * Pad the rest of the block with zeros and flush.
-     *
-     * @param factor
-     *            The size in bits of the block to pad. This will typically be
-     *            8, 16, 32, 64, 128, 256, etc.
-     * @return true if the block was zero padded, or false if the the padding
-     *         contains any one bits.
-     * @throws IOException
-     */
-    public void pad(int factor) throws IOException;
-
-    /**
-     * Write some bits. Up to 32 bits can be written at a time.
-     *
-     * @param bits
-     *            The bits to be written.
-     * @param width
-     *            The number of bits to write. (0..32)
-     * @throws IOException
-     */
-    public void write(int bits, int width) throws IOException;
-
-    /**
-     * Write a 0 bit.
-     *
-     * @throws IOException
-     */
-    public void zero() throws IOException;
-}
diff --git a/src/org/json/zip/Compressor.java b/src/org/json/zip/Compressor.java
deleted file mode 100644
index 6dddff4..0000000
--- a/src/org/json/zip/Compressor.java
+++ /dev/null
@@ -1,575 +0,0 @@
-package org.json.zip;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.Map;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.Kim;
-
-/*
- Copyright (c) 2013 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * JSONzip is a compression scheme for JSON text.
- *
- * @author JSON.org
- * @version 2013-04-18
- */
-
-/**
- * A compressor implements the compression behavior of JSONzip. It provides a
- * zip method that takes a JSONObject or JSONArray and delivers a stream of
- * bits to a BitWriter.
- *
- * FOR EVALUATION PURPOSES ONLY. THIS PACKAGE HAS NOT BEEN TESTED ADEQUATELY
- * FOR PRODUCTION USE.
- */
-public class Compressor extends JSONzip {
-
-    /**
-     * A compressor outputs to a BitWriter.
-     */
-    final BitWriter bitwriter;
-
-    /**
-     * Create a new compressor. It may be used for an entire session or
-     * subsession.
-     *
-     * @param bitwriter
-     *            The BitWriter this Compressor will output to. Don't forget to
-     *            flush.
-     */
-    public Compressor(BitWriter bitwriter) {
-        super();
-        this.bitwriter = bitwriter;
-    }
-
-    /**
-     * Return a 4 bit code for a character in a JSON number. The digits '0' to
-     * '9' get the codes 0 to 9. '.' is 10, '-' is 11, '+' is 12, and 'E' or
-     * 'e' is 13.
-     *
-     * @param digit
-     *            An ASCII character from a JSIN number.
-     * @return
-     */
-    private static int bcd(char digit) {
-        if (digit >= '0' && digit <= '9') {
-            return digit - '0';
-        }
-        switch (digit) {
-        case '.':
-            return 10;
-        case '-':
-            return 11;
-        case '+':
-            return 12;
-        default:
-            return 13;
-        }
-    }
-
-    /**
-     * Finish the final byte and flush the bitwriter. This does the same thing
-     * as pad(8).
-     *
-     * @throws JSONException
-     */
-    public void flush() throws JSONException {
-        pad(8);
-    }
-
-    /**
-     * Output a one bit.
-     *
-     * @throws IOException
-     */
-    private void one() throws JSONException {
-        if (probe) {
-            log(1);
-        }
-        write(1, 1);
-    }
-
-    /**
-     * Pad the output to fill an allotment of bits.
-     *
-     * @param factor
-     *            The size of the bit allotment. A value of 8 will complete and
-     *            flush the current byte. If you don't pad, then some of the
-     *            last bits might not be sent to the Output Stream.
-     * @throws JSONException
-     */
-    public void pad(int factor) throws JSONException {
-        try {
-            this.bitwriter.pad(factor);
-        } catch (Throwable e) {
-            throw new JSONException(e);
-        }
-    }
-
-    /**
-     * Write a number, using the number of bits necessary to hold the number.
-     *
-     * @param integer
-     *            The value to be encoded.
-     * @param width
-     *            The number of bits to encode the value, between 0 and 32.
-     * @throws JSONException
-     */
-    private void write(int integer, int width) throws JSONException {
-        try {
-            this.bitwriter.write(integer, width);
-            if (probe) {
-                log(integer, width);
-            }
-        } catch (Throwable e) {
-            throw new JSONException(e);
-        }
-    }
-
-    /**
-     * Write an integer with Huffman encoding. The bit pattern that is written
-     * will be determined by the Huffman encoder.
-     *
-     * @param integer
-     *            The value to be written.
-     * @param huff
-     *            The Huffman encoder.
-     * @throws JSONException
-     */
-    private void write(int integer, Huff huff) throws JSONException {
-        huff.write(integer, this.bitwriter);
-    }
-
-    /**
-     * Write each of the bytes in a kim with Huffman encoding.
-     *
-     * @param kim
-     *            A kim containing the bytes to be written.
-     * @param huff
-     *            The Huffman encoder.
-     * @throws JSONException
-     */
-    private void write(Kim kim, Huff huff) throws JSONException {
-        write(kim, 0, kim.length, huff);
-    }
-
-    /**
-     * Write a range of bytes from a Kim with Huffman encoding.
-     *
-     * @param kim
-     *            A Kim containing the bytes to be written.
-     * @param from
-     *            The index of the first byte to write.
-     * @param thru
-     *            The index after the last byte to write.
-     * @param huff
-     *            The Huffman encoder.
-     * @throws JSONException
-     */
-    private void write(Kim kim, int from, int thru, Huff huff)
-            throws JSONException {
-        for (int at = from; at < thru; at += 1) {
-            write(kim.get(at), huff);
-        }
-    }
-
-    /**
-     * Write an integer, using the number of bits necessary to hold the number
-     * as determined by its keep, and increment its usage count in the keep.
-     *
-     * @param integer
-     *            The value to be encoded.
-     * @param keep
-     *            The Keep that the integer is one of.
-     * @throws JSONException
-     */
-    private void writeAndTick(int integer, Keep keep) throws JSONException {
-        int width = keep.bitsize();
-        keep.tick(integer);
-        if (probe) {
-            log("\"" + keep.value(integer) + "\"");
-        }
-        write(integer, width);
-    }
-
-    /**
-     * Write a JSON Array.
-     *
-     * @param jsonarray
-     * @throws JSONException
-     */
-    private void writeArray(JSONArray jsonarray) throws JSONException {
-
-// JSONzip has three encodings for arrays:
-// The array is empty (zipEmptyArray).
-// First value in the array is a string (zipArrayString).
-// First value in the array is not a string (zipArrayValue).
-
-        boolean stringy = false;
-        int length = jsonarray.length();
-        if (length == 0) {
-            write(zipEmptyArray, 3);
-        } else {
-            Object value = jsonarray.get(0);
-            if (value == null) {
-                value = JSONObject.NULL;
-            }
-            if (value instanceof String) {
-                stringy = true;
-                write(zipArrayString, 3);
-                writeString((String) value);
-            } else {
-                write(zipArrayValue, 3);
-                writeValue(value);
-            }
-            for (int i = 1; i < length; i += 1) {
-                if (probe) {
-                    log();
-                }
-                value = jsonarray.get(i);
-                if (value == null) {
-                    value = JSONObject.NULL;
-                }
-                if (value instanceof String != stringy) {
-                    zero();
-                }
-                one();
-                if (value instanceof String) {
-                    writeString((String) value);
-                } else {
-                    writeValue(value);
-                }
-            }
-            zero();
-            zero();
-
-        }
-    }
-
-    /**
-     * Write a JSON value.
-     *
-     * @param value
-     *            One of these types: JSONObject, JSONArray (or Map or
-     *            Collection or array), Number (or Integer or Long or Double),
-     *            or String, or Boolean, or JSONObject.NULL, or null.
-     * @throws JSONException
-     */
-    private void writeJSON(Object value) throws JSONException {
-        if (JSONObject.NULL.equals(value)) {
-            write(zipNull, 3);
-        } else if (Boolean.FALSE.equals(value)) {
-            write(zipFalse, 3);
-        } else if (Boolean.TRUE.equals(value)) {
-            write(zipTrue, 3);
-        } else {
-            if (value instanceof Map) {
-                value = new JSONObject((Map) value);
-            } else if (value instanceof Collection) {
-                value = new JSONArray((Collection) value);
-            } else if (value.getClass().isArray()) {
-                value = new JSONArray(value);
-            }
-            if (value instanceof JSONObject) {
-                writeObject((JSONObject) value);
-            } else if (value instanceof JSONArray) {
-                writeArray((JSONArray) value);
-            } else {
-                throw new JSONException("Unrecognized object");
-            }
-        }
-    }
-
-    /**
-     * Write the name of an object property. Names have their own Keep and
-     * Huffman encoder because they are expected to be a more restricted set.
-     *
-     * @param name
-     * @throws JSONException
-     */
-    private void writeName(String name) throws JSONException {
-
-// If this name has already been registered, then emit its integer and
-// increment its usage count.
-
-        Kim kim = new Kim(name);
-        int integer = this.namekeep.find(kim);
-        if (integer != none) {
-            one();
-            writeAndTick(integer, this.namekeep);
-        } else {
-
-// Otherwise, emit the string with Huffman encoding, and register it.
-
-            zero();
-            write(kim, this.namehuff);
-            write(end, namehuff);
-            this.namekeep.register(kim);
-        }
-    }
-
-    /**
-     * Write a JSON object.
-     *
-     * @param jsonobject
-     * @return
-     * @throws JSONException
-     */
-    private void writeObject(JSONObject jsonobject) throws JSONException {
-
-// JSONzip has two encodings for objects: Empty Objects (zipEmptyObject) and
-// non-empty objects (zipObject).
-
-        boolean first = true;
-        Iterator keys = jsonobject.keys();
-        while (keys.hasNext()) {
-            if (probe) {
-                log("\n");
-            }
-            Object key = keys.next();
-            if (key instanceof String) {
-                if (first) {
-                    first = false;
-                    write(zipObject, 3);
-                } else {
-                    one();
-                }
-                writeName((String) key);
-                Object value = jsonobject.get((String) key);
-                if (value instanceof String) {
-                    zero();
-                    writeString((String) value);
-                } else {
-                    one();
-                    writeValue(value);
-                }
-            }
-        }
-        if (first) {
-            write(zipEmptyObject, 3);
-        } else {
-            zero();
-        }
-    }
-
-    /**
-     * Write a string.
-     *
-     * @param string
-     * @throws JSONException
-     */
-    private void writeString(String string) throws JSONException {
-
-// Special case for empty strings.
-
-        if (string.length() == 0) {
-            zero();
-            zero();
-            write(end, this.substringhuff);
-            zero();
-        } else {
-            Kim kim = new Kim(string);
-
-// Look for the string in the strings keep. If it is found, emit its
-// integer and count that as a use.
-
-            int integer = this.stringkeep.find(kim);
-            if (integer != none) {
-                one();
-                writeAndTick(integer, this.stringkeep);
-            } else {
-
-// But if it is not found, emit the string's substrings. Register the string
-// so that the next lookup will succeed.
-
-                writeSubstring(kim);
-                this.stringkeep.register(kim);
-            }
-        }
-    }
-
-    /**
-     * Write a string, attempting to match registered substrings.
-     *
-     * @param kim
-     * @throws JSONException
-     */
-    private void writeSubstring(Kim kim) throws JSONException {
-        this.substringkeep.reserve();
-        zero();
-        int from = 0;
-        int thru = kim.length;
-        int until = thru - JSONzip.minSubstringLength;
-        int previousFrom = none;
-        int previousThru = 0;
-
-// Find a substring from the substring keep.
-
-        while (true) {
-            int at;
-            int integer = none;
-            for (at = from; at <= until; at += 1) {
-                integer = this.substringkeep.match(kim, at, thru);
-                if (integer != none) {
-                    break;
-                }
-            }
-            if (integer == none) {
-                break;
-            }
-
-// If a substring is found, emit any characters that were before the matched
-// substring. Then emit the substring's integer and loop back to match the
-// remainder with another substring.
-
-            if (from != at) {
-                zero();
-                write(kim, from, at, this.substringhuff);
-                write(end, this.substringhuff);
-                if (previousFrom != none) {
-                    this.substringkeep.registerOne(kim, previousFrom,
-                            previousThru);
-                    previousFrom = none;
-                }
-            }
-            one();
-            writeAndTick(integer, this.substringkeep);
-            from = at + this.substringkeep.length(integer);
-            if (previousFrom != none) {
-                this.substringkeep.registerOne(kim, previousFrom,
-                        previousThru);
-                previousFrom = none;
-            }
-            previousFrom = at;
-            previousThru = from + 1;
-        }
-
-// If a substring is not found, then emit the remaining characters.
-
-        zero();
-        if (from < thru) {
-            write(kim, from, thru, this.substringhuff);
-            if (previousFrom != none) {
-                this.substringkeep.registerOne(kim, previousFrom, previousThru);
-            }
-        }
-        write(end, this.substringhuff);
-        zero();
-
-// Register the string's substrings in the trie in hopes of future substring
-// matching.
-
-        substringkeep.registerMany(kim);
-    }
-
-    /**
-     * Write a value.
-     *
-     * @param value
-     *            One of these types: Boolean, Number, etc.
-     * @throws JSONException
-     */
-    private void writeValue(Object value) throws JSONException {
-        if (value instanceof Number) {
-            String string = JSONObject.numberToString((Number) value);
-            int integer = this.values.find(string);
-            if (integer != none) {
-                write(2, 2);
-                writeAndTick(integer, this.values);
-                return;
-            }
-            if (value instanceof Integer || value instanceof Long) {
-                long longer = ((Number) value).longValue();
-                if (longer >= 0 && longer < int14) {
-                    write(0, 2);
-                    if (longer < int4) {
-                        zero();
-                        write((int) longer, 4);
-                        return;
-                    }
-                    one();
-                    if (longer < int7) {
-                        zero();
-                        write((int) longer, 7);
-                        return;
-                    }
-                    one();
-                    write((int) longer, 14);
-                    return;
-                }
-            }
-            write(1, 2);
-            for (int i = 0; i < string.length(); i += 1) {
-                write(bcd(string.charAt(i)), 4);
-            }
-            write(endOfNumber, 4);
-            this.values.register(string);
-        } else {
-            write(3, 2);
-            writeJSON(value);
-        }
-    }
-
-    /**
-     * Output a zero bit.
-     *
-     * @throws JSONException
-     *
-     * @throws IOException
-     */
-    private void zero() throws JSONException {
-        if (probe) {
-            log(0);
-        }
-        write(0, 1);
-    }
-
-    /**
-     * Compress a JSONObject.
-     *
-     * @param jsonobject
-     * @throws JSONException
-     */
-    public void zip(JSONObject jsonobject) throws JSONException {
-        begin();
-        writeJSON(jsonobject);
-    }
-
-    /**
-     * Compress a JSONArray.
-     *
-     * @param jsonarray
-     * @throws JSONException
-     */
-    public void zip(JSONArray jsonarray) throws JSONException {
-        begin();
-        writeJSON(jsonarray);
-    }
-}
diff --git a/src/org/json/zip/Decompressor.java b/src/org/json/zip/Decompressor.java
deleted file mode 100644
index 108a2e2..0000000
--- a/src/org/json/zip/Decompressor.java
+++ /dev/null
@@ -1,325 +0,0 @@
-package org.json.zip;
-
-import java.io.UnsupportedEncodingException;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-import org.json.Kim;
-
-/*
- Copyright (c) 2012 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * JSONzip is a compression scheme for JSON text.
- *
- * @author JSON.org
- * @version 2013-04-18
- */
-
-public class Decompressor extends JSONzip {
-
-    /**
-     * A decompressor reads bits from a BitReader.
-     */
-    BitReader bitreader;
-
-    /**
-     * Create a new compressor. It may be used for an entire session or
-     * subsession.
-     *
-     * @param bitreader
-     *            The bitreader that this decompressor will read from.
-     */
-    public Decompressor(BitReader bitreader) {
-        super();
-        this.bitreader = bitreader;
-    }
-
-    /**
-     * Read one bit.
-     *
-     * @return true if 1, false if 0.
-     * @throws JSONException
-     */
-    private boolean bit() throws JSONException {
-        boolean value;
-        try {
-            value = this.bitreader.bit();
-            if (probe) {
-                log(value ? 1 : 0);
-            }
-            return value;
-        } catch (Throwable e) {
-            throw new JSONException(e);
-        }
-
-    }
-
-    /**
-     * Read enough bits to obtain an integer from the keep, and increase that
-     * integer's weight.
-     *
-     * @param keep
-     * @param bitreader
-     * @return
-     * @throws JSONException
-     */
-    private Object getAndTick(Keep keep, BitReader bitreader)
-            throws JSONException {
-        try {
-            int width = keep.bitsize();
-            int integer = bitreader.read(width);
-            Object value = keep.value(integer);
-            if (JSONzip.probe) {
-                JSONzip.log("\"" + value + "\"");
-                JSONzip.log(integer, width);
-            }
-            if (integer >= keep.length) {
-                throw new JSONException("Deep error.");
-            }
-            keep.tick(integer);
-            return value;
-        } catch (Throwable e) {
-            throw new JSONException(e);
-        }
-    }
-
-    /**
-     * The pad method skips the bits that padded a stream to fit some
-     * allocation. pad(8) will skip over the remainder of a byte.
-     *
-     * @param factor
-     * @return true if all of the padding bits were zero.
-     * @throws JSONException
-     */
-    public boolean pad(int factor) throws JSONException {
-        try {
-            return this.bitreader.pad(factor);
-        } catch (Throwable e) {
-            throw new JSONException(e);
-        }
-    }
-
-    /**
-     * Read an integer, specifying its width in bits.
-     *
-     * @param width
-     *            0 to 32.
-     * @return An unsigned integer.
-     * @throws JSONException
-     */
-    private int read(int width) throws JSONException {
-        try {
-            int value = this.bitreader.read(width);
-            if (probe) {
-                log(value, width);
-            }
-            return value;
-        } catch (Throwable e) {
-            throw new JSONException(e);
-        }
-    }
-
-    /**
-     * Read a JSONArray.
-     *
-     * @param stringy
-     *            true if the first element is a string.
-     * @return
-     * @throws JSONException
-     */
-    private JSONArray readArray(boolean stringy) throws JSONException {
-        JSONArray jsonarray = new JSONArray();
-        jsonarray.put(stringy ? readString() : readValue());
-        while (true) {
-            if (probe) {
-                log("\n");
-            }
-            if (!bit()) {
-                if (!bit()) {
-                    return jsonarray;
-                }
-                jsonarray.put(stringy ? readValue() : readString());
-            } else {
-                jsonarray.put(stringy ? readString() : readValue());
-            }
-        }
-    }
-
-    /**
-     * Read a JSON value. The type of value is determined by the next 3 bits.
-     *
-     * @return
-     * @throws JSONException
-     */
-    private Object readJSON() throws JSONException {
-        switch (read(3)) {
-        case zipObject:
-            return readObject();
-        case zipArrayString:
-            return readArray(true);
-        case zipArrayValue:
-            return readArray(false);
-        case zipEmptyObject:
-            return new JSONObject();
-        case zipEmptyArray:
-            return new JSONArray();
-        case zipTrue:
-            return Boolean.TRUE;
-        case zipFalse:
-            return Boolean.FALSE;
-        default:
-            return JSONObject.NULL;
-        }
-    }
-
-    private String readName() throws JSONException {
-        byte[] bytes = new byte[65536];
-        int length = 0;
-        if (!bit()) {
-            while (true) {
-                int c = this.namehuff.read(this.bitreader);
-                if (c == end) {
-                    break;
-                }
-                bytes[length] = (byte) c;
-                length += 1;
-            }
-            if (length == 0) {
-                return "";
-            }
-            Kim kim = new Kim(bytes, length);
-            this.namekeep.register(kim);
-            return kim.toString();
-        }
-        return getAndTick(this.namekeep, this.bitreader).toString();
-    }
-
-    private JSONObject readObject() throws JSONException {
-        JSONObject jsonobject = new JSONObject();
-        while (true) {
-            if (probe) {
-                log("\n");
-            }
-            String name = readName();
-            jsonobject.put(name, !bit() ? readString() : readValue());
-            if (!bit()) {
-                return jsonobject;
-            }
-        }
-    }
-
-    private String readString() throws JSONException {
-        Kim kim;
-        int from = 0;
-        int thru = 0;
-        int previousFrom = none;
-        int previousThru = 0;
-        if (bit()) {
-            return getAndTick(this.stringkeep, this.bitreader).toString();
-        }
-        byte[] bytes = new byte[65536];
-        boolean one = bit();
-        this.substringkeep.reserve();
-        while (true) {
-            if (one) {
-                from = thru;
-                kim = (Kim) getAndTick(this.substringkeep, this.bitreader);
-                thru = kim.copy(bytes, from);
-                if (previousFrom != none) {
-                    this.substringkeep.registerOne(new Kim(bytes, previousFrom,
-                            previousThru + 1));
-                }
-                previousFrom = from;
-                previousThru = thru;
-                one = bit();
-            } else {
-                from = none;
-                while (true) {
-                    int c = this.substringhuff.read(this.bitreader);
-                    if (c == end) {
-                        break;
-                    }
-                    bytes[thru] = (byte) c;
-                    thru += 1;
-                    if (previousFrom != none) {
-                        this.substringkeep.registerOne(new Kim(bytes,
-                                previousFrom, previousThru + 1));
-                        previousFrom = none;
-                    }
-                }
-                if (!bit()) {
-                    break;
-                }
-                one = true;
-            }
-        }
-        if (thru == 0) {
-            return "";
-        }
-        kim = new Kim(bytes, thru);
-        this.stringkeep.register(kim);
-        this.substringkeep.registerMany(kim);
-        return kim.toString();
-    }
-
-    private Object readValue() throws JSONException {
-        switch (read(2)) {
-        case 0:
-            return new Integer(read(!bit() ? 4 : !bit() ? 7 : 14));
-        case 1:
-            byte[] bytes = new byte[256];
-            int length = 0;
-            while (true) {
-                int c = read(4);
-                if (c == endOfNumber) {
-                    break;
-                }
-                bytes[length] = bcd[c];
-                length += 1;
-            }
-            Object value;
-            try {
-                value = JSONObject.stringToValue(new String(bytes, 0, length,
-                        "US-ASCII"));
-            } catch (UnsupportedEncodingException e) {
-                throw new JSONException(e);
-            }
-            this.values.register(value);
-            return value;
-        case 2:
-            return getAndTick(this.values, this.bitreader);
-        case 3:
-            return readJSON();
-        default:
-            throw new JSONException("Impossible.");
-        }
-    }
-
-    public Object unzip() throws JSONException {
-        begin();
-        return readJSON();
-    }
-}
diff --git a/src/org/json/zip/Huff.java b/src/org/json/zip/Huff.java
deleted file mode 100644
index 2e1d1c9..0000000
--- a/src/org/json/zip/Huff.java
+++ /dev/null
@@ -1,406 +0,0 @@
-package org.json.zip;
-
-import org.json.JSONException;
-
-/*
- Copyright (c) 2013 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * JSONzip is a compression scheme for JSON text.
- * @author JSON.org
- * @version 2013-04-18
- */
-
-/**
- * A Huffman encoder/decoder. It operates over a domain of integers, which may
- * map to characters or other symbols. Symbols that are used frequently are
- * given shorter codes than symbols that are used infrequently. This usually
- * produces shorter messages.
- *
- * Initially, all of the symbols are given the same weight. The weight of a
- * symbol is incremented by the tick method. The generate method is used to
- * generate the encoding table. The table must be generated before encoding or
- * decoding. You may regenerate the table with the latest weights at any time.
- */
-public class Huff implements None, PostMortem {
-
-    /**
-     * The number of symbols known to the encoder.
-     */
-    private final int domain;
-
-    /**
-     * An array that maps symbol values to symbols.
-     */
-    private final Symbol[] symbols;
-
-    /**
-     * The root of the decoding table, and the terminal of the encoding table.
-     */
-    private Symbol table;
-
-    /**
-     * Have any weights changed since the table was last generated?
-     */
-    private boolean upToDate = false;
-
-    /**
-     * The number of bits in the last symbol. This is used in tracing.
-     */
-    private int width;
-
-    private static class Symbol implements PostMortem {
-        public Symbol back;
-        public Symbol next;
-        public Symbol zero;
-        public Symbol one;
-        public final int integer;
-        public long weight;
-
-        /**
-         * Make a symbol representing a character or other value.
-         *
-         * @param integer
-         *            The symbol's number
-         */
-        public Symbol(int integer) {
-            this.integer = integer;
-            this.weight = 0;
-            this.next = null;
-            this.back = null;
-            this.one = null;
-            this.zero = null;
-        }
-
-        public boolean postMortem(PostMortem pm) {
-            boolean result = true;
-            Symbol that = (Symbol) pm;
-
-            if (this.integer != that.integer || this.weight != that.weight) {
-                return false;
-            }
-            if ((this.back != null) != (that.back != null)) {
-                return false;
-            }
-            Symbol zero = this.zero;
-            Symbol one = this.one;
-            if (zero == null) {
-                if (that.zero != null) {
-                    return false;
-                }
-            } else {
-                result = zero.postMortem(that.zero);
-            }
-            if (one == null) {
-                if (that.one != null) {
-                    return false;
-                }
-            } else {
-                result = one.postMortem(that.one);
-            }
-            return result;
-        }
-
-    }
-
-    /**
-     * Construct a Huffman encoder/decoder.
-     *
-     * @param domain
-     *            The number of values known to the object.
-     */
-    public Huff(int domain) {
-        this.domain = domain;
-        int length = domain * 2 - 1;
-        this.symbols = new Symbol[length];
-
-// Make the leaf symbols.
-
-        for (int i = 0; i < domain; i += 1) {
-            symbols[i] = new Symbol(i);
-        }
-
-// SMake the links.
-
-        for (int i = domain; i < length; i += 1) {
-            symbols[i] = new Symbol(none);
-        }
-    }
-
-    /**
-     * Generate the encoding/decoding table. The table determines the bit
-     * sequences used by the read and write methods.
-     *
-     * @return this
-     */
-    public void generate() {
-        if (!this.upToDate) {
-
-// Phase One: Sort the symbols by weight into a linked list.
-
-            Symbol head = this.symbols[0];
-            Symbol next;
-            Symbol previous = head;
-            Symbol symbol;
-
-            this.table = null;
-            head.next = null;
-            for (int i = 1; i < this.domain; i += 1) {
-                symbol = symbols[i];
-
-// If this symbol weights less than the head, then it becomes the new head.
-
-                if (symbol.weight < head.weight) {
-                    symbol.next = head;
-                    head = symbol;
-                } else {
-
-// To save time, we will start the search from the previous symbol instead
-// of the head unless the current symbol weights less than the previous symbol.
-
-                    if (symbol.weight < previous.weight) {
-                        previous = head;
-                    }
-
-// Find a connected pair (previous and next) where the symbol weighs the same
-// or more than previous but less than the next. Link the symbol between them.
-
-                    while (true) {
-                        next = previous.next;
-                        if (next == null || symbol.weight < next.weight) {
-                            break;
-                        }
-                        previous = next;
-                    }
-                    symbol.next = next;
-                    previous.next = symbol;
-                    previous = symbol;
-                }
-            }
-
-// Phase Two: Make new symbols from the two lightest symbols until only one
-// symbol remains. The final symbol becomes the root of the table binary tree.
-
-            int avail = this.domain;
-            Symbol first;
-            Symbol second;
-            previous = head;
-            while (true) {
-                first = head;
-                second = first.next;
-                head = second.next;
-                symbol = this.symbols[avail];
-                avail += 1;
-                symbol.weight = first.weight + second.weight;
-                symbol.zero = first;
-                symbol.one = second;
-                symbol.back = null;
-                first.back = symbol;
-                second.back = symbol;
-                if (head == null) {
-                    break;
-                }
-
-// Insert the new symbol back into the sorted list.
-
-                if (symbol.weight < head.weight) {
-                    symbol.next = head;
-                    head = symbol;
-                    previous = head;
-                } else {
-                    while (true) {
-                        next = previous.next;
-                        if (next == null || symbol.weight < next.weight) {
-                            break;
-                        }
-                        previous = next;
-                    }
-                    symbol.next = next;
-                    previous.next = symbol;
-                    previous = symbol;
-                }
-
-            }
-
-// The last remaining symbol is the root of the table.
-
-            this.table = symbol;
-            this.upToDate = true;
-        }
-    }
-
-    private boolean postMortem(int integer) {
-        int[] bits = new int[this.domain];
-        Symbol symbol = this.symbols[integer];
-        if (symbol.integer != integer) {
-            return false;
-        }
-        int i = 0;
-        while (true) {
-            Symbol back = symbol.back;
-            if (back == null) {
-                break;
-            }
-            if (back.zero == symbol) {
-                bits[i] = 0;
-            } else if (back.one == symbol) {
-                bits[i] = 1;
-            } else {
-                return false;
-            }
-            i += 1;
-            symbol = back;
-        }
-        if (symbol != this.table) {
-            return false;
-        }
-        this.width = 0;
-        symbol = this.table;
-        while (symbol.integer == none) {
-            i -= 1;
-            symbol = bits[i] != 0 ? symbol.one : symbol.zero;
-        }
-        return symbol.integer == integer && i == 0;
-    }
-
-    /**
-     * Compare two Huffman tables.
-     */
-    public boolean postMortem(PostMortem pm) {
-
-// Go through every integer in the domain, generating its bit sequence, and
-// then proving that that bit sequence produces the same integer.
-
-        for (int integer = 0; integer < this.domain; integer += 1) {
-            if (!postMortem(integer)) {
-                JSONzip.log("\nBad huff ");
-                JSONzip.logchar(integer, integer);
-                return false;
-            }
-        }
-        return this.table.postMortem(((Huff) pm).table);
-    }
-
-    /**
-     * Read bits until a symbol can be identified. The weight of the read
-     * symbol will be incremented.
-     *
-     * @param bitreader
-     *            The source of bits.
-     * @return The integer value of the symbol.
-     * @throws JSONException
-     */
-    public int read(BitReader bitreader) throws JSONException {
-        try {
-            this.width = 0;
-            Symbol symbol = this.table;
-            while (symbol.integer == none) {
-                this.width += 1;
-                symbol = bitreader.bit() ? symbol.one : symbol.zero;
-            }
-            tick(symbol.integer);
-            if (JSONzip.probe) {
-                JSONzip.logchar(symbol.integer, this.width);
-            }
-            return symbol.integer;
-        } catch (Throwable e) {
-            throw new JSONException(e);
-        }
-    }
-
-    /**
-     * Increase by 1 the weight associated with a value.
-     *
-     * @param value
-     *            The number of the symbol to tick
-     * @return this
-     */
-    public void tick(int value) {
-        this.symbols[value].weight += 1;
-        this.upToDate = false;
-    }
-
-    /**
-     * Increase by 1 the weight associated with a range of values.
-     *
-     * @param from
-     *            The first symbol to tick
-     * @param to
-     *            The last symbol to tick
-     * @return this
-     */
-    public void tick(int from, int to) {
-        for (int value = from; value <= to; value += 1) {
-            tick(value);
-        }
-    }
-
-    /**
-     * Recur from a symbol back, emitting bits. We recur before emitting to
-     * make the bits come out in the right order.
-     *
-     * @param symbol
-     *            The symbol to write.
-     * @param bitwriter
-     *            The bitwriter to write it to.
-     * @throws JSONException
-     */
-    private void write(Symbol symbol, BitWriter bitwriter)
-            throws JSONException {
-        try {
-            Symbol back = symbol.back;
-            if (back != null) {
-                this.width += 1;
-                write(back, bitwriter);
-                if (back.zero == symbol) {
-                    bitwriter.zero();
-                } else {
-                    bitwriter.one();
-                }
-            }
-        } catch (Throwable e) {
-            throw new JSONException(e);
-        }
-    }
-
-    /**
-     * Write the bits corresponding to a symbol. The weight of the symbol will
-     * be incremented.
-     *
-     * @param value
-     *            The number of the symbol to write
-     * @param bitwriter
-     *            The destination of the bits.
-     * @return this
-     * @throws JSONException
-     */
-    public void write(int value, BitWriter bitwriter) throws JSONException {
-        this.width = 0;
-        write(this.symbols[value], bitwriter);
-        tick(value);
-        if (JSONzip.probe) {
-            JSONzip.logchar(value, this.width);
-        }
-    }
-}
diff --git a/src/org/json/zip/JSONzip.java b/src/org/json/zip/JSONzip.java
deleted file mode 100644
index 2128742..0000000
--- a/src/org/json/zip/JSONzip.java
+++ /dev/null
@@ -1,281 +0,0 @@
-package org.json.zip;
-
-
-/*
- Copyright (c) 2013 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * JSONzip is a binary-encoded JSON dialect. It is designed to compress the
- * messages in a session. It is adaptive, so with each message seen, it should
- * improve its compression. It minimizes JSON's overhead, reducing punctuation
- * to a small number of bits. It uses Huffman encoding to reduce the average
- * size of characters. It uses caches (or Keeps) to keep recently seen strings
- * and values, so repetitive content (such as object keys) can be
- * substantially reduced. It uses a character encoding called Kim (Keep it
- * minimal) that is smaller than UTF-8 for most East European, African, and
- * Asian scripts.
- *
- * JSONzip tends to reduce most content by about half. If there is a lot of
- * recurring information, the reduction can be much more dramatic.
- *
- * FOR EVALUATION PURPOSES ONLY. THIS PACKAGE HAS NOT YET BEEN TESTED
- * ADEQUATELY FOR PRODUCTION USE.
- *
- * @author JSON.org
- * @version 2013-04-18
- */
-public abstract class JSONzip implements None, PostMortem {
-    /**
-     * Powers of 2.
-     */
-    public static final int[] twos = {
-        1, 2, 4, 8, 16, 32, 64, 128, 256, 512,
-        1024, 2048, 4096, 8192, 16384, 32768, 65536
-    };
-
-    /**
-     * The characters in JSON numbers can be reduced to 4 bits each.
-     */
-    public static final byte[] bcd = {
-        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '-', '+', 'E'
-    };
-
-    /**
-     * The number of integers that can be encoded in 4 bits.
-     */
-    public static final long int4 = 16;
-
-    /**
-     * The number of integers that can be encoded in 7 bits.
-     */
-    public static final long int7 = 128;
-
-    /**
-     * The number of integers that can be encoded in 14 bits.
-     */
-    public static final long int14 = 16384;
-
-    /**
-     * The end of string code.
-     */
-    public static final int end = 256;
-
-    /**
-     * The end of number code.
-     */
-    public static final int endOfNumber = bcd.length;
-
-    /**
-     * The maximum substring length when registering many. The registration of
-     * one substring may be longer.
-     */
-    public static final int maxSubstringLength = 10;
-
-    /**
-     * The minimum substring length.
-     */
-    public static final int minSubstringLength = 3;
-
-    /**
-     * The package supports tracing for debugging.
-     */
-    public static final boolean probe = false;
-
-    /**
-     * The maximum number of substrings added to the substrings keep per
-     * string.
-     */
-    public static final int substringLimit = 40;
-
-    /**
-     * The value code for an empty object.
-     */
-    public static final int zipEmptyObject = 0;
-
-    /**
-     * The value code for an empty array.
-     */
-    public static final int zipEmptyArray = 1;
-
-    /**
-     * The value code for true.
-     */
-    public static final int zipTrue = 2;
-
-    /**
-     * The value code for false.
-     */
-    public static final int zipFalse = 3;
-
-    /**
-     * The value code for null.
-     */
-    public static final int zipNull = 4;
-
-    /**
-     * The value code for a non-empty object.
-     */
-    public static final int zipObject = 5;
-
-    /**
-     * The value code for an array with a string as its first element.
-     */
-    public static final int zipArrayString = 6;
-
-    /**
-     * The value code for an array with a non-string value as its first element.
-     */
-    public static final int zipArrayValue = 7;
-
-    /**
-     * A Huffman encoder for names.
-     */
-    protected final Huff namehuff;
-
-    /**
-     * A place to keep the names (keys).
-     */
-    protected final MapKeep namekeep;
-
-    /**
-     * A place to keep the strings.
-     */
-    protected final MapKeep stringkeep;
-
-    /**
-     * A Huffman encoder for string values.
-     */
-    protected final Huff substringhuff;
-
-    /**
-     * A place to keep the strings.
-     */
-    protected final TrieKeep substringkeep;
-
-    /**
-     * A place to keep the values.
-     */
-    protected final MapKeep values;
-
-    /**
-     * Initialize the data structures.
-     */
-    protected JSONzip() {
-        this.namehuff = new Huff(end + 1);
-        this.namekeep = new MapKeep(9);
-        this.stringkeep = new MapKeep(11);
-        this.substringhuff = new Huff(end + 1);
-        this.substringkeep = new TrieKeep(12);
-        this.values = new MapKeep(10);
-
-// Increase the weights of the ASCII letters, digits, and special characters
-// because they are highly likely to occur more frequently. The weight of each
-// character will increase as it is used. The Huffman encoder will tend to
-// use fewer bits to encode heavier characters.
-
-        this.namehuff.tick(' ', '}');
-        this.namehuff.tick('a', 'z');
-        this.namehuff.tick(end);
-        this.namehuff.tick(end);
-        this.substringhuff.tick(' ', '}');
-        this.substringhuff.tick('a', 'z');
-        this.substringhuff.tick(end);
-        this.substringhuff.tick(end);
-    }
-
-    /**
-     *
-     */
-    protected void begin() {
-        this.namehuff.generate();
-        this.substringhuff.generate();
-    }
-
-    /**
-     * Write an end-of-line to the console.
-     */
-    static void log() {
-        log("\n");
-    }
-
-    /**
-     * Write an integer to the console.
-     *
-     * @param integer
-     */
-    static void log(int integer) {
-        log(integer + " ");
-    }
-
-    /**
-     * Write two integers, separated by ':' to the console.
-     *
-     * @param integer
-     * @param width
-     */
-    static void log(int integer, int width) {
-        log(integer + ":" + width + " ");
-    }
-
-    /**
-     * Write a string to the console.
-     *
-     * @param string
-     */
-    static void log(String string) {
-        System.out.print(string);
-    }
-
-    /**
-     * Write a character or its code to the console.
-     *
-     * @param integer
-     * @param width
-     */
-    static void logchar(int integer, int width) {
-        if (integer > ' ' && integer <= '}') {
-            log("'" + (char) integer + "':" + width + " ");
-        } else {
-            log(integer, width);
-        }
-    }
-
-    /**
-     * This method is used for testing the implementation of JSONzip. It is not
-     * suitable for any other purpose. It is used to compare a Compressor and a
-     * Decompressor, verifying that the data structures that were built during
-     * zipping and unzipping were the same.
-     *
-     * @return true if the structures match.
-     */
-    public boolean postMortem(PostMortem pm) {
-        JSONzip that = (JSONzip) pm;
-        return this.namehuff.postMortem(that.namehuff)
-                && this.namekeep.postMortem(that.namekeep)
-                && this.stringkeep.postMortem(that.stringkeep)
-                && this.substringhuff.postMortem(that.substringhuff)
-                && this.substringkeep.postMortem(that.substringkeep)
-                && this.values.postMortem(that.values);
-    }
-}
diff --git a/src/org/json/zip/Keep.java b/src/org/json/zip/Keep.java
deleted file mode 100644
index 377e344..0000000
--- a/src/org/json/zip/Keep.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package org.json.zip;
-
-
-/*
- Copyright (c) 2013 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * A keep is a data structure that associates strings (or substrings) with
- * numbers. This allows the sending of small integers instead of strings.
- *
- * @author JSON.org
- * @version 2013-04-18
- */
-abstract class Keep implements None, PostMortem {
-    protected int capacity;
-    protected int length;
-    protected int power;
-    protected long[] uses;
-
-    public Keep(int bits) {
-        this.capacity = JSONzip.twos[bits];
-        this.length = 0;
-        this.power = 0;
-        this.uses = new long[this.capacity];
-    }
-
-    /**
-     * When an item ages, its use count is reduced by at least half.
-     *
-     * @param use
-     *            The current use count of an item.
-     * @return The new use count for that item.
-     */
-    public static long age(long use) {
-        return use >= 32 ? 16 : use / 2;
-    }
-
-    /**
-     * Return the number of bits required to contain an integer based on the
-     * current length of the keep. As the keep fills up, the number of bits
-     * required to identify one of its items goes up.
-     */
-    public int bitsize() {
-        while (JSONzip.twos[this.power] < this.length) {
-            this.power += 1;
-        }
-        return this.power;
-    }
-
-    /**
-     * Increase the usage count on an integer value.
-     */
-    public void tick(int integer) {
-        this.uses[integer] += 1;
-    }
-
-    /**
-     * Get the value associated with an integer.
-     * @param integer The number of an item in the keep.
-     * @return The value.
-     */
-    abstract public Object value(int integer);
-}
diff --git a/src/org/json/zip/MapKeep.java b/src/org/json/zip/MapKeep.java
deleted file mode 100644
index 1374e08..0000000
--- a/src/org/json/zip/MapKeep.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package org.json.zip;
-
-import java.util.HashMap;
-
-import org.json.Kim;
-
-/*
- Copyright (c) 2013 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * A keep is an associative data structure that maintains usage counts of each
- * of the associations in its keeping. When the keep becomes full, it purges
- * little used associations, and ages the survivors. Each key is assigned an
- * integer value. When the keep is compacted, each key can be given a new
- * value.
- */
-class MapKeep extends Keep {
-    private Object[] list;
-    private HashMap map;
-
-    /**
-     * Create a new Keep.
-     * @param bits
-     *              The capacity of the keep expressed in the number of bits
-     *              required to hold an integer.
-     */
-    public MapKeep(int bits) {
-        super(bits);
-        this.list = new Object[this.capacity];
-        this.map = new HashMap(this.capacity);
-    }
-
-    /**
-     * Compact the keep. A keep may contain at most this.capacity elements.
-     * The keep contents can be reduced by deleting all elements with low use
-     * counts, and by reducing the use counts of the survivors.
-     */
-    private void compact() {
-        int from = 0;
-        int to = 0;
-        while (from < this.capacity) {
-            Object key = this.list[from];
-            long usage = age(this.uses[from]);
-            if (usage > 0) {
-                this.uses[to] = usage;
-                this.list[to] = key;
-                this.map.put(key, new Integer(to));
-                to += 1;
-            } else {
-                this.map.remove(key);
-            }
-            from += 1;
-        }
-        if (to < this.capacity) {
-            this.length = to;
-        } else {
-            this.map.clear();
-            this.length = 0;
-        }
-        this.power = 0;
-    }
-
-    /**
-     * Find the integer value associated with this key, or nothing if this key
-     * is not in the keep.
-     *
-     * @param key
-     *            An object.
-     * @return An integer
-     */
-    public int find(Object key) {
-        Object o = this.map.get(key);
-        return o instanceof Integer ? ((Integer) o).intValue() : none;
-    }
-
-    public boolean postMortem(PostMortem pm) {
-        MapKeep that = (MapKeep) pm;
-        if (this.length != that.length) {
-            JSONzip.log(this.length + " <> " + that.length);
-            return false;
-        }
-        for (int i = 0; i < this.length; i += 1) {
-            boolean b;
-            if (this.list[i] instanceof Kim) {
-                b = ((Kim) this.list[i]).equals(that.list[i]);
-            } else {
-                Object o = this.list[i];
-                Object q = that.list[i];
-                if (o instanceof Number) {
-                    o = o.toString();
-                }
-                if (q instanceof Number) {
-                    q = q.toString();
-                }
-                b = o.equals(q);
-            }
-            if (!b) {
-                JSONzip.log("\n[" + i + "]\n " + this.list[i] + "\n "
-                        + that.list[i] + "\n " + this.uses[i] + "\n "
-                        + that.uses[i]);
-                return false;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Register a value in the keep. Compact the keep if it is full. The next
-     * time this value is encountered, its integer can be sent instead.
-     * @param value A value.
-     */
-    public void register(Object value) {
-        if (JSONzip.probe) {
-            int integer = find(value);
-            if (integer >= 0) {
-                JSONzip.log("\nDuplicate key " + value);
-            }
-        }
-        if (this.length >= this.capacity) {
-            compact();
-        }
-        this.list[this.length] = value;
-        this.map.put(value, new Integer(this.length));
-        this.uses[this.length] = 1;
-        if (JSONzip.probe) {
-            JSONzip.log("<" + this.length + " " + value + "> ");
-        }
-        this.length += 1;
-    }
-
-    /**
-     * Return the value associated with the integer.
-     * @param integer The number of an item in the keep.
-     * @return The value.
-     */
-    public Object value(int integer) {
-        return this.list[integer];
-    }
-}
diff --git a/src/org/json/zip/None.java b/src/org/json/zip/None.java
deleted file mode 100644
index 818e68d..0000000
--- a/src/org/json/zip/None.java
+++ /dev/null
@@ -1,15 +0,0 @@
-package org.json.zip;
-
-/**
- * None is an interface that makes the constant <i>none</i> (short for
- * negative one or long for -1) available to any class that implements it.
- * The none value is used to stand for an integer that is not an integer,
- * such as the negative result of a search.
- */
-public interface None {
-    /**
-     * Negative One.
-     */
-    public static final int none = -1;
-
-}
diff --git a/src/org/json/zip/PostMortem.java b/src/org/json/zip/PostMortem.java
deleted file mode 100644
index 22416d7..0000000
--- a/src/org/json/zip/PostMortem.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package org.json.zip;
-
-/*
- Copyright (c) 2013 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * The PostMortem interface allows for testing the internal state of JSONzip
- * processors. Testing that JSONzip can compress an object and reproduce a
- * corresponding object is not sufficient. Complete testing requires that the
- * same internal data structures were constructed on both ends. If those
- * structures are not equivalent, then it is likely that the implementations
- * are not correct, even if convention tests are passed.
- *
- * PostMortem allows for testing of deep structures without breaking
- * encapsulation.
- */
-public interface PostMortem {
-    /**
-     * Determine if two objects are equivalent.
-     *
-     * @param pm
-     *            Another object of the same type.
-     * @return true if they match.
-     */
-    public boolean postMortem(PostMortem pm);
-}
diff --git a/src/org/json/zip/README b/src/org/json/zip/README
deleted file mode 100644
index 93e6470..0000000
--- a/src/org/json/zip/README
+++ /dev/null
@@ -1,2 +0,0 @@
-FOR EVALUATION PURPOSES ONLY. THIS PACKAGE HAS NOT BEEN TESTED ADEQUATELY FOR
-PRODUCTION USE.
diff --git a/src/org/json/zip/TrieKeep.java b/src/org/json/zip/TrieKeep.java
deleted file mode 100644
index dcb13c7..0000000
--- a/src/org/json/zip/TrieKeep.java
+++ /dev/null
@@ -1,396 +0,0 @@
-package org.json.zip;
-
-import org.json.Kim;
-
-/*
- Copyright (c) 2013 JSON.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
-
- The Software shall be used for Good, not Evil.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- */
-
-/**
- * A TrieKeep is a Keep that implements a Trie.
- */
-class TrieKeep extends Keep {
-
-    /**
-     * The trie is made of nodes.
-     */
-    class Node implements PostMortem {
-        private int integer;
-        private Node[] next;
-
-        /**
-         * Each non-leaf node contains links to up to 256 next nodes. Each node
-         * has an integer value.
-         */
-        public Node() {
-            this.integer = none;
-            this.next = null;
-        }
-
-        /**
-         * Get one of a node's 256 links. If it is a leaf node, it returns
-         * null.
-         *
-         * @param cell
-         *            A integer between 0 and 255.
-         * @return
-         */
-        public Node get(int cell) {
-            return this.next == null ? null : this.next[cell];
-        }
-
-        /**
-         * Get one of a node's 256 links. If it is a leap node, it returns
-         * null. The argument is treated as an unsigned integer.
-         *
-         * @param cell
-         *            A byte.
-         * @return
-         */
-        public Node get(byte cell) {
-            return get(((int) cell) & 0xFF);
-        }
-
-        /**
-         * Compare two nodes. Their lengths must be equal. Their links must
-         * also compare.
-         */
-        public boolean postMortem(PostMortem pm) {
-            Node that = (Node) pm;
-            if (that == null) {
-                JSONzip.log("\nMisalign");
-                return false;
-            }
-            if (this.integer != that.integer) {
-                JSONzip.log("\nInteger " + this.integer + " <> " +
-                        that.integer);
-                return false;
-            }
-            if (this.next == null) {
-                if (that.next == null) {
-                    return true;
-                }
-                JSONzip.log("\nNext is null " + this.integer);
-                return false;
-            }
-            for (int i = 0; i < 256; i += 1) {
-                Node node = this.next[i];
-                if (node != null) {
-                    if (!node.postMortem(that.next[i])) {
-                        return false;
-                    }
-                } else if (that.next[i] != null) {
-                    JSONzip.log("\nMisalign " + i);
-                    return false;
-                }
-            }
-            return true;
-        }
-
-        /**
-         * Set a node's link to another node.
-         *
-         * @param cell
-         *            An integer between 0 and 255.
-         * @param node
-         *            The new value for the cell.
-         */
-        public void set(int cell, Node node) {
-            if (this.next == null) {
-                this.next = new Node[256];
-            }
-            if (JSONzip.probe) {
-                if (node == null || this.next[cell] != null) {
-                    JSONzip.log("\nUnexpected set.\n");
-                }
-            }
-            this.next[cell] = node;
-        }
-
-        /**
-         * Set a node's link to another node.
-         *
-         * @param cell
-         *            A byte.
-         * @param node
-         *            The new value for the cell.
-         */
-        public void set(byte cell, Node node) {
-            set(((int) cell) & 0xFF, node);
-        }
-
-        /**
-         * Get one of a node's 256 links. It will not return null. If there is
-         * no link, then a link is manufactured.
-         *
-         * @param cell
-         *            A integer between 0 and 255.
-         * @return
-         */
-        public Node vet(int cell) {
-            Node node = get(cell);
-            if (node == null) {
-                node = new Node();
-                set(cell, node);
-            }
-            return node;
-        }
-
-        /**
-         * Get one of a node's 256 links. It will not return null. If there is
-         * no link, then a link is manufactured.
-         *
-         * @param cell
-         *            A byte.
-         * @return
-         */
-        public Node vet(byte cell) {
-            return vet(((int) cell) & 0xFF);
-        }
-    }
-
-    private int[] froms;
-    private int[] thrus;
-    private Node root;
-    private Kim[] kims;
-
-    /**
-     * Create a new Keep of kims.
-     *
-     * @param bits
-     *            The log2 of the capacity of the Keep. For example, if bits is
-     *            12, then the keep's capacity will be 4096.
-     */
-    public TrieKeep(int bits) {
-        super(bits);
-        this.froms = new int[this.capacity];
-        this.thrus = new int[this.capacity];
-        this.kims = new Kim[this.capacity];
-        this.root = new Node();
-    }
-
-    /**
-     * Get the kim associated with an integer.
-     *
-     * @param integer
-     * @return
-     */
-    public Kim kim(int integer) {
-        Kim kim = this.kims[integer];
-        int from = this.froms[integer];
-        int thru = this.thrus[integer];
-        if (from != 0 || thru != kim.length) {
-            kim = new Kim(kim, from, thru);
-            this.froms[integer] = 0;
-            this.thrus[integer] = kim.length;
-            this.kims[integer] = kim;
-        }
-        return kim;
-    }
-
-    /**
-     * Get the length of the Kim associated with an integer. This is sometimes
-     * much faster than get(integer).length.
-     *
-     * @param integer
-     * @return
-     */
-    public int length(int integer) {
-        return this.thrus[integer] - this.froms[integer];
-    }
-
-    /**
-     * Find the integer value associated with this key, or nothing if this key
-     * is not in the keep.
-     *
-     * @param key
-     *            An object.
-     * @return An integer
-     */
-    public int match(Kim kim, int from, int thru) {
-        Node node = this.root;
-        int best = none;
-        for (int at = from; at < thru; at += 1) {
-            node = node.get(kim.get(at));
-            if (node == null) {
-                break;
-            }
-            if (node.integer != none) {
-                best = node.integer;
-            }
-            from += 1;
-        }
-        return best;
-    }
-
-    public boolean postMortem(PostMortem pm) {
-        boolean result = true;
-        TrieKeep that = (TrieKeep) pm;
-        if (this.length != that.length) {
-            JSONzip.log("\nLength " + this.length + " <> " + that.length);
-            return false;
-        }
-        if (this.capacity != that.capacity) {
-            JSONzip.log("\nCapacity " + this.capacity + " <> " +
-                    that.capacity);
-            return false;
-        }
-        for (int i = 0; i < this.length; i += 1) {
-            Kim thiskim = this.kim(i);
-            Kim thatkim = that.kim(i);
-            if (!thiskim.equals(thatkim)) {
-                JSONzip.log("\n[" + i + "] " + thiskim + " <> " + thatkim);
-                result = false;
-            }
-        }
-        return result && this.root.postMortem(that.root);
-    }
-
-    public void registerMany(Kim kim) {
-        int length = kim.length;
-        int limit = this.capacity - this.length;
-        if (limit > JSONzip.substringLimit) {
-            limit = JSONzip.substringLimit;
-        }
-        int until = length - (JSONzip.minSubstringLength - 1);
-        for (int from = 0; from < until; from += 1) {
-            int len = length - from;
-            if (len > JSONzip.maxSubstringLength) {
-                len = JSONzip.maxSubstringLength;
-            }
-            len += from;
-            Node node = this.root;
-            for (int at = from; at < len; at += 1) {
-                Node next = node.vet(kim.get(at));
-                if (next.integer == none
-                        && at - from >= (JSONzip.minSubstringLength - 1)) {
-                    next.integer = this.length;
-                    this.uses[this.length] = 1;
-                    this.kims[this.length] = kim;
-                    this.froms[this.length] = from;
-                    this.thrus[this.length] = at + 1;
-                    if (JSONzip.probe) {
-                        try {
-                            JSONzip.log("<<" + this.length + " "
-                                    + new Kim(kim, from, at + 1) + ">> ");
-                        } catch (Throwable ignore) {
-                        }
-                    }
-                    this.length += 1;
-                    limit -= 1;
-                    if (limit <= 0) {
-                        return;
-                    }
-                }
-                node = next;
-            }
-        }
-    }
-
-    public void registerOne(Kim kim) {
-        int integer = registerOne(kim, 0, kim.length);
-        if (integer != none) {
-            this.kims[integer] = kim;
-        }
-    }
-
-    public int registerOne(Kim kim, int from, int thru) {
-        if (this.length < this.capacity) {
-            Node node = this.root;
-            for (int at = from; at < thru; at += 1) {
-                node = node.vet(kim.get(at));
-            }
-            if (node.integer == none) {
-                int integer = this.length;
-                node.integer = integer;
-                this.uses[integer] = 1;
-                this.kims[integer] = kim;
-                this.froms[integer] = from;
-                this.thrus[integer] = thru;
-                if (JSONzip.probe) {
-                    try {
-                        JSONzip.log("<<" + integer + " " + new Kim(kim, from, thru) + ">> ");
-                    } catch (Throwable ignore) {
-                    }
-                }
-                this.length += 1;
-                return integer;
-            }
-        }
-        return none;
-    }
-
-    /**
-     * Reserve space in the keep, compacting if necessary. A keep may contain
-     * at most -capacity- elements. The keep contents can be reduced by
-     * deleting all elements with low use counts, rebuilding the trie with the
-     * survivors.
-     */
-    public void reserve() {
-        if (this.capacity - this.length < JSONzip.substringLimit) {
-            int from = 0;
-            int to = 0;
-            this.root = new Node();
-            while (from < this.capacity) {
-                if (this.uses[from] > 1) {
-                    Kim kim = this.kims[from];
-                    int thru = this.thrus[from];
-                    Node node = this.root;
-                    for (int at = this.froms[from]; at < thru; at += 1) {
-                        Node next = node.vet(kim.get(at));
-                        node = next;
-                    }
-                    node.integer = to;
-                    this.uses[to] = age(this.uses[from]);
-                    this.froms[to] = this.froms[from];
-                    this.thrus[to] = thru;
-                    this.kims[to] = kim;
-                    to += 1;
-                }
-                from += 1;
-            }
-
-// It is possible, but highly unlikely, that too many items survive.
-// If that happens, clear the keep.
-
-            if (this.capacity - to < JSONzip.substringLimit) {
-                this.power = 0;
-                this.root = new Node();
-                to = 0;
-            }
-            this.length = to;
-            while (to < this.capacity) {
-                this.uses[to] = 0;
-                this.kims[to] = null;
-                this.froms[to] = 0;
-                this.thrus[to] = 0;
-                to += 1;
-
-            }
-        }
-    }
-
-    public Object value(int integer) {
-        return kim(integer);
-    }
-}
diff --git a/src/test/beast/BEASTTestCase.java b/src/test/beast/BEASTTestCase.java
index 4c0053c..156128e 100644
--- a/src/test/beast/BEASTTestCase.java
+++ b/src/test/beast/BEASTTestCase.java
@@ -1,8 +1,6 @@
 package test.beast;
 
 
-import junit.framework.TestCase;
-
 import java.util.ArrayList;
 import java.util.List;
 
@@ -10,6 +8,7 @@ import beast.evolution.alignment.Alignment;
 import beast.evolution.alignment.Sequence;
 import beast.evolution.tree.Tree;
 import beast.util.TreeParser;
+import junit.framework.TestCase;
 
 
 public class BEASTTestCase extends TestCase {
diff --git a/src/test/beast/app/BeautiSubTemplateTest.java b/src/test/beast/app/BeautiSubTemplateTest.java
index 1e137ff..8832af1 100644
--- a/src/test/beast/app/BeautiSubTemplateTest.java
+++ b/src/test/beast/app/BeautiSubTemplateTest.java
@@ -18,8 +18,8 @@ public class BeautiSubTemplateTest extends TestCase {
 				"value", "<parameter id='kappa' value='1.0'/>"
 				);
 		assertEquals(0, t.connectorsInput.get().size());
-		String sXML = t.sXMLInput.get().replaceAll("\\s+", " ");
-		assertEquals("<![CDATA[ <parameter id=\"kappa\" value=\"1.0\"/> ]]>", sXML);
+		String xml = t.xMLInput.get().replaceAll("\\s+", " ");
+		assertEquals("<![CDATA[ <parameter id=\"kappa\" value=\"1.0\"/> ]]>", xml);
 
 		// minimal template + connector
 		t = new BeautiSubTemplate();
@@ -29,12 +29,12 @@ public class BeautiSubTemplateTest extends TestCase {
 				);
 		assertEquals(1, t.connectorsInput.get().size());
 		BeautiConnector c = t.connectorsInput.get().get(0);
-		assertEquals("kappa", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("parameter", c.sInputNameInput.get());
-		assertEquals(null, c.sConditionInput.get());
-		sXML = t.sXMLInput.get().replaceAll("\\s+", " ");
-		assertEquals("<![CDATA[ <parameter id=\"kappa\" value=\"1.0\"/> ]]>", sXML);
+		assertEquals("kappa", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("parameter", c.inputNameInput.get());
+		assertEquals(null, c.conditionInput.get());
+		xml = t.xMLInput.get().replaceAll("\\s+", " ");
+		assertEquals("<![CDATA[ <parameter id=\"kappa\" value=\"1.0\"/> ]]>", xml);
 
 		// minimal template + connector + name
 		t = new BeautiSubTemplate();
@@ -44,12 +44,12 @@ public class BeautiSubTemplateTest extends TestCase {
 				);
 		assertEquals(1, t.connectorsInput.get().size());
 		c = t.connectorsInput.get().get(0);
-		assertEquals("kappa", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("stateNode", c.sInputNameInput.get());
-		assertEquals(null, c.sConditionInput.get());
-		sXML = t.sXMLInput.get().replaceAll("\\s+", " ");
-		assertEquals("<![CDATA[ <parameter id=\"kappa\" name=\"stateNode\" value=\"1.0\"/> ]]>", sXML);
+		assertEquals("kappa", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("stateNode", c.inputNameInput.get());
+		assertEquals(null, c.conditionInput.get());
+		xml = t.xMLInput.get().replaceAll("\\s+", " ");
+		assertEquals("<![CDATA[ <parameter id=\"kappa\" name=\"stateNode\" value=\"1.0\"/> ]]>", xml);
 
 		// minimal template + connector + name + condition
 		t = new BeautiSubTemplate();
@@ -59,12 +59,12 @@ public class BeautiSubTemplateTest extends TestCase {
 				);
 		assertEquals(1, t.connectorsInput.get().size());
 		c = t.connectorsInput.get().get(0);
-		assertEquals("kappa", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("stateNode", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
-		sXML = t.sXMLInput.get().replaceAll("\\s+", " ");
-		assertEquals("<![CDATA[ <parameter id=\"kappa\" name=\"stateNode\" value=\"1.0\"/> ]]>", sXML);
+		assertEquals("kappa", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("stateNode", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
+		xml = t.xMLInput.get().replaceAll("\\s+", " ");
+		assertEquals("<![CDATA[ <parameter id=\"kappa\" name=\"stateNode\" value=\"1.0\"/> ]]>", xml);
 	}
 
 	@Test
@@ -79,12 +79,12 @@ public class BeautiSubTemplateTest extends TestCase {
 				);
 		assertEquals(1, t.connectorsInput.get().size());
 		BeautiConnector c = t.connectorsInput.get().get(0);
-		assertEquals("kappa", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("stateNode", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
-		String sXML = t.sXMLInput.get();
-		assertEquals("<![CDATA[\n<parameter id=\"kappa\" name=\"stateNode\" value=\"1.0\"/>\n]]>", sXML);
+		assertEquals("kappa", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("stateNode", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
+		String xml = t.xMLInput.get();
+		assertEquals("<![CDATA[\n<parameter id=\"kappa\" name=\"stateNode\" value=\"1.0\"/>\n]]>", xml);
 	}
 	
 	@Test
@@ -101,20 +101,20 @@ public class BeautiSubTemplateTest extends TestCase {
 				);
 		assertEquals(2, t.connectorsInput.get().size());
 		BeautiConnector c = t.connectorsInput.get().get(0);
-		assertEquals("kappa", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("stateNode", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
+		assertEquals("kappa", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("stateNode", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
 		c = t.connectorsInput.get().get(1);
-		assertEquals("gamma", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("parameter", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
-		String sXML = t.sXMLInput.get();
+		assertEquals("gamma", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("parameter", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
+		String xml = t.xMLInput.get();
 		assertEquals("<![CDATA[\n"+
 "<parameter id=\"kappa\" name=\"stateNode\" value=\"1.0\"/>\n"+
 "<parameter id=\"gamma\" value=\"3.0\"/>\n"+
-"]]>", sXML);
+"]]>", xml);
 
 		t = new BeautiSubTemplate();
 		// minimal template + connector + name + condition for 2 entries
@@ -128,19 +128,19 @@ public class BeautiSubTemplateTest extends TestCase {
 				);
 		assertEquals(2, t.connectorsInput.get().size());
 		c = t.connectorsInput.get().get(0);
-		assertEquals("kappa", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("stateNode", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
+		assertEquals("kappa", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("stateNode", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
 		c = t.connectorsInput.get().get(1);
-		assertEquals("gamma", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("parameter", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
-		sXML = t.sXMLInput.get();
+		assertEquals("gamma", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("parameter", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
+		xml = t.xMLInput.get();
 		assertEquals("<![CDATA[\n"+
 "<parameter id=\"kappa\" name=\"stateNode\" value=\"1.0\"/>\n"+
-"]]>", sXML);
+"]]>", xml);
 
 		t = new BeautiSubTemplate();
 		// minimal template + connector + name + condition for 2 entries
@@ -154,19 +154,19 @@ public class BeautiSubTemplateTest extends TestCase {
 				);
 		assertEquals(2, t.connectorsInput.get().size());
 		c = t.connectorsInput.get().get(1);
-		assertEquals("kappa", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("stateNode", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
+		assertEquals("kappa", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("stateNode", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
 		c = t.connectorsInput.get().get(0);
-		assertEquals("gamma", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("parameter", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
-		sXML = t.sXMLInput.get();
+		assertEquals("gamma", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("parameter", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
+		xml = t.xMLInput.get();
 		assertEquals("<![CDATA[\n"+
 "<parameter id=\"kappa\" name=\"stateNode\" value=\"1.0\"/>\n"+
-"]]>", sXML);
+"]]>", xml);
 	}
 	
 	@Test
@@ -190,28 +190,28 @@ public class BeautiSubTemplateTest extends TestCase {
 				);
 		assertEquals(4, t.connectorsInput.get().size());
 		BeautiConnector c = t.connectorsInput.get().get(0);
-		assertEquals("kappa", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("stateNode", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
+		assertEquals("kappa", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("stateNode", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
 		c = t.connectorsInput.get().get(1);
-		assertEquals("gamma", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("parameter", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
+		assertEquals("gamma", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("parameter", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
 		c = t.connectorsInput.get().get(2);
-		assertEquals("kappa", c.sSourceIDInput.get());
-		assertEquals("tracer", c.sTargetIDInput.get());
-		assertEquals("log", c.sInputNameInput.get());
-		assertEquals("gamma/estimate=true", c.sConditionInput.get());
+		assertEquals("kappa", c.sourceIDInput.get());
+		assertEquals("tracer", c.targetIDInput.get());
+		assertEquals("log", c.inputNameInput.get());
+		assertEquals("gamma/estimate=true", c.conditionInput.get());
 		c = t.connectorsInput.get().get(3);
-		assertEquals("gamma", c.sSourceIDInput.get());
-		assertEquals("tracer", c.sTargetIDInput.get());
-		assertEquals("log", c.sInputNameInput.get());
-		assertEquals("gamma/estimate=true", c.sConditionInput.get());
-		String sXML = t.sXMLInput.get();
+		assertEquals("gamma", c.sourceIDInput.get());
+		assertEquals("tracer", c.targetIDInput.get());
+		assertEquals("log", c.inputNameInput.get());
+		assertEquals("gamma/estimate=true", c.conditionInput.get());
+		String xml = t.xMLInput.get();
 		assertEquals("<![CDATA[      <parameter id=\"kappa\" name=\"stateNode\" value=\"1.0\"/>    <parameter id=\"gamma\" value=\"3.0\"/>              ]]>"
-, sXML);
+, xml);
 	}
 
 	@Test
@@ -231,27 +231,27 @@ public class BeautiSubTemplateTest extends TestCase {
 				);
 		assertEquals(4, t.connectorsInput.get().size());
 		BeautiConnector c = t.connectorsInput.get().get(0);
-		assertEquals("kappa", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("stateNode", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
+		assertEquals("kappa", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("stateNode", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
 		c = t.connectorsInput.get().get(1);
-		assertEquals("gamma", c.sSourceIDInput.get());
-		assertEquals("thestate", c.sTargetIDInput.get());
-		assertEquals("parameter", c.sInputNameInput.get());
-		assertEquals("gamma/estimate=true", c.sConditionInput.get());
+		assertEquals("gamma", c.sourceIDInput.get());
+		assertEquals("thestate", c.targetIDInput.get());
+		assertEquals("parameter", c.inputNameInput.get());
+		assertEquals("gamma/estimate=true", c.conditionInput.get());
 		c = t.connectorsInput.get().get(2);
-		assertEquals("kappa", c.sSourceIDInput.get());
-		assertEquals("tracer", c.sTargetIDInput.get());
-		assertEquals("log", c.sInputNameInput.get());
-		assertEquals("kappa/estimate=true", c.sConditionInput.get());
+		assertEquals("kappa", c.sourceIDInput.get());
+		assertEquals("tracer", c.targetIDInput.get());
+		assertEquals("log", c.inputNameInput.get());
+		assertEquals("kappa/estimate=true", c.conditionInput.get());
 		c = t.connectorsInput.get().get(3);
-		assertEquals("gamma", c.sSourceIDInput.get());
-		assertEquals("tracer", c.sTargetIDInput.get());
-		assertEquals("log", c.sInputNameInput.get());
-		assertEquals("gamma/estimate=true", c.sConditionInput.get());
-		String sXML = t.sXMLInput.get().replaceAll("\\s+", " ");
+		assertEquals("gamma", c.sourceIDInput.get());
+		assertEquals("tracer", c.targetIDInput.get());
+		assertEquals("log", c.inputNameInput.get());
+		assertEquals("gamma/estimate=true", c.conditionInput.get());
+		String xml = t.xMLInput.get().replaceAll("\\s+", " ");
 		assertEquals("<![CDATA[ <parameter id=\"kappa\" name=\"stateNode\" value=\"1.0\"/> <parameter id=\"gamma\" value=\"3.0\"/> ]]>"
-, sXML);
+, xml);
 	}
 }
diff --git a/src/test/beast/app/BeautiTest.java b/src/test/beast/app/BeautiTest.java
index e16b54a..6675833 100644
--- a/src/test/beast/app/BeautiTest.java
+++ b/src/test/beast/app/BeautiTest.java
@@ -5,22 +5,18 @@ import java.io.PrintStream;
 
 import org.junit.Test;
 
-import test.beast.integration.ExampleXmlParsingTest;
-
 import beast.app.beauti.Beauti;
 import beast.app.beauti.BeautiDoc;
-
-
-
 import junit.framework.TestCase;
+import test.beast.integration.ExampleXmlParsingTest;
 
 public class BeautiTest extends TestCase {
 	{
 		ExampleXmlParsingTest.setUpTestDir();
 	}
 	
-    String sFile = "test/tmp123x666.xml";
-    String sTemplateFile = "test/template123x666.xml";
+    String fileName = "test/tmp123x666.xml";
+    String templateFile = "test/template123x666.xml";
 
     @Test
     // test that beauti can merge an alignment with a template and write out a file
@@ -35,12 +31,12 @@ public class BeautiTest extends TestCase {
 
         // ignore test if no X11 display available
         if (!java.awt.GraphicsEnvironment.isHeadless()) {
-            File f = new File(sFile);
+            File f = new File(fileName);
             if (f.exists()) {
                 f.delete();
             }
-            Beauti.main(("-template templates/Standard.xml -nex examples/nexus/dna.nex -out " + sFile + " -exitaction writexml").split(" "));
-            f = new File(sFile);
+            Beauti.main(("-template templates/Standard.xml -nex examples/nexus/dna.nex -out " + fileName + " -exitaction writexml").split(" "));
+            f = new File(fileName);
             assertEquals(f.exists() && f.length() > 0, true);
         }
     }
@@ -56,12 +52,12 @@ public class BeautiTest extends TestCase {
         }
         // ignore test if no X11 display available
         if (!java.awt.GraphicsEnvironment.isHeadless()) {
-            File f = new File(sFile);
+            File f = new File(fileName);
             if (f.exists()) {
                 f.delete();
             }
-            Beauti.main(("-template templates/StarBeast.xml -nex examples/nexus/26.nex -nex examples/nexus/29.nex -out " + sFile + " -exitaction writexml").split(" "));
-            f = new File(sFile);
+            Beauti.main(("-template templates/StarBeast.xml -nex examples/nexus/26.nex -nex examples/nexus/29.nex -out " + fileName + " -exitaction writexml").split(" "));
+            f = new File(fileName);
             assertEquals(f.exists() && f.length() > 0, true);
         }
     }
@@ -130,21 +126,21 @@ public class BeautiTest extends TestCase {
     public void testCustomBatchMode() {
         BeautiDoc doc = new BeautiDoc();
         try {
-        	PrintStream out = new PrintStream(sTemplateFile);
+        	PrintStream out = new PrintStream(templateFile);
         	out.print(template);
         	out.close();
-            doc.processTemplate(sTemplateFile);
+            doc.processTemplate(templateFile);
         } catch (Exception e) {
             assertEquals(true, false);
         }
         // ignore test if no X11 display available
         if (!java.awt.GraphicsEnvironment.isHeadless()) {
-            File f = new File(sFile);
+            File f = new File(fileName);
             if (f.exists()) {
                 f.delete();
             }
-            Beauti.main(("-template " + sTemplateFile + " -nex examples/nexus/anolis.nex -out " + sFile + " -exitaction writexml").split(" "));
-            f = new File(sFile);
+            Beauti.main(("-template " + templateFile + " -nex examples/nexus/anolis.nex -out " + fileName + " -exitaction writexml").split(" "));
+            f = new File(fileName);
             assertEquals(f.exists() && f.length() > 0, true);
         }
     }
diff --git a/src/test/beast/app/beauti/BeautiBase.java b/src/test/beast/app/beauti/BeautiBase.java
index f003f68..d3f2eee 100644
--- a/src/test/beast/app/beauti/BeautiBase.java
+++ b/src/test/beast/app/beauti/BeautiBase.java
@@ -30,13 +30,13 @@ import org.fest.swing.junit.testcase.FestSwingJUnitTestCase;
 import beast.app.beauti.Beauti;
 import beast.app.beauti.BeautiDoc;
 import beast.app.util.Utils;
+import beast.core.BEASTObject;
 import beast.core.Distribution;
 import beast.core.Logger;
 import beast.core.MCMC;
 import beast.core.Operator;
 import beast.core.State;
 import beast.core.StateNode;
-import beast.core.BEASTObject;
 import beast.core.util.CompoundDistribution;
 import beast.util.XMLParser;
 
@@ -52,6 +52,7 @@ public class BeautiBase extends FestSwingJUnitTestCase {
 	protected Beauti beauti;
 	protected BeautiDoc doc;
 
+	@Override
 	protected void onSetUp() {
 		beautiFrame = new FrameFixture(robot(), createNewEditor());
 		beautiFrame.show();
@@ -64,6 +65,7 @@ public class BeautiBase extends FestSwingJUnitTestCase {
 	@RunsInEDT
 	private static JFrame createNewEditor() {
 		return execute(new GuiQuery<JFrame>() {
+			@Override
 			protected JFrame executeInEDT() throws Throwable {
 				Beauti beauti = Beauti.main2(new String[] {});
 				return beauti.frame;
@@ -102,9 +104,9 @@ public class BeautiBase extends FestSwingJUnitTestCase {
 		}
 		StringBuffer bf = new StringBuffer();
 		for (Object o : list) {
-			BEASTObject plugin = (BEASTObject) o;
+			BEASTObject beastObject = (BEASTObject) o;
 			bf.append('"');
-			bf.append(plugin.getID());
+			bf.append(beastObject.getID());
 			bf.append("\", ");
 		}
 		String str = bf.toString();
@@ -122,9 +124,9 @@ public class BeautiBase extends FestSwingJUnitTestCase {
 					found = true;
 				}
 			}
-			assertThat(found).as("Could not find plugin with ID " + id).isEqualTo(true);
+			assertThat(found).as("Could not find beastObject with ID " + id).isEqualTo(true);
 		}
-		assertThat(ids.length).as("list of plugins do not match").isEqualTo(priors.size());;
+		assertThat(ids.length).as("list of beastObjects do not match").isEqualTo(priors.size());;
 	}
 
 	private void asserListsEqual(List<?> list, String[] ids) {
@@ -138,7 +140,7 @@ public class BeautiBase extends FestSwingJUnitTestCase {
 					break;
 				}
 			}
-			assertThat(found).as("Could not find plugin with ID " + id).isEqualTo(true);
+			assertThat(found).as("Could not find beastObject with ID " + id).isEqualTo(true);
 		}
 		// check all items in list have a unique ie
 		Set<String> idsInList = new HashSet<String>();
@@ -169,7 +171,7 @@ public class BeautiBase extends FestSwingJUnitTestCase {
 					extraIDs.add(id);
 				}
 			}
-			assertThat(ids.length).as("list of plugins do not match: found extra items " + Arrays.toString(extraIDs.toArray())).isEqualTo(list.size());
+			assertThat(ids.length).as("list of beastObjects do not match: found extra items " + Arrays.toString(extraIDs.toArray())).isEqualTo(list.size());
 		}
 	}
 
@@ -273,7 +275,8 @@ public class BeautiBase extends FestSwingJUnitTestCase {
 		} else {
 			_file = new File(dir + "/" + file);
 			execute(new GuiTask() {
-		        protected void executeInEDT() {
+		        @Override
+				protected void executeInEDT() {
 		        	try {
 		        		beauti.doc.save(_file);
 		        	} catch (Exception e) {
@@ -303,7 +306,8 @@ public class BeautiBase extends FestSwingJUnitTestCase {
 			for (File file : files) {
 				_file = new File(dir + "/" + file.getName());
 				execute(new GuiTask() {
-			        protected void executeInEDT() {
+			        @Override
+					protected void executeInEDT() {
 			        	try {
 			        		beauti.doc.importNexus(_file);
 			    			beauti.refreshPanel();
diff --git a/src/test/beast/app/beauti/BeautiDivergenceDatingTest.java b/src/test/beast/app/beauti/BeautiDivergenceDatingTest.java
index b659289..a818b59 100644
--- a/src/test/beast/app/beauti/BeautiDivergenceDatingTest.java
+++ b/src/test/beast/app/beauti/BeautiDivergenceDatingTest.java
@@ -1,25 +1,36 @@
 package test.beast.app.beauti;
 
 
+import static org.fest.assertions.Assertions.assertThat;
+
+import java.awt.Component;
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+
 import org.fest.swing.data.Index;
 import org.fest.swing.data.TableCell;
 import org.fest.swing.finder.WindowFinder;
-import org.fest.swing.fixture.*;
+import org.fest.swing.fixture.DialogFixture;
+import org.fest.swing.fixture.JButtonFixture;
+import org.fest.swing.fixture.JCheckBoxFixture;
+import org.fest.swing.fixture.JComboBoxFixture;
+import org.fest.swing.fixture.JListFixture;
+import org.fest.swing.fixture.JOptionPaneFixture;
+import org.fest.swing.fixture.JTabbedPaneFixture;
+import org.fest.swing.fixture.JTableCellFixture;
+import org.fest.swing.fixture.JTableFixture;
+import org.fest.swing.fixture.JTextComponentFixture;
 import org.fest.swing.image.ScreenshotTaker;
 import org.junit.Test;
 
 import test.beast.beast2vs1.TestFramework;
 import test.beast.beast2vs1.trace.Expectation;
 
-import javax.swing.*;
-import java.awt.*;
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import static org.fest.assertions.Assertions.assertThat;
-
 public class BeautiDivergenceDatingTest extends BeautiBase {
     final static String PREFIX = "doc/tutorials/DivergenceDating/figures/BEAUti_";
 
@@ -91,7 +102,7 @@ public class BeautiDivergenceDatingTest extends BeautiBase {
         f.selectTab("Partitions");
         JTableCellFixture cell = beautiFrame.table().cell(TableCell.row(0).column(7));
         Component editor = cell.editor();
-        JComboBoxFixture comboBox = new JComboBoxFixture(robot(), (JComboBox) editor);
+        JComboBoxFixture comboBox = new JComboBoxFixture(robot(), (JComboBox<?>) editor);
         cell.startEditing();
         comboBox.selectAllText();
         comboBox.enterText("tree");
@@ -118,7 +129,7 @@ public class BeautiDivergenceDatingTest extends BeautiBase {
         warning("3b. and call the uncorrelated relaxed molecular clock \"clock\"");
         cell = beautiFrame.table().cell(TableCell.row(0).column(6));
         editor = cell.editor();
-        comboBox = new JComboBoxFixture(robot(), (JComboBox) editor);
+        comboBox = new JComboBoxFixture(robot(), (JComboBox<?>) editor);
         cell.startEditing();
         comboBox.selectAllText();
         comboBox.enterText("clock");
@@ -288,8 +299,8 @@ public class BeautiDivergenceDatingTest extends BeautiBase {
 		DivergenceDatingRunner(File file) {
 			super();
 			setUp(new String[]{"/x.xml"});
-			sDir = file.getPath();
-			sLogDir = "";
+			dirName = file.getPath();
+			logDir = "";
 			useSeed = false;
 			checkESS = false;
 			testFile = "primate-mtDNA";
@@ -420,7 +431,7 @@ public class BeautiDivergenceDatingTest extends BeautiBase {
             f.selectTab("Partitions");
             JTableCellFixture cell = beautiFrame.table().cell(TableCell.row(0).column(7));
             Component editor = cell.editor();
-            JComboBoxFixture comboBox = new JComboBoxFixture(robot(), (JComboBox) editor);
+            JComboBoxFixture comboBox = new JComboBoxFixture(robot(), (JComboBox<?>) editor);
             cell.startEditing();
             comboBox.selectAllText();
             comboBox.enterText("tree");
@@ -447,7 +458,7 @@ public class BeautiDivergenceDatingTest extends BeautiBase {
             warning("3b. and call the uncorrelated relaxed molecular clock \"clock\"");
             cell = beautiFrame.table().cell(TableCell.row(0).column(6));
             editor = cell.editor();
-            comboBox = new JComboBoxFixture(robot(), (JComboBox) editor);
+            comboBox = new JComboBoxFixture(robot(), (JComboBox<?>) editor);
             cell.startEditing();
             comboBox.selectAllText();
             comboBox.enterText("clock");
diff --git a/src/test/beast/app/beauti/BeautiRateTutorialTest.java b/src/test/beast/app/beauti/BeautiRateTutorialTest.java
index b8877e8..e2d8d5d 100644
--- a/src/test/beast/app/beauti/BeautiRateTutorialTest.java
+++ b/src/test/beast/app/beauti/BeautiRateTutorialTest.java
@@ -28,11 +28,10 @@ import org.fest.swing.fixture.JTableFixture;
 import org.fest.swing.image.ScreenshotTaker;
 import org.junit.Test;
 
+import beast.app.util.Utils;
 import test.beast.beast2vs1.TestFramework;
 import test.beast.beast2vs1.trace.Expectation;
 
-import beast.app.util.Utils;
-
 
 
 public class BeautiRateTutorialTest extends BeautiBase {
@@ -107,7 +106,7 @@ public class BeautiRateTutorialTest extends BeautiBase {
 		f.selectTab("Partitions");
 		JTableCellFixture cell = beautiFrame.table().cell(TableCell.row(0).column(7));
 		Component editor = cell.editor();
-		JComboBoxFixture comboBox = new JComboBoxFixture(robot(), (JComboBox) editor);
+		JComboBoxFixture comboBox = new JComboBoxFixture(robot(), (JComboBox<?>) editor);
 		cell.startEditing();
 		comboBox.selectAllText();
 		comboBox.enterText("tree");
@@ -131,7 +130,7 @@ public class BeautiRateTutorialTest extends BeautiBase {
 		warning("2b. and call the uncorrelated relaxed molecular clock \"clock\"");
 		cell = beautiFrame.table().cell(TableCell.row(0).column(6));
 		editor = cell.editor();
-		comboBox = new JComboBoxFixture(robot(), (JComboBox) editor);
+		comboBox = new JComboBoxFixture(robot(), (JComboBox<?>) editor);
 		cell.startEditing();
 		comboBox.selectAllText();
 		comboBox.enterText("clock");
@@ -261,8 +260,8 @@ public class BeautiRateTutorialTest extends BeautiBase {
 		MEPRunner(File file) {
 			super();
 			setUp(new String[]{"/x.xml"});
-			sDir = file.getPath();
-			sLogDir = "";
+			dirName = file.getPath();
+			logDir = "";
 			useSeed = false;
 	        checkESS = false;
 			testFile = "RSV2";
@@ -296,6 +295,7 @@ public class BeautiRateTutorialTest extends BeautiBase {
     
 
 
+	
 	@Test
 	public void MEPBSPTutorial() throws InterruptedException {
 		if (true) {return;}
@@ -317,7 +317,8 @@ public class BeautiRateTutorialTest extends BeautiBase {
 		} else {
 			_file = new File(dir + "/" + file);
 			execute(new GuiTask() {
-		        protected void executeInEDT() {
+		        @Override
+				protected void executeInEDT() {
 	                doc.newAnalysis();
 	                doc.setFileName(_file.getAbsolutePath());
 	                try {
@@ -343,11 +344,11 @@ public class BeautiRateTutorialTest extends BeautiBase {
 		warning("3. change group and population size parameters");
 		beautiFrame.menuItemWithPath("View","Show Initialization panel").click();
 		
-		beautiFrame.button("bPopSizes.t:tree.editButton").click();
+		beautiFrame.button("isPopSizes.t:tree.editButton").click();
 		beautiFrame.textBox("dimension").selectAll().setText("3");
-		beautiFrame.button("bPopSizes.t:tree.editButton").click();
+		beautiFrame.button("isPopSizes.t:tree.editButton").click();
 		
-		beautiFrame.button("bGroupSizes.t:tree.editButton").click();
+		beautiFrame.button("isGroupSizes.t:tree.editButton").click();
 		beautiFrame.textBox("dimension").selectAll().setText("3");
 		screenshotTaker.saveComponentAsPng(beauti.frame, PREFIX + "init.png");
 		printBeautiState(f);
@@ -383,6 +384,7 @@ public class BeautiRateTutorialTest extends BeautiBase {
 		
 		}
 	}
+	
 
 }
 
diff --git a/src/test/beast/app/beauti/BeautiSimpleTest.java b/src/test/beast/app/beauti/BeautiSimpleTest.java
index edd542d..ad602d0 100644
--- a/src/test/beast/app/beauti/BeautiSimpleTest.java
+++ b/src/test/beast/app/beauti/BeautiSimpleTest.java
@@ -2,29 +2,17 @@ package test.beast.app.beauti;
 
 
 import static org.fest.assertions.Assertions.assertThat;
-import static org.fest.swing.driver.ComponentStateValidator.validateIsEnabledAndShowing;
-import static org.fest.swing.edt.GuiActionRunner.execute;
-import static org.fest.swing.finder.JFileChooserFinder.findFileChooser;
 
-import java.awt.Button;
 import java.awt.Component;
-import java.awt.FileDialog;
 import java.io.File;
 import java.util.Arrays;
 
 import javax.swing.JComboBox;
 
-import org.fest.swing.core.ComponentMatcher;
-import org.fest.swing.core.GenericTypeMatcher;
 import org.fest.swing.data.Index;
 import org.fest.swing.data.TableCell;
-import org.fest.swing.edt.GuiTask;
-import org.fest.swing.finder.DialogFinder;
-import org.fest.swing.finder.WindowFinder;
-import org.fest.swing.fixture.DialogFixture;
 import org.fest.swing.fixture.JCheckBoxFixture;
 import org.fest.swing.fixture.JComboBoxFixture;
-import org.fest.swing.fixture.JFileChooserFixture;
 import org.fest.swing.fixture.JTabbedPaneFixture;
 import org.fest.swing.fixture.JTableCellFixture;
 import org.fest.swing.fixture.JTableFixture;
@@ -32,8 +20,6 @@ import org.fest.swing.fixture.JTextComponentFixture;
 import org.fest.swing.image.ScreenshotTaker;
 import org.junit.Test;
 
-import beast.app.beauti.TaxonSetDialog;
-
 
 
 public class BeautiSimpleTest extends BeautiBase {
@@ -106,7 +92,7 @@ public class BeautiSimpleTest extends BeautiBase {
 		f.selectTab("Partitions");
 		JTableCellFixture cell = beautiFrame.table().cell(TableCell.row(0).column(7));
 		Component editor = cell.editor();
-		JComboBoxFixture comboBox = new JComboBoxFixture(robot(), (JComboBox) editor);
+		JComboBoxFixture comboBox = new JComboBoxFixture(robot(), (JComboBox<?>) editor);
 		cell.startEditing();
 		comboBox.selectAllText();
 		comboBox.enterText("tree");
diff --git a/src/test/beast/app/beauti/BeautiStarBeastTest.java b/src/test/beast/app/beauti/BeautiStarBeastTest.java
index 50a7992..fb93ff2 100644
--- a/src/test/beast/app/beauti/BeautiStarBeastTest.java
+++ b/src/test/beast/app/beauti/BeautiStarBeastTest.java
@@ -7,7 +7,6 @@ import java.io.File;
 import java.util.ArrayList;
 import java.util.List;
 
-
 import org.fest.swing.fixture.JComboBoxFixture;
 import org.fest.swing.fixture.JMenuItemFixture;
 import org.fest.swing.fixture.JOptionPaneFixture;
@@ -139,8 +138,8 @@ public class BeautiStarBeastTest extends BeautiBase {
 		StarBEASTRunner(File file) {
 			super();
 			setUp(new String[]{"/x.xml"});
-			sDir = file.getPath();
-			sLogDir = "";
+			dirName = file.getPath();
+			logDir = "";
 			testFile = "beast_";
 			checkESS = false;
 		}
diff --git a/src/test/beast/app/beauti/CloneTest.java b/src/test/beast/app/beauti/CloneTest.java
index 0ccb4b7..f0acfde 100644
--- a/src/test/beast/app/beauti/CloneTest.java
+++ b/src/test/beast/app/beauti/CloneTest.java
@@ -10,7 +10,6 @@ import org.fest.swing.fixture.JButtonFixture;
 import org.fest.swing.fixture.JCheckBoxFixture;
 import org.fest.swing.fixture.JComboBoxFixture;
 import org.fest.swing.fixture.JListFixture;
-import org.fest.swing.fixture.JOptionPaneFixture;
 import org.fest.swing.fixture.JTabbedPaneFixture;
 import org.fest.swing.fixture.JTextComponentFixture;
 import org.junit.Test;
diff --git a/src/test/beast/app/beauti/FixedMeanRateTest.java b/src/test/beast/app/beauti/FixedMeanRateTest.java
index 3cef921..53740a4 100644
--- a/src/test/beast/app/beauti/FixedMeanRateTest.java
+++ b/src/test/beast/app/beauti/FixedMeanRateTest.java
@@ -4,14 +4,12 @@ package test.beast.app.beauti;
 import java.io.File;
 import java.util.List;
 
-import org.fest.assertions.AssertExtension;
 import org.fest.swing.data.TableCell;
 import org.fest.swing.fixture.JTabbedPaneFixture;
 import org.junit.Test;
 
-import junit.framework.TestCase;
-import beast.app.beauti.SiteModelInputEditor;
 import beast.evolution.operators.DeltaExchangeOperator;
+import junit.framework.Assert;
 
 /** test how the FixedMeanRate flag interact with link/unlink **/
 public class FixedMeanRateTest extends BeautiBase {
@@ -44,7 +42,7 @@ public class FixedMeanRateTest extends BeautiBase {
 		DeltaExchangeOperator operator = (DeltaExchangeOperator) beauti.doc.pluginmap.get("FixMeanMutationRatesOperator");
 		int nrOfParameters = operator.parameterInput.get().size();
 		if(nrOfParameters != 2) {
-			throw new Exception("Expected 2 parameters for deltaExchangeOperator, not " + nrOfParameters);
+			throw new IllegalArgumentException("Expected 2 parameters for deltaExchangeOperator, not " + nrOfParameters);
 		}
 	}
 	
@@ -68,14 +66,14 @@ public class FixedMeanRateTest extends BeautiBase {
 		DeltaExchangeOperator operator = (DeltaExchangeOperator) beauti.doc.pluginmap.get("FixMeanMutationRatesOperator");
 		int nrOfParameters = operator.parameterInput.get().size();
 		if (nrOfParameters != 3) {
-			throw new Exception("Expected 3 parameters for deltaExchangeOperator, not " + nrOfParameters);
+			throw new IllegalArgumentException("Expected 3 parameters for deltaExchangeOperator, not " + nrOfParameters);
 		}
 
 		List<Integer> weights = operator.parameterWeightsInput.get().valuesInput.get();
-		TestCase.assertEquals(weights.size(), 3);
-		TestCase.assertEquals(weights.get(0), (Integer)614);
-		TestCase.assertEquals(weights.get(1), (Integer)601);
-		TestCase.assertEquals(weights.get(2), (Integer)819);
+		Assert.assertEquals(weights.size(), 3);
+		Assert.assertEquals(weights.get(0), (Integer)614);
+		Assert.assertEquals(weights.get(1), (Integer)601);
+		Assert.assertEquals(weights.get(2), (Integer)819);
 
 		beautiFrame.table().selectCells(TableCell.row(0).column(1), TableCell.row(2).column(1));
 		beautiFrame.button("Link Site Models").click();
@@ -85,12 +83,12 @@ public class FixedMeanRateTest extends BeautiBase {
 		//SiteModelInputEditor.customConnector(doc);
 		
 		if (nrOfParameters != 2) {
-			throw new Exception("Expected 2 parameters for deltaExchangeOperator, not " + nrOfParameters);
+			throw new IllegalArgumentException("Expected 2 parameters for deltaExchangeOperator, not " + nrOfParameters);
 		}
 		weights = operator.parameterWeightsInput.get().valuesInput.get();
-		TestCase.assertEquals(weights.size(), 2);
-		TestCase.assertEquals(weights.get(0), (Integer)(614 + 819));
-		TestCase.assertEquals(weights.get(1), (Integer)601);
+		Assert.assertEquals(weights.size(), 2);
+		Assert.assertEquals(weights.get(0), (Integer)(614 + 819));
+		Assert.assertEquals(weights.get(1), (Integer)601);
 
 		makeSureXMLParses();
 	}
diff --git a/src/test/beast/app/beauti/LinkUnlinkTest.java b/src/test/beast/app/beauti/LinkUnlinkTest.java
index b7c8355..52443f2 100644
--- a/src/test/beast/app/beauti/LinkUnlinkTest.java
+++ b/src/test/beast/app/beauti/LinkUnlinkTest.java
@@ -5,11 +5,11 @@ package test.beast.app.beauti;
 
 import java.io.File;
 
+import org.fest.assertions.Assertions;
 import org.fest.swing.data.TableCell;
 import org.fest.swing.fixture.JTabbedPaneFixture;
 import org.fest.swing.fixture.JTableFixture;
 import org.junit.Test;
-import org.fest.assertions.Assertions;
 
 public class LinkUnlinkTest extends BeautiBase {
 
diff --git a/src/test/beast/beast2vs1/ClockModelTest.java b/src/test/beast/beast2vs1/ClockModelTest.java
index 05ce3dc..ce5b371 100644
--- a/src/test/beast/beast2vs1/ClockModelTest.java
+++ b/src/test/beast/beast2vs1/ClockModelTest.java
@@ -35,7 +35,8 @@ public class ClockModelTest extends TestFramework {
         super.setUp(XML_FILES);
     }
 
-    protected List<Expectation> giveExpectations(int index_XML) throws Exception {
+    @Override
+	protected List<Expectation> giveExpectations(int index_XML) throws Exception {
         List<Expectation> expList = new ArrayList<Expectation>();
 
         // all values below are from BEAST 1.7
diff --git a/src/test/beast/beast2vs1/StarBEASTTest.java b/src/test/beast/beast2vs1/StarBEASTTest.java
index f2cca5d..3130db0 100644
--- a/src/test/beast/beast2vs1/StarBEASTTest.java
+++ b/src/test/beast/beast2vs1/StarBEASTTest.java
@@ -45,7 +45,8 @@ public class StarBEASTTest extends TestFramework {
         super.setUp(XML_FILES);
     }
 
-    protected List<Expectation> giveExpectations(int index_XML) throws Exception {
+    @Override
+	protected List<Expectation> giveExpectations(int index_XML) throws Exception {
         List<Expectation> expList = new ArrayList<Expectation>();
 
         // all values below are from BEAST 1.6.2
diff --git a/src/test/beast/beast2vs1/SubstitutionModelTest.java b/src/test/beast/beast2vs1/SubstitutionModelTest.java
index ce31dcb..4c3136c 100644
--- a/src/test/beast/beast2vs1/SubstitutionModelTest.java
+++ b/src/test/beast/beast2vs1/SubstitutionModelTest.java
@@ -35,7 +35,8 @@ public class SubstitutionModelTest extends TestFramework {
         super.setUp(XML_FILES);
     }
 
-    protected List<Expectation> giveExpectations(int index_XML) throws Exception {
+    @Override
+	protected List<Expectation> giveExpectations(int index_XML) throws Exception {
         List<Expectation> expList = new ArrayList<Expectation>();
 
         // all values below are from BEAST 1.7
diff --git a/src/test/beast/beast2vs1/TaxonOrderTest.java b/src/test/beast/beast2vs1/TaxonOrderTest.java
index 4da0adb..9659695 100644
--- a/src/test/beast/beast2vs1/TaxonOrderTest.java
+++ b/src/test/beast/beast2vs1/TaxonOrderTest.java
@@ -20,7 +20,8 @@ public class TaxonOrderTest extends TestFramework {
         super.setUp(XML_FILES);
     }
 
-    protected List<Expectation> giveExpectations(int index_XML) throws Exception {
+    @Override
+	protected List<Expectation> giveExpectations(int index_XML) throws Exception {
         List<Expectation> expList = new ArrayList<Expectation>();
 
         // all values below are from BEAST2/examples/testStarBeast.xml
diff --git a/src/test/beast/beast2vs1/TestFramework.java b/src/test/beast/beast2vs1/TestFramework.java
index 560cb65..71411fd 100644
--- a/src/test/beast/beast2vs1/TestFramework.java
+++ b/src/test/beast/beast2vs1/TestFramework.java
@@ -1,7 +1,5 @@
 package test.beast.beast2vs1;
 
-import junit.framework.TestCase;
-
 import java.io.File;
 import java.util.List;
 
@@ -9,6 +7,8 @@ import beagle.BeagleFlag;
 import beast.core.Logger;
 import beast.util.Randomizer;
 import beast.util.XMLParser;
+import junit.framework.Assert;
+import junit.framework.TestCase;
 import test.beast.beast2vs1.trace.Expectation;
 import test.beast.beast2vs1.trace.LogAnalyser;
 
@@ -18,15 +18,15 @@ public abstract class TestFramework extends TestCase {
 
     protected abstract List<Expectation> giveExpectations(int index_XML) throws Exception;
 
-    public String sDir;
-    public String sLogDir;
+    public String dirName;
+    public String logDir;
     public String testFile = "/test.";
     public boolean useSeed = true;
     public boolean checkESS = true;
     
     public TestFramework() {
-    	sDir = System.getProperty("user.dir") + "/examples/beast2vs1/";
-    	sLogDir = System.getProperty("user.dir");
+    	dirName = System.getProperty("user.dir") + "/examples/beast2vs1/";
+    	logDir = System.getProperty("user.dir");
     }
     
     protected void setUp(String[] xmls) { // throws Exception {
@@ -47,32 +47,32 @@ public abstract class TestFramework extends TestCase {
         System.setProperty("beagle.preferred.flags", Long.toString(beagleFlags));
 
 
-        String sFileName = sDir + xmls[index_XML];
+        String fileName = dirName + xmls[index_XML];
 
-        System.out.println("Processing " + sFileName);
+        System.out.println("Processing " + fileName);
         XMLParser parser = new XMLParser();
-        beast.core.Runnable runable = parser.parseFile(new File(sFileName));
+        beast.core.Runnable runable = parser.parseFile(new File(fileName));
         runable.setStateFile("tmp.state", false);
 //		   runable.setInputValue("preBurnin", 0);
 //		   runable.setInputValue("chainLength", 1000);
         runable.run();
 
-        String logFile = sLogDir + testFile + (useSeed ? SEED : "") + ".log";
+        String logFile = logDir + testFile + (useSeed ? SEED : "") + ".log";
         System.out.println("\nAnalysing log " + logFile);
         LogAnalyser logAnalyser = new LogAnalyser(logFile, giveExpectations(index_XML)); // burnIn = 0.1 * maxState
 
         for (Expectation expectation : logAnalyser.m_pExpectations.get()) {
-            TestCase.assertTrue(xmls[index_XML] + ": Expected " + expectation.traceName.get() + " delta mean: "
+            Assert.assertTrue(xmls[index_XML] + ": Expected " + expectation.traceName.get() + " delta mean: "
                     + expectation.expValue.get() + " - " + expectation.getTraceStatistics().getMean()
                     + " <= delta stdErr: 2*(" + expectation.getStdError() + " + "
                     + expectation.getTraceStatistics().getStdErrorOfMean() + ")", expectation.isPassed());
 
             if (checkESS)
-            	TestCase.assertTrue(xmls[index_XML] + ":  has very low effective sample sizes (ESS) "
+            	Assert.assertTrue(xmls[index_XML] + ":  has very low effective sample sizes (ESS) "
                     + expectation.getTraceStatistics().getESS(), expectation.isValid());
         }
 
-        System.out.println("\nSucceed " + sFileName);
+        System.out.println("\nSucceed " + fileName);
         System.out.println("\n***************************************\n");
 //            }
 //        }
diff --git a/src/test/beast/beast2vs1/TipTimeTest.java b/src/test/beast/beast2vs1/TipTimeTest.java
index 4f332cc..b78cac5 100644
--- a/src/test/beast/beast2vs1/TipTimeTest.java
+++ b/src/test/beast/beast2vs1/TipTimeTest.java
@@ -38,7 +38,8 @@ public class TipTimeTest extends TestFramework {
         super.setUp(XML_FILES);
     }
 
-    protected List<Expectation> giveExpectations(int index_XML) throws Exception {
+    @Override
+	protected List<Expectation> giveExpectations(int index_XML) throws Exception {
         List<Expectation> expList = new ArrayList<Expectation>();
 
         // all values below are from BEAST 1.6.2
diff --git a/src/test/beast/beast2vs1/TreePriorTest.java b/src/test/beast/beast2vs1/TreePriorTest.java
index 3c37d34..5bbefab 100644
--- a/src/test/beast/beast2vs1/TreePriorTest.java
+++ b/src/test/beast/beast2vs1/TreePriorTest.java
@@ -55,7 +55,8 @@ public class TreePriorTest extends TestFramework {
         super.setUp(XML_FILES);
     }
 
-    protected List<Expectation> giveExpectations(int index_XML) throws Exception {
+    @Override
+	protected List<Expectation> giveExpectations(int index_XML) throws Exception {
         List<Expectation> expList = new ArrayList<Expectation>();
 
         // all values below are from BEAST 1.7
diff --git a/src/test/beast/beast2vs1/TreeTest.java b/src/test/beast/beast2vs1/TreeTest.java
index bd0e4de..ee514e0 100644
--- a/src/test/beast/beast2vs1/TreeTest.java
+++ b/src/test/beast/beast2vs1/TreeTest.java
@@ -26,7 +26,8 @@ public class TreeTest extends TestFramework {
         super.setUp(XML_FILES);
     }
 
-    protected List<Expectation> giveExpectations(int index_XML) throws Exception {
+    @Override
+	protected List<Expectation> giveExpectations(int index_XML) throws Exception {
         List<Expectation> expList = new ArrayList<Expectation>();
 
         // all values below are from BEAST 1.7
diff --git a/src/test/beast/beast2vs1/trace/DiscreteStatistics.java b/src/test/beast/beast2vs1/trace/DiscreteStatistics.java
index 56c2509..f98fd00 100644
--- a/src/test/beast/beast2vs1/trace/DiscreteStatistics.java
+++ b/src/test/beast/beast2vs1/trace/DiscreteStatistics.java
@@ -52,7 +52,7 @@ public class DiscreteStatistics {
             }
         }
 
-        return m / (double) count;
+        return m / count;
     }
 
     /**
@@ -138,7 +138,7 @@ public class DiscreteStatistics {
             count = count - 1; // for ML estimate
         }
 
-        return var / (double) count;
+        return var / count;
     }
 
 
@@ -149,7 +149,6 @@ public class DiscreteStatistics {
      * @param y list of numbers
      * @return covariance of x and y
      */
-    @SuppressWarnings({"SuspiciousNameCombination"})
     public static double covariance(double[] x, double[] y) {
 
         return covariance(x, y, mean(x), mean(y), stdev(x), stdev(y));
@@ -239,7 +238,7 @@ public class DiscreteStatistics {
      * @return variance of x (ML estimator)
      */
     public static double varianceSampleMean(double[] x, double mean) {
-        return variance(x, mean) / (double) x.length;
+        return variance(x, mean) / x.length;
     }
 
     /**
@@ -249,7 +248,7 @@ public class DiscreteStatistics {
      * @return variance of x (ML estimator)
      */
     public static double varianceSampleMean(double[] x) {
-        return variance(x) / (double) x.length;
+        return variance(x) / x.length;
     }
 
 
@@ -319,7 +318,7 @@ public class DiscreteStatistics {
         double minRange = Double.MAX_VALUE;
         int hpdIndex = 0;
 
-        final int diff = (int) Math.round(proportion * (double) x.length);
+        final int diff = (int) Math.round(proportion * x.length);
         for (int i = 0; i <= (x.length - diff); i++) {
             final double minValue = x[indices[i]];
             final double maxValue = x[indices[i + diff - 1]];
@@ -389,6 +388,6 @@ public class DiscreteStatistics {
             gm += Math.log(x[i]);
         }
 
-        return Math.exp(gm / (double) len);
+        return Math.exp(gm / len);
     }
 }
diff --git a/src/test/beast/beast2vs1/trace/Expectation.java b/src/test/beast/beast2vs1/trace/Expectation.java
index 5d4a885..df9acb0 100644
--- a/src/test/beast/beast2vs1/trace/Expectation.java
+++ b/src/test/beast/beast2vs1/trace/Expectation.java
@@ -1,9 +1,9 @@
 package test.beast.beast2vs1.trace;
 
+import beast.core.BEASTObject;
 import beast.core.Citation;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.BEASTObject;
 import beast.core.Input.Validate;
 
 
@@ -14,13 +14,13 @@ import beast.core.Input.Validate;
 @Citation("Created by Walter Xie")
 public class Expectation extends BEASTObject {
 
-    public Input<String> traceName = new Input<String>("traceName", "The trace name of a loggable plugin", Validate.REQUIRED);
+    public Input<String> traceName = new Input<>("traceName", "The trace name of a loggable beastObject", Validate.REQUIRED);
 
     public Input<Double> expValue =
-            new Input<Double>("expectedValue", "The expected value of the referred loggable plugin", Validate.REQUIRED);
+            new Input<>("expectedValue", "The expected value of the referred loggable beastObject", Validate.REQUIRED);
 
     public Input<Double> standErrorOfMean =
-            new Input<Double>("stdError", "The expected standard error of mean. If not given, it will estimate error from log",
+            new Input<>("stdError", "The expected standard error of mean. If not given, it will estimate error from log",
                     Validate.REQUIRED);
 
     private boolean isPassed = true; // assert result
@@ -83,12 +83,13 @@ public class Expectation extends BEASTObject {
 //        return stderr;
     }
 
-    public String toString() {
+    @Override
+	public String toString() {
         return traceName.get() + " " + expValue.get();
     }
 
 	@Override
-	public void initAndValidate() throws Exception {
+	public void initAndValidate() {
 		// TODO Auto-generated method stub
 		
 	}
diff --git a/src/test/beast/beast2vs1/trace/LogAnalyser.java b/src/test/beast/beast2vs1/trace/LogAnalyser.java
index 29368ec..a29be29 100644
--- a/src/test/beast/beast2vs1/trace/LogAnalyser.java
+++ b/src/test/beast/beast2vs1/trace/LogAnalyser.java
@@ -31,8 +31,11 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
-import beast.core.*;
+import beast.core.Citation;
+import beast.core.Description;
+import beast.core.Input;
 import beast.core.Input.Validate;
+import beast.core.MCMC;
 import beast.core.Runnable;
 
 
@@ -42,22 +45,22 @@ import beast.core.Runnable;
 @Citation("Created by Alexei Drummond and modified by Walter Xie")
 public class LogAnalyser extends Runnable {
     public Input<String> m_sFileName =
-            new Input<String>("fileName", "Name of the log file to be analysed", Validate.REQUIRED);
+            new Input<>("fileName", "Name of the log file to be analysed", Validate.REQUIRED);
     public Input<Integer> m_iBurnIn =
-            new Input<Integer>("burnIn", "Number of burn in samples taken before log statistics analysis. " +
+            new Input<>("burnIn", "Number of burn in samples taken before log statistics analysis. " +
                     "If burnIn = -1 then burnIn = 0.1 * maxState.", -1);
     public Input<Boolean> m_bDisplayStat =
-            new Input<Boolean>("displayStatistics", "Display a brief statistics result", true);
+            new Input<>("displayStatistics", "Display a brief statistics result", true);
     public Input<Boolean> m_bDisplayAll =
-            new Input<Boolean>("displayAll", "Display all availble statistics result", false);
+            new Input<>("displayAll", "Display all availble statistics result", false);
     public Input<Boolean> m_bReport =
-            new Input<Boolean>("report", "Display all availble information", false);
+            new Input<>("report", "Display all availble information", false);
 
-    public Input<List<Expectation>> m_pExpectations = new Input<List<Expectation>>("expectation",
-            "Expectation of log statistics analysis regarding a loggable plugin.",
+    public Input<List<Expectation>> m_pExpectations = new Input<>("expectation",
+            "Expectation of log statistics analysis regarding a loggable beastObject.",
             new ArrayList<Expectation>(), Validate.REQUIRED);
-    public Input<MCMC> m_pMCMC = new Input<MCMC>("expectation",
-            "Expectation of log statistics analysis regarding a loggable plugin.", Validate.REQUIRED);
+    public Input<MCMC> m_pMCMC = new Input<>("expectation",
+            "Expectation of log statistics analysis regarding a loggable beastObject.", Validate.REQUIRED);
 
 //    <run spec='beast.trace.LogAnalyser' fileName="test.$(seed).log" report="true">
 //        <input idref='MCMC'/>   
@@ -83,7 +86,7 @@ public class LogAnalyser extends Runnable {
     }
 
     @Override
-    public void initAndValidate() throws Exception {
+    public void initAndValidate() {
 
     }
 
diff --git a/src/test/beast/beast2vs1/trace/LogFileTraces.java b/src/test/beast/beast2vs1/trace/LogFileTraces.java
index a03b831..db6d9c7 100644
--- a/src/test/beast/beast2vs1/trace/LogFileTraces.java
+++ b/src/test/beast/beast2vs1/trace/LogFileTraces.java
@@ -147,6 +147,7 @@ public class LogFileTraces {
                 }
 
             } catch (NumberFormatException nfe) {
+                reader.close();
                 throw new TraceException("State " + state + ":Expected real value in column " + reader.getLineNumber());
             }
 
@@ -157,11 +158,13 @@ public class LogFileTraces {
                     try {
                         valuesList.get(i).add(Double.parseDouble(value));
                     } catch (NumberFormatException nfe) {
+                        reader.close();
                         throw new TraceException("State " + state + ": Expected correct number type (Double) in column "
                                 + (i + 1) + " (Line " + reader.getLineNumber() + ")");
                     }
 
                 } else {
+                    reader.close();
                     throw new TraceException("State " + state + ": missing values at line " + reader.getLineNumber());
                 }
             }
@@ -170,6 +173,7 @@ public class LogFileTraces {
         }
 
         burnIn = (int) (0.1 * lastState);
+        reader.close();
     }
 
     /**
diff --git a/src/test/beast/beast2vs1/trace/NumberFormatter.java b/src/test/beast/beast2vs1/trace/NumberFormatter.java
index ad92809..94fa135 100644
--- a/src/test/beast/beast2vs1/trace/NumberFormatter.java
+++ b/src/test/beast/beast2vs1/trace/NumberFormatter.java
@@ -64,7 +64,7 @@ public class NumberFormatter {
         cutoffTable = new double[sf];
         long num = 10;
         for (int i = 0; i < cutoffTable.length; i++) {
-            cutoffTable[i] = (double) num;
+            cutoffTable[i] = num;
             num *= 10;
         }
         decimalFormat.setMinimumIntegerDigits(1);
diff --git a/src/test/beast/beast2vs1/trace/TraceException.java b/src/test/beast/beast2vs1/trace/TraceException.java
index 1d96f63..2cda5db 100644
--- a/src/test/beast/beast2vs1/trace/TraceException.java
+++ b/src/test/beast/beast2vs1/trace/TraceException.java
@@ -33,7 +33,9 @@ package test.beast.beast2vs1.trace;
  */
 
 public class TraceException extends Exception {
-    public TraceException() {
+	private static final long serialVersionUID = 1L;
+
+	public TraceException() {
         super();
     }
 
diff --git a/src/test/beast/beast2vs1/trace/TraceStatistics.java b/src/test/beast/beast2vs1/trace/TraceStatistics.java
index 475b301..5b4610a 100644
--- a/src/test/beast/beast2vs1/trace/TraceStatistics.java
+++ b/src/test/beast/beast2vs1/trace/TraceStatistics.java
@@ -113,7 +113,7 @@ public class TraceStatistics {
                 //varGammaStat[lag] += (del1*del1*del2*del2);
             }
 
-            gammaStat[lag] /= ((double) (samples - lag));
+            gammaStat[lag] /= (samples - lag);
             //varGammaStat[lag] /= ((double) samples-lag);
             //varGammaStat[lag] -= (gammaStat[0] * gammaStat[0]);
 
@@ -141,7 +141,7 @@ public class TraceStatistics {
         // effective sample size
         ESS = (stepSize * samples) / autoCorrelationTime;
         // standard deviation of autocorrelation time
-        stdevAutoCorrelationTime = (2.0 * Math.sqrt(2.0 * (2.0 * (double) (maxLag + 1)) / samples) * (varStat / gammaStat[0]) * stepSize);
+        stdevAutoCorrelationTime = (2.0 * Math.sqrt(2.0 * (2.0 * (maxLag + 1)) / samples) * (varStat / gammaStat[0]) * stepSize);
 
         isValid = true;
     }
diff --git a/src/test/beast/beast2vs1/trace/TraceType.java b/src/test/beast/beast2vs1/trace/TraceType.java
index 32a7ef5..77cb8f1 100644
--- a/src/test/beast/beast2vs1/trace/TraceType.java
+++ b/src/test/beast/beast2vs1/trace/TraceType.java
@@ -9,13 +9,14 @@ public enum TraceType {
     INTEGER("integer", "I", Integer.class),
     STRING("string", "S", String.class);
 
-    TraceType(String name, String brief, Class type) {
+    TraceType(String name, String brief, Class<?> type) {
         this.name = name;
         this.brief = brief;
         this.type = type;
     }
 
-    public String toString() {
+    @Override
+	public String toString() {
         return name;
     }
 
@@ -23,11 +24,11 @@ public enum TraceType {
         return brief;
     }
 
-    public Class getType() {
+    public Class<?> getType() {
         return type;
     }
 
     private final String name;
     private final String brief;
-    private final Class type;
+    private final Class<?> type;
 }
diff --git a/src/test/beast/beast2vs1/trace/TrimLineReader.java b/src/test/beast/beast2vs1/trace/TrimLineReader.java
index 410f65c..db98a7b 100644
--- a/src/test/beast/beast2vs1/trace/TrimLineReader.java
+++ b/src/test/beast/beast2vs1/trace/TrimLineReader.java
@@ -16,7 +16,8 @@ public class TrimLineReader extends BufferedReader {
         super(reader);
     }
 
-    public String readLine() throws IOException {
+    @Override
+	public String readLine() throws IOException {
         lineNumber += 1;
         String line = super.readLine();
         if (line != null) return line.trim();
diff --git a/src/test/beast/core/BEASTInterfaceTest.java b/src/test/beast/core/BEASTInterfaceTest.java
index 341f4b9..1b5e5c5 100644
--- a/src/test/beast/core/BEASTInterfaceTest.java
+++ b/src/test/beast/core/BEASTInterfaceTest.java
@@ -1,14 +1,15 @@
 package test.beast.core;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 import org.junit.Test;
 
 import beast.core.BEASTInterface;
-import beast.core.BEASTObject;
 import beast.core.Citation;
 import beast.core.Description;
 import beast.core.Input;
@@ -20,10 +21,11 @@ public class BEASTInterfaceTest extends TestCase {
 	@Description("class that impements BEASTInterface but is not a BEASTObject")
 	@Citation("this is a dummy citation")
 	public class BEASTi implements BEASTInterface {
-		public Input<String> msgInput = new Input<String>("value", "message for this BEASTi object", Validate.REQUIRED);
-		public Input<BEASTi> beastiInput = new Input<BEASTi>("other", "link to another BEASTi object");
+		final public Input<String> msgInput = new Input<>("value", "message for this BEASTi object", Validate.REQUIRED);
+		final public Input<BEASTi> beastiInput = new Input<>("other", "link to another BEASTi object");
 		String ID;
 		Set<BEASTInterface> outputs = new HashSet<BEASTInterface>();
+		Map<String, Input<?>> inputs;
 
 		@Override
 		public String getID() {
@@ -36,13 +38,23 @@ public class BEASTInterfaceTest extends TestCase {
 		}
 
 		@Override
-		public Set getOutputs() {
+		public Set<BEASTInterface> getOutputs() {
 			return outputs;
 		}
 
 		@Override
-		public void initAndValidate() throws Exception {
-			// nothting to do;
+		public void initAndValidate() {
+			// nothing to do;
+		}
+
+		@Override
+		public Map<String, Input<?>> getInputs() {
+			if (inputs == null) {
+				inputs = new HashMap<>();
+				inputs.put("value", msgInput);
+				inputs.put("other", beastiInput);
+			}
+			return inputs;
 		}
 	}
 	
@@ -57,7 +69,7 @@ public class BEASTInterfaceTest extends TestCase {
 
 		System.err.println("test initByName");
 		beasti.initByName("value", "hello world");
-		Input<String> input = (Input<String>) beasti.getInput("value");
+		Input<?> input = beasti.getInput("value");
 		assertEquals("hello world", input.get());
 		
 		System.err.println("test listInputs");
@@ -95,11 +107,11 @@ public class BEASTInterfaceTest extends TestCase {
 		b = beasti.isPrimitive("other");
 		assertEquals(false, b);
 		
-		List<BEASTInterface> plugins = beasti.listActivePlugins();
-		assertEquals(1, plugins.size());
-		assertEquals(beasti2, plugins.get(0));
-		plugins = beasti2.listActivePlugins();
-		assertEquals(0, plugins.size());
+		List<BEASTInterface> beastObjbects = beasti.listActiveBEASTObjects();
+		assertEquals(1, beastObjbects.size());
+		assertEquals(beasti2, beastObjbects.get(0));
+		beastObjbects = beasti2.listActiveBEASTObjects();
+		assertEquals(0, beastObjbects.size());
 		
 		
 		beasti.validateInputs();
diff --git a/src/test/beast/core/StateNodeInitialiserTest.java b/src/test/beast/core/StateNodeInitialiserTest.java
index 3b319ec..a2bba4b 100644
--- a/src/test/beast/core/StateNodeInitialiserTest.java
+++ b/src/test/beast/core/StateNodeInitialiserTest.java
@@ -6,11 +6,8 @@ import beast.evolution.alignment.Alignment;
 import beast.evolution.tree.Tree;
 import beast.util.ClusterTree;
 import beast.util.TreeParser;
-
-
-import test.beast.BEASTTestCase;
-
 import junit.framework.TestCase;
+import test.beast.BEASTTestCase;
 
 public class StateNodeInitialiserTest extends TestCase {
 
diff --git a/src/test/beast/core/parameter/BooleanParameterListTest.java b/src/test/beast/core/parameter/BooleanParameterListTest.java
index 7675a5e..1b43155 100644
--- a/src/test/beast/core/parameter/BooleanParameterListTest.java
+++ b/src/test/beast/core/parameter/BooleanParameterListTest.java
@@ -1,22 +1,22 @@
 package test.beast.core.parameter;
 
-import beast.core.Operator;
-import beast.core.State;
-import beast.core.parameter.BooleanParameter;
-import beast.core.parameter.BooleanParameterList;
-import beast.core.parameter.Parameter;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
 
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.junit.Test;
-
-import static org.junit.Assert.*;
-
 import org.w3c.dom.Document;
 import org.w3c.dom.NodeList;
 
+import beast.core.Operator;
+import beast.core.State;
+import beast.core.parameter.BooleanParameter;
+import beast.core.parameter.BooleanParameterList;
+import beast.core.parameter.Parameter;
+
 /**
  * Unit tests for ParameterList class.
  *
@@ -154,7 +154,7 @@ public class BooleanParameterListTest extends Operator {
     }
 
 	@Override
-	public void initAndValidate() throws Exception {
+	public void initAndValidate() {
 		// TODO Auto-generated method stub
 		
 	}
diff --git a/src/test/beast/core/parameter/IntegerParameterListTest.java b/src/test/beast/core/parameter/IntegerParameterListTest.java
index eee2367..96c7323 100644
--- a/src/test/beast/core/parameter/IntegerParameterListTest.java
+++ b/src/test/beast/core/parameter/IntegerParameterListTest.java
@@ -1,22 +1,22 @@
 package test.beast.core.parameter;
 
-import beast.core.Operator;
-import beast.core.State;
-import beast.core.parameter.Parameter;
-import beast.core.parameter.IntegerParameter;
-import beast.core.parameter.IntegerParameterList;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
 
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.junit.Test;
-
-import static org.junit.Assert.*;
-
 import org.w3c.dom.Document;
 import org.w3c.dom.NodeList;
 
+import beast.core.Operator;
+import beast.core.State;
+import beast.core.parameter.IntegerParameter;
+import beast.core.parameter.IntegerParameterList;
+import beast.core.parameter.Parameter;
+
 /**
  * Unit tests for ParameterList class.
  *
@@ -122,7 +122,7 @@ public class IntegerParameterListTest extends Operator {
     }
 
 	@Override
-	public void initAndValidate() throws Exception {
+	public void initAndValidate() {
 		// TODO Auto-generated method stub
 		
 	}
diff --git a/src/test/beast/core/parameter/ParameterTest.java b/src/test/beast/core/parameter/ParameterTest.java
index 3666e67..fd9f53d 100644
--- a/src/test/beast/core/parameter/ParameterTest.java
+++ b/src/test/beast/core/parameter/ParameterTest.java
@@ -3,8 +3,6 @@ package test.beast.core.parameter;
 import org.junit.Test;
 
 import beast.core.parameter.RealParameter;
-
-
 import junit.framework.TestCase;
 
 public class ParameterTest extends TestCase {
diff --git a/src/test/beast/core/parameter/RealParameterListTest.java b/src/test/beast/core/parameter/RealParameterListTest.java
index cf6e1bb..5af1054 100644
--- a/src/test/beast/core/parameter/RealParameterListTest.java
+++ b/src/test/beast/core/parameter/RealParameterListTest.java
@@ -1,23 +1,21 @@
 package test.beast.core.parameter;
 
-import beast.core.Operator;
-import beast.core.State;
-import beast.core.parameter.Parameter;
-import beast.core.parameter.GeneralParameterList;
-import beast.core.parameter.RealParameter;
-import beast.core.parameter.RealParameterList;
+import static org.junit.Assert.assertEquals;
 
 import java.io.ByteArrayInputStream;
 
 import javax.xml.parsers.DocumentBuilderFactory;
 
 import org.junit.Test;
-
-import static org.junit.Assert.*;
-
 import org.w3c.dom.Document;
 import org.w3c.dom.NodeList;
 
+import beast.core.Operator;
+import beast.core.State;
+import beast.core.parameter.Parameter;
+import beast.core.parameter.RealParameter;
+import beast.core.parameter.RealParameterList;
+
 /**
  * Unit tests for ParameterList class.
  *
@@ -122,7 +120,7 @@ public class RealParameterListTest extends Operator {
     }
 
 	@Override
-	public void initAndValidate() throws Exception {
+	public void initAndValidate() {
 		// TODO Auto-generated method stub
 		
 	}
diff --git a/src/test/beast/evolution/alignment/FilteredAlignmentTest.java b/src/test/beast/evolution/alignment/FilteredAlignmentTest.java
index 382fff4..1fabb81 100644
--- a/src/test/beast/evolution/alignment/FilteredAlignmentTest.java
+++ b/src/test/beast/evolution/alignment/FilteredAlignmentTest.java
@@ -5,10 +5,15 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
-import beast.evolution.alignment.*;
-import junit.framework.TestCase;
 import org.junit.Test;
 
+import beast.evolution.alignment.Alignment;
+import beast.evolution.alignment.FilteredAlignment;
+import beast.evolution.alignment.Sequence;
+import beast.evolution.alignment.Taxon;
+import beast.evolution.alignment.TaxonSet;
+import junit.framework.TestCase;
+
 /** test FilteredAlignment as well as some aspects of Alignment **/
 public class FilteredAlignmentTest extends TestCase {
 
@@ -268,17 +273,17 @@ public class FilteredAlignmentTest extends TestCase {
     }
 
     String alignmentToString(Alignment data, int iTaxon) throws Exception {
-        int[] nStates = new int[data.getPatternCount()];
+        int[] states = new int[data.getPatternCount()];
 //        for (int i = 0; i < data.getSiteCount(); i++) {
 //            int iPattern = data.getPatternIndex(i);
 //            int[] sitePattern = data.getPattern(iPattern);
-//            nStates[i] = sitePattern[iTaxon];
+//            states[i] = sitePattern[iTaxon];
 //        }
 
         for (int i = 0; i < data.getPatternCount(); i++) {
             int[] sitePattern = data.getPattern(i);
-            nStates[i] = sitePattern[iTaxon];
+            states[i] = sitePattern[iTaxon];
         }
-        return data.getDataType().state2string(nStates);
+        return data.getDataType().state2string(states);
     }
 }
diff --git a/src/test/beast/evolution/alignment/UncertainAlignmentTest.java b/src/test/beast/evolution/alignment/UncertainAlignmentTest.java
index cc7bc46..78173c5 100644
--- a/src/test/beast/evolution/alignment/UncertainAlignmentTest.java
+++ b/src/test/beast/evolution/alignment/UncertainAlignmentTest.java
@@ -1,11 +1,8 @@
 package test.beast.evolution.alignment;
 
 
-import java.util.ArrayList;
 import java.util.List;
 
-import junit.framework.TestCase;
-
 import org.junit.Test;
 
 import beast.evolution.alignment.Alignment;
@@ -13,6 +10,7 @@ import beast.evolution.alignment.Sequence;
 import beast.evolution.datatype.DataType;
 import beast.evolution.tree.Tree;
 import beast.util.TreeParser;
+import junit.framework.TestCase;
 
 public class UncertainAlignmentTest extends TestCase {
 
@@ -93,9 +91,9 @@ public class UncertainAlignmentTest extends TestCase {
     	DataType dataType = data.getDataType();
     	
        	System.out.println("Tip likelihoods:");
-    	int nSites = data.getCounts().get(0).size();
+    	int sites = data.getCounts().get(0).size();
     	for (int taxon=0; taxon<data.getTaxonCount(); taxon++) {
-    		for (int i=0; i<nSites; i++) {
+    		for (int i=0; i<sites; i++) {
 	    		double[] probs = data.getTipLikelihoods(taxon,i);
 	    		for (int j=0; j<probs.length; j++) {
 	        		System.out.print(probs[j]+" ");
diff --git a/src/test/beast/evolution/alignment/UnorderedAlignmentsTest.java b/src/test/beast/evolution/alignment/UnorderedAlignmentsTest.java
index c533503..517741a 100644
--- a/src/test/beast/evolution/alignment/UnorderedAlignmentsTest.java
+++ b/src/test/beast/evolution/alignment/UnorderedAlignmentsTest.java
@@ -1,6 +1,12 @@
 package test.beast.evolution.alignment;
 
 
+import java.util.Collections;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.junit.Test;
+
 import beast.app.seqgen.SimulatedAlignment;
 import beast.core.parameter.RealParameter;
 import beast.evolution.alignment.Alignment;
@@ -15,11 +21,6 @@ import beast.evolution.tree.TraitSet;
 import beast.evolution.tree.Tree;
 import beast.evolution.tree.coalescent.ConstantPopulation;
 import junit.framework.TestCase;
-import org.junit.Test;
-
-import java.util.Collections;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
 
 public class UnorderedAlignmentsTest extends TestCase {
 
@@ -67,7 +68,7 @@ public class UnorderedAlignmentsTest extends TestCase {
 
     static public Alignment getAlignment(TaxonSet taxa, Tree tree, SiteModel siteModel) throws Exception {
         Alignment dummy = new Alignment();
-        String[] args = new String[2 * taxa.getTaxonCount() + 2];
+        Object [] args = new String[2 * taxa.getTaxonCount() + 2];
         args[args.length - 2] = "dataType";
         args[args.length - 1] = "nucleotide";
         for (int i = 0; i < taxa.getTaxonCount(); ++i) {
diff --git a/src/test/beast/evolution/likelihood/TreeLikelihoodTest.java b/src/test/beast/evolution/likelihood/TreeLikelihoodTest.java
index 07a3032..652b1ab 100644
--- a/src/test/beast/evolution/likelihood/TreeLikelihoodTest.java
+++ b/src/test/beast/evolution/likelihood/TreeLikelihoodTest.java
@@ -1,7 +1,6 @@
 package test.beast.evolution.likelihood;
 
 
-import junit.framework.TestCase;
 import org.junit.Test;
 
 import beast.core.parameter.RealParameter;
@@ -25,7 +24,7 @@ import beast.evolution.substitutionmodel.MutationDeathModel;
 import beast.evolution.substitutionmodel.SubstitutionModel;
 import beast.evolution.substitutionmodel.WAG;
 import beast.evolution.tree.Tree;
-
+import junit.framework.TestCase;
 import test.beast.BEASTTestCase;
 import test.beast.evolution.alignment.UncertainAlignmentTest;
 
@@ -59,13 +58,13 @@ public class TreeLikelihoodTest extends TestCase {
 
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1992.2056440317247, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1992.2056440317247, BEASTTestCase.PRECISION);
 
         likelihood.initByName("useAmbiguities", true, "data", data, "tree", tree, "siteModel", siteModel);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1992.2056440317247, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1992.2056440317247, BEASTTestCase.PRECISION);
     }
 
     @Test
@@ -118,16 +117,16 @@ public class TreeLikelihoodTest extends TestCase {
         System.out.println("Without tip likelihoods:");
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel, "scaling", TreeLikelihood.Scaling.none);        
-        double[] fLogP = new double[2];
-        fLogP[0] = likelihood.calculateLogP();
-        System.out.println(fLogP[0]);
+        double[] logP = new double[2];
+        logP[0] = likelihood.calculateLogP();
+        System.out.println(logP[0]);
 
         System.out.println("With tip likelihoods:");
         likelihood.initByName("useTipLikelihoods", true, "data", data, "tree", tree, "siteModel", siteModel, "scaling", TreeLikelihood.Scaling.none);
-        fLogP[1]= likelihood.calculateLogP();
-        System.out.println(fLogP[1]);
+        logP[1]= likelihood.calculateLogP();
+        System.out.println(logP[1]);
 
-        return fLogP;
+        return logP;
     }
     
     @Test
@@ -149,10 +148,10 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
+        double logP = 0;
+        logP = likelihood.calculateLogP();
         // the following number comes from Beast 1.6        
-        assertEquals(fLogP, -737.7140695360017, BEASTTestCase.PRECISION);
+        assertEquals(logP, -737.7140695360017, BEASTTestCase.PRECISION);
     }
 
     @Test
@@ -174,13 +173,13 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1856.303048876734, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1856.303048876734, BEASTTestCase.PRECISION);
 
         likelihood.initByName("useAmbiguities", true, "data", data, "tree", tree, "siteModel", siteModel);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1856.303048876734, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1856.303048876734, BEASTTestCase.PRECISION);
     }
 
     @Test
@@ -201,13 +200,13 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1825.2131708068507, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1825.2131708068507, BEASTTestCase.PRECISION);
 
         likelihood.initByName("useAmbiguities", true, "data", data, "tree", tree, "siteModel", siteModel);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1825.2131708068507, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1825.2131708068507, BEASTTestCase.PRECISION);
     }
 
 
@@ -232,14 +231,14 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        System.err.println(fLogP - -1789.7593576610134);
-        assertEquals(fLogP, -1789.7593576610134, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        System.err.println(logP - -1789.7593576610134);
+        assertEquals(logP, -1789.7593576610134, BEASTTestCase.PRECISION);
 
         likelihood.initByName("useAmbiguities", true, "data", data, "tree", tree, "siteModel", siteModel);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1789.7593576610134, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1789.7593576610134, BEASTTestCase.PRECISION);
     }
 
     @Test
@@ -263,13 +262,13 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1789.912401996943, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1789.912401996943, BEASTTestCase.PRECISION);
 
         likelihood.initByName("useAmbiguities", true, "data", data, "tree", tree, "siteModel", siteModel);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1789.912401996943, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1789.912401996943, BEASTTestCase.PRECISION);
     }
 
     @Test
@@ -293,13 +292,13 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1789.639227747059, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1789.639227747059, BEASTTestCase.PRECISION);
 
         likelihood.initByName("useAmbiguities", true, "data", data, "tree", tree, "siteModel", siteModel);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1789.639227747059, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1789.639227747059, BEASTTestCase.PRECISION);
     }
 
 
@@ -322,13 +321,13 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1969.145839307625, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1969.145839307625, BEASTTestCase.PRECISION);
 
         likelihood.initByName("useAmbiguities", false, "data", data, "tree", tree, "siteModel", siteModel);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1969.145839307625, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1969.145839307625, BEASTTestCase.PRECISION);
     }
 
     @Test
@@ -352,13 +351,13 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1948.8417455357564, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1948.8417455357564, BEASTTestCase.PRECISION);
 
         likelihood.initByName("useAmbiguities", false, "data", data, "tree", tree, "siteModel", siteModel);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1948.8417455357564, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1948.8417455357564, BEASTTestCase.PRECISION);
     }
 
     @Test
@@ -381,13 +380,13 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1949.0360143622, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1949.0360143622, BEASTTestCase.PRECISION);
 
         likelihood.initByName("useAmbiguities", false, "data", data, "tree", tree, "siteModel", siteModel);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1949.0360143622, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1949.0360143622, BEASTTestCase.PRECISION);
     }
 
     @Test
@@ -411,16 +410,16 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1947.5829396144961, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1947.5829396144961, BEASTTestCase.PRECISION);
 
         likelihood.initByName("useAmbiguities", false, "data", data, "tree", tree, "siteModel", siteModel);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, -1947.5829396144961, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, -1947.5829396144961, BEASTTestCase.PRECISION);
     }
 
-    void aminoacidModelTest(SubstitutionModel substModel, double fExpectedValue) throws Exception {
+    void aminoacidModelTest(SubstitutionModel substModel, double expectedValue) throws Exception {
         Alignment data = BEASTTestCase.getAminoAcidAlignment();
         Tree tree = BEASTTestCase.getAminoAcidTree(data);
         SiteModel siteModel = new SiteModel();
@@ -428,9 +427,9 @@ public class TreeLikelihoodTest extends TestCase {
 
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fExpectedValue, fLogP, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(expectedValue, logP, BEASTTestCase.PRECISION);
     }
 
     @Test
@@ -485,7 +484,7 @@ public class TreeLikelihoodTest extends TestCase {
 
     }
 
-    void aminoacidModelTestI(SubstitutionModel substModel, double fExpectedValue) throws Exception {
+    void aminoacidModelTestI(SubstitutionModel substModel, double expectedValue) throws Exception {
         Alignment data = BEASTTestCase.getAminoAcidAlignment();
         Tree tree = BEASTTestCase.getAminoAcidTree(data);
         SiteModel siteModel = new SiteModel();
@@ -494,9 +493,9 @@ public class TreeLikelihoodTest extends TestCase {
 
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fExpectedValue, fLogP, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(expectedValue, logP, BEASTTestCase.PRECISION);
     }
 
     @Test
@@ -548,7 +547,7 @@ public class TreeLikelihoodTest extends TestCase {
 
     }
 
-    void aminoacidModelTestIG(SubstitutionModel substModel, double fExpectedValue) throws Exception {
+    void aminoacidModelTestIG(SubstitutionModel substModel, double expectedValue) throws Exception {
         Alignment data = BEASTTestCase.getAminoAcidAlignment();
         Tree tree = BEASTTestCase.getAminoAcidTree(data);
         SiteModel siteModel = new SiteModel();
@@ -559,9 +558,9 @@ public class TreeLikelihoodTest extends TestCase {
 
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fExpectedValue, fLogP, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP();
+        assertEquals(expectedValue, logP, BEASTTestCase.PRECISION);
     }
 
     @Test
@@ -653,11 +652,11 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
+        double logP = 0;
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel, "useAmbiguities", true);
-        fLogP = likelihood.calculateLogP();
+        logP = likelihood.calculateLogP();
         // beast1 xml gives -3551.6436
-        assertEquals(fLogP, -3551.6436270344648, BEASTTestCase.PRECISION);
+        assertEquals(logP, -3551.6436270344648, BEASTTestCase.PRECISION);
     }
 
 
@@ -680,11 +679,11 @@ public class TreeLikelihoodTest extends TestCase {
         TreeLikelihood likelihood = newTreeLikelihood();
         likelihood.initByName("data", data, "tree", tree, "siteModel", siteModel);
 
-        double fLogP = 0;
+        double logP = 0;
         likelihood.initByName("useAmbiguities", true, "data", data, "tree", tree, "siteModel", siteModel);
-        fLogP = likelihood.calculateLogP();
+        logP = likelihood.calculateLogP();
         // beast1 xml gives -1730.5363
-        assertEquals(fLogP, -1730.53631739, BEASTTestCase.PRECISION);
+        assertEquals(logP, -1730.53631739, BEASTTestCase.PRECISION);
     }
 
 } // class TreeLikelihoodTest
diff --git a/src/test/beast/evolution/operator/ExchangeOperatorTest.java b/src/test/beast/evolution/operator/ExchangeOperatorTest.java
index 56b1498..58a48a3 100644
--- a/src/test/beast/evolution/operator/ExchangeOperatorTest.java
+++ b/src/test/beast/evolution/operator/ExchangeOperatorTest.java
@@ -8,8 +8,6 @@ import beast.evolution.alignment.Sequence;
 import beast.evolution.operators.Exchange;
 import beast.util.Randomizer;
 import beast.util.TreeParser;
-
-
 import junit.framework.TestCase;
 
 public class ExchangeOperatorTest extends TestCase {
diff --git a/src/test/beast/evolution/operator/IntRandomWalkOperatorTest.java b/src/test/beast/evolution/operator/IntRandomWalkOperatorTest.java
index bdfe8cd..4db1df8 100644
--- a/src/test/beast/evolution/operator/IntRandomWalkOperatorTest.java
+++ b/src/test/beast/evolution/operator/IntRandomWalkOperatorTest.java
@@ -8,8 +8,6 @@ import org.junit.Test;
 import beast.core.State;
 import beast.core.parameter.IntegerParameter;
 import beast.evolution.operators.IntRandomWalkOperator;
-
-
 import junit.framework.TestCase;
 
 public class IntRandomWalkOperatorTest extends TestCase {
@@ -51,7 +49,7 @@ public class IntRandomWalkOperatorTest extends TestCase {
 		            operator.proposal();
 		            Integer [] values = parameter.getValues();
 		            for (int k = 0; k < values.length; k++) {
-		                int j = (int) values[k];
+		                int j = values[k];
 		                count[k][j] += 1; 
 		            }
 		        }
diff --git a/src/test/beast/evolution/operator/UniformIntegerOperatorTest.java b/src/test/beast/evolution/operator/UniformIntegerOperatorTest.java
index 7d8a53b..8c34997 100644
--- a/src/test/beast/evolution/operator/UniformIntegerOperatorTest.java
+++ b/src/test/beast/evolution/operator/UniformIntegerOperatorTest.java
@@ -6,8 +6,6 @@ import beast.core.State;
 import beast.core.parameter.IntegerParameter;
 import beast.core.parameter.RealParameter;
 import beast.evolution.operators.UniformOperator;
-
-
 import junit.framework.Test;
 import junit.framework.TestCase;
 import junit.framework.TestSuite;
@@ -73,7 +71,7 @@ public class UniformIntegerOperatorTest extends TestCase {
 	            uniformOperator.proposal();
 	            Integer [] values = parameter.getValues();
 	            for (int k = 0; k < values.length; k++) {
-	                int j = (int)(double) values[k];
+	                int j = values[k];
 	                count[k][j] += 1; 
 	            }
 	        }
diff --git a/src/test/beast/evolution/speciation/BirthDeathGernhard08ModelTest.java b/src/test/beast/evolution/speciation/BirthDeathGernhard08ModelTest.java
index bcf1c89..dc49b9e 100644
--- a/src/test/beast/evolution/speciation/BirthDeathGernhard08ModelTest.java
+++ b/src/test/beast/evolution/speciation/BirthDeathGernhard08ModelTest.java
@@ -6,8 +6,8 @@ import beast.core.parameter.RealParameter;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.speciation.BirthDeathGernhard08Model;
 import beast.evolution.tree.Tree;
-import test.beast.BEASTTestCase;
 import junit.framework.TestCase;
+import test.beast.BEASTTestCase;
 
 public class BirthDeathGernhard08ModelTest extends TestCase {
 
@@ -28,38 +28,38 @@ public class BirthDeathGernhard08ModelTest extends TestCase {
                 "relativeDeathRate", relativeDeathRate);
 
 
-        double fLogP = 0;
-        fLogP = likelihood.calculateLogP(); // -3.520936119641363
-        assertEquals(fLogP, 2.5878899503981287, BEASTTestCase.PRECISION);
+        double logP = 0;
+        logP = likelihood.calculateLogP(); // -3.520936119641363
+        assertEquals(logP, 2.5878899503981287, BEASTTestCase.PRECISION);
 
         likelihood.initByName("type", "timesonly",
                 "tree", tree,
                 "birthDiffRate", birthDiffRate,
                 "relativeDeathRate", relativeDeathRate);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, 9.16714116240823, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, 9.16714116240823, BEASTTestCase.PRECISION);
 
         likelihood.initByName("type", "oriented",
                 "tree", tree,
                 "birthDiffRate", birthDiffRate,
                 "relativeDeathRate", relativeDeathRate);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, 4.379649419626184, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, 4.379649419626184, BEASTTestCase.PRECISION);
 
         likelihood.initByName("type", "labeled",
                 "tree", tree,
                 "birthDiffRate", birthDiffRate,
                 "relativeDeathRate", relativeDeathRate);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, 1.2661341104158121, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, 1.2661341104158121, BEASTTestCase.PRECISION);
         
         likelihood.initByName("type", "labeled",
         		"tree", tree,
         		"birthDiffRate", birthDiffRate,
         		"relativeDeathRate", relativeDeathRate,
         		"originHeight", originHeight);
-        fLogP = likelihood.calculateLogP();
-        assertEquals(fLogP, 8.41413452832378, BEASTTestCase.PRECISION);
+        logP = likelihood.calculateLogP();
+        assertEquals(logP, 8.41413452832378, BEASTTestCase.PRECISION);
     }
 
 }
diff --git a/src/test/beast/evolution/substmodel/GTRTest.java b/src/test/beast/evolution/substmodel/GTRTest.java
index 02f1c76..9201dd7 100644
--- a/src/test/beast/evolution/substmodel/GTRTest.java
+++ b/src/test/beast/evolution/substmodel/GTRTest.java
@@ -38,19 +38,23 @@ public class GTRTest extends TestCase {
      * expm(q0 * d)
      */
     protected Instance test0 = new Instance() {
-        public Double[] getPi() {
+        @Override
+		public Double[] getPi() {
             return new Double[]{0.25, 0.25, 0.25, 0.25};
         }
 
-        public Double [] getRates() {
+        @Override
+		public Double [] getRates() {
             return new Double[] {0.5, 1.0, 0.5, 0.5, 1.0, 0.5};
         }
 
-        public double getDistance() {
+        @Override
+		public double getDistance() {
             return 0.1;
         }
 
-        public double[] getExpectedResult() {
+        @Override
+		public double[] getExpectedResult() {
             return new double[]{
                     0.906563342722, 0.023790645491, 0.045855366296, 0.023790645491,
                     0.023790645491, 0.906563342722, 0.023790645491, 0.045855366296,
@@ -61,19 +65,23 @@ public class GTRTest extends TestCase {
     };
 
     protected Instance test1 = new Instance() {
-        public Double[] getPi() {
+        @Override
+		public Double[] getPi() {
             return new Double[]{0.50, 0.20, 0.2, 0.1};
         }
 
-        public Double [] getRates() {
+        @Override
+		public Double [] getRates() {
             return new Double[] {0.5, 1.0, 0.5, 0.5, 1.0, 0.5};
         }
 
-        public double getDistance() {
+        @Override
+		public double getDistance() {
             return 0.1;
         }
 
-        public double[] getExpectedResult() {
+        @Override
+		public double[] getExpectedResult() {
             return new double[]{
                     0.928287993055, 0.021032136637, 0.040163801989, 0.010516068319,
                     0.052580341593, 0.906092679369, 0.021032136637, 0.020294842401,
@@ -84,19 +92,23 @@ public class GTRTest extends TestCase {
     };
 
     protected Instance test2 = new Instance() {
-        public Double[] getPi() {
+        @Override
+		public Double[] getPi() {
             return new Double[]{0.20, 0.30, 0.25, 0.25};
         }
 
-        public Double [] getRates() {
+        @Override
+		public Double [] getRates() {
             return new Double[] {0.2, 1.0, 0.2, 0.2, 1.0, 0.2};
         }
 
-        public double getDistance() {
+        @Override
+		public double getDistance() {
             return 0.1;
         }
 
-        public double[] getExpectedResult() {
+        @Override
+		public double[] getExpectedResult() {
             return new double[]{
                     0.904026219693, 0.016708646875, 0.065341261036, 0.013923872396,
                     0.011139097917, 0.910170587813, 0.013923872396, 0.064766441875,
@@ -107,19 +119,23 @@ public class GTRTest extends TestCase {
     };
 
     protected Instance test3 = new Instance() {
-        public Double[] getPi() {
+        @Override
+		public Double[] getPi() {
             return new Double[]{0.20, 0.30, 0.25, 0.25};
         }
 
-        public Double [] getRates() {
+        @Override
+		public Double [] getRates() {
             return new Double[] {0.2, 1.0, 0.3, 0.4, 1.0, 0.5};
         }
 
-        public double getDistance() {
+        @Override
+		public double getDistance() {
             return 0.1;
         }
 
-        public double[] getExpectedResult() {
+        @Override
+		public double[] getExpectedResult() {
             return new double[]{
             		0.9151233523912986, 0.01419463331835106, 0.053614529507541434, 0.017067484782809166, 
             		0.009463088878900653, 0.9148659231065082, 0.022324155452048293, 0.05334683256254297, 
@@ -130,19 +146,23 @@ public class GTRTest extends TestCase {
     };
     
     protected Instance test4 = new Instance() {
-        public Double[] getPi() {
+        @Override
+		public Double[] getPi() {
             return new Double[]{0.20, 0.30, 0.25, 0.25};
         }
 
-        public Double [] getRates() {
+        @Override
+		public Double [] getRates() {
             return new Double[] {0.2, 10.0, 0.3, 0.4, 5.0, 0.5};
         }
 
-        public double getDistance() {
+        @Override
+		public double getDistance() {
             return 0.1;
         }
 
-        public double[] getExpectedResult() {
+        @Override
+		public double[] getExpectedResult() {
             return new double[]{
             			0.8780963047046206, 0.0033252855682803723, 0.11461112844510626, 0.003967281281992822, 
             			0.002216857045520258, 0.9327483979953872, 0.005055665025823634, 0.05997907993326873, 
diff --git a/src/test/beast/evolution/substmodel/HKYTest.java b/src/test/beast/evolution/substmodel/HKYTest.java
index a675e8f..55bb3ea 100644
--- a/src/test/beast/evolution/substmodel/HKYTest.java
+++ b/src/test/beast/evolution/substmodel/HKYTest.java
@@ -4,7 +4,6 @@ import beast.core.Description;
 import beast.core.parameter.RealParameter;
 import beast.evolution.substitutionmodel.Frequencies;
 import beast.evolution.substitutionmodel.HKY;
-import beast.evolution.tree.Node;
 import junit.framework.TestCase;
 
 /**
@@ -41,19 +40,23 @@ public class HKYTest extends TestCase {
      * expm(q0 * d)
      */
     protected Instance test0 = new Instance() {
-        public Double[] getPi() {
+        @Override
+		public Double[] getPi() {
             return new Double[]{0.25, 0.25, 0.25, 0.25};
         }
 
-        public Double getKappa() {
+        @Override
+		public Double getKappa() {
             return 2.0;
         }
 
-        public double getDistance() {
+        @Override
+		public double getDistance() {
             return 0.1;
         }
 
-        public double[] getExpectedResult() {
+        @Override
+		public double[] getExpectedResult() {
             return new double[]{
                     0.906563342722, 0.023790645491, 0.045855366296, 0.023790645491,
                     0.023790645491, 0.906563342722, 0.023790645491, 0.045855366296,
@@ -64,19 +67,23 @@ public class HKYTest extends TestCase {
     };
 
     protected Instance test1 = new Instance() {
-        public Double[] getPi() {
+        @Override
+		public Double[] getPi() {
             return new Double[]{0.50, 0.20, 0.2, 0.1};
         }
 
-        public Double getKappa() {
+        @Override
+		public Double getKappa() {
             return 2.0;
         }
 
-        public double getDistance() {
+        @Override
+		public double getDistance() {
             return 0.1;
         }
 
-        public double[] getExpectedResult() {
+        @Override
+		public double[] getExpectedResult() {
             return new double[]{
                     0.928287993055, 0.021032136637, 0.040163801989, 0.010516068319,
                     0.052580341593, 0.906092679369, 0.021032136637, 0.020294842401,
@@ -87,19 +94,23 @@ public class HKYTest extends TestCase {
     };
 
     protected Instance test2 = new Instance() {
-        public Double[] getPi() {
+        @Override
+		public Double[] getPi() {
             return new Double[]{0.20, 0.30, 0.25, 0.25};
         }
 
-        public Double getKappa() {
+        @Override
+		public Double getKappa() {
             return 5.0;
         }
 
-        public double getDistance() {
+        @Override
+		public double getDistance() {
             return 0.1;
         }
 
-        public double[] getExpectedResult() {
+        @Override
+		public double[] getExpectedResult() {
             return new double[]{
                     0.904026219693, 0.016708646875, 0.065341261036, 0.013923872396,
                     0.011139097917, 0.910170587813, 0.013923872396, 0.064766441875,
diff --git a/src/test/beast/evolution/tree/RandomTreeTest.java b/src/test/beast/evolution/tree/RandomTreeTest.java
index 824caa7..9de939b 100644
--- a/src/test/beast/evolution/tree/RandomTreeTest.java
+++ b/src/test/beast/evolution/tree/RandomTreeTest.java
@@ -19,6 +19,11 @@
 
 package test.beast.evolution.tree;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
 import beast.core.parameter.RealParameter;
 import beast.evolution.alignment.Alignment;
 import beast.evolution.alignment.Sequence;
@@ -28,9 +33,6 @@ import beast.evolution.tree.TraitSet;
 import beast.evolution.tree.coalescent.ConstantPopulation;
 import beast.evolution.tree.coalescent.TreeIntervals;
 import beast.util.Randomizer;
-import java.util.ArrayList;
-import java.util.List;
-import org.junit.Test;
 
 /**
  * @author Tim Vaughan <tgvaughan at gmail.com>
diff --git a/src/test/beast/evolution/tree/TreeAnnotatorTest.java b/src/test/beast/evolution/tree/TreeAnnotatorTest.java
index 8a535c4..3d5a630 100644
--- a/src/test/beast/evolution/tree/TreeAnnotatorTest.java
+++ b/src/test/beast/evolution/tree/TreeAnnotatorTest.java
@@ -1,15 +1,16 @@
 package test.beast.evolution.tree;
 
-import beast.app.treeannotator.CladeSystem;
-import beast.app.treeannotator.TreeAnnotator;
-import beast.evolution.tree.Tree;
-import beast.util.TreeParser;
+import java.util.BitSet;
+import java.util.Map;
+
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 
-import java.util.BitSet;
-import java.util.Map;
+import beast.app.treeannotator.CladeSystem;
+import beast.app.treeannotator.TreeAnnotator;
+import beast.evolution.tree.Tree;
+import beast.util.TreeParser;
 
 /**
  * @author Walter Xie
diff --git a/src/test/beast/evolution/tree/coalescent/BayesianSkylineTest.java b/src/test/beast/evolution/tree/coalescent/BayesianSkylineTest.java
index efd3162..09f0730 100644
--- a/src/test/beast/evolution/tree/coalescent/BayesianSkylineTest.java
+++ b/src/test/beast/evolution/tree/coalescent/BayesianSkylineTest.java
@@ -1,12 +1,12 @@
 package test.beast.evolution.tree.coalescent;
 
 
-import junit.framework.TestCase;
 import org.junit.Test;
 
 import beast.evolution.tree.Tree;
 import beast.evolution.tree.coalescent.BayesianSkyline;
 import beast.evolution.tree.coalescent.TreeIntervals;
+import junit.framework.TestCase;
 
 
 
diff --git a/src/test/beast/integration/DocumentationTest.java b/src/test/beast/integration/DocumentationTest.java
index 736b63c..46b6dc4 100644
--- a/src/test/beast/integration/DocumentationTest.java
+++ b/src/test/beast/integration/DocumentationTest.java
@@ -4,47 +4,52 @@ import java.lang.annotation.Annotation;
 import java.util.ArrayList;
 import java.util.List;
 
-import junit.framework.TestCase;
 import org.junit.Test;
 
+import beast.core.BEASTObject;
 import beast.core.Description;
 import beast.core.Input;
-import beast.core.BEASTObject;
 import beast.util.AddOnManager;
+import junit.framework.TestCase;
 
 
 
 public class DocumentationTest extends TestCase {
 
+	
+	{
+		System.setProperty("beast.is.junit.testing", "true");
+	}
+	
     /**
      * Check all plug-ins have a proper description so that
      * everything is at least moderately well documented. *
      */
     @Test
     public void testDescriptions() {
-        final List<String> sPluginNames = AddOnManager.find(beast.core.BEASTObject.class, AddOnManager.IMPLEMENTATION_DIR);
-        final List<String> sUndocumentedPlugins = new ArrayList<String>();
-        for (final String sPlugin : sPluginNames) {
+        final List<String> pluginNames = AddOnManager.find(beast.core.BEASTObject.class, AddOnManager.IMPLEMENTATION_DIR);
+        final List<String> undocumentedPlugins = new ArrayList<String>();
+        for (final String beastObjectName : pluginNames) {
             try {
-                final Class<?> pluginClass = Class.forName(sPlugin);
+                final Class<?> pluginClass = Class.forName(beastObjectName);
                 final Annotation[] classAnnotations = pluginClass.getAnnotations();
                 boolean hasSatisfactoryDescription = false;
                 for (final Annotation annotation : classAnnotations) {
                     if (annotation instanceof Description) {
                         final Description description = (Description) annotation;
-                        final String sDescription = description.value();
-                        if (isProperDocString(sDescription)) {
+                        final String descriptionString = description.value();
+                        if (isProperDocString(descriptionString)) {
                             hasSatisfactoryDescription = true;
                         }
                     }
                 }
                 if (!hasSatisfactoryDescription) {
-                    sUndocumentedPlugins.add(sPlugin);
+                    undocumentedPlugins.add(beastObjectName);
                 }
             } catch (Exception e) {
             }
         }
-        assertTrue("No proper description for: " + sUndocumentedPlugins.toString(), sUndocumentedPlugins.size() == 0);
+        assertTrue("No proper description for: " + undocumentedPlugins.toString(), undocumentedPlugins.size() == 0);
     } // testDescriptions
 
     /**
@@ -53,20 +58,20 @@ public class DocumentationTest extends TestCase {
      */
     @Test
     public void testInputTipText() {
-        final List<String> sPluginNames = AddOnManager.find(beast.core.BEASTObject.class, AddOnManager.IMPLEMENTATION_DIR);
-        final List<String> sUndocumentedInputs = new ArrayList<String>();
-        for (final String sPlugin : sPluginNames) {
+        final List<String> pluginNames = AddOnManager.find(beast.core.BEASTObject.class, AddOnManager.IMPLEMENTATION_DIR);
+        final List<String> undocumentedInputs = new ArrayList<String>();
+        for (final String beastObjectName : pluginNames) {
             try {
-                final BEASTObject plugin = (BEASTObject) Class.forName(sPlugin).newInstance();
-                final List<Input<?>> inputs = plugin.listInputs();
+                final BEASTObject beastObject = (BEASTObject) Class.forName(beastObjectName).newInstance();
+                final List<Input<?>> inputs = beastObject.listInputs();
                 for (final Input<?> input : inputs) {
                     boolean hasSatisfactoryDescription = false;
-                    final String sTipText = input.getTipText();
-                    if (isProperDocString(sTipText)) {
+                    final String tipText = input.getTipText();
+                    if (isProperDocString(tipText)) {
                         hasSatisfactoryDescription = true;
                     }
                     if (!hasSatisfactoryDescription) {
-                        sUndocumentedInputs.add(sPlugin + ":" + input.getName());
+                        undocumentedInputs.add(beastObjectName + ":" + input.getName());
                     }
                 }
             } catch (Exception e) {
@@ -74,7 +79,7 @@ public class DocumentationTest extends TestCase {
         }
 
         assertTrue("No proper input tip text (at least " + N_WORDS + " words and " + N_CHARS + " characters) for: "
-                + sUndocumentedInputs.toString(), sUndocumentedInputs.size() == 0);
+                + undocumentedInputs.toString(), undocumentedInputs.size() == 0);
     } // testInputTipText
 
 
@@ -85,14 +90,14 @@ public class DocumentationTest extends TestCase {
     @Test
     public void test_DocMaker() throws Exception {
         // this code runs just fine stand alone, but not in ant. TODO: figure out why
-//		String [] sArgs = {"."};
-//		DocMaker b = new DocMaker(sArgs);
+//		String [] args = {"."};
+//		DocMaker b = new DocMaker(args);
 //		b.generateDocs();
 //		// clean up
-//		String [] sFiles = new File(".").list();
-//		for (String sFile : sFiles) {
-//			if (sFile.endsWith(".html")) {
-//				new File(sFile).delete();
+//		String [] files = new File(".").list();
+//		for (String fileName : files) {
+//			if (fileName.endsWith(".html")) {
+//				new File(fileName).delete();
 //			}
 //		}
     } // test_DocMaker
@@ -103,14 +108,14 @@ public class DocumentationTest extends TestCase {
 
     // description of at least 15 chars and at least 4 words is satisfactory?!?
     // TODO: needs a bit more smarts to prevent as df a hsf jasd;fajasdf
-    boolean isProperDocString(final String sStr) {
+    boolean isProperDocString(final String str) {
         // check length
-        if (sStr.length() < N_CHARS) {
+        if (str.length() < N_CHARS) {
             return false;
         }
         // count nr of words
-        final String[] sWords = sStr.split("\\s+");
-        if (sWords.length < N_WORDS) {
+        final String[] words = str.split("\\s+");
+        if (words.length < N_WORDS) {
             return false;
         }
         return true;
diff --git a/src/test/beast/integration/ExampleJSONParsingTest.java b/src/test/beast/integration/ExampleJSONParsingTest.java
index cb51a1c..8020cad 100644
--- a/src/test/beast/integration/ExampleJSONParsingTest.java
+++ b/src/test/beast/integration/ExampleJSONParsingTest.java
@@ -12,8 +12,6 @@ import beast.core.Logger;
 import beast.core.MCMC;
 import beast.util.JSONParser;
 import beast.util.Randomizer;
-
-
 import junit.framework.TestCase;
 
 /**
@@ -35,15 +33,16 @@ public class ExampleJSONParsingTest extends TestCase {
             Randomizer.setSeed(127);
             Logger.FILE_MODE = Logger.LogFileMode.overwrite;
             System.out.println("Test JSON Examples in " + dir);
-            File sExampleDir = new File(dir);
-            String[] sExampleFiles = sExampleDir.list(new FilenameFilter() {
-                public boolean accept(File dir, String name) {
+            File exampleDir = new File(dir);
+            String[] exampleFiles = exampleDir.list(new FilenameFilter() {
+                @Override
+				public boolean accept(File dir, String name) {
                     return name.endsWith(".json");
                 }
             });
 
-            List<String> sFailedFiles = new ArrayList<String>();
-            for (String fileName : sExampleFiles) {
+            List<String> failedFiles = new ArrayList<String>();
+            for (String fileName : exampleFiles) {
                 System.out.println("Processing " + fileName);
                 JSONParser parser = new JSONParser();
                 try {
@@ -51,16 +50,16 @@ public class ExampleJSONParsingTest extends TestCase {
                 } catch (Exception e) {
                     System.out.println("ExampleJSONParsing::Failed for " + fileName
                             + ": " + e.getMessage());
-                    sFailedFiles.add(fileName);
+                    failedFiles.add(fileName);
                 }
                 System.out.println("Done " + fileName);
             }
-            if (sFailedFiles.size() > 0) {
-                System.out.println("\ntest_ThatJSONExamplesParse::Failed for : " + sFailedFiles.toString());
+            if (failedFiles.size() > 0) {
+                System.out.println("\ntest_ThatJSONExamplesParse::Failed for : " + failedFiles.toString());
             } else {
                 System.out.println("\ntest_ThatJSONExamplesParse::Success");
             }
-            assertTrue(sFailedFiles.toString(), sFailedFiles.size() == 0);
+            assertTrue(failedFiles.toString(), failedFiles.size() == 0);
         } catch (Exception e) {
             System.out.println("exception thrown ");
             System.out.println(e.getMessage());
@@ -77,18 +76,19 @@ public class ExampleJSONParsingTest extends TestCase {
         try {
             Logger.FILE_MODE = Logger.LogFileMode.overwrite;
             System.out.println("Test that JSON Examples run in " + dir);
-            File sExampleDir = new File(dir);
-            String[] sExampleFiles = sExampleDir.list(new FilenameFilter() {
-                public boolean accept(File dir, String name) {
+            File exampleDir = new File(dir);
+            String[] exampleFiles = exampleDir.list(new FilenameFilter() {
+                @Override
+				public boolean accept(File dir, String name) {
                     return name.endsWith(".json");
                 }
             });
 
-            List<String> sFailedFiles = new ArrayList<String>();
-            int nSeed = 127;
-            for (String fileName : sExampleFiles) {
-                Randomizer.setSeed(nSeed);
-                nSeed += 10; // need more than one to prevent trouble with multiMCMC logs
+            List<String> failedFiles = new ArrayList<String>();
+            int seed = 127;
+            for (String fileName : exampleFiles) {
+                Randomizer.setSeed(seed);
+                seed += 10; // need more than one to prevent trouble with multiMCMC logs
                 System.out.println("Processing " + fileName);
                 JSONParser parser = new JSONParser();
                 try {
@@ -102,16 +102,16 @@ public class ExampleJSONParsingTest extends TestCase {
                 } catch (Exception e) {
                     System.out.println("ExampleJSONParsing::Failed for " + fileName
                             + ": " + e.getMessage());
-                    sFailedFiles.add(fileName);
+                    failedFiles.add(fileName);
                 }
                 System.out.println("Done " + fileName);
             }
-            if (sFailedFiles.size() > 0) {
-                System.out.println("\ntest_ThatJSONExamplesRun::Failed for : " + sFailedFiles.toString());
+            if (failedFiles.size() > 0) {
+                System.out.println("\ntest_ThatJSONExamplesRun::Failed for : " + failedFiles.toString());
             } else {
                 System.out.println("SUCCESS!!!");
             }
-            assertTrue(sFailedFiles.toString(), sFailedFiles.size() == 0);
+            assertTrue(failedFiles.toString(), failedFiles.size() == 0);
         } catch (Exception e) {
             System.out.println("exception thrown ");
             System.out.println(e.getMessage());
diff --git a/src/test/beast/integration/ExampleXmlParsingTest.java b/src/test/beast/integration/ExampleXmlParsingTest.java
index 5565dde..f20c79e 100644
--- a/src/test/beast/integration/ExampleXmlParsingTest.java
+++ b/src/test/beast/integration/ExampleXmlParsingTest.java
@@ -12,8 +12,6 @@ import beast.core.Logger;
 import beast.core.MCMC;
 import beast.util.Randomizer;
 import beast.util.XMLParser;
-
-
 import junit.framework.TestCase;
 
 /**
@@ -44,15 +42,16 @@ public class ExampleXmlParsingTest extends TestCase {
             Randomizer.setSeed(127);
             Logger.FILE_MODE = Logger.LogFileMode.overwrite;
             System.out.println("Test XML Examples in " + dir);
-            File sExampleDir = new File(dir);
-            String[] sExampleFiles = sExampleDir.list(new FilenameFilter() {
-                public boolean accept(File dir, String name) {
+            File exampleDir = new File(dir);
+            String[] exampleFiles = exampleDir.list(new FilenameFilter() {
+                @Override
+				public boolean accept(File dir, String name) {
                     return name.endsWith(".xml");
                 }
             });
 
-            List<String> sFailedFiles = new ArrayList<String>();
-            for (String fileName : sExampleFiles) {
+            List<String> failedFiles = new ArrayList<String>();
+            for (String fileName : exampleFiles) {
                 System.out.println("Processing " + fileName);
                 XMLParser parser = new XMLParser();
                 try {
@@ -60,16 +59,16 @@ public class ExampleXmlParsingTest extends TestCase {
                 } catch (Exception e) {
                     System.out.println("ExampleXmlParsing::Failed for " + fileName
                             + ": " + e.getMessage());
-                    sFailedFiles.add(fileName);
+                    failedFiles.add(fileName);
                 }
                 System.out.println("Done " + fileName);
             }
-            if (sFailedFiles.size() > 0) {
-                System.out.println("\ntest_ThatXmlExamplesParse::Failed for : " + sFailedFiles.toString());
+            if (failedFiles.size() > 0) {
+                System.out.println("\ntest_ThatXmlExamplesParse::Failed for : " + failedFiles.toString());
             } else {
                 System.out.println("\ntest_ThatXmlExamplesParse::Success");
             }
-            assertTrue(sFailedFiles.toString(), sFailedFiles.size() == 0);
+            assertTrue(failedFiles.toString(), failedFiles.size() == 0);
         } catch (Exception e) {
             System.out.println("exception thrown ");
             System.out.println(e.getMessage());
@@ -86,18 +85,19 @@ public class ExampleXmlParsingTest extends TestCase {
         try {
             Logger.FILE_MODE = Logger.LogFileMode.overwrite;
             System.out.println("Test that XML Examples run in " + dir);
-            File sExampleDir = new File(dir);
-            String[] sExampleFiles = sExampleDir.list(new FilenameFilter() {
-                public boolean accept(File dir, String name) {
+            File exampleDir = new File(dir);
+            String[] exampleFiles = exampleDir.list(new FilenameFilter() {
+                @Override
+				public boolean accept(File dir, String name) {
                     return name.endsWith(".xml");
                 }
             });
 
-            List<String> sFailedFiles = new ArrayList<String>();
-            int nSeed = 127;
-            for (String fileName : sExampleFiles) {
-                Randomizer.setSeed(nSeed);
-                nSeed += 10; // need more than one to prevent trouble with multiMCMC logs
+            List<String> failedFiles = new ArrayList<String>();
+            int seed = 127;
+            for (String fileName : exampleFiles) {
+                Randomizer.setSeed(seed);
+                seed += 10; // need more than one to prevent trouble with multiMCMC logs
                 System.out.println("Processing " + fileName);
                 XMLParser parser = new XMLParser();
                 try {
@@ -111,16 +111,16 @@ public class ExampleXmlParsingTest extends TestCase {
                 } catch (Exception e) {
                     System.out.println("ExampleXmlParsing::Failed for " + fileName
                             + ": " + e.getMessage());
-                    sFailedFiles.add(fileName);
+                    failedFiles.add(fileName);
                 }
                 System.out.println("Done " + fileName);
             }
-            if (sFailedFiles.size() > 0) {
-                System.out.println("\ntest_ThatXmlExamplesRun::Failed for : " + sFailedFiles.toString());
+            if (failedFiles.size() > 0) {
+                System.out.println("\ntest_ThatXmlExamplesRun::Failed for : " + failedFiles.toString());
             } else {
                 System.out.println("SUCCESS!!!");
             }
-            assertTrue(sFailedFiles.toString(), sFailedFiles.size() == 0);
+            assertTrue(failedFiles.toString(), failedFiles.size() == 0);
         } catch (Exception e) {
             System.out.println("exception thrown ");
             System.out.println(e.getMessage());
diff --git a/src/test/beast/integration/InputTypeTest.java b/src/test/beast/integration/InputTypeTest.java
index 3edd32f..156c63a 100644
--- a/src/test/beast/integration/InputTypeTest.java
+++ b/src/test/beast/integration/InputTypeTest.java
@@ -1,50 +1,156 @@
 package test.beast.integration;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.List;
 
 import org.junit.Test;
 
-import beast.core.Input;
+import beast.core.BEASTInterface;
 import beast.core.BEASTObject;
+import beast.core.Input;
+import beast.core.Param;
 import beast.util.AddOnManager;
+import junit.framework.TestCase;
 
+public class InputTypeTest extends TestCase {
 
-import junit.framework.TestCase;
+	{
+		System.setProperty("beast.is.junit.testing", "true");
+	}
 
-public class InputTypeTest  extends TestCase {
-	
-	
-	/* Test that the type of an input can be determined,
-	 * If not, the programmer has to manually initialise the type of the input 
-	 * (most easily done through a constructor of Input) */
+	/*
+	 * Test that the type of an input can be determined, If not, the programmer
+	 * has to manually initialise the type of the input (most easily done
+	 * through a constructor of Input)
+	 */
 	@Test
 	public void testInputTypeCanBeSet() throws Exception {
-        List<String> sPluginNames = AddOnManager.find(beast.core.BEASTObject.class, AddOnManager.IMPLEMENTATION_DIR);
-        List<String> failingInputs = new ArrayList<String>();
-        for (String sPlugin : sPluginNames) {
-            try {
-                BEASTObject plugin = (BEASTObject) Class.forName(sPlugin).newInstance();
-                List<Input<?>> inputs = plugin.listInputs();
-                for (Input<?> input : inputs) {
-                	if (input.getType() == null) {
-                		try {
-                			input.determineClass(plugin);
-                			if (input.getType() == null) {
-                    			failingInputs.add(sPlugin + ":" + input.getName());
-                			}
-                		} catch (Exception e2) {
-                			failingInputs.add(sPlugin + ":" + input.getName());
-                		}
-                	}
-                }
-            } catch (Exception e) {
-            	// ignore
-            }
-        }
-                
-        assertTrue("Type of input could not be set for these inputs (probably requires to be set by using the appropriate constructure of Input): "
-                + failingInputs.toString(), failingInputs.size() == 0);
+		List<String> beastObjectNames = AddOnManager.find(beast.core.BEASTObject.class,
+				AddOnManager.IMPLEMENTATION_DIR);
+		List<String> failingInputs = new ArrayList<String>();
+		for (String beastObjectName : beastObjectNames) {
+			try {
+				BEASTObject beastObject = (BEASTObject) Class.forName(beastObjectName).newInstance();
+				List<Input<?>> inputs = beastObject.listInputs();
+				for (Input<?> input : inputs) {
+					if (input.getType() == null) {
+						try {
+							input.determineClass(beastObject);
+							if (input.getType() == null) {
+								failingInputs.add(beastObject + ":" + input.getName());
+							}
+						} catch (Exception e2) {
+							failingInputs.add(beastObject + ":" + input.getName());
+						}
+					}
+				}
+			} catch (Exception e) {
+				// ignore
+			}
+		}
+
+		assertTrue(
+				"Type of input could not be set for these inputs (probably requires to be set by using the appropriate constructure of Input): "
+						+ failingInputs.toString(),
+				failingInputs.size() == 0);
+	}
+
+	@Test
+	public void testAnnotatedInputHasGetters() throws Exception {
+		testAnnotatedInputHasGetters(AddOnManager.IMPLEMENTATION_DIR);
 	}
+	
+	public void testAnnotatedInputHasGetters(String [] packages) throws Exception {
+		List<String> beastObjectNames = AddOnManager.find(Object.class, packages);
+		System.err.println("Testing " + beastObjectNames.size() + " classes");
+		List<String> failingInputs = new ArrayList<String>();
+		for (String beastObject : beastObjectNames) {
+			try {
+				Class<?> _class = Class.forName(beastObject);
+			    Constructor<?>[] allConstructors = _class.getDeclaredConstructors();
+			    for (Constructor<?> ctor : allConstructors) {
+			    	Annotation[][] annotations = ctor.getParameterAnnotations();
+			    	List<Param> paramAnnotations = new ArrayList<>();
+			    	for (Annotation [] a0 : annotations) {
+				    	for (Annotation a : a0) {
+				    		if (a instanceof Param) {
+				    			paramAnnotations.add((Param) a);
+				    		}
+				    	}
+			    	}
+			    	if (paramAnnotations.size() > 0 && !BEASTInterface.class.isAssignableFrom(_class)) {
+			    		failingInputs.add(_class.getName() + " has Param annotations but does not implement BEASTInterface\n");
+			    	}
+			    	Class<?>[] types  = ctor.getParameterTypes();	    	
+		    		Type[] gtypes = ctor.getGenericParameterTypes();
+			    	if (types.length > 0 && paramAnnotations.size() > 0) {
+			    		int offset = 0;
+			    		if (types.length == paramAnnotations.size() + 1) {
+			    			offset = 1;
+			    		}
+			    		for (int i = 0; i < paramAnnotations.size(); i++) {
+			    			Class<?> type;
+			    			Class<?> clazz = null;
+			    			boolean isList = false;
+							String typeName = types[i + offset].getTypeName();
+							if (typeName.endsWith("[]")) {
+								failingInputs.add(_class.getName() + " constructor has arrray as argument, should be a List\n");
+							} else {
+								switch (typeName) {
+								case "int" : type = Integer.class; break;
+								case "long" : type = Long.class; break;
+								case "float" : type = Float.class; break;
+								case "double" : type = Double.class; break;
+								case "boolean" : type = Boolean.class; break;
+								default:
+									clazz = Class.forName(typeName);
+					    			if (clazz.isAssignableFrom(List.class)) {
+				                        Type[] genericTypes2 = ((ParameterizedType) gtypes[i + offset]).getActualTypeArguments();
+				                        type = (Class<?>) genericTypes2[0];
+				                        isList = true;
+					    			} else {
+					    				type =  types[i + offset];
+					    			}
+								}
+				    			
+						    	String name = paramAnnotations.get(i).name();
+						    	String getter = "get" + name.substring(0, 1).toUpperCase() + name.substring(1);
+						    	try {
+						    		Method method = _class.getMethod(getter);
+						    		if (isList) {
+						    			if (!method.getReturnType().isAssignableFrom(List.class)) {
+											failingInputs.add(_class.getName() + ":" + getter + "() should return List<" + type.getName() + "> instead of " + method.getReturnType().getName() + "\n");
+						    			}
+						    		} else if (!method.getReturnType().isAssignableFrom(type)) {
+										failingInputs.add(_class.getName() + ":" + getter + "() should return " + type.getName() + " instead of " + method.getReturnType().getName() + "\n");
+						    		}
+						    	} catch (NoSuchMethodException e) {
+									failingInputs.add(_class.getName() + ":" + getter + "() missing\n");
+						    	}
+						    	String setter = "set" + name.substring(0, 1).toUpperCase() + name.substring(1);
+						    	try {
+						    		_class.getMethod(setter, type);
+						    	} catch (NoSuchMethodException e) {
+									failingInputs.add(_class.getName() + ":" + setter + "("+ type.getName() + ") missing, or does not have correct argument\n");
+						    	}
+							}
+			    		}
+			    	}
+				}
+			} catch (Exception e) {
+				System.err.println(beastObject + " " + e.getClass().getName() + " " + e.getMessage());
+			}
+		}
+		System.err.println("Done!");
 
+		assertTrue(
+				"Something is wrong with these annotated constructor(s): \n"
+						+ failingInputs.toString(),
+				failingInputs.size() == 0);
+	}
 }
diff --git a/src/test/beast/integration/ResumeTest.java b/src/test/beast/integration/ResumeTest.java
index b1bc758..bbb94d6 100644
--- a/src/test/beast/integration/ResumeTest.java
+++ b/src/test/beast/integration/ResumeTest.java
@@ -1,6 +1,6 @@
 package test.beast.integration;
 
-import junit.framework.TestCase;
+import java.io.File;
 
 import org.junit.Test;
 
@@ -8,10 +8,7 @@ import beast.core.Logger;
 import beast.core.MCMC;
 import beast.util.Randomizer;
 import beast.util.XMLParser;
-
-
-
-import java.io.File;
+import junit.framework.TestCase;
 
 /**
  * check that a chain can be resumed after termination *
diff --git a/src/test/beast/integration/XMLElementNameTest.java b/src/test/beast/integration/XMLElementNameTest.java
index c241573..f201a70 100644
--- a/src/test/beast/integration/XMLElementNameTest.java
+++ b/src/test/beast/integration/XMLElementNameTest.java
@@ -8,13 +8,10 @@ import java.util.Set;
 
 import org.junit.Test;
 
-import beast.core.Input;
 import beast.core.BEASTObject;
+import beast.core.Input;
 import beast.util.AddOnManager;
 import beast.util.XMLParser;
-
-
-
 import junit.framework.TestCase;
 
 
@@ -25,20 +22,20 @@ public class XMLElementNameTest extends TestCase {
      */
     @Test
     public void test_NameUniqueness() {
-        List<String> sPluginNames = AddOnManager.find(beast.core.BEASTObject.class, AddOnManager.IMPLEMENTATION_DIR);
-        List<String> sImproperInputs = new ArrayList<String>();
-        for (String sPlugin : sPluginNames) {
+        List<String> pluginNames = AddOnManager.find(beast.core.BEASTObject.class, AddOnManager.IMPLEMENTATION_DIR);
+        List<String> improperInputs = new ArrayList<String>();
+        for (String beastObjectName : pluginNames) {
             try {
-                BEASTObject plugin = (BEASTObject) Class.forName(sPlugin).newInstance();
-                List<Input<?>> inputs = plugin.listInputs();
-                Set<String> sNames = new HashSet<String>();
+                BEASTObject beastObject = (BEASTObject) Class.forName(beastObjectName).newInstance();
+                List<Input<?>> inputs = beastObject.listInputs();
+                Set<String> names = new HashSet<String>();
                 for (Input<?> input : inputs) {
-                    String sName = input.getName();
-                    if (sNames.contains(sName)) {
-                        sImproperInputs.add(sPlugin + "." + sName);
+                    String name = input.getName();
+                    if (names.contains(name)) {
+                        improperInputs.add(beastObjectName + "." + name);
                         break;
                     }
-                    sNames.add(sName);
+                    names.add(name);
 
                 }
             } catch (InstantiationException e) {
@@ -47,13 +44,13 @@ public class XMLElementNameTest extends TestCase {
                 // ignore
             }
         }
-        if (sImproperInputs.size() > 0) {
-            String sStr = sImproperInputs.toString();
-            sStr = sStr.replaceAll(",", "\n");
-            System.err.println("Input names are not unique:\n" + sStr);
+        if (improperInputs.size() > 0) {
+            String str = improperInputs.toString();
+            str = str.replaceAll(",", "\n");
+            System.err.println("Input names are not unique:\n" + str);
         }
         // not activated till problem with naming is solved
-        assertTrue("Input names are not unique: " + sImproperInputs.toString(), sImproperInputs.size() == 0);
+        assertTrue("Input names are not unique: " + improperInputs.toString(), improperInputs.size() == 0);
     }
 
     /**
@@ -63,28 +60,28 @@ public class XMLElementNameTest extends TestCase {
     public void test_ReservedElementNames() {
         // retrieve list of reserved names and their classes
         XMLParser parser = new XMLParser();
-        HashMap<String, String> sElement2ClassMap = parser.getElement2ClassMap();
+        HashMap<String, String> element2ClassMap = parser.getElement2ClassMap();
 
         // allow 'parameter' for any of the various parameter derivatives, not just RealParameter
-        sElement2ClassMap.put("parameter", "beast.core.parameter.Parameter");
+        element2ClassMap.put("parameter", "beast.core.parameter.Parameter");
 
-        // check each plugin
-        List<String> sPluginNames = AddOnManager.find(beast.core.BEASTObject.class, AddOnManager.IMPLEMENTATION_DIR);
-        List<String> sImproperInputs = new ArrayList<String>();
-        for (String sPlugin : sPluginNames) {
+        // check each beastObject
+        List<String> pluginNames = AddOnManager.find(beast.core.BEASTObject.class, AddOnManager.IMPLEMENTATION_DIR);
+        List<String> improperInputs = new ArrayList<String>();
+        for (String beastObjectName : pluginNames) {
             try {
-                BEASTObject plugin = (BEASTObject) Class.forName(sPlugin).newInstance();
+                BEASTObject beastObject = (BEASTObject) Class.forName(beastObjectName).newInstance();
                 // check each input
-                List<Input<?>> inputs = plugin.listInputs();
+                List<Input<?>> inputs = beastObject.listInputs();
                 for (Input<?> input : inputs) {
-                    if (sElement2ClassMap.containsKey(input.getName())) {
-                        if (plugin.getClass() == null) {
-                            input.determineClass(plugin);
+                    if (element2ClassMap.containsKey(input.getName())) {
+                        if (beastObject.getClass() == null) {
+                            input.determineClass(beastObject);
                         }
                         Class<?> type = input.getType();
-                        String sBaseType = sElement2ClassMap.get(input.getName());
-                        if (!isDerivedType(type, sBaseType)) {
-                            sImproperInputs.add(sPlugin + "." + input.getName());
+                        String baseType = element2ClassMap.get(input.getName());
+                        if (!isDerivedType(type, baseType)) {
+                            improperInputs.add(beastObjectName + "." + input.getName());
                         }
                     }
                 }
@@ -94,25 +91,25 @@ public class XMLElementNameTest extends TestCase {
                 // ignore
             }
         }
-        if (sImproperInputs.size() > 0) {
-            String sStr = sImproperInputs.toString();
-            sStr = sStr.replaceAll(",", "\n");
-            System.err.println("Reserved element names used for wrong types in:\n" + sStr);
+        if (improperInputs.size() > 0) {
+            String str = improperInputs.toString();
+            str = str.replaceAll(",", "\n");
+            System.err.println("Reserved element names used for wrong types in:\n" + str);
         }
         // not activated till problem with naming is solved
-        assertTrue("Reserved element names used for wrong types in: " + sImproperInputs.toString(), sImproperInputs.size() == 0);
+        assertTrue("Reserved element names used for wrong types in: " + improperInputs.toString(), improperInputs.size() == 0);
     }
 
     /**
-     * true if type is a class equal to or derived from sBaseType *
+     * true if type is a class equal to or derived from baseType *
      */
-    boolean isDerivedType(Class<?> type, String sBaseType) {
-        if (sBaseType.equals(type.getName())) {
+    boolean isDerivedType(Class<?> type, String baseType) {
+        if (baseType.equals(type.getName())) {
             return true;
         }
         Class<?> superType = type.getSuperclass();
         if (!superType.equals(Object.class)) {
-            return isDerivedType(superType, sBaseType);
+            return isDerivedType(superType, baseType);
         }
 
         return false;
diff --git a/src/test/beast/integration/XMLProducerTest.java b/src/test/beast/integration/XMLProducerTest.java
index a4f427a..59fad5b 100644
--- a/src/test/beast/integration/XMLProducerTest.java
+++ b/src/test/beast/integration/XMLProducerTest.java
@@ -5,8 +5,6 @@ import java.io.FilenameFilter;
 import java.util.ArrayList;
 import java.util.List;
 
-import junit.framework.TestCase;
-
 import org.junit.Test;
 
 import beast.core.BEASTInterface;
@@ -14,6 +12,7 @@ import beast.core.Logger;
 import beast.util.Randomizer;
 import beast.util.XMLParser;
 import beast.util.XMLProducer;
+import junit.framework.TestCase;
 
 public class XMLProducerTest extends TestCase {
 
@@ -33,46 +32,52 @@ public class XMLProducerTest extends TestCase {
             Randomizer.setSeed(127);
             Logger.FILE_MODE = Logger.LogFileMode.overwrite;
             System.out.println("Test XML Examples in " + dir);
-            File sExampleDir = new File(dir);
-            String[] sExampleFiles = sExampleDir.list(new FilenameFilter() {
-                public boolean accept(File dir, String name) {
+            File exampleDir = new File(dir);
+            String[] exampleFiles = exampleDir.list(new FilenameFilter() {
+                @Override
+				public boolean accept(File dir, String name) {
                     return name.endsWith(".xml");
                 }
             });
 
-            List<String> sFailedFiles = new ArrayList<String>();
-            for (String fileName : sExampleFiles) {
+            List<String> failedFiles = new ArrayList<String>();
+            for (String fileName : exampleFiles) {
             	if (exceptions.contains(fileName)) {
                     System.out.println("Skipping exception " + fileName);
             	} else {
 	                System.out.println("Processing " + fileName);
-	                XMLProducer parser = new XMLProducer();
+	                XMLProducer producer = new XMLProducer();
 	                BEASTInterface o = null;
 	                try {
-	                    o = parser.parseFile(new File(dir + "/" + fileName));
+	                    o = producer.parseFile(new File(dir + "/" + fileName));
 	                } catch (Exception e) {
 	                	o = null;
 	                }
 	                if (o != null) {
-	                	String xml = parser.toXML(o);
+	                	String xml = producer.toXML(o);
+	                	
+	                    //FileWriter outfile = new FileWriter(new File("/tmp/XMLProducerTest.xml"));
+	                    //outfile.write(xml);
+	                    //outfile.close();
+
 	                	XMLParser parser2 = new XMLParser();
 	                    try {
 	                    	parser2.parseFragment(xml, false);
 	                    } catch (Exception e) {
 	                        System.out.println("test_ThatXmlExamplesProduces::Failed for " + fileName
 	                                + ": " + e.getMessage());
-	                        sFailedFiles.add(fileName);
+	                        failedFiles.add(fileName);
 	                    }
 	                }
 	                System.out.println("Done " + fileName);
             	}
             }
-            if (sFailedFiles.size() > 0) {
-                System.out.println("\ntest_ThatXmlExamplesProduces::Failed for : " + sFailedFiles.toString());
+            if (failedFiles.size() > 0) {
+                System.out.println("\ntest_ThatXmlExamplesProduces::Failed for : " + failedFiles.toString());
             } else {
                 System.out.println("\ntest_ThatXmlExamplesProduces::Success");
             }
-            assertTrue(sFailedFiles.toString(), sFailedFiles.size() == 0);
+            assertTrue(failedFiles.toString(), failedFiles.size() == 0);
         } catch (Exception e) {
             System.out.println("exception thrown ");
             System.out.println(e.getMessage());
diff --git a/src/test/beast/math/distributions/LogNormalDistributionModelTest.java b/src/test/beast/math/distributions/LogNormalDistributionModelTest.java
index 19714c6..39cde57 100644
--- a/src/test/beast/math/distributions/LogNormalDistributionModelTest.java
+++ b/src/test/beast/math/distributions/LogNormalDistributionModelTest.java
@@ -6,9 +6,6 @@ import org.junit.Test;
 import beast.core.parameter.RealParameter;
 import beast.math.distributions.LogNormalDistributionModel;
 import beast.util.XMLParser;
-
-
-
 import junit.framework.TestCase;
 
 public class LogNormalDistributionModelTest extends TestCase {
@@ -59,14 +56,14 @@ public class LogNormalDistributionModelTest extends TestCase {
     @Test
     public void testCalcLogP2() throws Exception {
         // does the same as testCalcLogP(), but with by constructing object through XML
-        String sXML = "<input spec='beast.math.distributions.LogNormalDistributionModel' " +
+        String xml = "<input spec='beast.math.distributions.LogNormalDistributionModel' " +
                 "offset='1200' " +
                 "M='2000' " +
                 "S='0.6' " +
                 "meanInRealSpace='true'/>";
         RealParameter p = new RealParameter(new Double[]{2952.6747000000014});
         XMLParser parser = new XMLParser();
-        LogNormalDistributionModel logNormal = (LogNormalDistributionModel) parser.parseBareFragment(sXML, true);
+        LogNormalDistributionModel logNormal = (LogNormalDistributionModel) parser.parseBareFragment(xml, true);
 
         double f0 = logNormal.calcLogP(p);
         assertEquals(-7.880210654973873, f0, 1e-10);
diff --git a/src/test/beast/math/distributions/MRCAPriorTest.java b/src/test/beast/math/distributions/MRCAPriorTest.java
index 5495c70..f15bbf7 100644
--- a/src/test/beast/math/distributions/MRCAPriorTest.java
+++ b/src/test/beast/math/distributions/MRCAPriorTest.java
@@ -8,9 +8,8 @@ import beast.evolution.alignment.TaxonSet;
 import beast.math.distributions.Exponential;
 import beast.math.distributions.MRCAPrior;
 import beast.util.TreeParser;
-
-import test.beast.BEASTTestCase;
 import junit.framework.TestCase;
+import test.beast.BEASTTestCase;
 
 public class MRCAPriorTest extends TestCase {
 
@@ -42,29 +41,29 @@ public class MRCAPriorTest extends TestCase {
         TaxonSet set = new TaxonSet();
         set.initByName("taxon", human, "taxon", bonobo, "taxon", chimp);
         prior.initByName("tree", tree, "taxonset", set, "monophyletic", true);
-        double fLogP = prior.calculateLogP();
-        assertEquals(fLogP, 0, 0);
+        double logP = prior.calculateLogP();
+        assertEquals(logP, 0, 0);
 
         /* check (gorilla, siamang) is NOT monophyletic **/
         set = new TaxonSet();
         set.initByName("taxon", gorilla, "taxon", siamang);
         prior.initByName("tree", tree, "taxonset", set, "monophyletic", true);
-        fLogP = prior.calculateLogP();
-        assertEquals(fLogP, Double.NEGATIVE_INFINITY, 0);
+        logP = prior.calculateLogP();
+        assertEquals(logP, Double.NEGATIVE_INFINITY, 0);
 
         /* check (gorilla, orangutan, siamang) is monophyletic **/
         set = new TaxonSet();
         set.initByName("taxon", gorilla, "taxon", orangutan, "taxon", siamang);
         prior.initByName("tree", tree, "taxonset", set, "monophyletic", true);
-        fLogP = prior.calculateLogP();
-        assertEquals(fLogP, 0, 0);
+        logP = prior.calculateLogP();
+        assertEquals(logP, 0, 0);
 
         /* check (human, gorilla) is NOT monophyletic **/
         set = new TaxonSet();
         set.initByName("taxon", human, "taxon", gorilla);
         prior.initByName("tree", tree, "taxonset", set, "monophyletic", true);
-        fLogP = prior.calculateLogP();
-        assertEquals(fLogP, Double.NEGATIVE_INFINITY, 0);
+        logP = prior.calculateLogP();
+        assertEquals(logP, Double.NEGATIVE_INFINITY, 0);
     }
 
     @Test
@@ -97,27 +96,27 @@ public class MRCAPriorTest extends TestCase {
 
         /* get distribution for set (human, bonobo, chimp) */
         prior.initByName("tree", tree, "taxonset", set, "monophyletic", true, "distr", exp);
-        double fLogP = prior.calculateLogP();
-        assertEquals(-0.024003, fLogP, BEASTTestCase.PRECISION);
+        double logP = prior.calculateLogP();
+        assertEquals(-0.024003, logP, BEASTTestCase.PRECISION);
 
         /* get distribution for set (human, chimp), do not require the set to by monophyletic */
         set = new TaxonSet();
         set.initByName("taxon", human, "taxon", chimp);
         prior.initByName("tree", tree, "taxonset", set, "monophyletic", false);
-        fLogP = prior.calculateLogP();
-        assertEquals(-0.024003, fLogP, BEASTTestCase.PRECISION);
+        logP = prior.calculateLogP();
+        assertEquals(-0.024003, logP, BEASTTestCase.PRECISION);
 
         /* get distribution for set (human, chimp), DO require the set to by monophyletic */
         prior.initByName("tree", tree, "taxonset", set, "monophyletic", true);
-        fLogP = prior.calculateLogP();
-        assertEquals(Double.NEGATIVE_INFINITY, fLogP, 0);
+        logP = prior.calculateLogP();
+        assertEquals(Double.NEGATIVE_INFINITY, logP, 0);
 
         /* get distribution for set (human, gorilla) = root, not monophyletic */
         set = new TaxonSet();
         set.initByName("taxon", human, "taxon", gorilla);
         prior.initByName("tree", tree, "taxonset", set, "monophyletic", false);
-        fLogP = prior.calculateLogP();
-        assertEquals(-0.024003 - 0.012035, fLogP, BEASTTestCase.PRECISION);
+        logP = prior.calculateLogP();
+        assertEquals(-0.024003 - 0.012035, logP, BEASTTestCase.PRECISION);
     }
 
 }
diff --git a/src/test/beast/math/distributions/MeanOfParametricDistributionTest.java b/src/test/beast/math/distributions/MeanOfParametricDistributionTest.java
index d4d3062..bf7bed6 100644
--- a/src/test/beast/math/distributions/MeanOfParametricDistributionTest.java
+++ b/src/test/beast/math/distributions/MeanOfParametricDistributionTest.java
@@ -11,9 +11,6 @@ import beast.math.distributions.LogNormalDistributionModel;
 import beast.math.distributions.Normal;
 import beast.math.distributions.Uniform;
 import beast.util.XMLParser;
-
-
-
 import junit.framework.TestCase;
 
 public class MeanOfParametricDistributionTest extends TestCase {
@@ -41,17 +38,17 @@ public class MeanOfParametricDistributionTest extends TestCase {
 		Gamma gamma = new Gamma();
 		gamma.initByName("alpha", "100", "beta", "10");
 		double mean = gamma.getMean();
-        assertEquals(mean, 10, 1e-10);
+        assertEquals(mean, 1000, 1e-10);
 
         gamma = new Gamma();
 		gamma.initByName("alpha", "100", "beta", "100");
 		mean = gamma.getMean();
-        assertEquals(mean, 1, 1e-10);
+        assertEquals(mean, 10000, 1e-10);
 
         gamma = new Gamma();
 		gamma.initByName("alpha", "100", "beta", "10", "offset", "3");
 		mean = gamma.getMean();
-        assertEquals(mean, 13, 1e-10);
+        assertEquals(mean, 1003, 1e-10);
 	}
 
 
@@ -94,7 +91,7 @@ public class MeanOfParametricDistributionTest extends TestCase {
             exp = new LogNormalDistributionModel();
     		exp.initByName("M", "1", "S", "1", "meanInRealSpace", false, "offset", "3");
     		mean = exp.getMean();
-            assertEquals(mean, 4, 1e-10);
+            assertEquals(mean, 4.4816890703380645, 1e-10);
         } catch (RuntimeException e) {
         	// we are fine here
         }
diff --git a/src/test/beast/util/AnnotatedRunnableTestClass.java b/src/test/beast/util/AnnotatedRunnableTestClass.java
new file mode 100644
index 0000000..c8301eb
--- /dev/null
+++ b/src/test/beast/util/AnnotatedRunnableTestClass.java
@@ -0,0 +1,97 @@
+package test.beast.util;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import beast.core.BEASTInterface;
+import beast.core.Description;
+import beast.core.Param;
+import beast.core.Runnable;
+import beast.evolution.alignment.Taxon;
+
+ at Description("Used for testing purposed only")
+public class AnnotatedRunnableTestClass extends Runnable {
+    
+    int param1;
+    List<Taxon> taxa;
+    List<Double> array;
+    
+	public List<Double> getArray() {
+		return array;
+	}
+
+	public void setArray(List<Double> array) {
+		this.array = array;
+	}
+
+	public void setArray(Double value) {
+		if (this.array == null) {
+			this.array = new ArrayList<>();
+		}
+		this.array.add(value);
+	}
+
+	public Integer getParam1() {
+		return param1;
+	}
+
+	public void setParam1(Integer param1) {
+		this.param1 = param1;
+	}
+
+	/** default constructor, should not be used **/
+	public AnnotatedRunnableTestClass() {
+    	this.param1 = 0;
+    	this.taxa = new ArrayList<>();
+	}
+
+	// note that if there are different constructors and an argument does not appear in the other constructor it has to be optional
+	public AnnotatedRunnableTestClass(
+			@Param(description = "test to see whether the JSON/XML parser/producer can handle annotated constructors", name = "param1", optional=true, defaultValue = "10") Integer param1,
+			@Param(description = "test to see whether the JSON/XML parser/producer can handle annotated List", name = "taxon", optional=true) List<Taxon> taxa) {
+    	this.param1 = param1;
+    	this.taxa = new ArrayList<>();
+    	this.taxa.addAll(taxa);
+    }
+	
+	public AnnotatedRunnableTestClass(
+			@Param(description = "test to see whether multiple constructors are handled, and list of Doubles", name = "array", optional=true) List<Double> array) {
+		this.array = array;
+	}
+    
+	@Override
+	public void initAndValidate() {
+	}
+
+	@Override
+	public String getID() {
+		return "JSONTest";
+	}
+
+	@Override
+	public void setID(String ID) {
+		// ignore
+	}
+
+    public List<Taxon> getTaxon() {
+		return taxa;
+	}
+	
+	public void setTaxon(Taxon taxon) {
+		this.taxa.add(taxon);
+	}
+	
+	Set<BEASTInterface> outputs = new HashSet<>();
+	
+	@Override
+	public Set<BEASTInterface> getOutputs() {
+		return outputs;
+	}
+
+	@Override
+	public void run() throws Exception {
+		System.out.println("We got a " + param1 + ". How's that?");		
+	}
+}
diff --git a/src/test/beast/util/JSONTest.java b/src/test/beast/util/JSONTest.java
index 9e85d38..2257ea1 100644
--- a/src/test/beast/util/JSONTest.java
+++ b/src/test/beast/util/JSONTest.java
@@ -1,29 +1,128 @@
 package test.beast.util;
 
 import java.io.File;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.List;
 
 import org.junit.Test;
 
 import beast.app.beauti.BeautiDoc;
+import beast.core.BEASTInterface;
 import beast.core.BEASTObject;
+import beast.core.parameter.RealParameter;
+import beast.evolution.alignment.Taxon;
 import beast.util.JSONParser;
 import beast.util.JSONProducer;
-
 import junit.framework.TestCase;
 
 public class JSONTest extends TestCase {
-	public static String JSON_FILE = "examples/testHKY.json";
+	public static String JSON_FILE = "examples/testUCLNclock.json";
 
     @Test
     public void testJSONtoXMLtoJSON() throws Exception {
     	JSONParser parser = new JSONParser();
-		BEASTObject plugin = parser.parseFile(new File(JSON_FILE));
+		BEASTObject beastObject = parser.parseFile(new File(JSON_FILE));
 		JSONProducer producer = new JSONProducer();
-		String actual = producer.toJSON(plugin).trim().replaceAll("\\s+", " ");
+		String actual = producer.toJSON(beastObject).trim();//.replaceAll("\\s+", " ");
 		
-		String expected = BeautiDoc.load(JSON_FILE).trim().replaceAll("\\s+", " ");
+		String expected = BeautiDoc.load(JSON_FILE).trim();//.replaceAll("\\s+", " ");
 		assertEquals("Produced JSON differs from original", 
 				expected, 
 				actual);
     }
+
+    @Test
+    public void testJSONFragmentParsing() throws Exception {
+    	JSONParser parser = new JSONParser();
+    	String json = "{version: \"2.3\",\n" + 
+    			"\n" + 
+    			"beast: [\n" + 
+    			"{spec:\"beast.core.parameter.RealParameter\",\n" +
+    			" value:\"2.345\"\n" +
+    			"}\n" +
+    			"]\n" +
+    			"}\n";
+    			;
+		List<Object> objects = parser.parseFragment(json, true);
+		assertEquals(1, objects.size());
+		RealParameter p = (RealParameter) objects.get(0);
+		assertEquals(2.345, p.getValue(), 1e-13);
+    }
+    	
+    @Test
+    public void testAnnotatedConstructor() throws Exception {
+    	List<Taxon> taxa = new ArrayList<>();
+    	taxa.add(new Taxon("first one"));
+    	taxa.add(new Taxon("second one"));
+    			
+    	AnnotatedRunnableTestClass t = new AnnotatedRunnableTestClass(3, taxa);
+    	
+    	JSONProducer producer = new JSONProducer();
+    	String json = producer.toJSON(t);
+
+    	assertEquals(3, (int) t.getParam1());
+
+    	
+        FileWriter outfile = new FileWriter(new File("/tmp/JSONTest.json"));
+        outfile.write(json);
+        outfile.close();
+
+    	
+    	JSONParser parser = new JSONParser();
+    	BEASTInterface b = parser.parseFile(new File("/tmp/JSONTest.json"));
+    	assertEquals(3, (int) ((AnnotatedRunnableTestClass) b).getParam1());
+    	assertEquals(2, ((AnnotatedRunnableTestClass) b).getTaxon().size());
+    	
+    	
+    	// test that default value for param1 comes through
+    	String json2 = "{version: \"2.3\",\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" + 
+    			"\n" + 
+    			"\n" + 
+    			"        {id: \"JSONTest\",\n" + 
+    			"         spec: \"test.beast.util.AnnotatedRunnableTestClass\",\n" + 
+    			"         taxon: [\n" + 
+    			"                 {id: \"first one\" },\n" + 
+    			"                 {id: \"second one\" }\n" + 
+    			"          ]\n" + 
+    			"        }\n" + 
+    			"]\n" + 
+    			"}";
+    	
+        outfile = new FileWriter(new File("/tmp/JSONTest2.json"));
+        outfile.write(json2);
+        outfile.close();
+
+        parser = new JSONParser();
+    	b = parser.parseFile(new File("/tmp/JSONTest2.json"));
+    	assertEquals(10, (int) ((AnnotatedRunnableTestClass) b).getParam1());
+    	assertEquals(2, ((AnnotatedRunnableTestClass) b).getTaxon().size());
+    	
+
+    	// test that array of doubles comes through in second constructor
+    	String json3 = "{version: \"2.3\",\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" + 
+    			"\n" + 
+    			"\n" + 
+    			"        {id: \"JSONTest\",\n" + 
+    			"         spec: \"test.beast.util.AnnotatedRunnableTestClass\",\n" + 
+    			"         array: [1.0, 2.0, 3.0]\n" + 
+    			"        }\n" + 
+    			"]\n" + 
+    			"}";
+    	
+        outfile = new FileWriter(new File("/tmp/JSONTest3.json"));
+        outfile.write(json3);
+        outfile.close();
+
+        parser = new JSONParser();
+    	b = parser.parseFile(new File("/tmp/JSONTest3.json"));
+    	assertEquals(3, ((AnnotatedRunnableTestClass) b).getArray().size());
+    }
+
 }
diff --git a/src/test/beast/util/NexusParserTest.java b/src/test/beast/util/NexusParserTest.java
index e3aab78..55052ca 100644
--- a/src/test/beast/util/NexusParserTest.java
+++ b/src/test/beast/util/NexusParserTest.java
@@ -1,49 +1,53 @@
 package test.beast.util;
 
-import junit.framework.TestCase;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeSet;
 
 import org.junit.Test;
 
 import beast.util.NexusParser;
-
-import java.io.File;
-import java.io.FilenameFilter;
-import java.io.StringReader;
-import java.util.*;
+import junit.framework.TestCase;
 
 public class NexusParserTest extends TestCase {
 
     @Test
     public void testThatNexusExamplesParse() {
         try {
-            String sDir = System.getProperty("user.dir") + "/examples/nexus";
-            System.out.println("Test Nexus Examples in " + sDir);
-            File sExampleDir = new File(sDir);
-            String[] sExampleFiles = sExampleDir.list(new FilenameFilter() {
-                public boolean accept(File dir, String name) {
+            String dirName = System.getProperty("user.dir") + "/examples/nexus";
+            System.out.println("Test Nexus Examples in " + dirName);
+            File exampleDir = new File(dirName);
+            String[] exampleFiles = exampleDir.list(new FilenameFilter() {
+                @Override
+				public boolean accept(File dir, String name) {
                     return name.endsWith(".nex") || name.endsWith(".nxs") ;
                 }
             });
 
-            List<String> sFailedFiles = new ArrayList<String>();
-            for (String sFileName : sExampleFiles) {
-                System.out.println("Processing " + sFileName);
+            List<String> failedFiles = new ArrayList<>();
+            for (String fileName : exampleFiles) {
+                System.out.println("Processing " + fileName);
                 NexusParser parser = new NexusParser();
                 try {
-                    parser.parseFile(new File(sDir + "/" + sFileName));
+                    parser.parseFile(new File(dirName + "/" + fileName));
                 } catch (Exception e) {
-                    System.out.println("ExampleNexusParsing::Failed for " + sFileName
+                    System.out.println("ExampleNexusParsing::Failed for " + fileName
                             + ": " + e.getMessage());
-                    sFailedFiles.add(sFileName);
+                    failedFiles.add(fileName);
                 }
-                System.out.println("Done " + sFileName);
+                System.out.println("Done " + fileName);
             }
-            if (sFailedFiles.size() > 0) {
-                System.out.println("\ntest_ThatNexusExamplesParse::Failed for : " + sFailedFiles.toString());
+            if (failedFiles.size() > 0) {
+                System.out.println("\ntest_ThatNexusExamplesParse::Failed for : " + failedFiles.toString());
             } else {
                 System.out.println("\ntest_ThatNexusExamplesParse::Success");
             }
-            assertTrue(sFailedFiles.toString(), sFailedFiles.size() == 0);
+            assertTrue(failedFiles.toString(), failedFiles.size() == 0);
         } catch (Exception e) {
             System.out.println("exception thrown ");
             System.out.println(e.getMessage());
@@ -72,7 +76,7 @@ public class NexusParserTest extends TestCase {
         NexusParser parser = new NexusParser();
         try {
 
-            Set<String> taxa = new TreeSet<String>();
+            Set<String> taxa = new TreeSet<>();
             taxa.add("ID0");
             taxa.add("ID1");
             taxa.add("ID2");
@@ -122,7 +126,7 @@ public class NexusParserTest extends TestCase {
         NexusParser parser = new NexusParser();
         try {
 
-            List<String> taxa = new ArrayList<String>();
+            List<String> taxa = new ArrayList<>();
             taxa.add("2");
             taxa.add("0");
             taxa.add("1");
@@ -150,9 +154,9 @@ public class NexusParserTest extends TestCase {
     @Test
     public void testAssumptionsParse() {
         try {
-            String sFile = System.getProperty("user.dir") + "/examples/nexus/Primates.nex";
+            String fileName = System.getProperty("user.dir") + "/examples/nexus/Primates.nex";
             NexusParser parser = new NexusParser();
-            parser.parseFile(new File(sFile));
+            parser.parseFile(new File(fileName));
             assertEquals(2, parser.filteredAlignments.size());
         } catch (Exception e) {
             System.out.println("exception thrown ");
diff --git a/src/test/beast/util/TreeParserTest.java b/src/test/beast/util/TreeParserTest.java
index d2d1eb2..d9d883f 100644
--- a/src/test/beast/util/TreeParserTest.java
+++ b/src/test/beast/util/TreeParserTest.java
@@ -1,11 +1,11 @@
 package test.beast.util;
 
-import beast.util.TreeParser;
-import junit.framework.TestCase;
+import org.junit.Assert;
 import org.junit.Test;
 
+import beast.util.TreeParser;
 
-public class TreeParserTest extends TestCase {
+public class TreeParserTest {
 
     @Test
     public void testFullyLabelledWithIntegers() {
@@ -19,14 +19,13 @@ public class TreeParserTest extends TestCase {
             TreeParser treeParser = new TreeParser(newick, false, false, isLabeled, 0);
             treeParser.offsetInput.setValue(0, treeParser);
 
-            assertEquals(newick.split(";")[0], treeParser.getRoot().toShortNewick(true));
+            Assert.assertEquals(newick.split(";")[0], treeParser.getRoot().toShortNewick(true));
 
         } catch (Exception e) {
             e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.  \
-            assertTrue("Exception!", false);
+            Assert.assertTrue("Exception!", false);
         }
 
-
     }
 
     @Test
@@ -34,20 +33,11 @@ public class TreeParserTest extends TestCase {
 
         String newick = "((A:1.0,B:1.0):1.0,(C:1.0,D:1.0):1.0):0.0;";
 
-//        try {
-
         boolean isLabeled = true;
 
         TreeParser treeParser = new TreeParser(newick, false, false, isLabeled, 1);
         System.out.println("adfgad");
-        assertEquals(newick.split(";")[0], treeParser.getRoot().toNewick());
-        // fix condition for adding the taxa and fix tree parse test
-
-//        } catch (Exception e) {
-//            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.  \
-//            assertTrue("Exception!", false);
-//        }
-
+        Assert.assertEquals(newick.split(";")[0], treeParser.getRoot().toNewick());
 
     }
 
@@ -63,7 +53,7 @@ public class TreeParserTest extends TestCase {
         
         String newick2 = treeParser.getRoot().toNewick();
         
-        assertEquals(newick.replaceAll(";", ""), newick2);
+        Assert.assertEquals(newick.replaceAll(";", ""), newick2);
     }
 
     @Test
@@ -77,11 +67,11 @@ public class TreeParserTest extends TestCase {
 
             TreeParser treeParser = new TreeParser(newick, false, false, isLabeled, 1);
 
-            assertEquals(newick.split(";")[0], treeParser.getRoot().toNewick());
+            Assert.assertEquals(newick.split(";")[0], treeParser.getRoot().toNewick());
 
         } catch (Exception e) {
             e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.  \
-            assertTrue("Exception!", false);
+            Assert.assertTrue("Exception!", false);
         }
 
 
@@ -98,13 +88,26 @@ public class TreeParserTest extends TestCase {
         try {
             boolean isLabeled = true;
             TreeParser treeParser = new TreeParser(newick, false, false, isLabeled, 1);
+            System.out.println(treeParser.getRoot().toNewick());
         } catch (RuntimeException e) {
             e.printStackTrace();
             exceptionRaised = true;
         }
 
-        assertTrue(exceptionRaised);
+        Assert.assertTrue(exceptionRaised);
     }
 
+    @Test
+    public void testMultifurcations() throws Exception {
+
+        String newick = "((A:1.0,B:1.0,C:1.0):1.0,(D:1.0,E:1.0,F:1.0,G:1.0):1.0):0.0;";
+        String binaryNewick = "((A:1.0,(B:1.0,C:1.0):0.0):1.0,(D:1.0,(E:1.0,(F:1.0,G:1.0):0.0):0.0):1.0):0.0;";
+
+        boolean isLabeled = true;
+
+        TreeParser treeParser = new TreeParser(newick, false, false, isLabeled, 1);
+        Assert.assertEquals(binaryNewick.split(";")[0], treeParser.getRoot().toNewick());
+
+    }
 
 }
diff --git a/src/test/beast/util/XMLTest.java b/src/test/beast/util/XMLTest.java
new file mode 100644
index 0000000..6e7854d
--- /dev/null
+++ b/src/test/beast/util/XMLTest.java
@@ -0,0 +1,43 @@
+package test.beast.util;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import beast.core.BEASTInterface;
+import beast.evolution.alignment.Taxon;
+import beast.util.XMLParser;
+import beast.util.XMLProducer;
+import junit.framework.TestCase;
+
+public class XMLTest extends TestCase {
+
+    @Test
+    public void testAnnotatedConstructor2() throws Exception {
+    	List<Taxon> taxa = new ArrayList<>();
+    	taxa.add(new Taxon("first one"));
+    	taxa.add(new Taxon("second one"));
+
+    	AnnotatedRunnableTestClass t = new AnnotatedRunnableTestClass(3, taxa);
+    	
+    	XMLProducer producer = new XMLProducer();
+    	String xml = producer.toXML(t);
+
+    	assertEquals(3, (int) t.getParam1());
+
+    	
+        FileWriter outfile = new FileWriter(new File("/tmp/XMLTest.xml"));
+        outfile.write(xml);
+        outfile.close();
+
+    	
+    	XMLParser parser = new XMLParser();
+    	BEASTInterface b = parser.parseFile(new File("/tmp/XMLTest.xml"));
+    	assertEquals(3, (int) ((AnnotatedRunnableTestClass) b).getParam1());
+    	assertEquals(2, ((AnnotatedRunnableTestClass) b).getTaxon().size());
+    }
+
+}
diff --git a/templates/Standard.xml b/templates/Standard.xml
index 138450c..4ee839b 100644
--- a/templates/Standard.xml
+++ b/templates/Standard.xml
@@ -149,7 +149,7 @@
 		<alignmentProvider id="Import Alignment" spec='BeautiAlignmentProvider' template='@StandardPartitionTemplate'/>
 
 
-        <partitiontemplate id='StandardPartitionTemplate' spec='BeautiSubTemplate' class='beast.evolution.likelihood.TreeLikelihood' mainid='mcmc'>
+        <partitiontemplate id='StandardPartitionTemplate' spec='BeautiSubTemplate' class='beast.evolution.likelihood.ThreadedTreeLikelihood' mainid='mcmc'>
 <![CDATA[
             <!-- site model                                                              -->
             <plugin spec='SiteModel' id="SiteModel.s:$(n)" gammaCategoryCount='0'>
@@ -159,7 +159,7 @@
                 <shape               spec='parameter.RealParameter' id='gammaShape.s:$(n)' value='1.0'         estimate='false'/>
             </plugin>
 
-            <plugin spec='TreeLikelihood' id="treeLikelihood.$(n)">
+            <plugin spec='ThreadedTreeLikelihood' id="treeLikelihood.$(n)">
                 <data idref="data"/>
                 <tree idref="Tree.t:$(n)"/>
                 <siteModel idref="SiteModel.s:$(n)"/>
diff --git a/templates/StarBeast.xml b/templates/StarBeast.xml
index 0b69a50..a32718f 100644
--- a/templates/StarBeast.xml
+++ b/templates/StarBeast.xml
@@ -199,7 +199,7 @@
 
             <plugin id='TreeHeight.t:$(n)' spec='beast.evolution.tree.TreeHeightLogger' tree='@Tree.t:$(n)'/>
 
-            <logger id='treelog.t:$(n)' spec='beast.core.Logger' logEvery="5000" fileName="$(tree).$(seed).trees" mode='tree'>
+            <logger id='treelog.t:$(n)' spec='beast.core.Logger' logEvery="5000" fileName="$(tree).trees" mode='tree'>
 	            <log id='TreeWithMetaDataLogger.t:$(n)' spec='beast.evolution.tree.TreeWithMetaDataLogger' tree='@Tree.t:$(n)'>
 	            </log>
             </logger>
@@ -389,7 +389,7 @@
 	
 	    <operator id='YuleBirthRateScaler.t:Species' spec='ScaleOperator' scaleFactor="0.75" weight="3" parameter="@birthRate.t:Species"/>
 
-        <logger id='tracelog' logEvery="5000" fileName="beast_$(seed).log" sort="smart">
+        <logger id='tracelog' logEvery="5000" fileName="beast.log" sort="smart">
 	        <model idref='posterior'/>
             <log idref="posterior"/>
             <log idref="likelihood"/>
@@ -397,10 +397,11 @@
 			<log idref="speciescoalescent"/>
 			<log idref="birthRate.t:Species"/>
 			<log idref="YuleModel.t:Species"/>
+			<log idref="popMean"/>
             <log id='TreeHeight.Species' spec='beast.evolution.tree.TreeHeightLogger' tree='@Tree.t:Species'/>
         </logger>
 
-		<logger fileName="species_$(seed).trees" id="speciesTreeLogger" logEvery="5000" mode="tree">
+		<logger fileName="species.trees" id="speciesTreeLogger" logEvery="5000" mode="tree">
 		    <log id='SpeciesTreeLoggerX' spec='SpeciesTreeLogger' popSize='@popSize' popSizeTop="@popSizeTop" tree="@Tree.t:Species" speciesTreePrior='@SpeciesTreePopSize.Species' treetop='@treeTopFinder'/>
 		</logger>
 
diff --git a/templates/TreePriors.xml b/templates/TreePriors.xml
index aafdf2f..54bcf30 100644
--- a/templates/TreePriors.xml
+++ b/templates/TreePriors.xml
@@ -336,7 +336,7 @@
                 <distr id="popPriorDist.EBSP" mean="@populationMean.alltrees" spec="Exponential"/>
             </prior>
 
-            <logger id="EBSPLogger" fileName='EBSP.$(seed).log' logEvery='5000' model="@demographic.alltrees">
+            <logger id="EBSPLogger" fileName='EBSP.log' logEvery='5000' model="@demographic.alltrees">
                 <log idref='demographic.alltrees'/>
             </logger>
             <log id='sumIndicators' spec='beast.core.util.Sum' arg='@indicators.alltrees'/>
diff --git a/version.xml b/version.xml
new file mode 100644
index 0000000..cc9b99b
--- /dev/null
+++ b/version.xml
@@ -0,0 +1 @@
+<addon name='BEAST' version='2.4.0' url="file:///Users/remco/tmp/BEAST.package.2.4.0.zip"/>

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



More information about the debian-med-commit mailing list