[med-svn] [libjloda-java] 01/05: New upstream version 0.0+20170502

Andreas Tille tille at debian.org
Wed May 3 10:44:54 UTC 2017


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

tille pushed a commit to branch master
in repository libjloda-java.

commit 1fe838422f740e43ebc331052394ae3d45ad8de8
Author: Andreas Tille <tille at debian.org>
Date:   Wed May 3 11:50:49 2017 +0200

    New upstream version 0.0+20170502
---
 antbuild/build.xml                                 |  54 +--
 jars/VectorGraphics2D-0.11.jar                     | Bin 0 -> 101185 bytes
 jars/VectorGraphics2D-License.txt                  | 133 ++++++
 jars/gnujpdf-license.txt                           | 460 ---------------------
 jars/gnujpdf-src.jar                               | Bin 75488 -> 0 bytes
 jars/gnujpdf.jar                                   | Bin 59551 -> 0 bytes
 src/com/apple/eawt/AboutHandler.java               |  30 ++
 src/com/apple/eawt/AppEvent.java                   |  40 ++
 src/com/apple/eawt/Application.java                |  48 +++
 src/com/apple/eawt/PreferencesHandler.java         |  29 ++
 src/com/apple/eawt/QuitHandler.java                |  29 ++
 src/com/apple/eawt/QuitResponse.java               |  29 ++
 src/jloda/export/EPSExportType.java                |   2 +-
 src/jloda/export/EPSGraphics.java                  |   2 +-
 src/jloda/export/ExportGraphicType.java            |   2 +-
 src/jloda/export/ExportImageDialog.java            |   2 +-
 src/jloda/export/ExportManager.java                |   6 +-
 src/jloda/export/GIFExportType.java                |   2 +-
 src/jloda/export/GraphicsFileFilters.java          |   2 +-
 src/jloda/export/JPGExportType.java                |   2 +-
 src/jloda/export/PDFExportType.java                |  26 +-
 src/jloda/export/PNGExportType.java                |   4 +-
 src/jloda/export/RenderedExportType.java           |   2 +-
 src/jloda/export/SVGExportType.java                |   2 +-
 src/jloda/export/SVGStringExportType.java          |   2 +-
 src/jloda/export/SaveImageDialog.java              |   2 +-
 src/jloda/export/TransferableGraphic.java          |   2 +-
 src/jloda/export/gifEncode/DirectGif89Frame.java   |   2 +-
 src/jloda/export/gifEncode/Gif89Encoder.java       |   2 +-
 src/jloda/export/gifEncode/Gif89Frame.java         |   2 +-
 src/jloda/export/gifEncode/IndexGif89Frame.java    |   2 +-
 src/jloda/export/gifEncode/Put.java                |   2 +-
 src/jloda/fx/ASelectionModel.java                  | 240 +++++++++++
 src/jloda/fx/ExtendedFXMLLoader.java               |  88 ++++
 src/jloda/fx/JButtonWithFXAction.java              |  53 +++
 src/jloda/graph/Dijkstra.java                      |   2 +-
 src/jloda/graph/Edge.java                          |   2 +-
 src/jloda/graph/EdgeArray.java                     |   4 +-
 src/jloda/graph/EdgeAssociation.java               |   2 +-
 src/jloda/graph/EdgeDoubleArray.java               |   2 +-
 src/jloda/graph/EdgeDoubleMap.java                 |   2 +-
 src/jloda/graph/EdgeIntegerArray.java              |   2 +-
 src/jloda/graph/EdgeIntegerMap.java                |   2 +-
 src/jloda/graph/EdgeMap.java                       |   3 +-
 src/jloda/graph/EdgeSet.java                       |   2 +-
 src/jloda/graph/Graph.java                         |  28 +-
 src/jloda/graph/GraphBase.java                     |   2 +-
 src/jloda/graph/GraphUpdateAdapter.java            |   2 +-
 src/jloda/graph/GraphUpdateListener.java           |   2 +-
 src/jloda/graph/IllegalSelfEdgeException.java      |   2 +-
 src/jloda/graph/MaxClique.java                     |   2 +-
 src/jloda/graph/Node.java                          |   8 +-
 src/jloda/graph/NodeArray.java                     |   4 +-
 src/jloda/graph/NodeAssociation.java               |   2 +-
 src/jloda/graph/NodeData.java                      |  42 +-
 src/jloda/graph/NodeDoubleArray.java               |   2 +-
 src/jloda/graph/NodeDoubleMap.java                 |   2 +-
 src/jloda/graph/NodeEdge.java                      |   4 +-
 src/jloda/graph/NodeEdgeEnumeration.java           |   2 +-
 src/jloda/graph/NodeIntegerArray.java              |   2 +-
 src/jloda/graph/NodeIntegerMap.java                |   2 +-
 src/jloda/graph/NodeMap.java                       |   2 +-
 src/jloda/graph/NodeSet.java                       |   2 +-
 src/jloda/graph/Num2EdgeArray.java                 |   2 +-
 src/jloda/graph/Num2NodeArray.java                 |   2 +-
 src/jloda/graphview/DefaultGraphDrawer.java        |   2 +-
 src/jloda/graphview/DefaultNodeDrawer.java         | 184 ++++++---
 src/jloda/graphview/EdgeActionAdapter.java         |   2 +-
 src/jloda/graphview/EdgeActionListener.java        |   2 +-
 src/jloda/graphview/EdgeView.java                  |  11 +-
 src/jloda/graphview/GraphEditor.java               |   2 +-
 src/jloda/graphview/GraphView.java                 |  22 +-
 src/jloda/graphview/GraphViewBase.java             |   2 +-
 src/jloda/graphview/GraphViewListener.java         |   2 +-
 src/jloda/graphview/IGraphDrawer.java              |   2 +-
 src/jloda/graphview/IGraphViewListener.java        |   2 +-
 src/jloda/graphview/INodeDrawer.java               |   2 +-
 src/jloda/graphview/INodeEdgeFormatable.java       |   2 +-
 src/jloda/graphview/IPopupListener.java            |   2 +-
 src/jloda/graphview/ITransformChangeListener.java  |   2 +-
 src/jloda/graphview/LabelLayoutRTree.java          |   2 +-
 src/jloda/graphview/LabelLayouter.java             |   2 +-
 src/jloda/graphview/LabelOverlapAvoider.java       |   2 +-
 src/jloda/graphview/Magnifier.java                 |   2 +-
 src/jloda/graphview/MagnifierUtil.java             |   2 +-
 src/jloda/graphview/NodeActionAdapter.java         |   2 +-
 src/jloda/graphview/NodeActionListener.java        |   2 +-
 src/jloda/graphview/NodeImage.java                 |   2 +-
 src/jloda/graphview/NodeShape.java                 |  38 ++
 src/jloda/graphview/NodeShapeIcon.java             |  54 +++
 src/jloda/graphview/NodeView.java                  |  72 ++--
 src/jloda/graphview/PanelActionListener.java       |   2 +-
 src/jloda/graphview/ScrollPaneAdjuster.java        |   2 +-
 src/jloda/graphview/Transform.java                 |   2 +-
 src/jloda/graphview/ViewBase.java                  |   2 +-
 src/jloda/gui/About.java                           |   2 +-
 src/jloda/gui/ActionJList.java                     |   2 +-
 src/jloda/gui/AppleStuff.java                      |   2 +-
 src/jloda/gui/ChooseColorDialog.java               |   2 +-
 src/jloda/gui/ChooseFileDialog.java                |  25 +-
 src/jloda/gui/ChooseFontDialog.java                |   2 +-
 src/jloda/gui/ColorTableManager.java               |   5 +-
 src/jloda/gui/DefaultLabelGetter.java              |   2 +-
 src/jloda/gui/GraphViewPopupListener.java          |  14 +-
 src/jloda/gui/HistogramPanel.java                  |   2 +-
 src/jloda/gui/ILabelGetter.java                    |   2 +-
 src/jloda/gui/IMenuModifier.java                   |   4 +-
 src/jloda/gui/IPopMenuModifier.java                |  31 ++
 src/jloda/gui/IPopupMenuModifier.java              |   2 +-
 src/jloda/gui/IToolBarModifier.java                |   4 +-
 src/jloda/gui/ListTransferHandler.java             |   2 +-
 src/jloda/gui/MemoryUsageManager.java              |   4 +-
 src/jloda/gui/MenuBar.java                         |   7 +-
 src/jloda/gui/MenuConfiguration.java               |   2 +-
 src/jloda/gui/Message.java                         |   2 +-
 src/jloda/gui/PopupMenu.java                       |  45 +-
 src/jloda/gui/ProgressDialog.java                  |   4 +-
 src/jloda/gui/ReorderListDialog.java               |   2 +-
 src/jloda/gui/StatusBar.java                       | 167 ++++----
 src/jloda/gui/ToolBar.java                         |   7 +-
 src/jloda/gui/WindowListenerAdapter.java           |   2 +-
 src/jloda/gui/WrapLayout.java                      |   2 +-
 src/jloda/gui/commands/CommandBase.java            |   2 +-
 src/jloda/gui/commands/CommandManager.java         |   6 +-
 src/jloda/gui/commands/ICheckBoxCommand.java       |   2 +-
 src/jloda/gui/commands/ICommand.java               |   2 +-
 src/jloda/gui/commands/MenuCreator.java            |   8 +-
 src/jloda/gui/commands/TeXGenerator.java           |   2 +-
 src/jloda/gui/commands/WrappedCheckBoxCommand.java |   2 +-
 src/jloda/gui/commands/WrappedCommand.java         |   2 +-
 src/jloda/gui/director/IDirectableViewer.java      |   2 +-
 src/jloda/gui/director/IDirector.java              |   2 +-
 src/jloda/gui/director/IDirectorListener.java      |   2 +-
 src/jloda/gui/director/IMainViewer.java            |   2 +-
 .../gui/director/IProjectsChangedListener.java     |   2 +-
 src/jloda/gui/director/IUpdateableView.java        |   2 +-
 src/jloda/gui/director/IUsesHeatMapColors.java     |  33 ++
 src/jloda/gui/director/IViewerWithFindToolBar.java |   2 +-
 src/jloda/gui/director/IViewerWithLegend.java      |   2 +-
 src/jloda/gui/director/ProjectManager.java         |   9 +-
 ...Searchers.java => CompositeObjectSearcher.java} | 185 ++++-----
 src/jloda/gui/find/EdgeLabelSearcher.java          |   2 +-
 src/jloda/gui/find/EmptySearcher.java              |   2 +-
 src/jloda/gui/find/FindToolBar.java                |   2 +-
 src/jloda/gui/find/FindWindow.java                 |   2 +-
 src/jloda/gui/find/IFindDialog.java                |   2 +-
 src/jloda/gui/find/IObjectSearcher.java            |   2 +-
 src/jloda/gui/find/ISearcher.java                  |   2 +-
 src/jloda/gui/find/ITextSearcher.java              |   2 +-
 src/jloda/gui/find/JListSearcher.java              |   2 +-
 src/jloda/gui/find/JTableSearcher.java             |   2 +-
 src/jloda/gui/find/JTreeSearcher.java              |   2 +-
 src/jloda/gui/find/NodeLabelSearcher.java          |   2 +-
 src/jloda/gui/find/SearchActions.java              |  12 +-
 src/jloda/gui/find/SearchManager.java              |   4 +-
 src/jloda/gui/find/SingleStringSearcher.java       | 154 +++++++
 src/jloda/gui/find/TableSearcher.java              |   2 +-
 src/jloda/gui/find/TextAreaSearcher.java           |   2 +-
 src/jloda/gui/format/Formatter.java                |  31 +-
 src/jloda/gui/format/FormatterActions.java         |  20 +-
 src/jloda/gui/format/FormatterMenuBar.java         |   2 +-
 src/jloda/gui/format/IFormatterListener.java       |   2 +-
 src/jloda/gui/message/MessageWindow.java           |   2 +-
 src/jloda/gui/message/MessageWindowActions.java    |   2 +-
 src/jloda/gui/message/MessageWindowMenuBar.java    |   2 +-
 src/jloda/phylo/HomoplasyScore.java                |   2 +-
 src/jloda/phylo/PhyloGraph.java                    |  10 +-
 src/jloda/phylo/PhyloGraphView.java                |   2 +-
 src/jloda/phylo/PhyloTree.java                     |  52 ++-
 src/jloda/phylo/PhyloTreeUtils.java                |   2 +-
 src/jloda/phylo/PhyloTreeView.java                 |  13 +-
 src/jloda/phylo/TreeDrawerAngled.java              |   2 +-
 src/jloda/phylo/TreeDrawerCircular.java            |   2 +-
 src/jloda/phylo/TreeDrawerParallel.java            |   2 +-
 src/jloda/phylo/TreeDrawerRadial.java              |   2 +-
 src/jloda/phylo/TreeParseException.java            |   2 +-
 src/jloda/progs/ApproximateBinaryExpansion.java    |   2 +-
 src/jloda/progs/ApproximateSquareRootOf2.java      |   2 +-
 src/jloda/progs/CoverDigraph.java                  |   2 +-
 src/jloda/progs/Date2Number.java                   |   2 +-
 src/jloda/progs/GeneEvolutionSimulator.java        |   2 +-
 src/jloda/progs/GraphPather.java                   |   2 +-
 src/jloda/progs/GraphViewDemo.java                 |   2 +-
 src/jloda/progs/Gunzip.java                        |   2 +-
 src/jloda/progs/ImageProcessor.java                |   2 +-
 src/jloda/progs/JTableWithRowHeaders.java          |   2 +-
 src/jloda/progs/Lines2FastA.java                   |   2 +-
 src/jloda/progs/MABlocker.java                     |   2 +-
 src/jloda/progs/MASampler.java                     |   2 +-
 src/jloda/progs/NewMABlocker.java                  |   2 +-
 src/jloda/progs/NextMABlocker.java                 |   2 +-
 src/jloda/progs/QuasiMedianClosure.java            |   2 +-
 src/jloda/progs/QuasiMedianNetwork.java            |   6 +-
 src/jloda/progs/RandomDNAGenerator.java            |   2 +-
 src/jloda/progs/RandomizeLines.java                |   2 +-
 src/jloda/progs/ReadTrimmer.java                   |   2 +-
 src/jloda/progs/SharedGenesDistance.java           |   2 +-
 src/jloda/progs/Tree2MeganCSV.java                 |   2 +-
 src/jloda/progs/TreeViewDemo.java                  |   2 +-
 src/jloda/util/Alert.java                          |   2 +-
 src/jloda/util/ArgsOptions.java                    |   4 +-
 src/jloda/util/Basic.java                          | 349 +++++++++++++---
 src/jloda/util/BlastFileFilter.java                |   2 +-
 src/jloda/util/Cache.java                          |   2 +-
 src/jloda/util/CanceledException.java              |   2 +-
 src/jloda/util/Colors.java                         |   2 +-
 src/jloda/util/CommandLineOptions.java             |   2 +-
 src/jloda/util/ConvexHull.java                     |   4 +-
 src/jloda/util/Counter.java                        |   2 +-
 src/jloda/util/Cursors.java                        |   2 +-
 src/jloda/util/DNAComplexityMeasure.java           |   2 +-
 src/jloda/util/DrawOval.java                       | 165 --------
 src/jloda/util/EditDistance.java                   |   2 +-
 src/jloda/util/FastA.java                          |   2 +-
 src/jloda/util/FastaFileFilter.java                |  25 +-
 src/jloda/util/FileFilter.java                     |   2 +-
 src/jloda/util/FileFilterBase.java                 |   2 +-
 src/jloda/util/FileInputIterator.java              |   4 +-
 src/jloda/util/FileIterator.java                   |   2 +-
 src/jloda/util/GZipUtils.java                      |   2 +-
 src/jloda/util/Geometry.java                       |   2 +-
 src/jloda/util/HeatSpectrum.java                   |   2 +-
 src/jloda/util/ICloseableIterator.java             |   2 +-
 src/jloda/util/IFileIterator.java                  |   2 +-
 src/jloda/util/IViewerWithJComponent.java          |  35 ++
 src/jloda/util/IteratorAdapter.java                |   2 +-
 src/jloda/util/JointIterators.java                 |  63 +++
 src/jloda/util/License.java                        | 353 ----------------
 src/jloda/util/ListOfLongs.java                    |   2 +-
 src/jloda/util/MenuMnemonics.java                  |   2 +-
 src/jloda/util/MultiIterator.java                  |  88 ++++
 src/jloda/util/MultiLineCellRenderer.java          |   2 +-
 src/jloda/util/NexusFileFilter.java                |   2 +-
 src/jloda/util/NotOwnerException.java              |   2 +-
 src/jloda/util/Pair.java                           |  47 ++-
 src/jloda/util/PeakMemoryUsageMonitor.java         |   2 +-
 src/jloda/util/PhylipUtils.java                    |   2 +-
 src/jloda/util/PluginClassLoader.java              |  31 +-
 src/jloda/util/PolygonDouble.java                  |   2 +-
 src/jloda/util/ProgramProperties.java              |   5 +-
 src/jloda/util/ProgressCmdLine.java                |   2 +-
 src/jloda/util/ProgressListener.java               |   2 +-
 src/jloda/util/ProgressPercentage.java             |   2 +-
 src/jloda/util/ProgressSilent.java                 |   2 +-
 src/jloda/util/PropertiesListListener.java         |   2 +-
 src/jloda/util/ProteinComplexityMeasure.java       |   2 +-
 src/jloda/util/RTFFileFilter.java                  |   2 +-
 src/jloda/util/RTree.java                          |   2 +-
 src/jloda/util/RandomGaussian.java                 |   2 +-
 src/jloda/util/RememberingComboBox.java            |   2 +-
 src/jloda/util/ResourceManager.java                |   2 +-
 src/jloda/util/RunLater.java                       |   2 +-
 src/jloda/util/SequenceUtils.java                  |   5 +-
 src/jloda/util/Shapes.java                         |  98 +++++
 src/jloda/util/Signer.java                         |   2 +-
 src/jloda/util/Single.java                         |   2 +-
 src/jloda/util/State.java                          |   2 +-
 src/jloda/util/Statistics.java                     |  86 +++-
 src/jloda/util/StreamGobbler.java                  |   2 +-
 src/jloda/util/StringParser.java                   |   2 +-
 src/jloda/util/Task.java                           |   2 +-
 src/jloda/util/TemporaryFileSet.java               |   2 +-
 src/jloda/util/TextFileFilter.java                 |   2 +-
 src/jloda/util/TextPrinter.java                    |   2 +-
 src/jloda/util/TextWindow.java                     |   2 +-
 src/jloda/util/TimeStamp.java                      |   2 +-
 src/jloda/util/ToolTipHelper.java                  |   2 +-
 src/jloda/util/Triplet.java                        |   2 +-
 src/jloda/util/UsageException.java                 |   2 +-
 src/jloda/util/lang/Language.java                  |   2 +-
 src/jloda/util/lang/Translator.java                |   2 +-
 src/jloda/util/parse/NexusStreamParser.java        |  45 +-
 src/jloda/util/parse/NexusStreamTokenizer.java     |   2 +-
 src/jloda/util/shapes/TaxaSetShape.java            |  76 ----
 274 files changed, 2634 insertions(+), 1850 deletions(-)

diff --git a/antbuild/build.xml b/antbuild/build.xml
index 73bc28e..3c893e5 100644
--- a/antbuild/build.xml
+++ b/antbuild/build.xml
@@ -1,29 +1,37 @@
 <project name="JLODA" default="compile" basedir=".">
+    <!-- set global properties for this build -->
+    <property name="jlodaSrcDir" value="../src"/>
+    <property name="srcDir" value="src"/>
+    <property name="classDir" value="class"/>
+    <property name="docDir" value="doc"/>
 
 
-	<path id="build.classpath">
+    <path id="build.classpath">
 	    <fileset dir="../../jloda/jars"  includes="*.jar"/>
     	    <fileset dir="../../jloda/jars/batik-1.8"  includes="*.jar"/>
 
     </path>
 
-
-    <!-- set global properties for this build -->
-    <property name="src" value="../src"/>
-    <property name="build" value="class"/>
-    <property name="doc" value="doc"/>
+    <!-- init -->
     <target name="init">
-        <mkdir dir="${build}"/>
-        <mkdir dir="${doc}"/>
-        <!-- Create the time stamp -->
-        <tstamp/>
+        <mkdir dir="${srcDir}"/>
+        <mkdir dir="${classDir}"/>
+        <mkdir dir="${docDir}"/>
+    </target>
+
+
+    <!-- copy sources -->
+    <target name="copy_sources" depends="init">
+        <copy todir="${srcDir}">
+            <fileset dir="${jlodaSrcDir}" excludes="com/apple/**"/>
+        </copy>
     </target>
 
-    <target name="compile" depends="init">
+     <target name="compile" depends="copy_sources">
 	    <!-- Compile the java code from ${src} into ${build} -->
 	     <javac  includeantruntime="false"
-        	srcdir="${src}"
-               destdir="${build}"
+        	srcdir="${srcDir}"
+               destdir="${classDir}"
                debug="on"
 	       classpathref="build.classpath">
 	       <compilerarg value="-XDignore.symbol.file=true"/> 
@@ -33,27 +41,21 @@
     <target name="jar" depends="compile">
         <!-- Put everything in ${build} into a jar file -->
         <jar jarfile="jloda.jar"
-             basedir="${build}"
+             basedir="${classDir}"
                 />
     </target>
 
     <target name="clean">
-        <!-- Delete the ${build} directory tree -->
-        <delete dir="${build}"/>
-    </target>
-
-    <target name="aseptic_clean">
-        <!-- Delete the ${build} directory tree -->
-        <delete dir="${build}"/>
-        <!-- Delete the ${doc} directory tree -->
-        <delete dir="${doc}"/>
+        <delete dir="${classDir}" includeEmptyDirs="true"/>
+        <delete dir="${srcDir}" includeEmptyDirs="true"/>
+        <delete file="${docDir}"/>
     </target>
 
-    <target name="doc" depends="init">
+    <target name="doc" depends="copy_sources">
         <javadoc packagenames=
                 "jloda.*"
-                 sourcepath="${src}"
-                 destdir="${doc}"
+                 sourcepath="${classDir}"
+                 destdir="${docDir}"
                  author="true"
                  version="true"
                  verbose="true"
diff --git a/jars/VectorGraphics2D-0.11.jar b/jars/VectorGraphics2D-0.11.jar
new file mode 100644
index 0000000..e1f5490
Binary files /dev/null and b/jars/VectorGraphics2D-0.11.jar differ
diff --git a/jars/VectorGraphics2D-License.txt b/jars/VectorGraphics2D-License.txt
new file mode 100644
index 0000000..2ddabac
--- /dev/null
+++ b/jars/VectorGraphics2D-License.txt
@@ -0,0 +1,133 @@
+GNU LESSER GENERAL PUBLIC LICENSE
+
+Version 3, 29 June 2007
+
+Copyright © 2007 Free Software Foundation, Inc. <http://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this license 
+document, but changing it is not allowed.
+
+This version of the GNU Lesser General Public License incorporates the terms 
+and conditions of version 3 of the GNU General Public License, supplemented by 
+the additional permissions listed below.
+
+0. Additional Definitions.
+As used herein, “this License” refers to version 3 of the GNU Lesser General 
+Public License, and the “GNU GPL” refers to version 3 of the GNU General Public 
+License.
+
+“The Library” refers to a covered work governed by this License, other than an 
+Application or a Combined Work as defined below.
+
+An “Application” is any work that makes use of an interface provided by the 
+Library, but which is not otherwise based on the Library. Defining a subclass 
+of a class defined by the Library is deemed a mode of using an interface 
+provided by the Library.
+
+A “Combined Work” is a work produced by combining or linking an Application 
+with the Library. The particular version of the Library with which the Combined 
+Work was made is also called the “Linked Version”.
+
+The “Minimal Corresponding Source” for a Combined Work means the Corresponding 
+Source for the Combined Work, excluding any source code for portions of the 
+Combined Work that, considered in isolation, are based on the Application, and 
+not on the Linked Version.
+
+The “Corresponding Application Code” for a Combined Work means the object code 
+and/or source code for the Application, including any data and utility programs 
+needed for reproducing the Combined Work from the Application, but excluding 
+the System Libraries of the Combined Work.
+
+1. Exception to Section 3 of the GNU GPL.
+You may convey a covered work under sections 3 and 4 of this License without 
+being bound by section 3 of the GNU GPL.
+
+2. Conveying Modified Versions.
+If you modify a copy of the Library, and, in your modifications, a facility 
+refers to a function or data to be supplied by an Application that uses the 
+facility (other than as an argument passed when the facility is invoked), then 
+you may convey a copy of the modified version:
+
+a) under this License, provided that you make a good faith effort to ensure 
+that, in the event an Application does not supply the function or data, the 
+facility still operates, and performs whatever part of its purpose remains 
+meaningful, or
+b) under the GNU GPL, with none of the additional permissions of this License 
+applicable to that copy.
+3. Object Code Incorporating Material from Library Header Files.
+The object code form of an Application may incorporate material from a header 
+file that is part of the Library. You may convey such object code under terms 
+of your choice, provided that, if the incorporated material is not limited to 
+numerical parameters, data structure layouts and accessors, or small macros, 
+inline functions and templates (ten or fewer lines in length), you do both of 
+the following:
+
+a) Give prominent notice with each copy of the object code that the Library is 
+used in it and that the Library and its use are covered by this License.
+b) Accompany the object code with a copy of the GNU GPL and this license 
+document.
+4. Combined Works.
+You may convey a Combined Work under terms of your choice that, taken together, 
+effectively do not restrict modification of the portions of the Library 
+contained in the Combined Work and reverse engineering for debugging such 
+modifications, if you also do each of the following:
+
+a) Give prominent notice with each copy of the Combined Work that the Library 
+is used in it and that the Library and its use are covered by this License.
+b) Accompany the Combined Work with a copy of the GNU GPL and this license 
+document.
+c) For a Combined Work that displays copyright notices during execution, 
+include the copyright notice for the Library among these notices, as well as a 
+reference directing the user to the copies of the GNU GPL and this license 
+document.
+d) Do one of the following:
+0) Convey the Minimal Corresponding Source under the terms of this License, and 
+the Corresponding Application Code in a form suitable for, and under terms that 
+permit, the user to recombine or relink the Application with a modified version 
+of the Linked Version to produce a modified Combined Work, in the manner 
+specified by section 6 of the GNU GPL for conveying Corresponding Source.
+1) Use a suitable shared library mechanism for linking with the Library. A 
+suitable mechanism is one that (a) uses at run time a copy of the Library 
+already present on the user's computer system, and (b) will operate properly 
+with a modified version of the Library that is interface-compatible with the 
+Linked Version.
+e) Provide Installation Information, but only if you would otherwise be 
+required to provide such information under section 6 of the GNU GPL, and only 
+to the extent that such information is necessary to install and execute a 
+modified version of the Combined Work produced by recombining or relinking the 
+Application with a modified version of the Linked Version. (If you use option 
+4d0, the Installation Information must accompany the Minimal Corresponding 
+Source and Corresponding Application Code. If you use option 4d1, you must 
+provide the Installation Information in the manner specified by section 6 of 
+the GNU GPL for conveying Corresponding Source.)
+5. Combined Libraries.
+You may place library facilities that are a work based on the Library side by 
+side in a single library together with other library facilities that are not 
+Applications and are not covered by this License, and convey such a combined 
+library under terms of your choice, if you do both of the following:
+
+a) Accompany the combined library with a copy of the same work based on the 
+Library, uncombined with any other library facilities, conveyed under the terms 
+of this License.
+b) Give prominent notice with the combined library that part of it is a work 
+based on the Library, and explaining where to find the accompanying uncombined 
+form of the same work.
+6. Revised Versions of the GNU Lesser General Public License.
+The Free Software Foundation may publish revised and/or new versions of the GNU 
+Lesser General Public License from time to time. Such new versions will be 
+similar in spirit to the present version, but may differ in detail to address 
+new problems or concerns.
+
+Each version is given a distinguishing version number. If the Library as you 
+received it specifies that a certain numbered version of the GNU Lesser General 
+Public License “or any later version” applies to it, you have the option of 
+following the terms and conditions either of that published version or of any 
+later version published by the Free Software Foundation. If the Library as you 
+received it does not specify a version number of the GNU Lesser General Public 
+License, you may choose any version of the GNU Lesser General Public License 
+ever published by the Free Software Foundation.
+
+If the Library as you received it specifies that a proxy can decide whether 
+future versions of the GNU Lesser General Public License shall apply, that 
+proxy's public statement of acceptance of any version is permanent 
+authorization for you to choose that version for the Library.
diff --git a/jars/gnujpdf-license.txt b/jars/gnujpdf-license.txt
deleted file mode 100644
index 01d72e7..0000000
--- a/jars/gnujpdf-license.txt
+++ /dev/null
@@ -1,460 +0,0 @@
-gnujpdf license:
-
-		  GNU LESSER GENERAL PUBLIC LICENSE
-		       Version 2.1, February 1999
-
- Copyright (C) 1991, 1999 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-[This is the first released version of the Lesser GPL.  It also counts
- as the successor of the GNU Library Public License, version 2, hence
- the version number 2.1.]
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Lesser General Public License, applies to some
-specially designated software packages--typically libraries--of the
-Free Software Foundation and other authors who decide to use it.  You
-can use it too, but we suggest you first think carefully about whether
-this license or the ordinary General Public License is the better
-strategy to use in any particular case, based on the explanations below.
-
-  When we speak of free software, we are referring to freedom of use,
-not price.  Our General Public Licenses are designed to make sure that
-you have the freedom to distribute copies of free software (and charge
-for this service if you wish); that you receive source code or can get
-it if you want it; that you can change the software and use pieces of
-it in new free programs; and that you are informed that you can do
-these things.
-
-  To protect your rights, we need to make restrictions that forbid
-distributors to deny you these rights or to ask you to surrender these
-rights.  These restrictions translate to certain responsibilities for
-you if you distribute copies of the library or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link other code with the library, you must provide
-complete object files to the recipients, so that they can relink them
-with the library after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  We protect your rights with a two-step method: (1) we copyright the
-library, and (2) we offer you this license, which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  To protect each distributor, we want to make it very clear that
-there is no warranty for the free library.  Also, if the library is
-modified by someone else and passed on, the recipients should know
-that what they have is not the original version, so that the original
-author's reputation will not be affected by problems that might be
-introduced by others.
-

-  Finally, software patents pose a constant threat to the existence of
-any free program.  We wish to make sure that a company cannot
-effectively restrict the users of a free program by obtaining a
-restrictive license from a patent holder.  Therefore, we insist that
-any patent license obtained for a version of the library must be
-consistent with the full freedom of use specified in this license.
-
-  Most GNU software, including some libraries, is covered by the
-ordinary GNU General Public License.  This license, the GNU Lesser
-General Public License, applies to certain designated libraries, and
-is quite different from the ordinary General Public License.  We use
-this license for certain libraries in order to permit linking those
-libraries into non-free programs.
-
-  When a program is linked with a library, whether statically or using
-a shared library, the combination of the two is legally speaking a
-combined work, a derivative of the original library.  The ordinary
-General Public License therefore permits such linking only if the
-entire combination fits its criteria of freedom.  The Lesser General
-Public License permits more lax criteria for linking other code with
-the library.
-
-  We call this license the "Lesser" General Public License because it
-does Less to protect the user's freedom than the ordinary General
-Public License.  It also provides other free software developers Less
-of an advantage over competing non-free programs.  These disadvantages
-are the reason we use the ordinary General Public License for many
-libraries.  However, the Lesser license provides advantages in certain
-special circumstances.
-
-  For example, on rare occasions, there may be a special need to
-encourage the widest possible use of a certain library, so that it becomes
-a de-facto standard.  To achieve this, non-free programs must be
-allowed to use the library.  A more frequent case is that a free
-library does the same job as widely used non-free libraries.  In this
-case, there is little to gain by limiting the free library to free
-software only, so we use the Lesser General Public License.
-
-  In other cases, permission to use a particular library in non-free
-programs enables a greater number of people to use a large body of
-free software.  For example, permission to use the GNU C Library in
-non-free programs enables many more people to use the whole GNU
-operating system, as well as its variant, the GNU/Linux operating
-system.
-
-  Although the Lesser General Public License is Less protective of the
-users' freedom, it does ensure that the user of a program that is
-linked with the Library has the freedom and the wherewithal to run
-that program using a modified version of the Library.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, whereas the latter must
-be combined with the library in order to run.
-

-		  GNU LESSER GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library or other
-program which contains a notice placed by the copyright holder or
-other authorized party saying it may be distributed under the terms of
-this Lesser General Public License (also called "this License").
-Each licensee is addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-  
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-

-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-

-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-

-  6. As an exception to the Sections above, you may also combine or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Use a suitable shared library mechanism for linking with the
-    Library.  A suitable mechanism is one that (1) uses at run time a
-    copy of the library already present on the user's computer system,
-    rather than copying library functions into the executable, and (2)
-    will operate properly with a modified version of the library, if
-    the user installs one, as long as the modified version is
-    interface-compatible with the version that the work was made with.
-
-    c) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    d) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    e) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the materials to be distributed need not include anything that is
-normally distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-

-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties with
-this License.
-

-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Lesser General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-

-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-			    NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
diff --git a/jars/gnujpdf-src.jar b/jars/gnujpdf-src.jar
deleted file mode 100644
index 81f7970..0000000
Binary files a/jars/gnujpdf-src.jar and /dev/null differ
diff --git a/jars/gnujpdf.jar b/jars/gnujpdf.jar
deleted file mode 100644
index d0d8819..0000000
Binary files a/jars/gnujpdf.jar and /dev/null differ
diff --git a/src/com/apple/eawt/AboutHandler.java b/src/com/apple/eawt/AboutHandler.java
new file mode 100644
index 0000000..548eb9d
--- /dev/null
+++ b/src/com/apple/eawt/AboutHandler.java
@@ -0,0 +1,30 @@
+/*
+ *  Copyright (C) 2016 Daniel H. Huson
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.apple.eawt;
+
+/**
+ * about
+ * Created by huson on 2/23/17.
+ */
+public class AboutHandler {
+
+    public void handleAbout(AppEvent.AboutEvent aboutEvent) {
+    }
+}
diff --git a/src/com/apple/eawt/AppEvent.java b/src/com/apple/eawt/AppEvent.java
new file mode 100644
index 0000000..b0d0c10
--- /dev/null
+++ b/src/com/apple/eawt/AppEvent.java
@@ -0,0 +1,40 @@
+/*
+ *  Copyright (C) 2016 Daniel H. Huson
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.apple.eawt;
+
+/**
+ * fake app event
+ * Created by huson on 2/23/17.
+ */
+public class AppEvent {
+    public static class QuitEvent {
+    }
+
+    ;
+
+    public static class AboutEvent {
+    }
+
+    ;
+
+    public static class PreferencesEvent {
+    }
+
+}
diff --git a/src/com/apple/eawt/Application.java b/src/com/apple/eawt/Application.java
new file mode 100644
index 0000000..c9f3ad8
--- /dev/null
+++ b/src/com/apple/eawt/Application.java
@@ -0,0 +1,48 @@
+/*
+ *  Copyright (C) 2016 Daniel H. Huson
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.apple.eawt;
+
+/**
+ * bare bones for compilation under winds
+ * Created by huson on 2/23/17.
+ */
+public class Application {
+    private static Application instance;
+
+    private Application() {
+
+    }
+
+    public static Application getApplication() {
+        if (instance == null)
+            instance = new Application();
+        return instance;
+    }
+
+    public void setQuitHandler(Object ignored) {
+    }
+
+    public void setAboutHandler(Object ignored) {
+    }
+
+    public void setPreferencesHandler(Object ignored) {
+    }
+
+}
diff --git a/src/com/apple/eawt/PreferencesHandler.java b/src/com/apple/eawt/PreferencesHandler.java
new file mode 100644
index 0000000..21336fb
--- /dev/null
+++ b/src/com/apple/eawt/PreferencesHandler.java
@@ -0,0 +1,29 @@
+/*
+ *  Copyright (C) 2016 Daniel H. Huson
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.apple.eawt;
+
+/**
+ * does nothing
+ * Created by huson on 2/23/17.
+ */
+public class PreferencesHandler {
+    public void handlePreferences(AppEvent.PreferencesEvent preferencesEvent) {
+    }
+}
diff --git a/src/com/apple/eawt/QuitHandler.java b/src/com/apple/eawt/QuitHandler.java
new file mode 100644
index 0000000..a1078e8
--- /dev/null
+++ b/src/com/apple/eawt/QuitHandler.java
@@ -0,0 +1,29 @@
+/*
+ *  Copyright (C) 2016 Daniel H. Huson
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.apple.eawt;
+
+/**
+ * do nothing quit handler
+ * Created by huson on 2/23/17.
+ */
+public class QuitHandler {
+    public void handleQuitRequestWith(AppEvent.QuitEvent quitEvent, QuitResponse quitResponse) {
+    }
+}
diff --git a/src/com/apple/eawt/QuitResponse.java b/src/com/apple/eawt/QuitResponse.java
new file mode 100644
index 0000000..cd5e5ce
--- /dev/null
+++ b/src/com/apple/eawt/QuitResponse.java
@@ -0,0 +1,29 @@
+/*
+ *  Copyright (C) 2016 Daniel H. Huson
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package com.apple.eawt;
+
+/**
+ * fake quit response
+ * Created by huson on 2/23/17.
+ */
+public class QuitResponse {
+    public void cancelQuit() {
+    }
+}
diff --git a/src/jloda/export/EPSExportType.java b/src/jloda/export/EPSExportType.java
index 1a05527..4851a02 100644
--- a/src/jloda/export/EPSExportType.java
+++ b/src/jloda/export/EPSExportType.java
@@ -1,6 +1,6 @@
 /**
  * EPSExportType.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/EPSGraphics.java b/src/jloda/export/EPSGraphics.java
index e32aa24..3a79148 100644
--- a/src/jloda/export/EPSGraphics.java
+++ b/src/jloda/export/EPSGraphics.java
@@ -1,6 +1,6 @@
 /**
  * EPSGraphics.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/ExportGraphicType.java b/src/jloda/export/ExportGraphicType.java
index 7ae0344..389b628 100644
--- a/src/jloda/export/ExportGraphicType.java
+++ b/src/jloda/export/ExportGraphicType.java
@@ -1,6 +1,6 @@
 /**
  * ExportGraphicType.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/ExportImageDialog.java b/src/jloda/export/ExportImageDialog.java
index 59c4ecc..1752e2f 100644
--- a/src/jloda/export/ExportImageDialog.java
+++ b/src/jloda/export/ExportImageDialog.java
@@ -1,6 +1,6 @@
 /**
  * ExportImageDialog.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/ExportManager.java b/src/jloda/export/ExportManager.java
index 71b0d93..870f186 100644
--- a/src/jloda/export/ExportManager.java
+++ b/src/jloda/export/ExportManager.java
@@ -1,6 +1,6 @@
 /**
  * ExportManager.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -113,18 +113,14 @@ public class ExportManager {
     }
 
     static private void doPaint(Graphics g0, JPanel imagePanel, Point apt, Dimension extent) {
-        //System.err.println("apt: " + apt);
-        //System.err.println("Extent: " + extent);
         g0.translate(-apt.x, -apt.y);
         g0.setClip(apt.x, apt.y, extent.width, extent.height);
         g0.setColor(imagePanel.getBackground());
         g0.fillRect(apt.x, apt.y, extent.width, extent.height);
         imagePanel.paint(g0);
         g0.translate(apt.x, apt.y);
-
     }
 
-
     /**
      * result is true, if we are currently in a writeToFile call.
      * This is used in paint to determine whether we are drawing to the screen or
diff --git a/src/jloda/export/GIFExportType.java b/src/jloda/export/GIFExportType.java
index f9714c2..e2b8dcd 100644
--- a/src/jloda/export/GIFExportType.java
+++ b/src/jloda/export/GIFExportType.java
@@ -1,6 +1,6 @@
 /**
  * GIFExportType.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/GraphicsFileFilters.java b/src/jloda/export/GraphicsFileFilters.java
index 4c8c92c..b52d558 100644
--- a/src/jloda/export/GraphicsFileFilters.java
+++ b/src/jloda/export/GraphicsFileFilters.java
@@ -1,6 +1,6 @@
 /**
  * GraphicsFileFilters.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/JPGExportType.java b/src/jloda/export/JPGExportType.java
index b743346..cf59d67 100644
--- a/src/jloda/export/JPGExportType.java
+++ b/src/jloda/export/JPGExportType.java
@@ -1,6 +1,6 @@
 /**
  * JPGExportType.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/PDFExportType.java b/src/jloda/export/PDFExportType.java
index 9e5318e..2a773e6 100644
--- a/src/jloda/export/PDFExportType.java
+++ b/src/jloda/export/PDFExportType.java
@@ -1,6 +1,6 @@
 /**
  * PDFExportType.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -20,14 +20,14 @@
 package jloda.export;
 
 
-import gnu.jpdf.PDFJob;
+import de.erichseifert.vectorgraphics2d.Document;
+import de.erichseifert.vectorgraphics2d.VectorGraphics2D;
+import de.erichseifert.vectorgraphics2d.pdf.PDFProcessor;
+import de.erichseifert.vectorgraphics2d.util.PageSize;
 import jloda.util.Basic;
 
 import javax.swing.*;
-import java.awt.*;
 import java.awt.datatransfer.DataFlavor;
-import java.awt.print.PageFormat;
-import java.awt.print.Paper;
 import java.io.*;
 
 
@@ -82,20 +82,12 @@ public class PDFExportType extends SVGExportType implements ExportGraphicType {
         int height = panel.getHeight();
 
         // Get the Graphics object for pdf writing
-        Graphics pdfGraphics;
-        PDFJob job = new PDFJob(out);
-
-        PageFormat pageFormat = new PageFormat();
-        Paper paper = new Paper();
-        paper.setSize(width, height);
-        pageFormat.setPaper(paper);
-
-        pdfGraphics = job.getGraphics(pageFormat);
-
+        VectorGraphics2D pdfGraphics = new VectorGraphics2D();
         panel.paint(pdfGraphics);
 
-        pdfGraphics.dispose();
-        job.end();
+        PDFProcessor processor = new PDFProcessor(false);
+        Document document = processor.getDocument(pdfGraphics.getCommands(), new PageSize(width, height));
+        document.writeTo(out);
         out.flush();
     }
 
diff --git a/src/jloda/export/PNGExportType.java b/src/jloda/export/PNGExportType.java
index 4f80528..f7591ce 100644
--- a/src/jloda/export/PNGExportType.java
+++ b/src/jloda/export/PNGExportType.java
@@ -1,6 +1,6 @@
 /**
  * PNGExportType.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -101,7 +101,7 @@ public class PNGExportType extends FileFilter implements ExportGraphicType {
      * @throws IOException
      */
     public void writeToFile(File file, final JPanel imagePanel, JScrollPane imageScrollPane, boolean showWholeImage) throws IOException {
-        JPanel panel;
+        final JPanel panel;
         if (showWholeImage || imageScrollPane == null)
             panel = imagePanel;
         else
diff --git a/src/jloda/export/RenderedExportType.java b/src/jloda/export/RenderedExportType.java
index 5a46e99..c6cfb1f 100644
--- a/src/jloda/export/RenderedExportType.java
+++ b/src/jloda/export/RenderedExportType.java
@@ -1,6 +1,6 @@
 /**
  * RenderedExportType.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/SVGExportType.java b/src/jloda/export/SVGExportType.java
index efedd6f..daf7efc 100644
--- a/src/jloda/export/SVGExportType.java
+++ b/src/jloda/export/SVGExportType.java
@@ -1,6 +1,6 @@
 /**
  * SVGExportType.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/SVGStringExportType.java b/src/jloda/export/SVGStringExportType.java
index 16d0ef9..4a7ed90 100644
--- a/src/jloda/export/SVGStringExportType.java
+++ b/src/jloda/export/SVGStringExportType.java
@@ -1,6 +1,6 @@
 /**
  * SVGStringExportType.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/SaveImageDialog.java b/src/jloda/export/SaveImageDialog.java
index 2736818..9750011 100644
--- a/src/jloda/export/SaveImageDialog.java
+++ b/src/jloda/export/SaveImageDialog.java
@@ -1,6 +1,6 @@
 /**
  * SaveImageDialog.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/TransferableGraphic.java b/src/jloda/export/TransferableGraphic.java
index 10bb8f8..1f0bff3 100644
--- a/src/jloda/export/TransferableGraphic.java
+++ b/src/jloda/export/TransferableGraphic.java
@@ -1,6 +1,6 @@
 /**
  * TransferableGraphic.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/gifEncode/DirectGif89Frame.java b/src/jloda/export/gifEncode/DirectGif89Frame.java
index 9232f2a..9a77e15 100644
--- a/src/jloda/export/gifEncode/DirectGif89Frame.java
+++ b/src/jloda/export/gifEncode/DirectGif89Frame.java
@@ -1,6 +1,6 @@
 /**
  * DirectGif89Frame.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/gifEncode/Gif89Encoder.java b/src/jloda/export/gifEncode/Gif89Encoder.java
index 61eed15..88a5d9a 100644
--- a/src/jloda/export/gifEncode/Gif89Encoder.java
+++ b/src/jloda/export/gifEncode/Gif89Encoder.java
@@ -1,6 +1,6 @@
 /**
  * Gif89Encoder.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/gifEncode/Gif89Frame.java b/src/jloda/export/gifEncode/Gif89Frame.java
index be998c3..5e4ed4b 100644
--- a/src/jloda/export/gifEncode/Gif89Frame.java
+++ b/src/jloda/export/gifEncode/Gif89Frame.java
@@ -1,6 +1,6 @@
 /**
  * Gif89Frame.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/gifEncode/IndexGif89Frame.java b/src/jloda/export/gifEncode/IndexGif89Frame.java
index 1a61153..fea0f43 100644
--- a/src/jloda/export/gifEncode/IndexGif89Frame.java
+++ b/src/jloda/export/gifEncode/IndexGif89Frame.java
@@ -1,6 +1,6 @@
 /**
  * IndexGif89Frame.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/export/gifEncode/Put.java b/src/jloda/export/gifEncode/Put.java
index 9c3835d..1dfcd0a 100644
--- a/src/jloda/export/gifEncode/Put.java
+++ b/src/jloda/export/gifEncode/Put.java
@@ -1,6 +1,6 @@
 /**
  * Put.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/fx/ASelectionModel.java b/src/jloda/fx/ASelectionModel.java
new file mode 100644
index 0000000..3ab5f01
--- /dev/null
+++ b/src/jloda/fx/ASelectionModel.java
@@ -0,0 +1,240 @@
+/*
+ *  Copyright (C) 2015 Daniel H. Huson
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package jloda.fx;
+
+
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
+import javafx.collections.ObservableSet;
+import javafx.collections.SetChangeListener;
+import javafx.scene.control.MultipleSelectionModel;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Selection model
+ * Created by huson on 12/15/15.
+ */
+public class ASelectionModel<T> extends MultipleSelectionModel<T> {
+
+    private final ObservableSet<Integer> selectedIndices; // the set of selected indices
+
+    private T[] items; // need a copy of this array to map indices to objects, when required
+
+    private int focusIndex = -1; // focus index
+
+    private final ObservableList<Integer> unmodifiableSelectedIndices; // unmodifiable list of selected indices
+    private final ObservableList<T> unmodifiableSelectedItems; // unmodifiable list of selected items
+
+    /**
+     * Constructor
+     *
+     * @param items 0 or more items
+     */
+    @SafeVarargs
+    public ASelectionModel(T... items) {
+        this.items = Arrays.copyOf(items, items.length);  // use copy for safety
+        selectedIndices = FXCollections.observableSet();
+
+        // setup unmodifiable lists
+        {
+            // first setup observable array lists that listen for changes of the selectedIndices set
+            final ObservableList<Integer> selectedIndicesAsList = FXCollections.observableArrayList();
+            final ObservableList<T> selectedItems = FXCollections.observableArrayList();
+            selectedIndices.addListener(new SetChangeListener<Integer>() {
+                @Override
+                public void onChanged(Change<? extends Integer> c) {
+                    if (c.wasAdded()) {
+                        selectedIndicesAsList.add(c.getElementAdded());
+                        selectedItems.add(ASelectionModel.this.getItems()[c.getElementAdded()]);
+                    } else if (c.wasRemoved()) {
+                        selectedIndicesAsList.remove(c.getElementRemoved());
+                        selectedItems.remove(ASelectionModel.this.getItems()[c.getElementRemoved()]);
+                    }
+                }
+            });
+            // wrap a unmodifiable observable list around the observable arrays lists
+            unmodifiableSelectedIndices = FXCollections.unmodifiableObservableList(selectedIndicesAsList);
+            unmodifiableSelectedItems = FXCollections.unmodifiableObservableList(selectedItems);
+        }
+    }
+
+    @Override
+    public ObservableList<Integer> getSelectedIndices() {
+        return unmodifiableSelectedIndices;
+    }
+
+    @Override
+    public ObservableList<T> getSelectedItems() {
+        return unmodifiableSelectedItems;
+    }
+
+    @Override
+    public void selectIndices(int index, int... indices) {
+        select(index);
+        for (int i : indices) {
+            select(i);
+        }
+    }
+
+    @Override
+    public void selectAll() {
+        for (int index = 0; index < items.length; index++) {
+            selectedIndices.add(index);
+        }
+        focusIndex = -1;
+    }
+
+    @Override
+    public void clearAndSelect(int index) {
+        clearSelection();
+        select(index);
+    }
+
+    @Override
+    public void select(int index) {
+        if (index >= 0 && index < items.length) {
+            selectedIndices.add(index);
+            focusIndex = index;
+        }
+    }
+
+    @Override
+    public void select(T item) {
+        for (int i = 0; i < items.length; i++) {
+            if (items[i].equals(item)) {
+                select(i);
+                return;
+            }
+        }
+        final T tmp[] = (T[]) new Object[items.length + 1];
+        System.arraycopy(items, 0, tmp, 0, items.length);
+        tmp[tmp.length - 1] = item;
+        items = tmp;
+        select(tmp.length - 1);
+    }
+
+    public void clearSelect(T item) {
+        for (int i = 0; i < items.length; i++) {
+            if (items[i].equals(item)) {
+                clearSelection(i);
+                return;
+            }
+        }
+    }
+
+    @Override
+    public void clearSelection(int index) {
+        if (index >= 0 && index < items.length) {
+            selectedIndices.remove(index);
+        }
+    }
+
+    @Override
+    public void clearSelection() {
+        selectedIndices.clear();
+        focusIndex = -1;
+    }
+
+    @Override
+    public boolean isSelected(int index) {
+        return index >= 0 && index < items.length && selectedIndices.contains(index);
+    }
+
+    @Override
+    public boolean isEmpty() {
+        return selectedIndices.isEmpty();
+    }
+
+    @Override
+    public void selectFirst() {
+        if (items.length > 0) {
+            select(0);
+        }
+    }
+
+    @Override
+    public void selectLast() {
+        if (items.length > 0) {
+            select(items.length - 1);
+        }
+    }
+
+    @Override
+    public void selectPrevious() {
+        select(focusIndex - 1);
+    }
+
+    @Override
+    public void selectNext() {
+        select(focusIndex + 1);
+    }
+
+    /**
+     * get the current array of items.
+     *
+     * @return items
+     */
+    public T[] getItems() {
+        return items;
+    }
+
+    /**
+     * clear selection and set list of items
+     *
+     * @param items
+     */
+    public void setItems(T... items) {
+        clearSelection();
+        this.items = Arrays.copyOf(items, items.length);  // use copy for safety
+    }
+
+    /**
+     * clear selection and set list of items
+     *
+     * @param items
+     */
+    public void setItems(Collection<T> items) {
+        clearSelection();
+        this.items = (T[]) new Object[items.size()];
+        int i = 0;
+        for (T item : items) {
+            this.items[i++] = item;
+        }
+    }
+
+
+    /**
+     * invert the current selection
+     */
+    public void invertSelection() {
+        final Set<Integer> toSelect = new HashSet<>();
+        for (int index = 0; index < items.length; index++) {
+            if (!selectedIndices.contains(index))
+                toSelect.add(index);
+        }
+        selectedIndices.clear();
+        selectedIndices.addAll(toSelect);
+        focusIndex = -1;
+    }
+}
diff --git a/src/jloda/fx/ExtendedFXMLLoader.java b/src/jloda/fx/ExtendedFXMLLoader.java
new file mode 100644
index 0000000..ae399c2
--- /dev/null
+++ b/src/jloda/fx/ExtendedFXMLLoader.java
@@ -0,0 +1,88 @@
+/*
+ *  Copyright (C) 2015 Daniel H. Huson and David J. Bryant
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package jloda.fx;
+
+import javafx.fxml.FXMLLoader;
+import javafx.scene.Parent;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * extended FXLoader
+ * Created by huson on 12/23/16.
+ */
+public class ExtendedFXMLLoader<C> {
+    private final FXMLLoader fxmlLoader;
+    private final Parent root;
+    private final C controller;
+
+    /**
+     * load the FXML from the fxml file associated with a class
+     * For example, if the path for clazz is splitstree5.gui.TaxaFilterView, parses the file splitstree5.gui.TaxaFilterView.fxml
+     *
+     * @param clazz
+     * @throws IOException
+     */
+    public ExtendedFXMLLoader(Class clazz) throws IOException {
+        fxmlLoader = new FXMLLoader();
+        String path = clazz.getCanonicalName().replaceAll("\\.", "/") + ".fxml";
+        final URL url = clazz.getClassLoader().getResource(path);
+        //System.err.println("path: " + path + " URL: " + url);
+        if (url == null)
+            throw new IOException("Failed to get resource: " + path);
+
+        try (final InputStream ins = url.openStream()) {
+            if (ins == null)
+                throw new IOException("Failed to open input stream for URL: " + url);
+
+            root = fxmlLoader.load(ins);
+        }
+        controller = fxmlLoader.getController();
+    }
+
+    /**
+     * get the loader
+     *
+     * @return loader
+     */
+    public FXMLLoader getFxmlLoader() {
+        return fxmlLoader;
+    }
+
+    /**
+     * get the root node
+     *
+     * @return root node
+     */
+    public Parent getRoot() {
+        return root;
+    }
+
+    /**
+     * get the controller object
+     *
+     * @return controller
+     */
+    public C getController() {
+        return controller;
+    }
+}
diff --git a/src/jloda/fx/JButtonWithFXAction.java b/src/jloda/fx/JButtonWithFXAction.java
new file mode 100644
index 0000000..00eb0cf
--- /dev/null
+++ b/src/jloda/fx/JButtonWithFXAction.java
@@ -0,0 +1,53 @@
+/*
+ *  Copyright (C) 2015 Daniel H. Huson
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package jloda.fx;
+
+import javafx.application.Platform;
+import javafx.event.ActionEvent;
+import javafx.event.EventHandler;
+
+import javax.swing.*;
+
+/**
+ * a swing button that calls an FX event handler
+ * Created by huson on 2/17/17.
+ */
+public class JButtonWithFXAction extends JButton {
+    /**
+     * constructor
+     *
+     * @param name
+     * @param eventHandler
+     */
+    public JButtonWithFXAction(String name, final EventHandler<ActionEvent> eventHandler) {
+        this.setAction(new AbstractAction(name) {
+            @Override
+            public void actionPerformed(java.awt.event.ActionEvent e) {
+                Platform.runLater(new Runnable() {
+                    @Override
+                    public void run() {
+                        eventHandler.handle(new ActionEvent(this, null));
+                    }
+                });
+            }
+        });
+    }
+
+}
diff --git a/src/jloda/graph/Dijkstra.java b/src/jloda/graph/Dijkstra.java
index 9707f76..f88b1a7 100644
--- a/src/jloda/graph/Dijkstra.java
+++ b/src/jloda/graph/Dijkstra.java
@@ -1,6 +1,6 @@
 /**
  * Dijkstra.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/Edge.java b/src/jloda/graph/Edge.java
index 730aee5..31e8df8 100644
--- a/src/jloda/graph/Edge.java
+++ b/src/jloda/graph/Edge.java
@@ -1,6 +1,6 @@
 /**
  * Edge.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/EdgeArray.java b/src/jloda/graph/EdgeArray.java
index 54949d0..5a07f2a 100644
--- a/src/jloda/graph/EdgeArray.java
+++ b/src/jloda/graph/EdgeArray.java
@@ -1,6 +1,6 @@
 /**
  * EdgeArray.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -191,8 +191,6 @@ public class EdgeArray<T> extends GraphBase implements EdgeAssociation<T> {
     public boolean isClear() {
         return isClear;
     }
-
-
 }
 
 // EOF
diff --git a/src/jloda/graph/EdgeAssociation.java b/src/jloda/graph/EdgeAssociation.java
index 27b13ba..c10119a 100644
--- a/src/jloda/graph/EdgeAssociation.java
+++ b/src/jloda/graph/EdgeAssociation.java
@@ -1,6 +1,6 @@
 /**
  * EdgeAssociation.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/EdgeDoubleArray.java b/src/jloda/graph/EdgeDoubleArray.java
index 775ffae..00bf904 100644
--- a/src/jloda/graph/EdgeDoubleArray.java
+++ b/src/jloda/graph/EdgeDoubleArray.java
@@ -1,6 +1,6 @@
 /**
  * EdgeDoubleArray.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/EdgeDoubleMap.java b/src/jloda/graph/EdgeDoubleMap.java
index f58a59c..51675db 100644
--- a/src/jloda/graph/EdgeDoubleMap.java
+++ b/src/jloda/graph/EdgeDoubleMap.java
@@ -1,6 +1,6 @@
 /**
  * EdgeDoubleMap.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/EdgeIntegerArray.java b/src/jloda/graph/EdgeIntegerArray.java
index 4fde377..f4fcffc 100644
--- a/src/jloda/graph/EdgeIntegerArray.java
+++ b/src/jloda/graph/EdgeIntegerArray.java
@@ -1,6 +1,6 @@
 /**
  * EdgeIntegerArray.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/EdgeIntegerMap.java b/src/jloda/graph/EdgeIntegerMap.java
index e4ce65a..45b451f 100644
--- a/src/jloda/graph/EdgeIntegerMap.java
+++ b/src/jloda/graph/EdgeIntegerMap.java
@@ -1,6 +1,6 @@
 /**
  * EdgeIntegerMap.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/EdgeMap.java b/src/jloda/graph/EdgeMap.java
index af5ab52..b957a02 100644
--- a/src/jloda/graph/EdgeMap.java
+++ b/src/jloda/graph/EdgeMap.java
@@ -1,6 +1,6 @@
 /**
  * EdgeMap.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -110,7 +110,6 @@ public class EdgeMap<T> extends GraphBase implements EdgeAssociation<T> {
             data.put(e, obj);
         if (obj != null && isClear)
             isClear = false;
-
     }
 
     /**
diff --git a/src/jloda/graph/EdgeSet.java b/src/jloda/graph/EdgeSet.java
index b4b9729..809c278 100644
--- a/src/jloda/graph/EdgeSet.java
+++ b/src/jloda/graph/EdgeSet.java
@@ -1,6 +1,6 @@
 /**
  * EdgeSet.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/Graph.java b/src/jloda/graph/Graph.java
index 547b828..108b377 100644
--- a/src/jloda/graph/Graph.java
+++ b/src/jloda/graph/Graph.java
@@ -1,6 +1,6 @@
 /**
  * Graph.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -45,18 +45,18 @@ import java.util.*;
  * Daniel Huson, 2002
  * <p/>
  */
-public class Graph extends GraphBase {
+public class Graph<V, E> extends GraphBase {
     private Node firstNode;
     private Node lastNode;
     private int numberNodes;
     private int numberOfNodesThatAreHidden;
-    private int idsNodes;
+    private int idsNodes; // number of ids assigned to nodes
 
     private Edge firstEdge;
     protected Edge lastEdge;
     private int numberEdges;
     private int numberOfEdgesThatAreHidden;
-    private int idsEdges;
+    private int idsEdges; // number of ids assigned to edges
 
     private boolean ignoreGraphHasChanged = false; // set this when we are deleting a whole graph
 
@@ -894,9 +894,10 @@ public class Graph extends GraphBase {
      * @param v node
      * @return the info
      */
-    public Object getInfo(Node v) {
+    @SuppressWarnings("unchecked")
+    public V getInfo(Node v) {
         checkOwner(v);
-        return v.getInfo();
+        return (V) v.getInfo();
     }
 
     /**
@@ -905,7 +906,7 @@ public class Graph extends GraphBase {
      * @param v   node
      * @param obj the info object
      */
-    public void setInfo(Node v, Object obj) {
+    public void setInfo(Node v, V obj) {
         checkOwner(v);
         v.setInfo(obj);
     }
@@ -916,9 +917,10 @@ public class Graph extends GraphBase {
      * @param e edge
      * @return the info
      */
-    public Object getInfo(Edge e) {
+    @SuppressWarnings("unchecked")
+    public E getInfo(Edge e) {
         checkOwner(e);
-        return e.getInfo();
+        return (E) e.getInfo();
     }
 
     /**
@@ -927,7 +929,7 @@ public class Graph extends GraphBase {
      * @param e   edge
      * @param obj the info object
      */
-    public void setInfo(Edge e, Object obj) {
+    public void setInfo(Edge e, E obj) {
         checkOwner(e);
         e.setInfo(obj);
     }
@@ -1063,7 +1065,7 @@ public class Graph extends GraphBase {
         for (Node v = src.getFirstNode(); v != null; v = src.getNextNode(v)) {
             Node w = newNode();
             w.setId(v.getId());
-            setInfo(w, src.getInfo(v));
+            setInfo(w, (V) src.getInfo(v));
             oldNode2newNode.set(v, w);
         }
         idsNodes = src.idsNodes;
@@ -1080,7 +1082,7 @@ public class Graph extends GraphBase {
             }
             if (src.isSpecial(e))
                 setSpecial(f, true);
-            setInfo(f, src.getInfo(e));
+            setInfo(f, (E) src.getInfo(e));
             oldEdge2newEdge.set(e, f);
         }
         idsEdges = src.idsEdges;
@@ -1501,7 +1503,7 @@ public class Graph extends GraphBase {
     public void getLeavesRec(Node v, NodeSet nodes) {
         for (Edge f = v.getFirstOutEdge(); f != null; f = v.getNextOutEdge(f)) {
            Node w = f.getTarget();
-           getLeavesRec(w,sons); 
+           getLeavesRec(w,sons);
        }
                   if (v.getOutDegree() == 0)
            nodes.add(w);
diff --git a/src/jloda/graph/GraphBase.java b/src/jloda/graph/GraphBase.java
index 34fa40c..b9d126e 100644
--- a/src/jloda/graph/GraphBase.java
+++ b/src/jloda/graph/GraphBase.java
@@ -1,6 +1,6 @@
 /**
  * GraphBase.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/GraphUpdateAdapter.java b/src/jloda/graph/GraphUpdateAdapter.java
index 26f2547..9413367 100644
--- a/src/jloda/graph/GraphUpdateAdapter.java
+++ b/src/jloda/graph/GraphUpdateAdapter.java
@@ -1,6 +1,6 @@
 /**
  * GraphUpdateAdapter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/GraphUpdateListener.java b/src/jloda/graph/GraphUpdateListener.java
index 69e3317..6beccdb 100644
--- a/src/jloda/graph/GraphUpdateListener.java
+++ b/src/jloda/graph/GraphUpdateListener.java
@@ -1,6 +1,6 @@
 /**
  * GraphUpdateListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/IllegalSelfEdgeException.java b/src/jloda/graph/IllegalSelfEdgeException.java
index e7a10ed..67272b6 100644
--- a/src/jloda/graph/IllegalSelfEdgeException.java
+++ b/src/jloda/graph/IllegalSelfEdgeException.java
@@ -1,6 +1,6 @@
 /**
  * IllegalSelfEdgeException.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/MaxClique.java b/src/jloda/graph/MaxClique.java
index 9508e91..9f48d5b 100644
--- a/src/jloda/graph/MaxClique.java
+++ b/src/jloda/graph/MaxClique.java
@@ -1,6 +1,6 @@
 /**
  * MaxClique.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/Node.java b/src/jloda/graph/Node.java
index 22e50de..205ffc7 100644
--- a/src/jloda/graph/Node.java
+++ b/src/jloda/graph/Node.java
@@ -1,6 +1,6 @@
 /**
  * Node.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -487,8 +487,8 @@ public class Node extends NodeEdge implements Comparable {
      * @return iterator over all adjacent edges
      */
     public Iterator<Edge> getAdjacentEdges() {
-        final Node v = this;
         return new IteratorAdapter<Edge>() {
+            final Node v = Node.this;
             private Edge e = v.getFirstAdjacentEdge();
 
             protected Edge findNext() throws NoSuchElementException {
@@ -509,8 +509,8 @@ public class Node extends NodeEdge implements Comparable {
      * @return iterator over all in edges
      */
     public Iterator<Edge> getInEdges() {
-        final Node v = this;
         return new IteratorAdapter<Edge>() {
+            final Node v = Node.this;
             private Edge e = v.getFirstAdjacentEdge();
 
             protected Edge findNext() throws NoSuchElementException {
@@ -534,8 +534,8 @@ public class Node extends NodeEdge implements Comparable {
      * @return iterator over all out edges
      */
     public Iterator<Edge> getOutEdges() {
-        final Node v = this;
         return new IteratorAdapter<Edge>() {
+            final Node v = Node.this;
             private Edge e = v.getFirstAdjacentEdge();
 
             protected Edge findNext() throws NoSuchElementException {
diff --git a/src/jloda/graph/NodeArray.java b/src/jloda/graph/NodeArray.java
index 91e3f28..8627bbc 100644
--- a/src/jloda/graph/NodeArray.java
+++ b/src/jloda/graph/NodeArray.java
@@ -1,6 +1,6 @@
 /**
  * NodeArray.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -200,8 +200,6 @@ public class NodeArray<T> extends GraphBase implements NodeAssociation<T> {
         }
         return result;
     }
-
-
 }
 
 // EOF
diff --git a/src/jloda/graph/NodeAssociation.java b/src/jloda/graph/NodeAssociation.java
index dfd31c3..a5a6a34 100644
--- a/src/jloda/graph/NodeAssociation.java
+++ b/src/jloda/graph/NodeAssociation.java
@@ -1,6 +1,6 @@
 /**
  * NodeAssociation.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/NodeData.java b/src/jloda/graph/NodeData.java
index 189b318..7071d31 100644
--- a/src/jloda/graph/NodeData.java
+++ b/src/jloda/graph/NodeData.java
@@ -1,6 +1,6 @@
 /**
  * NodeData.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -26,12 +26,12 @@ import jloda.util.Basic;
  * Daniel Huson, 1.2013
  */
 public class NodeData {
-    private int[] assigned;
-    private int[] summarized;
-    private int countAssigned;
-    private int maxAssigned;
-    private int countSummarized;
-    private int maxSummarized;
+    private float[] assigned;
+    private float[] summarized;
+    private float countAssigned;
+    private float maxAssigned;
+    private float countSummarized;
+    private float maxSummarized;
 
     private double upPValue = -1; // p-value of left
     private double downPValue = -1;   // p-value for right
@@ -42,45 +42,45 @@ public class NodeData {
      * @param assigned
      * @param summarized
      */
-    public NodeData(int[] assigned, int[] summarized) {
+    public NodeData(float[] assigned, float[] summarized) {
         setAssigned(assigned);
         setSummarized(summarized);
     }
 
-    public int[] getAssigned() {
+    public float[] getAssigned() {
         return assigned;
     }
 
-    public int getAssigned(int i) {
+    public float getAssigned(int i) {
         return assigned[i];
     }
 
-    public void setAssigned(int[] assigned) {
+    public void setAssigned(float[] assigned) {
         this.assigned = assigned;
         countAssigned = 0;
         maxAssigned = 0;
         if (assigned != null) {
-            for (int value : assigned) {
+            for (float value : assigned) {
                 countAssigned += value;
                 maxAssigned = Math.max(maxAssigned, value);
             }
         }
     }
 
-    public int[] getSummarized() {
+    public float[] getSummarized() {
         return summarized;
     }
 
-    public int getSummarized(int i) {
+    public float getSummarized(int i) {
         return summarized[i];
     }
 
-    public void setSummarized(int[] summarized) {
+    public void setSummarized(float[] summarized) {
         this.summarized = summarized;
         countSummarized = 0;
         maxSummarized = 0;
         if (summarized != null) {
-            for (int value : summarized) {
+            for (float value : summarized) {
                 countSummarized += value;
                 maxSummarized = Math.max(maxSummarized, value);
             }
@@ -94,19 +94,19 @@ public class NodeData {
             maxSummarized = summarized[i];
     }
 
-    public int getCountAssigned() {
+    public float getCountAssigned() {
         return countAssigned;
     }
 
-    public int getMaxAssigned() {
+    public float getMaxAssigned() {
         return maxAssigned;
     }
 
-    public int getCountSummarized() {
+    public float getCountSummarized() {
         return countSummarized;
     }
 
-    public int getMaxSummarized() {
+    public float getMaxSummarized() {
         return maxSummarized;
     }
 
@@ -127,7 +127,7 @@ public class NodeData {
     }
 
     public String toString() {
-        return "assigned: " + Basic.toString(assigned, ",") + ", summarized: " + Basic.toString(summarized, ",");
+        return "assigned: " + Basic.toString(assigned, 0, assigned.length, ",", true) + ", summarized: " + Basic.toString(summarized, 0, summarized.length, ",", true);
     }
 
     public NodeData clone() {
diff --git a/src/jloda/graph/NodeDoubleArray.java b/src/jloda/graph/NodeDoubleArray.java
index 448d4d6..00c8445 100644
--- a/src/jloda/graph/NodeDoubleArray.java
+++ b/src/jloda/graph/NodeDoubleArray.java
@@ -1,6 +1,6 @@
 /**
  * NodeDoubleArray.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/NodeDoubleMap.java b/src/jloda/graph/NodeDoubleMap.java
index 39538f3..ca9908a 100644
--- a/src/jloda/graph/NodeDoubleMap.java
+++ b/src/jloda/graph/NodeDoubleMap.java
@@ -1,6 +1,6 @@
 /**
  * NodeDoubleMap.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/NodeEdge.java b/src/jloda/graph/NodeEdge.java
index 3dc3289..0cf8e97 100644
--- a/src/jloda/graph/NodeEdge.java
+++ b/src/jloda/graph/NodeEdge.java
@@ -1,6 +1,6 @@
 /**
  * NodeEdge.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -108,7 +108,7 @@ public class NodeEdge extends GraphBase {
     }
 
     /**
-     * is this node hidden? If hidden, this node will not be considered when using an iteration
+     * is this node hidden? If hidden, this node or edge will not be considered when using an iteration
      *
      * @return hidden
      */
diff --git a/src/jloda/graph/NodeEdgeEnumeration.java b/src/jloda/graph/NodeEdgeEnumeration.java
index 80239b0..baf040d 100644
--- a/src/jloda/graph/NodeEdgeEnumeration.java
+++ b/src/jloda/graph/NodeEdgeEnumeration.java
@@ -1,6 +1,6 @@
 /**
  * NodeEdgeEnumeration.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/NodeIntegerArray.java b/src/jloda/graph/NodeIntegerArray.java
index 4dad681..4e59f77 100644
--- a/src/jloda/graph/NodeIntegerArray.java
+++ b/src/jloda/graph/NodeIntegerArray.java
@@ -1,6 +1,6 @@
 /**
  * NodeIntegerArray.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/NodeIntegerMap.java b/src/jloda/graph/NodeIntegerMap.java
index a3bb608..53701e5 100644
--- a/src/jloda/graph/NodeIntegerMap.java
+++ b/src/jloda/graph/NodeIntegerMap.java
@@ -1,6 +1,6 @@
 /**
  * NodeIntegerMap.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/NodeMap.java b/src/jloda/graph/NodeMap.java
index 80d5bf7..29c6f3a 100644
--- a/src/jloda/graph/NodeMap.java
+++ b/src/jloda/graph/NodeMap.java
@@ -1,6 +1,6 @@
 /**
  * NodeMap.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/NodeSet.java b/src/jloda/graph/NodeSet.java
index eb4975d..2ac8920 100644
--- a/src/jloda/graph/NodeSet.java
+++ b/src/jloda/graph/NodeSet.java
@@ -1,6 +1,6 @@
 /**
  * NodeSet.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/Num2EdgeArray.java b/src/jloda/graph/Num2EdgeArray.java
index 2ba46ad..781e9dc 100644
--- a/src/jloda/graph/Num2EdgeArray.java
+++ b/src/jloda/graph/Num2EdgeArray.java
@@ -1,6 +1,6 @@
 /**
  * Num2EdgeArray.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graph/Num2NodeArray.java b/src/jloda/graph/Num2NodeArray.java
index b810c5e..55ea828 100644
--- a/src/jloda/graph/Num2NodeArray.java
+++ b/src/jloda/graph/Num2NodeArray.java
@@ -1,6 +1,6 @@
 /**
  * Num2NodeArray.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/DefaultGraphDrawer.java b/src/jloda/graphview/DefaultGraphDrawer.java
index 96328fa..4e97445 100644
--- a/src/jloda/graphview/DefaultGraphDrawer.java
+++ b/src/jloda/graphview/DefaultGraphDrawer.java
@@ -1,6 +1,6 @@
 /**
  * DefaultGraphDrawer.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/DefaultNodeDrawer.java b/src/jloda/graphview/DefaultNodeDrawer.java
index ac4f042..fddde7a 100644
--- a/src/jloda/graphview/DefaultNodeDrawer.java
+++ b/src/jloda/graphview/DefaultNodeDrawer.java
@@ -1,6 +1,6 @@
 /**
  * DefaultNodeDrawer.java
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  * <p>
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  * <p>
@@ -19,13 +19,15 @@
  */
 package jloda.graphview;
 
-import gnu.jpdf.PDFGraphics;
 import jloda.graph.Node;
 import jloda.util.Geometry;
 import jloda.util.ProgramProperties;
+import jloda.util.Shapes;
+import org.apache.batik.ext.awt.geom.Polygon2D;
 
 import java.awt.*;
 import java.awt.geom.AffineTransform;
+import java.awt.geom.Ellipse2D;
 import java.awt.geom.Point2D;
 import java.io.IOException;
 
@@ -45,7 +47,8 @@ public class DefaultNodeDrawer implements INodeDrawer {
      */
     public DefaultNodeDrawer(GraphView graphView) {
         this.graphView = graphView;
-        this.trans = graphView.trans;
+        if (graphView != null)
+            this.trans = graphView.trans;
     }
 
     /**
@@ -56,7 +59,8 @@ public class DefaultNodeDrawer implements INodeDrawer {
      */
     public void setup(GraphView graphView, Graphics2D gc) {
         this.graphView = graphView;
-        this.trans = graphView.trans;
+        if (graphView != null)
+            this.trans = graphView.trans;
         this.gc = gc;
     }
 
@@ -107,14 +111,18 @@ public class DefaultNodeDrawer implements INodeDrawer {
     /**
      * Draw the node.
      */
-    private void draw(NodeView nv) {
+    public void draw(NodeView nv) {
         if (nv.getLocation() == null)
             return; // no location, don't draw
-        Point apt = trans.w2d(nv.getLocation());
+        Point apt;
+        if (trans != null)
+            apt = trans.w2d(nv.getLocation());
 
+        else
+            apt = new Point((int) Math.round(nv.getLocation().getX()), (int) Math.round(nv.getLocation().getY()));
         int scaledWidth;
         int scaledHeight;
-        if (nv.getFixedSize()) {
+        if (nv.getFixedSize() || trans == null) {
             scaledWidth = nv.getWidth();
             scaledHeight = nv.getHeight();
         } else {
@@ -122,70 +130,121 @@ public class DefaultNodeDrawer implements INodeDrawer {
             scaledHeight = NodeView.computeScaledHeight(trans, nv.getHeight());
         }
 
-        apt.x -= (scaledWidth >> 1);
-        apt.y -= (scaledHeight >> 1);
+        apt.x -= scaledHeight / 2;
+        apt.y -= scaledHeight / 2;
 
-        if (nv.getBorderColor() != null) {   // selected
-            if (nv.isEnabled())
-                gc.setColor(nv.getBorderColor());
-            else
-                gc.setColor(NodeView.DISABLED_COLOR);
-            if (nv.getShape() == NodeView.OVAL_NODE) {
-                gc.drawOval(apt.x - 2, apt.y - 2, scaledWidth + 4, scaledHeight + 4);
-                gc.drawOval(apt.x - 3, apt.y - 3, scaledWidth + 6, scaledHeight + 6);
-            } else if (nv.getShape() == NodeView.RECT_NODE) {
-                // default shape==GraphView.RECT_NODE
-                gc.drawRect(apt.x - 2, apt.y - 2, scaledWidth + 4, scaledHeight + 4);
-                gc.drawRect(apt.x - 3, apt.y - 3, scaledWidth + 6, scaledHeight + 6);
-            } else if (nv.getShape() == NodeView.TRIANGLE_NODE) {
-                Shape polygon = new Polygon(new int[]{apt.x - 2, apt.x + scaledWidth + 2, apt.x + scaledHeight / 2},
-                        new int[]{apt.y + scaledHeight + 2, apt.y + scaledHeight + 2, apt.y - 2}, 3);
-                gc.draw(polygon);
-            } else if (nv.getShape() == NodeView.DIAMOND_NODE) {
-                Shape polygon = new Polygon(new int[]{apt.x - 2, apt.x + scaledWidth / 2, apt.x + scaledWidth + 2, apt.x + scaledHeight / 2},
-                        new int[]{apt.y + scaledHeight / 2, apt.y + scaledHeight + 2, apt.y + scaledHeight / 2, apt.y - 2}, 4);
-                gc.draw(polygon);
+        final Shape shape;
+        Shape shape2 = null;
+
+        switch (nv.getNodeShape()) {
+            case None:
+                return;
+            default:
+            case Oval: {
+                shape = new Ellipse2D.Float(apt.x, apt.y, scaledWidth, scaledHeight);
+                break;
+            }
+            case Rectangle: {
+                shape = new Rectangle(apt.x, apt.y, scaledWidth, scaledHeight);
+                break;
+            }
+            case Triangle: {
+                shape = new Polygon2D(new float[]{apt.x, apt.x + scaledWidth, apt.x + 0.5f * scaledWidth},
+                        new float[]{apt.y + scaledHeight, apt.y + scaledHeight, apt.y}, 3);
+                break;
             }
+            case Diamond: {
+                shape = new Polygon(new int[]{apt.x, apt.x + scaledWidth / 2, apt.x + scaledWidth, apt.x + scaledWidth / 2},
+                        new int[]{apt.y + scaledHeight / 2, apt.y + scaledHeight, apt.y + scaledHeight / 2, apt.y}, 4);
+                break;
+            }
+            case Star4: {
+                final float[][] coords = Shapes.createStar(apt.x, apt.y, scaledWidth, scaledHeight, 4);
+                shape = new Polygon2D(coords[0], coords[1], coords[0].length);
+                break;
+            }
+            case Star5: {
+                final float[][] coords = Shapes.createStar(apt.x, apt.y, scaledWidth, scaledHeight, 5);
+                shape = new Polygon2D(coords[0], coords[1], coords[0].length);
+                break;
+            }
+            case Star6: {
+                final float[][] coords = Shapes.createStar(apt.x, apt.y, scaledWidth, scaledHeight, 6);
+                shape = new Polygon2D(coords[0], coords[1], coords[0].length);
+                break;
+            }
+            case CrossPlus: {
+                final float[][] coords = Shapes.createCrossPlus(apt.x, apt.y, scaledWidth, scaledHeight);
+                shape = new Polygon2D(coords[0], coords[1], coords[0].length);
+                break;
+            }
+            case CrossX: {
+                final float[][] coords = Shapes.createCrossX(apt.x, apt.y, scaledWidth, scaledHeight);
+                shape = new Polygon2D(coords[0], coords[1], coords[0].length);
+                break;
 
-            // else draw nothing
-        }
+            }
+            case Pentagon: {
+                final float[][] coords = Shapes.createRegularPolygon(apt.x, apt.y, scaledWidth, scaledHeight, 5);
+                shape = new Polygon2D(coords[0], coords[1], coords[0].length);
+                break;
+            }
+            case Hexagon: {
+                final float[][] coords = Shapes.createRegularPolygon(apt.x, apt.y, scaledWidth, scaledHeight, 6);
+                shape = new Polygon2D(coords[0], coords[1], coords[0].length);
+                break;
+            }
 
+            case TriangleDown: {
+                shape = new Polygon2D(new float[]{apt.x, apt.x + scaledWidth, apt.x + 0.5f * scaledWidth},
+                        new float[]{apt.y, apt.y, apt.y + scaledHeight}, 3);
+                break;
+            }
+            case CirclePlus: {
+                shape = new Ellipse2D.Float(apt.x, apt.y, scaledWidth, scaledHeight);
+                final float[][] coords = Shapes.createCrossPlus(apt.x + 1, apt.y + 1, scaledWidth - 2, scaledHeight - 2);
+                shape2 = new Polygon2D(coords[0], coords[1], coords[0].length);
+                break;
+            }
+            case CircleX: {
+                shape = new Ellipse2D.Float(apt.x, apt.y, scaledWidth, scaledHeight);
+                final float[][] coords = Shapes.createCrossX(apt.x + 2, apt.y + 2, scaledWidth - 4, scaledHeight - 4);
+                shape2 = new Polygon2D(coords[0], coords[1], coords[0].length);
+                break;
+            }
+            case SquarePlus: {
+                shape = new Rectangle(apt.x, apt.y, scaledWidth, scaledHeight);
+                final float[][] coords = Shapes.createCrossPlus(apt.x, apt.y, scaledWidth - 1, scaledHeight - 1);
+                shape2 = new Polygon2D(coords[0], coords[1], coords[0].length);
+                break;
+            }
+            case SquareX: {
+                shape = new Rectangle(apt.x, apt.y, scaledWidth, scaledHeight);
+                final float[][] coords = Shapes.createCrossX(apt.x, apt.y - 1, scaledWidth, scaledHeight);
+                shape2 = new Polygon2D(coords[0], coords[1], coords[0].length);
+                break;
+            }
+        }
         if (nv.getBackgroundColor() != null) {
             if (nv.isEnabled())
                 gc.setColor(nv.getBackgroundColor());
             else
                 gc.setColor(Color.WHITE);
-            if (nv.getShape() == NodeView.OVAL_NODE)
-                gc.fillOval(apt.x, apt.y, scaledWidth, scaledHeight);
-            else if (nv.getShape() == NodeView.RECT_NODE)
-                gc.fillRect(apt.x, apt.y, scaledWidth, scaledHeight);
-            else if (nv.getShape() == NodeView.TRIANGLE_NODE) {
-                Shape polygon = new Polygon(new int[]{apt.x, apt.x + scaledWidth, apt.x + scaledHeight / 2},
-                        new int[]{apt.y + scaledHeight, apt.y + scaledHeight, apt.y}, 3);
-                gc.fill(polygon);
-            } else if (nv.getShape() == NodeView.DIAMOND_NODE) {
-                Shape polygon = new Polygon(new int[]{apt.x, apt.x + scaledWidth / 2, apt.x + scaledWidth, apt.x + scaledHeight / 2},
-                        new int[]{apt.y + scaledHeight / 2, apt.y + scaledHeight, apt.y + scaledHeight / 2, apt.y}, 4);
-                gc.fill(polygon);
+            gc.fill(shape);
+            if (shape2 != null) {
+                gc.setColor(new Color(1f, 1f, 1f, 0.8f));
+                gc.fill(shape2);
             }
+
         }
         if (nv.getColor() != null) {
             if (nv.isEnabled())
                 gc.setColor(nv.getColor());
             else
                 gc.setColor(NodeView.DISABLED_COLOR);
-            if (nv.getShape() == NodeView.OVAL_NODE)
-                gc.drawOval(apt.x, apt.y, scaledWidth, scaledHeight);
-            else if (nv.getShape() == NodeView.RECT_NODE)
-                gc.drawRect(apt.x, apt.y, scaledWidth, scaledHeight);
-            else if (nv.getShape() == NodeView.TRIANGLE_NODE) {
-                Shape polygon = new Polygon(new int[]{apt.x, apt.x + scaledWidth, apt.x + scaledHeight / 2},
-                        new int[]{apt.y + scaledHeight, apt.y + scaledHeight, apt.y}, 3);
-                gc.draw(polygon);
-            } else if (nv.getShape() == NodeView.DIAMOND_NODE) {
-                Shape polygon = new Polygon(new int[]{apt.x, apt.x + scaledWidth / 2, apt.x + scaledWidth, apt.x + scaledHeight / 2},
-                        new int[]{apt.y + scaledHeight / 2, apt.y + scaledHeight, apt.y + scaledHeight / 2, apt.y}, 4);
-                gc.draw(polygon);
+            gc.draw(shape);
+            if (shape2 != null) {
+                gc.draw(shape2);
             }
         }
     }
@@ -198,7 +257,7 @@ public class DefaultNodeDrawer implements INodeDrawer {
             return;
         int scaledWidth;
         int scaledHeight;
-        if (nv.getShape() == NodeView.NONE_NODE) {
+        if (nv.getNodeShape() == NodeShape.None) {
             scaledWidth = scaledHeight = 2;
         } else {
             if (nv.getFixedSize()) {
@@ -287,17 +346,9 @@ public class DefaultNodeDrawer implements INodeDrawer {
                     if (nv.getLabelAngle() == 0) {
                         gc.drawString(nv.getLabel(), (int) apt.getX(), (int) apt.getY());
                     } else {
-                        float labelAngle = nv.getLabelAngle() + 0.00001f; // to ensure that labels all get same orientation in
+                        final float labelAngle = nv.getLabelAngle() + 0.00001f; // to ensure that labels all get same orientation in
 
-                        Dimension labelSize = nv.getLabelSize();
-                        if (gc instanceof PDFGraphics) {
-                            if (labelAngle >= 0.5 * Math.PI && labelAngle <= 1.5 * Math.PI) {
-                                apt = Geometry.translateByAngle(apt, labelAngle, labelSize.getWidth());
-                                ((PDFGraphics) gc).drawString(nv.getLabel(), (float) (apt.getX()), (float) (apt.getY()), (float) (labelAngle - Math.PI));
-                            } else {
-                                ((PDFGraphics) gc).drawString(nv.getLabel(), (float) (apt.getX()), (float) (apt.getY()), labelAngle);
-                            }
-                        } else {
+                        final Dimension labelSize = nv.getLabelSize();
                             // save current transform:
                             AffineTransform saveTransform = gc.getTransform();
                             // a vertical phylogram view
@@ -324,7 +375,6 @@ public class DefaultNodeDrawer implements INodeDrawer {
                             }
                             gc.drawString(nv.getLabel(), (int) apt.getX(), (int) apt.getY());
                             gc.setTransform(saveTransform);
-                        }
                     }
                 }
             }
diff --git a/src/jloda/graphview/EdgeActionAdapter.java b/src/jloda/graphview/EdgeActionAdapter.java
index 7ffd38f..8a98784 100644
--- a/src/jloda/graphview/EdgeActionAdapter.java
+++ b/src/jloda/graphview/EdgeActionAdapter.java
@@ -1,6 +1,6 @@
 /**
  * EdgeActionAdapter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/EdgeActionListener.java b/src/jloda/graphview/EdgeActionListener.java
index 4869cda..991c003 100644
--- a/src/jloda/graphview/EdgeActionListener.java
+++ b/src/jloda/graphview/EdgeActionListener.java
@@ -1,6 +1,6 @@
 /**
  * EdgeActionListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/EdgeView.java b/src/jloda/graphview/EdgeView.java
index 64997b6..d9cebf3 100644
--- a/src/jloda/graphview/EdgeView.java
+++ b/src/jloda/graphview/EdgeView.java
@@ -1,6 +1,6 @@
 /**
  * EdgeView.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -26,7 +26,6 @@
  */
 package jloda.graphview;
 
-import gnu.jpdf.PDFGraphics;
 import jloda.util.Basic;
 import jloda.util.Geometry;
 import jloda.util.ProgramProperties;
@@ -697,14 +696,6 @@ final public class EdgeView extends ViewBase implements Cloneable { //, IEdgeVie
 
             if (labelAngle == 0) {
                 gc.drawString(label, (int) apt.getX(), (int) apt.getY());
-            } else if (gc instanceof PDFGraphics) {
-                if (labelAngle >= 0.5 * Math.PI && labelAngle <= 1.5 * Math.PI) {
-                    double d = getLabelSize().getWidth();
-                    apt = Geometry.translateByAngle(apt, labelAngle, d);
-                    ((PDFGraphics) gc).drawString(label, (float) apt.getX(), (float) apt.getY(), (float) (labelAngle - Math.PI));
-                } else {
-                    ((PDFGraphics) gc).drawString(label, (float) apt.getX(), (float) apt.getY(), labelAngle);
-                }
             } else {
                 // save current transform:
                 AffineTransform saveTransform = gc.getTransform();
diff --git a/src/jloda/graphview/GraphEditor.java b/src/jloda/graphview/GraphEditor.java
index 3b47fb2..f277dac 100644
--- a/src/jloda/graphview/GraphEditor.java
+++ b/src/jloda/graphview/GraphEditor.java
@@ -1,6 +1,6 @@
 /**
  * GraphEditor.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/GraphView.java b/src/jloda/graphview/GraphView.java
index cf57eae..4b33418 100644
--- a/src/jloda/graphview/GraphView.java
+++ b/src/jloda/graphview/GraphView.java
@@ -1,6 +1,6 @@
 /**
  * GraphView.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -536,6 +536,15 @@ public class GraphView extends JPanel implements Printable, Scrollable, INodeEdg
     }
 
     /**
+     * gets the node shape
+     *
+     * @param v
+     * @return node shape
+     */
+    public NodeShape getNodeShape(Node v) {
+        return getNV(v).getNodeShape();
+    }
+    /**
      * Set the default edge label.
      *
      * @param a the default value
@@ -1136,6 +1145,16 @@ public class GraphView extends JPanel implements Printable, Scrollable, INodeEdg
     }
 
     /**
+     * Sets the shape.
+     *
+     * @param v the node
+     * @param a the shape
+     */
+    public void setNodeShape(Node v, NodeShape a) {
+        getNV(v).setNodeShape(a);
+    }
+
+    /**
      * Gets the shape.
      *
      * @param v the node
@@ -3842,6 +3861,7 @@ public class GraphView extends JPanel implements Printable, Scrollable, INodeEdg
     public void setFrame(JFrame frame) {
         this.frame = frame;
     }
+
 }
 
 // EOF
diff --git a/src/jloda/graphview/GraphViewBase.java b/src/jloda/graphview/GraphViewBase.java
index d53809f..2ea2945 100644
--- a/src/jloda/graphview/GraphViewBase.java
+++ b/src/jloda/graphview/GraphViewBase.java
@@ -1,6 +1,6 @@
 /**
  * GraphViewBase.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/GraphViewListener.java b/src/jloda/graphview/GraphViewListener.java
index 1142cf4..a2f169b 100644
--- a/src/jloda/graphview/GraphViewListener.java
+++ b/src/jloda/graphview/GraphViewListener.java
@@ -1,6 +1,6 @@
 /**
  * GraphViewListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/IGraphDrawer.java b/src/jloda/graphview/IGraphDrawer.java
index b7493a4..08555e3 100644
--- a/src/jloda/graphview/IGraphDrawer.java
+++ b/src/jloda/graphview/IGraphDrawer.java
@@ -1,6 +1,6 @@
 /**
  * IGraphDrawer.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/IGraphViewListener.java b/src/jloda/graphview/IGraphViewListener.java
index e914fbe..9174064 100644
--- a/src/jloda/graphview/IGraphViewListener.java
+++ b/src/jloda/graphview/IGraphViewListener.java
@@ -1,6 +1,6 @@
 /**
  * IGraphViewListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/INodeDrawer.java b/src/jloda/graphview/INodeDrawer.java
index e1d8317..354469a 100644
--- a/src/jloda/graphview/INodeDrawer.java
+++ b/src/jloda/graphview/INodeDrawer.java
@@ -1,6 +1,6 @@
 /**
  * INodeDrawer.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/INodeEdgeFormatable.java b/src/jloda/graphview/INodeEdgeFormatable.java
index abe31d0..d597f83 100644
--- a/src/jloda/graphview/INodeEdgeFormatable.java
+++ b/src/jloda/graphview/INodeEdgeFormatable.java
@@ -1,6 +1,6 @@
 /**
  * INodeEdgeFormatable.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/IPopupListener.java b/src/jloda/graphview/IPopupListener.java
index 7ad597b..3c5e4d1 100644
--- a/src/jloda/graphview/IPopupListener.java
+++ b/src/jloda/graphview/IPopupListener.java
@@ -1,6 +1,6 @@
 /**
  * IPopupListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/ITransformChangeListener.java b/src/jloda/graphview/ITransformChangeListener.java
index 518d3d6..d7c2858 100644
--- a/src/jloda/graphview/ITransformChangeListener.java
+++ b/src/jloda/graphview/ITransformChangeListener.java
@@ -1,6 +1,6 @@
 /**
  * ITransformChangeListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/LabelLayoutRTree.java b/src/jloda/graphview/LabelLayoutRTree.java
index b4c825f..8faef2e 100644
--- a/src/jloda/graphview/LabelLayoutRTree.java
+++ b/src/jloda/graphview/LabelLayoutRTree.java
@@ -1,6 +1,6 @@
 /**
  * LabelLayoutRTree.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/LabelLayouter.java b/src/jloda/graphview/LabelLayouter.java
index 10795d0..85387f8 100644
--- a/src/jloda/graphview/LabelLayouter.java
+++ b/src/jloda/graphview/LabelLayouter.java
@@ -1,6 +1,6 @@
 /**
  * LabelLayouter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/LabelOverlapAvoider.java b/src/jloda/graphview/LabelOverlapAvoider.java
index d3a4374..b259512 100644
--- a/src/jloda/graphview/LabelOverlapAvoider.java
+++ b/src/jloda/graphview/LabelOverlapAvoider.java
@@ -1,6 +1,6 @@
 /**
  * LabelOverlapAvoider.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/Magnifier.java b/src/jloda/graphview/Magnifier.java
index 98af1f9..ed9d056 100644
--- a/src/jloda/graphview/Magnifier.java
+++ b/src/jloda/graphview/Magnifier.java
@@ -1,6 +1,6 @@
 /**
  * Magnifier.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/MagnifierUtil.java b/src/jloda/graphview/MagnifierUtil.java
index a0d5f39..901244a 100644
--- a/src/jloda/graphview/MagnifierUtil.java
+++ b/src/jloda/graphview/MagnifierUtil.java
@@ -1,6 +1,6 @@
 /**
  * MagnifierUtil.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/NodeActionAdapter.java b/src/jloda/graphview/NodeActionAdapter.java
index 4067bb7..919d2e8 100644
--- a/src/jloda/graphview/NodeActionAdapter.java
+++ b/src/jloda/graphview/NodeActionAdapter.java
@@ -1,6 +1,6 @@
 /**
  * NodeActionAdapter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/NodeActionListener.java b/src/jloda/graphview/NodeActionListener.java
index 53b18be..31fd59f 100644
--- a/src/jloda/graphview/NodeActionListener.java
+++ b/src/jloda/graphview/NodeActionListener.java
@@ -1,6 +1,6 @@
 /**
  * NodeActionListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/NodeImage.java b/src/jloda/graphview/NodeImage.java
index 8d613b4..e0e5ac8 100644
--- a/src/jloda/graphview/NodeImage.java
+++ b/src/jloda/graphview/NodeImage.java
@@ -1,6 +1,6 @@
 /**
  * NodeImage.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/NodeShape.java b/src/jloda/graphview/NodeShape.java
new file mode 100644
index 0000000..c24f94f
--- /dev/null
+++ b/src/jloda/graphview/NodeShape.java
@@ -0,0 +1,38 @@
+/*
+ *  Copyright (C) 2015 Daniel H. Huson and David J. Bryant
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package jloda.graphview;
+
+/**
+ * node shapes
+ * Created by huson on 2/13/17.
+ */
+public enum NodeShape {
+    None, Rectangle, Oval, Triangle, Diamond, TriangleDown, Star4, Star5, Pentagon, Star6, CrossPlus, CrossX, Hexagon, CirclePlus, CircleX, SquarePlus, SquareX;
+
+    public static NodeShape valueOfIgnoreCase(String name) {
+        if (name == null)
+            return null;
+        for (NodeShape shape : values()) {
+            if (shape.toString().equalsIgnoreCase(name))
+                return shape;
+        }
+        return null;
+    }
+}
diff --git a/src/jloda/graphview/NodeShapeIcon.java b/src/jloda/graphview/NodeShapeIcon.java
new file mode 100644
index 0000000..d3eeb5e
--- /dev/null
+++ b/src/jloda/graphview/NodeShapeIcon.java
@@ -0,0 +1,54 @@
+/*
+ *  Copyright (C) 2015 Daniel H. Huson and David J. Bryant
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package jloda.graphview;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.BufferedImage;
+
+/**
+ * a node shape icon
+ * Created by huson on 2/13/17.
+ */
+public class NodeShapeIcon extends ImageIcon {
+    /**
+     * constructor
+     *
+     * @param shape
+     * @param bgColor
+     */
+    public NodeShapeIcon(NodeShape shape, int size, Color bgColor) {
+        final DefaultNodeDrawer drawer = new DefaultNodeDrawer(null);
+        final NodeView nodeView = new NodeView();
+        nodeView.setLocation(size / 2, size / 2);
+        nodeView.setBackgroundColor(bgColor);
+        nodeView.setColor(Color.BLACK);
+        nodeView.setNodeShape(shape);
+        nodeView.setWidth(size);
+        nodeView.setHeight(size);
+        final BufferedImage image = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
+        Graphics2D g = image.createGraphics();
+        drawer.setup(null, (Graphics2D) g);
+        drawer.draw(nodeView);
+        g.dispose();
+        setImage(image);
+
+    }
+}
diff --git a/src/jloda/graphview/NodeView.java b/src/jloda/graphview/NodeView.java
index b17b20f..ea681d6 100644
--- a/src/jloda/graphview/NodeView.java
+++ b/src/jloda/graphview/NodeView.java
@@ -1,6 +1,6 @@
 /**
  * NodeView.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -26,7 +26,6 @@
  */
 package jloda.graphview;
 
-import gnu.jpdf.PDFGraphics;
 import jloda.util.Basic;
 import jloda.util.Geometry;
 import jloda.util.ProgramProperties;
@@ -46,16 +45,20 @@ final public class NodeView extends ViewBase implements Cloneable {
     private final int GAPSIZE = 2; // gap between edge of node and start of edge
 
     private Color borderColor = null;
-    private byte shape = OVAL_NODE;
+    private NodeShape nodeShape = NodeShape.Oval;
     //private byte imageLayout = NORTH;
     protected Point2D location = null;
     boolean fixedSize = true;
 
+    // legacy implementation of node shape:
+    public static final byte NONE_NODE = 0;
     public static final byte RECT_NODE = 1;
     public static final byte OVAL_NODE = 2;
     public static final byte TRIANGLE_NODE = 3;
     public static final byte DIAMOND_NODE = 4;
-    public static final byte NONE_NODE = 0;
+
+    // do not changer order of first 5 items for backward compatiblity
+
 
     private NodeImage image = null;
     protected Color bgColor = Color.WHITE;
@@ -93,7 +96,7 @@ final public class NodeView extends ViewBase implements Cloneable {
         setBackgroundColor(src.getBackgroundColor());
         height = src.height;
         width = src.width;
-        shape = src.shape;
+        nodeShape = src.nodeShape;
         fixedSize = src.getFixedSize();
     }
 
@@ -118,7 +121,7 @@ final public class NodeView extends ViewBase implements Cloneable {
             return null;
 
         Point apt = trans.w2d(getLocation());
-        if (shape == NONE_NODE)
+        if (nodeShape == NodeShape.None)
             return apt;
 
         int scaledWidth;
@@ -141,7 +144,7 @@ final public class NodeView extends ViewBase implements Cloneable {
 
         Point p = new Point();
 
-        if (shape == RECT_NODE) {
+        if (nodeShape == NodeShape.Rectangle) {
             if (y >= x && y >= -x) // top
             {
                 p.x = apt.x;
@@ -203,7 +206,7 @@ final public class NodeView extends ViewBase implements Cloneable {
 
         int scaledWidth;
         int scaledHeight;
-        if (shape == NONE_NODE) {
+        if (nodeShape == NodeShape.None) {
             scaledWidth = scaledHeight = 2;
         } else {
             if (fixedSize) {
@@ -250,19 +253,28 @@ final public class NodeView extends ViewBase implements Cloneable {
      * Sets the node shape.
      *
      * @param a int
+     *  @deprecated use setNodeShape
      */
     public void setShape(byte a) {
-        shape = a;
+        nodeShape = NodeShape.values()[a];
     }
 
     /**
      * Gets the node shape.
      *
      * @return the shape
+     * @deprecated use getNodeShape
      */
-
     public byte getShape() {
-        return shape;
+        return (byte) nodeShape.ordinal();
+    }
+
+    public void setNodeShape(NodeShape nodeShape) {
+        this.nodeShape = nodeShape;
+    }
+
+    public NodeShape getNodeShape() {
+        return nodeShape;
     }
 
     /**
@@ -325,10 +337,10 @@ final public class NodeView extends ViewBase implements Cloneable {
                 gc.setColor(this.borderColor);
             else
                 gc.setColor(DISABLED_COLOR);
-            if (shape == OVAL_NODE) {
+            if (nodeShape == NodeShape.Oval) {
                 gc.drawOval(apt.x - 2, apt.y - 2, scaledWidth + 4, scaledHeight + 4);
                 gc.drawOval(apt.x - 3, apt.y - 3, scaledWidth + 6, scaledHeight + 6);
-            } else if (shape == RECT_NODE) {
+            } else if (nodeShape == NodeShape.Rectangle) {
 // default shape==GraphView.RECT_NODE
                 gc.drawRect(apt.x - 2, apt.y - 2, scaledWidth + 4, scaledHeight + 4);
                 gc.drawRect(apt.x - 3, apt.y - 3, scaledWidth + 6, scaledHeight + 6);
@@ -341,10 +353,11 @@ final public class NodeView extends ViewBase implements Cloneable {
                 gc.setColor(bgColor);
             else
                 gc.setColor(Color.WHITE);
-            if (shape == OVAL_NODE)
+            if (nodeShape == NodeShape.Oval) {
                 gc.fillOval(apt.x, apt.y, scaledWidth, scaledHeight);
-            else if (shape == RECT_NODE)
+            } else if (nodeShape == NodeShape.Rectangle) {
                 gc.fillRect(apt.x, apt.y, scaledWidth, scaledHeight);
+            }
 
         }
         if (fgColor != null) {
@@ -352,10 +365,11 @@ final public class NodeView extends ViewBase implements Cloneable {
                 gc.setColor(fgColor);
             else
                 gc.setColor(DISABLED_COLOR);
-            if (shape == OVAL_NODE)
+            if (nodeShape == NodeShape.Oval) {
                 gc.drawOval(apt.x, apt.y, scaledWidth, scaledHeight);
-            else if (shape == RECT_NODE)
+            } else if (nodeShape == NodeShape.Rectangle) {
                 gc.drawRect(apt.x, apt.y, scaledWidth, scaledHeight);
+            }
         }
     }
 
@@ -398,7 +412,7 @@ final public class NodeView extends ViewBase implements Cloneable {
             return;
         int scaledWidth;
         int scaledHeight;
-        if (shape == NONE_NODE) {
+        if (nodeShape == NodeShape.None) {
             scaledWidth = scaledHeight = 2;
         } else {
             if (fixedSize) {
@@ -497,17 +511,8 @@ final public class NodeView extends ViewBase implements Cloneable {
                     if (labelAngle == 0) {
                         gc.drawString(label, (int) apt.getX(), (int) apt.getY());
                     } else {
-                        float labelAngle = this.labelAngle + 0.00001f; // to ensure that labels all get same orientation in
+                        final float labelAngle = this.labelAngle + 0.00001f; // to ensure that labels all get same orientation in
 
-                        Dimension labelSize = getLabelSize();
-                        if (gc instanceof PDFGraphics) {
-                            if (labelAngle >= 0.5 * Math.PI && labelAngle <= 1.5 * Math.PI) {
-                                apt = Geometry.translateByAngle(apt, labelAngle, labelSize.getWidth());
-                                ((PDFGraphics) gc).drawString(label, (float) (apt.getX()), (float) (apt.getY()), (float) (labelAngle - Math.PI));
-                            } else {
-                                ((PDFGraphics) gc).drawString(label, (float) (apt.getX()), (float) (apt.getY()), labelAngle);
-                            }
-                        } else {
                             // save current transform:
                             AffineTransform saveTransform = gc.getTransform();
                             // a vertical phylogram view
@@ -534,7 +539,6 @@ final public class NodeView extends ViewBase implements Cloneable {
                             }
                             gc.drawString(label, (int) apt.getX(), (int) apt.getY());
                             gc.setTransform(saveTransform);
-                        }
                     }
                 }
             }
@@ -605,7 +609,7 @@ final public class NodeView extends ViewBase implements Cloneable {
         int scaledWidth;
         int scaledHeight;
 
-        if (shape == NONE_NODE)
+        if (nodeShape == NodeShape.None)
             scaledWidth = scaledHeight = 2;
         else {
             if (fixedSize) {
@@ -824,8 +828,8 @@ final public class NodeView extends ViewBase implements Cloneable {
             buf.append(" bd=").append(Basic.toString3Int(borderColor));
         if (previousNV == null || linewidth != previousNV.linewidth)
             buf.append(" w=").append(linewidth);
-        if (previousNV == null || shape != previousNV.shape)
-            buf.append(" sh=").append(shape);
+        if (previousNV == null || nodeShape != previousNV.nodeShape)
+            buf.append(" sh=").append(getShape());
         if (withCoordinates && location != null) {
             buf.append(" x=").append((float) location.getX());
             buf.append(" y=").append((float) location.getY());
@@ -898,9 +902,9 @@ final public class NodeView extends ViewBase implements Cloneable {
         bgColor = np.findIgnoreCase(tokens, "bg=", prevNV.bgColor);
         borderColor = np.findIgnoreCase(tokens, "bd=", prevNV.borderColor);
         linewidth = (byte) np.findIgnoreCase(tokens, "w=", prevNV.linewidth);
-        shape = (byte) np.findIgnoreCase(tokens, "sh=", prevNV.shape);
+        setShape((byte) np.findIgnoreCase(tokens, "sh=", prevNV.getShape()));
 
-        if ((prevNV != null && prevNV != this) || (tokens.contains("x=") && tokens.contains("y="))) {
+        if (prevNV != this || (tokens.contains("x=") && tokens.contains("y="))) {
             double x = np.findIgnoreCase(tokens, "x=", prevNV.getLocation() != null ? (float) prevNV.getLocation().getX() : 0);
             double y = np.findIgnoreCase(tokens, "y=", prevNV.getLocation() != null ? (float) prevNV.getLocation().getY() : 0);
             setLocation(new Point2D.Double(x, y));
diff --git a/src/jloda/graphview/PanelActionListener.java b/src/jloda/graphview/PanelActionListener.java
index b54f71e..4680c3d 100644
--- a/src/jloda/graphview/PanelActionListener.java
+++ b/src/jloda/graphview/PanelActionListener.java
@@ -1,6 +1,6 @@
 /**
  * PanelActionListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/ScrollPaneAdjuster.java b/src/jloda/graphview/ScrollPaneAdjuster.java
index fdd18ee..fcfa2dd 100644
--- a/src/jloda/graphview/ScrollPaneAdjuster.java
+++ b/src/jloda/graphview/ScrollPaneAdjuster.java
@@ -1,6 +1,6 @@
 /**
  * ScrollPaneAdjuster.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/Transform.java b/src/jloda/graphview/Transform.java
index ee2b601..be6d459 100644
--- a/src/jloda/graphview/Transform.java
+++ b/src/jloda/graphview/Transform.java
@@ -1,6 +1,6 @@
 /**
  * Transform.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/graphview/ViewBase.java b/src/jloda/graphview/ViewBase.java
index f927204..f3da922 100644
--- a/src/jloda/graphview/ViewBase.java
+++ b/src/jloda/graphview/ViewBase.java
@@ -1,6 +1,6 @@
 /**
  * ViewBase.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/About.java b/src/jloda/gui/About.java
index 1dfc16e..cf19045 100644
--- a/src/jloda/gui/About.java
+++ b/src/jloda/gui/About.java
@@ -1,6 +1,6 @@
 /**
  * About.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/ActionJList.java b/src/jloda/gui/ActionJList.java
index 6e4c6f4..b1b3a38 100644
--- a/src/jloda/gui/ActionJList.java
+++ b/src/jloda/gui/ActionJList.java
@@ -1,6 +1,6 @@
 /**
  * ActionJList.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/AppleStuff.java b/src/jloda/gui/AppleStuff.java
index baf2c31..56210e2 100644
--- a/src/jloda/gui/AppleStuff.java
+++ b/src/jloda/gui/AppleStuff.java
@@ -1,6 +1,6 @@
 /**
  * AppleStuff.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/ChooseColorDialog.java b/src/jloda/gui/ChooseColorDialog.java
index a6722d5..92c8aff 100644
--- a/src/jloda/gui/ChooseColorDialog.java
+++ b/src/jloda/gui/ChooseColorDialog.java
@@ -1,6 +1,6 @@
 /**
  * ChooseColorDialog.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/ChooseFileDialog.java b/src/jloda/gui/ChooseFileDialog.java
index 841109b..b65cc2f 100644
--- a/src/jloda/gui/ChooseFileDialog.java
+++ b/src/jloda/gui/ChooseFileDialog.java
@@ -1,6 +1,6 @@
 /**
  * ChooseFileDialog.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -50,15 +50,7 @@ public class ChooseFileDialog {
     public static File chooseFileToOpen(Component parent, File lastOpenFile, FileFilter fileFilter, FilenameFilter fileNameFilter, ActionEvent event, String message) {
         File file = null;
 
-        JFrame frame = null;
-        if (parent != null && parent instanceof JFrame)
-            frame = (JFrame) parent;
-        if (frame != null && frame.getJMenuBar() != null) {
-            // frame.getJMenuBar().setEnabled(false); // todo: to do this we need to remember the state of all menu items and then reenable them below...
-        }
-
-        try {
-            if (ProgramProperties.isMacOS() && (event == null || (event.getModifiers() & Event.SHIFT_MASK) == 0)) {
+        if (ProgramProperties.isMacOS() && (event == null || (event.getModifiers() & Event.SHIFT_MASK) == 0)) {
                 //Use native file dialog on mac
                 java.awt.FileDialog dialog;
                 if (parent != null && parent instanceof JFrame)
@@ -98,11 +90,6 @@ public class ChooseFileDialog {
                     file = chooser.getSelectedFile();
                 }
             }
-        } finally {
-            if (frame != null && frame.getJMenuBar() != null) {
-                // frame.getJMenuBar().setEnabled(true);
-            }
-        }
         return file;
     }
 
@@ -199,8 +186,7 @@ public class ChooseFileDialog {
      * @param defaultSuffix  .suff or null
      * @return file or null
      */
-    public static File chooseFileToSave(Component parent, File lastOpenFile, FileFilter fileFilter, FilenameFilter fileNameFilter, ActionEvent event, String message,
-                                        String defaultSuffix) {
+    public static File chooseFileToSave(Component parent, File lastOpenFile, FileFilter fileFilter, FilenameFilter fileNameFilter, ActionEvent event, String message, String defaultSuffix) {
         if (defaultSuffix != null && !defaultSuffix.startsWith("."))
             defaultSuffix = "." + defaultSuffix;
         File file = null;
@@ -275,10 +261,7 @@ public class ChooseFileDialog {
                 }
                 if (file.exists()) {
                     switch (
-                            JOptionPane.showConfirmDialog(parent,
-                                    "This file already exists. Overwrite the existing file?",
-                                    "Save File",
-                                    JOptionPane.YES_NO_CANCEL_OPTION)) {
+                            JOptionPane.showConfirmDialog(parent, "This file already exists. Overwrite the existing file?", "Save File", JOptionPane.YES_NO_CANCEL_OPTION)) {
                         case JOptionPane.YES_OPTION:
                             okToWrite = true;
                             break;
diff --git a/src/jloda/gui/ChooseFontDialog.java b/src/jloda/gui/ChooseFontDialog.java
index effcd23..47fecc3 100644
--- a/src/jloda/gui/ChooseFontDialog.java
+++ b/src/jloda/gui/ChooseFontDialog.java
@@ -1,6 +1,6 @@
 /**
  * ChooseFontDialog.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/ColorTableManager.java b/src/jloda/gui/ColorTableManager.java
index cb0e81a..b31438a 100644
--- a/src/jloda/gui/ColorTableManager.java
+++ b/src/jloda/gui/ColorTableManager.java
@@ -82,7 +82,10 @@ public class ColorTableManager {
                     "0x47b047;0x45af46;0x43af45;0x42ae43;0x40ad42;0x3dac41;0x3cac3f;0x3aab3e;0x39aa3c;0x37aa3b;0x35a93b;0x34a839;0x32a838;0x30a736;0x2fa535;0x2ca533;0x2aa431;" +
                     "0x29a230;0x27a22f;0x25a12d;0x23a02c;0x229f2a;0x209f29;0x1e9e27;0x1d9c26;0x1b9c25;0x1b9a24;0x1a9824;0x199623;0x199422;0x189223;0x199024;0x188e24;0x188c24;" +
                     "0x178a23;0x168822;0x178624;0x168424;0x168224;0x158024;0x147f22;0x147d23;0x147b24;0x157924;0x157725;0x137624;0x127423;0x117223;0x127023;0x136f25;0x126d25;" +
-                    "0x126b25;0x116924;0x106723;0x106523;0x106525;0x116326;0x106126;0x105f25;0xf5d25;0xd5b24;0xe5926;0xf5727;0xf5526;"
+                    "0x126b25;0x116924;0x106723;0x106523;0x106525;0x116326;0x106126;0x105f25;0xf5d25;0xd5b24;0xe5926;0xf5727;0xf5526;",
+            "Red;1;0xf10000;",
+            "Green;1;0x00f100;",
+            "Blue;1;0x0000f1;"
     };
 
     private static void init() {
diff --git a/src/jloda/gui/DefaultLabelGetter.java b/src/jloda/gui/DefaultLabelGetter.java
index dcdf6ec..9e56de5 100644
--- a/src/jloda/gui/DefaultLabelGetter.java
+++ b/src/jloda/gui/DefaultLabelGetter.java
@@ -1,6 +1,6 @@
 /**
  * DefaultLabelGetter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/GraphViewPopupListener.java b/src/jloda/gui/GraphViewPopupListener.java
index c14f645..74feccb 100644
--- a/src/jloda/gui/GraphViewPopupListener.java
+++ b/src/jloda/gui/GraphViewPopupListener.java
@@ -1,6 +1,6 @@
 /**
  * GraphViewPopupListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -33,11 +33,11 @@ import java.awt.event.MouseEvent;
  * Daniel Huson, 8.2010
  */
 public class GraphViewPopupListener implements IPopupListener {
-    final JPopupMenu nodeMenu;
+    final PopupMenu nodeMenu;
     //JPopupMenu nodeLabelMenu;
-    final JPopupMenu edgeMenu;
+    final PopupMenu edgeMenu;
     //JPopupMenu EdgeLabelMenu;
-    final JPopupMenu panelMenu;
+    final PopupMenu panelMenu;
     private final GraphView viewer;
 
     /**
@@ -51,9 +51,9 @@ public class GraphViewPopupListener implements IPopupListener {
      */
     public GraphViewPopupListener(GraphView viewer, String nodeConfig, String edgeConfig, String panelConfig, CommandManager commandManager) {
         this.viewer = viewer;
-        nodeMenu = new PopupMenu(nodeConfig, commandManager);
-        edgeMenu = new PopupMenu(edgeConfig, commandManager);
-        panelMenu = new PopupMenu(panelConfig, commandManager);
+        nodeMenu = new PopupMenu(viewer, nodeConfig, commandManager, false, true, false);
+        edgeMenu = new PopupMenu(viewer, edgeConfig, commandManager, false, false, true);
+        panelMenu = new PopupMenu(viewer, panelConfig, commandManager);
     }
 
     /**
diff --git a/src/jloda/gui/HistogramPanel.java b/src/jloda/gui/HistogramPanel.java
index c67e7a0..ab8f204 100644
--- a/src/jloda/gui/HistogramPanel.java
+++ b/src/jloda/gui/HistogramPanel.java
@@ -1,6 +1,6 @@
 /**
  * HistogramPanel.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/ILabelGetter.java b/src/jloda/gui/ILabelGetter.java
index a7c3437..6e6fcf0 100644
--- a/src/jloda/gui/ILabelGetter.java
+++ b/src/jloda/gui/ILabelGetter.java
@@ -1,6 +1,6 @@
 /**
  * ILabelGetter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/IMenuModifier.java b/src/jloda/gui/IMenuModifier.java
index bcd1834..63db735 100644
--- a/src/jloda/gui/IMenuModifier.java
+++ b/src/jloda/gui/IMenuModifier.java
@@ -1,6 +1,6 @@
 /**
  * IMenuModifier.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -28,5 +28,5 @@ import javax.swing.*;
  * Daniel Huson, 5.2015
  */
 public interface IMenuModifier {
-    void apply(JMenu menu, CommandManager commandManager);
+    void apply(JMenu menu, Object viewer, CommandManager commandManager);
 }
diff --git a/src/jloda/gui/IPopMenuModifier.java b/src/jloda/gui/IPopMenuModifier.java
new file mode 100644
index 0000000..2717da1
--- /dev/null
+++ b/src/jloda/gui/IPopMenuModifier.java
@@ -0,0 +1,31 @@
+/*
+ *  Copyright (C) 2015 Daniel H. Huson and David J. Bryant
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jloda.gui;
+
+import jloda.gui.commands.CommandManager;
+
+import javax.swing.*;
+
+/**
+ * menu modifier interface
+ * Daniel Huson, 5.2015
+ */
+public interface IPopMenuModifier {
+    void apply(JPopupMenu menu, Object viewer, CommandManager commandManager);
+}
diff --git a/src/jloda/gui/IPopupMenuModifier.java b/src/jloda/gui/IPopupMenuModifier.java
index 33de3a6..e6a69ce 100644
--- a/src/jloda/gui/IPopupMenuModifier.java
+++ b/src/jloda/gui/IPopupMenuModifier.java
@@ -1,6 +1,6 @@
 /**
  * IPopupMenuModifier.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/IToolBarModifier.java b/src/jloda/gui/IToolBarModifier.java
index ac84625..9cb4ae9 100644
--- a/src/jloda/gui/IToolBarModifier.java
+++ b/src/jloda/gui/IToolBarModifier.java
@@ -1,6 +1,6 @@
 /**
  * IToolBarModifier.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -28,5 +28,5 @@ import javax.swing.*;
  * Daniel Huson, 5.2015
  */
 public interface IToolBarModifier {
-    void apply(JToolBar toolBar, CommandManager commandManager);
+    void apply(JToolBar toolBar, Object viewer, CommandManager commandManager);
 }
diff --git a/src/jloda/gui/ListTransferHandler.java b/src/jloda/gui/ListTransferHandler.java
index f176d5e..731d542 100644
--- a/src/jloda/gui/ListTransferHandler.java
+++ b/src/jloda/gui/ListTransferHandler.java
@@ -1,6 +1,6 @@
 /**
  * ListTransferHandler.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/MemoryUsageManager.java b/src/jloda/gui/MemoryUsageManager.java
index 12fe99c..c5dc0cd 100644
--- a/src/jloda/gui/MemoryUsageManager.java
+++ b/src/jloda/gui/MemoryUsageManager.java
@@ -1,6 +1,6 @@
 /**
  * MemoryUsageManager.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -67,7 +67,7 @@ public class MemoryUsageManager {
                     Basic.caught(e);
                 }
             }
-        }, 0, 5, SECONDS);
+        }, 0, 2, SECONDS);
     }
 
     public static void addChangeListener(ChangeListener changeListener) {
diff --git a/src/jloda/gui/MenuBar.java b/src/jloda/gui/MenuBar.java
index cb7fee4..71bf18c 100644
--- a/src/jloda/gui/MenuBar.java
+++ b/src/jloda/gui/MenuBar.java
@@ -1,6 +1,6 @@
 /**
  * MenuBar.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -43,10 +43,11 @@ public class MenuBar extends JMenuBar {
     /**
      * creates the window menu bar
      *
+     * @param viewer
      * @param commandManager
      */
-    public MenuBar(MenuConfiguration configuration, CommandManager commandManager) {
-        MenuCreator menuCreator = new MenuCreator(commandManager);
+    public MenuBar(Object viewer, MenuConfiguration configuration, CommandManager commandManager) {
+        MenuCreator menuCreator = new MenuCreator(viewer, commandManager);
         try {
             menuCreator.buildMenuBar("main", configuration, this);
         } catch (Exception e) {
diff --git a/src/jloda/gui/MenuConfiguration.java b/src/jloda/gui/MenuConfiguration.java
index f27d3a9..0b8fffb 100644
--- a/src/jloda/gui/MenuConfiguration.java
+++ b/src/jloda/gui/MenuConfiguration.java
@@ -1,6 +1,6 @@
 /**
  * MenuConfiguration.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/Message.java b/src/jloda/gui/Message.java
index 356831b..bc649e4 100644
--- a/src/jloda/gui/Message.java
+++ b/src/jloda/gui/Message.java
@@ -1,6 +1,6 @@
 /**
  * Message.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/PopupMenu.java b/src/jloda/gui/PopupMenu.java
index c14fe0c..1bf7e70 100644
--- a/src/jloda/gui/PopupMenu.java
+++ b/src/jloda/gui/PopupMenu.java
@@ -1,6 +1,6 @@
 /**
  * PopupMenu.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -32,24 +32,43 @@ import javax.swing.*;
  * Daniel Huson, 11.2010
  */
 public class PopupMenu extends JPopupMenu {
+    private static IPopMenuModifier menuModifier;
+    private final boolean isEdgePopup;
+    private final boolean isNodePopup;
+
+    /**
+     * constructor
+     *
+     * @param viewer
+     * @param configuration
+     * @param commandManager
+     */
+    public PopupMenu(Object viewer, String configuration, CommandManager commandManager) {
+        this(viewer, configuration, commandManager, false, false, false);
+    }
+
     /**
      * constructor
      *
+     * @param viewer
      * @param configuration
      * @param commandManager
      */
-    public PopupMenu(String configuration, CommandManager commandManager) {
-        this(configuration, commandManager, false);
+    public PopupMenu(Object viewer, String configuration, CommandManager commandManager, boolean showApplicableOnly) {
+        this(viewer, configuration, commandManager, showApplicableOnly, false, false);
     }
 
     /**
      * constructor
      *
+     * @param viewer
      * @param configuration
      * @param commandManager
      */
-    public PopupMenu(String configuration, CommandManager commandManager, boolean showApplicableOnly) {
+    public PopupMenu(Object viewer, String configuration, CommandManager commandManager, boolean showApplicableOnly, boolean isNodePopup, boolean isEdgePopup) {
         super();
+        this.isNodePopup = isNodePopup;
+        this.isEdgePopup = isEdgePopup;
         if (configuration != null && configuration.length() > 0) {
             String[] tokens = configuration.split(";");
 
@@ -78,6 +97,8 @@ public class PopupMenu extends JPopupMenu {
                 }
             }
         }
+        if (menuModifier != null)
+            menuModifier.apply(this, viewer, commandManager);
         if (ProgramProperties.get("showtex", false)) {
             System.out.println(TeXGenerator.getPopupMenuLaTeX(configuration, commandManager));
         }
@@ -86,4 +107,20 @@ public class PopupMenu extends JPopupMenu {
         } catch (Exception ex) {
         }
     }
+
+    public static IPopMenuModifier getMenuModifier() {
+        return menuModifier;
+    }
+
+    public static void setMenuModifier(IPopMenuModifier menuModifier) {
+        PopupMenu.menuModifier = menuModifier;
+    }
+
+    public boolean isEdgePopup() {
+        return isEdgePopup;
+    }
+
+    public boolean isNodePopup() {
+        return isNodePopup;
+    }
 }
diff --git a/src/jloda/gui/ProgressDialog.java b/src/jloda/gui/ProgressDialog.java
index 3f2b3a7..86ab6c5 100644
--- a/src/jloda/gui/ProgressDialog.java
+++ b/src/jloda/gui/ProgressDialog.java
@@ -1,6 +1,6 @@
 /**
  * ProgressDialog.java
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  * <p>
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  * <p>
@@ -482,7 +482,7 @@ public class ProgressDialog implements ProgressListener {
     }
 
     /**
-     * run a task either directly, if in swing thread, or later, if FX thread, or invoke or wait, otherwise
+     * run a task either directly, if in swing thread, or later,  otherwise
      *
      * @param runnable
      */
diff --git a/src/jloda/gui/ReorderListDialog.java b/src/jloda/gui/ReorderListDialog.java
index a1c1115..effb40e 100644
--- a/src/jloda/gui/ReorderListDialog.java
+++ b/src/jloda/gui/ReorderListDialog.java
@@ -1,6 +1,6 @@
 /**
  * ReorderListDialog.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/StatusBar.java b/src/jloda/gui/StatusBar.java
index a41cfc5..d139ed8 100644
--- a/src/jloda/gui/StatusBar.java
+++ b/src/jloda/gui/StatusBar.java
@@ -1,45 +1,44 @@
 /**
- * StatusBar.java 
- * Copyright (C) 2016 Daniel H. Huson
- *
+ * StatusBar.java
+ * Copyright (C) 2017 Daniel H. Huson
+ * <p>
  * (Some files contain contributions from other authors, who are then mentioned separately.)
- *
+ * <p>
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
- *
+ * <p>
  * This program 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 General Public License for more details.
- *
+ * <p>
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
+ */
 package jloda.gui;
 
 import jloda.util.Basic;
-import jloda.util.ProgramProperties;
 
 import javax.swing.*;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ChangeListener;
 import java.awt.*;
+import java.util.ArrayList;
 
 /**
  * StatusBar for windows
  *
- * @author Daniel Huson, 1.2011
+ * @author Daniel Huson, 1.2011, 4.2017
  */
 public class StatusBar extends JPanel {
-    private final JTextArea text1 = new JTextArea();
+    private final JTextField text1 = new JTextField();
     private final JPanel panel1 = new JPanel();
-    private final JTextArea text2 = new JTextArea();
+    private final ArrayList<JTextField> text2items = new ArrayList<>();
     private final JPanel panel2 = new JPanel();
     private final JLabel text3 = new JLabel();
-    private final JSplitPane splitPane1;
-    private final JSplitPane splitPane2;
+    private final JPanel panel3 = new JPanel();
 
     private final ChangeListener changeListener;
 
@@ -54,50 +53,30 @@ public class StatusBar extends JPanel {
      * Constructor for the status bar of the window
      */
     public StatusBar(boolean showMemoryUsage) {
+        panel1.setLayout(new WrapLayout(FlowLayout.LEFT, 4, 2));
+        panel2.setLayout(new WrapLayout(FlowLayout.LEFT, 4, 2));
+        panel3.setLayout(new WrapLayout(FlowLayout.RIGHT, 4, 2));
+
         this.setLayout(new BorderLayout());
         this.setBorder(BorderFactory.createEtchedBorder());
 
         text1.setFont(new Font("Dialog", Font.PLAIN, 10));
         text1.setEditable(false);
-        text1.setBackground(text3.getBackground());
+        text1.setBorder(null);
+        text1.setBackground(panel1.getBackground());
         //text1.setFocusable(false);
-        text2.setFont(new Font("Dialog", Font.PLAIN, 10));
-        text2.setEditable(false);
-        text2.setBackground(text3.getBackground());
         // text2.setFocusable(false);
         text3.setFont(new Font("Dialog", Font.PLAIN, 10));
         text3.setText(Basic.getMemoryUsageString(100));
         text3.setFocusable(false);
 
         panel1.add(text1);
-        panel1.setToolTipText("Number of taxa currently displayed");
-
-        panel2.add(text2);
-        panel2.setToolTipText("Number of reads, algorithm settings");
-
-        splitPane1 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, panel1, panel2);
-        splitPane1.setBorder(BorderFactory.createEmptyBorder());
-        splitPane1.setResizeWeight(0);
-
-        if (ProgramProperties.isMacOS())
-            splitPane1.setDividerSize(10);
-        else splitPane1.setDividerSize(1);
-
-        JPanel text3Panel = new JPanel();
-        splitPane2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, splitPane1, text3Panel);
-        splitPane2.setBorder(BorderFactory.createEmptyBorder());
-        splitPane2.setResizeWeight(1);
-        if (ProgramProperties.isMacOS())
-            splitPane2.setDividerSize(10);
-        else splitPane2.setDividerSize(1);
-
-        this.add(splitPane2, BorderLayout.CENTER);
 
         if (showMemoryUsage) {
             setText3("------------");
-            text3Panel.add(text3);
-            text3Panel.setToolTipText("Memory usage");
-            this.add(Box.createHorizontalStrut(10), BorderLayout.EAST);
+            panel3.add(text3);
+            panel3.setToolTipText("Memory usage");
+            panel3.add(Box.createHorizontalStrut(10), BorderLayout.EAST);
 
             changeListener = new ChangeListener() {
                 public void stateChanged(ChangeEvent changeEvent) {
@@ -108,6 +87,10 @@ public class StatusBar extends JPanel {
         } else {
             changeListener = null;
         }
+
+        add(panel1, BorderLayout.WEST);
+        add(panel2, BorderLayout.CENTER);
+        add(panel3, BorderLayout.EAST);
     }
 
     /**
@@ -115,10 +98,12 @@ public class StatusBar extends JPanel {
      *
      * @param text
      */
-    public void setText1(String text) {
-        this.text1.setText(text);
-        splitPane1.resetToPreferredSizes();
-        splitPane2.resetToPreferredSizes();
+    public void setText1(final String text) {
+        synchronized (panel1) {
+            text1.setText(text + "     ");
+            revalidate();
+            repaint();
+        }
     }
 
     public String getText1() {
@@ -130,49 +115,79 @@ public class StatusBar extends JPanel {
      *
      * @param text
      */
-    public void setText2(String text) {
-        this.text2.setText(text + "   ");
-        splitPane1.resetToPreferredSizes();
-        splitPane2.resetToPreferredSizes();
+    public void setText2(final String text) {
+        synchronized (panel2) {
+            text2items.clear();
+            panel2.removeAll();
+
+            final String[] tokens = text.split("\\s+");
+            for (String label : tokens) {
+                final JTextField textField = new JTextField();
+                textField.setFont(new Font("Dialog", Font.PLAIN, 10));
+                textField.setBorder(null);
+                textField.setEditable(false);
+                textField.setText(label);
+                textField.setBackground(panel2.getBackground());
+                text2items.add(textField);
+                panel2.add(textField);
+            }
+            revalidate();
+            repaint();
+        }
     }
 
     public String getText2() {
-        return text2.getText().trim();
+        final StringBuilder buf = new StringBuilder();
+        boolean first = true;
+        for (JTextField textField : text2items) {
+            if (first)
+                first = false;
+            else
+                buf.append(" ");
+            buf.append(textField.getText());
+        }
+        return buf.toString();
     }
 
-    public void setExternalPanel1(JComponent externalPanel, boolean visible) {
-        panel1.removeAll();
-        if (visible)
-            panel1.add(externalPanel);
-        else
-            panel1.add(text1);
-        splitPane1.resetToPreferredSizes();
-        splitPane2.resetToPreferredSizes();
-        panel1.repaint();
+    public void setExternalPanel1(final JComponent externalPanel, final boolean visible) {
+        synchronized (panel1) {
+            panel1.removeAll();
+            if (visible)
+                panel1.add(externalPanel);
+            else
+                panel1.add(text1);
+            revalidate();
+            repaint();
+        }
     }
 
-    public void setComponent2(JComponent externalPanel, boolean visible) {
-        panel2.removeAll();
-        if (visible)
-            panel2.add(externalPanel);
-        else
-            panel2.add(text2);
-        splitPane1.resetToPreferredSizes();
-        splitPane2.resetToPreferredSizes();
-        panel2.repaint();
+    public void setComponent2(final JComponent externalPanel, final boolean visible) {
+        synchronized (panel2) {
+            panel2.removeAll();
+            if (visible)
+                panel2.add(externalPanel);
+            else {
+                for (JTextField textField : text2items) {
+                    panel2.add(textField);
+                }
+            }
+            revalidate();
+            repaint();
+        }
+
     }
 
     /**
      * set the text3 directly
      *
-     * @param text3
+     * @param text
      */
-    public void setText3(String text3) {
-        this.text3.setText(text3 + " ");
-        if (splitPane1 != null)
-            splitPane1.resetToPreferredSizes();
-        if (splitPane2 != null)
-            splitPane2.resetToPreferredSizes();
+    public void setText3(final String text) {
+        synchronized (panel3) {
+            text3.setText(text + " ");
+            revalidate();
+            repaint();
+        }
     }
 
     public String getText3() {
diff --git a/src/jloda/gui/ToolBar.java b/src/jloda/gui/ToolBar.java
index 37450d3..1203da8 100644
--- a/src/jloda/gui/ToolBar.java
+++ b/src/jloda/gui/ToolBar.java
@@ -1,6 +1,6 @@
 /**
  * ToolBar.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -43,11 +43,12 @@ public class ToolBar extends JToolBar {
      * To add a button with text label, tooltip and popup menu, use this syntax:
      * {;label(tooltip);command1;command2;command3;};
      *
+     * @param viewer
      * @param configuration
      * @param commandManager
      * @throws Exception
      */
-    public ToolBar(String configuration, CommandManager commandManager) {
+    public ToolBar(Object viewer, String configuration, CommandManager commandManager) {
         super();
         this.setRollover(true);
         this.setBorder(BorderFactory.createEtchedBorder());
@@ -132,7 +133,7 @@ public class ToolBar extends JToolBar {
             }
         }
         if (toolBarModifier != null)
-            toolBarModifier.apply(this, commandManager);
+            toolBarModifier.apply(this, viewer, commandManager);
 
         if (ProgramProperties.get("showtex", false)) {
             System.out.println(TeXGenerator.getToolBarLaTeX(configuration, commandManager));
diff --git a/src/jloda/gui/WindowListenerAdapter.java b/src/jloda/gui/WindowListenerAdapter.java
index aa88d17..3569dfb 100644
--- a/src/jloda/gui/WindowListenerAdapter.java
+++ b/src/jloda/gui/WindowListenerAdapter.java
@@ -1,6 +1,6 @@
 /**
  * WindowListenerAdapter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/WrapLayout.java b/src/jloda/gui/WrapLayout.java
index 25f258a..e9e8915 100644
--- a/src/jloda/gui/WrapLayout.java
+++ b/src/jloda/gui/WrapLayout.java
@@ -1,6 +1,6 @@
 /**
  * WrapLayout.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/commands/CommandBase.java b/src/jloda/gui/commands/CommandBase.java
index 563b979..295fa72 100644
--- a/src/jloda/gui/commands/CommandBase.java
+++ b/src/jloda/gui/commands/CommandBase.java
@@ -1,6 +1,6 @@
 /**
  * CommandBase.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/commands/CommandManager.java b/src/jloda/gui/commands/CommandManager.java
index edd699f..d50c270 100644
--- a/src/jloda/gui/commands/CommandManager.java
+++ b/src/jloda/gui/commands/CommandManager.java
@@ -1,6 +1,6 @@
 /**
  * CommandManager.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -250,7 +250,7 @@ public class CommandManager {
      * @param on
      */
     public void setEnableCritical(boolean on) {
-        /**
+        /*
          * update selection state of all menu items
          */
         for (JMenuItem menuItem : menuItem2Command.keySet()) {
@@ -260,7 +260,7 @@ public class CommandManager {
             }
         }
 
-        /**
+        /*
          * update selection state of all check boxes
          */
         for (AbstractButton button : button2Command.keySet()) {
diff --git a/src/jloda/gui/commands/ICheckBoxCommand.java b/src/jloda/gui/commands/ICheckBoxCommand.java
index 7ccede1..13ed694 100644
--- a/src/jloda/gui/commands/ICheckBoxCommand.java
+++ b/src/jloda/gui/commands/ICheckBoxCommand.java
@@ -1,6 +1,6 @@
 /**
  * ICheckBoxCommand.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/commands/ICommand.java b/src/jloda/gui/commands/ICommand.java
index c4431c6..d7af169 100644
--- a/src/jloda/gui/commands/ICommand.java
+++ b/src/jloda/gui/commands/ICommand.java
@@ -1,6 +1,6 @@
 /**
  * ICommand.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/commands/MenuCreator.java b/src/jloda/gui/commands/MenuCreator.java
index fbd9432..a74940c 100644
--- a/src/jloda/gui/commands/MenuCreator.java
+++ b/src/jloda/gui/commands/MenuCreator.java
@@ -1,6 +1,6 @@
 /**
  * MenuCreator.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -41,11 +41,13 @@ public class MenuCreator {
     static IMenuModifier menuModifer;
 
     private final CommandManager commandManager;
+    private final Object viewer;
 
     /**
      * constructor
      */
-    public MenuCreator(CommandManager commandManager) {
+    public MenuCreator(Object viewer, CommandManager commandManager) {
+        this.viewer = viewer;
         this.commandManager = commandManager;
     }
 
@@ -193,7 +195,7 @@ public class MenuCreator {
             }
         }
         if (menuModifer != null)
-            menuModifer.apply(menu, commandManager);
+            menuModifer.apply(menu, viewer, commandManager);
         if (ProgramProperties.get("showtex", false)) {
             System.out.println(TeXGenerator.getMenuLaTeX(commandManager, menuBarConfiguration, menusConfigurations));
         }
diff --git a/src/jloda/gui/commands/TeXGenerator.java b/src/jloda/gui/commands/TeXGenerator.java
index 765d6c8..e189454 100644
--- a/src/jloda/gui/commands/TeXGenerator.java
+++ b/src/jloda/gui/commands/TeXGenerator.java
@@ -1,6 +1,6 @@
 /**
  * TeXGenerator.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/commands/WrappedCheckBoxCommand.java b/src/jloda/gui/commands/WrappedCheckBoxCommand.java
index cd682d8..4695337 100644
--- a/src/jloda/gui/commands/WrappedCheckBoxCommand.java
+++ b/src/jloda/gui/commands/WrappedCheckBoxCommand.java
@@ -1,6 +1,6 @@
 /**
  * WrappedCheckBoxCommand.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/commands/WrappedCommand.java b/src/jloda/gui/commands/WrappedCommand.java
index 74dea33..d138a82 100644
--- a/src/jloda/gui/commands/WrappedCommand.java
+++ b/src/jloda/gui/commands/WrappedCommand.java
@@ -1,6 +1,6 @@
 /**
  * WrappedCommand.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/director/IDirectableViewer.java b/src/jloda/gui/director/IDirectableViewer.java
index f77e772..78b446c 100644
--- a/src/jloda/gui/director/IDirectableViewer.java
+++ b/src/jloda/gui/director/IDirectableViewer.java
@@ -1,6 +1,6 @@
 /**
  * IDirectableViewer.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/director/IDirector.java b/src/jloda/gui/director/IDirector.java
index 1ebd627..4a7f448 100644
--- a/src/jloda/gui/director/IDirector.java
+++ b/src/jloda/gui/director/IDirector.java
@@ -1,6 +1,6 @@
 /**
  * IDirector.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/director/IDirectorListener.java b/src/jloda/gui/director/IDirectorListener.java
index c2b623a..bb08f35 100644
--- a/src/jloda/gui/director/IDirectorListener.java
+++ b/src/jloda/gui/director/IDirectorListener.java
@@ -1,6 +1,6 @@
 /**
  * IDirectorListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/director/IMainViewer.java b/src/jloda/gui/director/IMainViewer.java
index ecf3403..1f101df 100644
--- a/src/jloda/gui/director/IMainViewer.java
+++ b/src/jloda/gui/director/IMainViewer.java
@@ -1,6 +1,6 @@
 /**
  * IMainViewer.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/director/IProjectsChangedListener.java b/src/jloda/gui/director/IProjectsChangedListener.java
index cf08f8f..259c68b 100644
--- a/src/jloda/gui/director/IProjectsChangedListener.java
+++ b/src/jloda/gui/director/IProjectsChangedListener.java
@@ -1,6 +1,6 @@
 /**
  * IProjectsChangedListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/director/IUpdateableView.java b/src/jloda/gui/director/IUpdateableView.java
index 40dd580..79e6cff 100644
--- a/src/jloda/gui/director/IUpdateableView.java
+++ b/src/jloda/gui/director/IUpdateableView.java
@@ -1,6 +1,6 @@
 /**
  * IUpdateableView.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/director/IUsesHeatMapColors.java b/src/jloda/gui/director/IUsesHeatMapColors.java
new file mode 100644
index 0000000..bf67bf8
--- /dev/null
+++ b/src/jloda/gui/director/IUsesHeatMapColors.java
@@ -0,0 +1,33 @@
+/*
+ *  Copyright (C) 2015 Daniel H. Huson
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package jloda.gui.director;
+
+/**
+ * indicates whether this viewer requires heatmap colors
+ * Created by huson on 2/17/17.
+ */
+public interface IUsesHeatMapColors {
+    /**
+     * returns true, if this class wants to use heatmap colors
+     *
+     * @return true, if heatmap colors required
+     */
+    boolean useHeatMapColors();
+}
diff --git a/src/jloda/gui/director/IViewerWithFindToolBar.java b/src/jloda/gui/director/IViewerWithFindToolBar.java
index 47f7150..7b7bcff 100644
--- a/src/jloda/gui/director/IViewerWithFindToolBar.java
+++ b/src/jloda/gui/director/IViewerWithFindToolBar.java
@@ -1,6 +1,6 @@
 /**
  * IViewerWithFindToolBar.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/director/IViewerWithLegend.java b/src/jloda/gui/director/IViewerWithLegend.java
index 68da830..b982a5c 100644
--- a/src/jloda/gui/director/IViewerWithLegend.java
+++ b/src/jloda/gui/director/IViewerWithLegend.java
@@ -1,6 +1,6 @@
 /**
  * IViewerWithLegend.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/director/ProjectManager.java b/src/jloda/gui/director/ProjectManager.java
index dc89cf8..c928265 100644
--- a/src/jloda/gui/director/ProjectManager.java
+++ b/src/jloda/gui/director/ProjectManager.java
@@ -1,6 +1,6 @@
 /**
  * ProjectManager.java
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  * <p>
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  * <p>
@@ -240,7 +240,10 @@ public class ProjectManager {
                                         mnenomicKey++;
                                     } else
                                         action.putValue(AbstractAction.NAME, "  " + title);
-                                    action.putValue(AbstractAction.SMALL_ICON, ResourceManager.getIcon("Empty16.gif"));
+                                    if (proj.getMainViewer().isLocked())
+                                        action.putValue(AbstractAction.SMALL_ICON, ResourceManager.getIcon("Updating16.gif"));
+                                    else
+                                        action.putValue(AbstractAction.SMALL_ICON, ResourceManager.getIcon("Empty16.gif"));
                                     action.putValue(AbstractAction.SHORT_DESCRIPTION, "Bring to front: " + title);
                                     if (first) {
                                         menu.addSeparator();
@@ -378,7 +381,7 @@ public class ProjectManager {
             }
         } catch (CanceledException ex) {
         } finally {
-            if (projects.isEmpty()) {
+            if (projects.isEmpty() && runOnQuitCanceled != null) {
                 runOnQuitCanceled.run();
             }
             setQuitting(false);
diff --git a/src/jloda/gui/find/CompositeObjectSearchers.java b/src/jloda/gui/find/CompositeObjectSearcher.java
similarity index 54%
rename from src/jloda/gui/find/CompositeObjectSearchers.java
rename to src/jloda/gui/find/CompositeObjectSearcher.java
index 093cbb8..0f57ae8 100644
--- a/src/jloda/gui/find/CompositeObjectSearchers.java
+++ b/src/jloda/gui/find/CompositeObjectSearcher.java
@@ -1,6 +1,6 @@
 /**
  * CompositeObjectSearchers.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -24,32 +24,29 @@ import java.awt.*;
 import java.util.Collection;
 
 /**
- * Composition of two object searchers
+ * Composition of multiple object searchers
  * Daniel Huson, 4.2013
  */
-public class CompositeObjectSearchers implements IObjectSearcher {
+public class CompositeObjectSearcher implements IObjectSearcher {
     public static final String SEARCHER_NAME = "Composite";
     private final Component frame;
     private final String name;
-    private final IObjectSearcher first;
-    private final IObjectSearcher second;
 
-    private enum Which {First, Second, None}
+    private IObjectSearcher[] searchers;
 
-    private Which which = Which.None;
+    private final int None = -1;
 
+    private int whichSearcher = None;
 
     /**
      * constructor
      *
-     * @param first
-     * @param second
+     * @param searchers
      */
-    public CompositeObjectSearchers(String name, Component frame, IObjectSearcher first, IObjectSearcher second) {
+    public CompositeObjectSearcher(String name, Component frame, IObjectSearcher... searchers) {
         this.name = name;
         this.frame = frame;
-        this.first = first;
-        this.second = second;
+        this.searchers = searchers;
     }
 
     /**
@@ -74,14 +71,13 @@ public class CompositeObjectSearchers implements IObjectSearcher {
      * goto the first object
      */
     public boolean gotoFirst() {
-        if (first.gotoFirst()) {
-            which = Which.First;
-            return true;
-        } else if (second.gotoFirst()) {
-            which = Which.Second;
-            return true;
+        for (int i = 0; i < searchers.length; i++) {
+            if (searchers[i].gotoFirst()) {
+                whichSearcher = i;
+                return true;
+            }
         }
-        which = Which.None;
+        whichSearcher = None;
         return false;
     }
 
@@ -89,32 +85,19 @@ public class CompositeObjectSearchers implements IObjectSearcher {
      * goto the next object
      */
     public boolean gotoNext() {
-        if (which == Which.First) {
-            if (first.gotoNext())
-                return true;
-            else if (second.gotoFirst()) {
-                which = Which.Second;
-                return true;
-            } else {
-                which = Which.None;
-                return false;
-            }
-        } else if (which == Which.Second) {
-            if (second.gotoNext())
-                return true;
-            else {
-                which = Which.None;
-                return false;
+        if (whichSearcher == None)
+            return false;
+        else if (searchers[whichSearcher].gotoNext())
+            return true;
+        else {
+            for (int i = whichSearcher + 1; i < searchers.length; i++) {
+                if (searchers[i].gotoFirst()) {
+                    whichSearcher = i;
+                    return true;
+                }
             }
-        } else {
-            if (first.gotoFirst()) {
-                which = Which.First;
-                return true;
-            } else if (second.gotoFirst()) {
-                which = Which.Second;
-                return true;
-            } else
-                return false;
+            whichSearcher = None;
+            return false;
         }
     }
 
@@ -122,47 +105,34 @@ public class CompositeObjectSearchers implements IObjectSearcher {
      * goto the last object
      */
     public boolean gotoLast() {
-        if (second.gotoLast()) {
-            which = Which.Second;
-            return true;
-        } else if (first.gotoLast()) {
-            which = Which.First;
-            return true;
+        for (int i = searchers.length - 1; i >= 0; i--) {
+            if (searchers[i].gotoLast()) {
+                whichSearcher = i;
+                return true;
+            }
         }
-        which = Which.None;
+        whichSearcher = None;
         return false;
+
     }
 
     /**
      * goto the previous object
      */
     public boolean gotoPrevious() {
-        if (which == Which.Second) {
-            if (second.gotoPrevious())
-                return true;
-            else if (first.gotoLast()) {
-                which = Which.First;
-                return true;
-            } else {
-                which = Which.None;
-                return false;
-            }
-        } else if (which == Which.First) {
-            if (first.gotoPrevious())
-                return true;
-            else {
-                which = Which.None;
-                return false;
+        if (whichSearcher == None)
+            return false;
+        else if (searchers[whichSearcher].gotoPrevious())
+            return true;
+        else {
+            for (int i = whichSearcher - 1; i >= 0; i--) {
+                if (searchers[i].gotoLast()) {
+                    whichSearcher = i;
+                    return true;
+                }
             }
-        } else {
-            if (second.gotoLast()) {
-                which = Which.Second;
-                return true;
-            } else if (first.gotoLast()) {
-                which = Which.First;
-                return true;
-            } else
-                return false;
+            whichSearcher = None;
+            return false;
         }
     }
 
@@ -172,7 +142,7 @@ public class CompositeObjectSearchers implements IObjectSearcher {
      * @return true, if selected
      */
     public boolean isCurrentSelected() {
-        return which == Which.First && first.isCurrentSelected() || which == Which.Second && second.isCurrentSelected();
+        return whichSearcher != None && searchers[whichSearcher].isCurrentSelected();
     }
 
     /**
@@ -181,10 +151,8 @@ public class CompositeObjectSearchers implements IObjectSearcher {
      * @param select
      */
     public void setCurrentSelected(boolean select) {
-        if (which == Which.First)
-            first.setCurrentSelected(select);
-        else if (which == Which.Second)
-            second.setCurrentSelected(select);
+        if (whichSearcher != None)
+            searchers[whichSearcher].setCurrentSelected(select);
     }
 
     /**
@@ -193,8 +161,9 @@ public class CompositeObjectSearchers implements IObjectSearcher {
      * @param select
      */
     public void selectAll(boolean select) {
-        first.selectAll(select);
-        second.selectAll(select);
+        for (IObjectSearcher searcher : searchers) {
+            searcher.selectAll(select);
+        }
     }
 
     /**
@@ -203,10 +172,9 @@ public class CompositeObjectSearchers implements IObjectSearcher {
      * @return label
      */
     public String getCurrentLabel() {
-        if (which == Which.First)
-            return first.getCurrentLabel();
-        else if (which == Which.Second)
-            return second.getCurrentLabel();
+        if (whichSearcher != None) {
+            return searchers[whichSearcher].getCurrentLabel();
+        }
         else
             return null;
     }
@@ -225,7 +193,11 @@ public class CompositeObjectSearchers implements IObjectSearcher {
      * @return true, if there is at least one object
      */
     public boolean isGlobalFindable() {
-        return first.isGlobalFindable() || second.isGlobalFindable();
+        for (IObjectSearcher searcher : searchers) {
+            if (searcher.isGlobalFindable())
+                return true;
+        }
+        return false;
     }
 
     /**
@@ -243,15 +215,16 @@ public class CompositeObjectSearchers implements IObjectSearcher {
      * @return true, if set
      */
     public boolean isCurrentSet() {
-        return which == Which.First && first.isCurrentSet() || which == Which.Second && second.isCurrentSet();
+        return whichSearcher != None && searchers[whichSearcher].isCurrentSet();
     }
 
     /**
      * something has been changed or selected, update view
      */
     public void updateView() {
-        first.updateView();
-        second.updateView();
+        for (IObjectSearcher searcher : searchers) {
+            searcher.updateView();
+        }
     }
 
     /**
@@ -269,11 +242,39 @@ public class CompositeObjectSearchers implements IObjectSearcher {
      * @return number of objects or -1
      */
     public int numberOfObjects() {
-        return first.numberOfObjects() + second.numberOfObjects();
+        int sum = 0;
+
+        for (IObjectSearcher searcher : searchers) {
+            int n = searcher.numberOfObjects();
+            if (n == -1)
+                return -1;
+            else
+                sum += n;
+        }
+        return sum;
     }
 
     @Override
     public Collection<AbstractButton> getAdditionalButtons() {
         return null;
     }
+
+    /**
+     * set the searchers
+     *
+     * @param searchers
+     */
+    public void setSearchers(IObjectSearcher... searchers) {
+        whichSearcher = None;
+        this.searchers = searchers;
+    }
+
+    /**
+     * get the searchers
+     *
+     * @return searchers
+     */
+    public IObjectSearcher[] getSearchers() {
+        return searchers;
+    }
 }
diff --git a/src/jloda/gui/find/EdgeLabelSearcher.java b/src/jloda/gui/find/EdgeLabelSearcher.java
index 2082a19..7410b71 100644
--- a/src/jloda/gui/find/EdgeLabelSearcher.java
+++ b/src/jloda/gui/find/EdgeLabelSearcher.java
@@ -1,6 +1,6 @@
 /**
  * EdgeLabelSearcher.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/EmptySearcher.java b/src/jloda/gui/find/EmptySearcher.java
index 3447216..d98b069 100644
--- a/src/jloda/gui/find/EmptySearcher.java
+++ b/src/jloda/gui/find/EmptySearcher.java
@@ -1,6 +1,6 @@
 /**
  * EmptySearcher.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/FindToolBar.java b/src/jloda/gui/find/FindToolBar.java
index 6fc1820..e4583ac 100644
--- a/src/jloda/gui/find/FindToolBar.java
+++ b/src/jloda/gui/find/FindToolBar.java
@@ -1,6 +1,6 @@
 /**
  * FindToolBar.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/FindWindow.java b/src/jloda/gui/find/FindWindow.java
index 11559c3..0ab61ec 100644
--- a/src/jloda/gui/find/FindWindow.java
+++ b/src/jloda/gui/find/FindWindow.java
@@ -1,6 +1,6 @@
 /**
  * FindWindow.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/IFindDialog.java b/src/jloda/gui/find/IFindDialog.java
index 1b988da..d930c3b 100644
--- a/src/jloda/gui/find/IFindDialog.java
+++ b/src/jloda/gui/find/IFindDialog.java
@@ -1,6 +1,6 @@
 /**
  * IFindDialog.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/IObjectSearcher.java b/src/jloda/gui/find/IObjectSearcher.java
index e9d8936..9414d29 100644
--- a/src/jloda/gui/find/IObjectSearcher.java
+++ b/src/jloda/gui/find/IObjectSearcher.java
@@ -1,6 +1,6 @@
 /**
  * IObjectSearcher.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/ISearcher.java b/src/jloda/gui/find/ISearcher.java
index b909431..969cf41 100644
--- a/src/jloda/gui/find/ISearcher.java
+++ b/src/jloda/gui/find/ISearcher.java
@@ -1,6 +1,6 @@
 /**
  * ISearcher.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/ITextSearcher.java b/src/jloda/gui/find/ITextSearcher.java
index d4805e7..816b2ed 100644
--- a/src/jloda/gui/find/ITextSearcher.java
+++ b/src/jloda/gui/find/ITextSearcher.java
@@ -1,6 +1,6 @@
 /**
  * ITextSearcher.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/JListSearcher.java b/src/jloda/gui/find/JListSearcher.java
index 209619e..d6c6471 100644
--- a/src/jloda/gui/find/JListSearcher.java
+++ b/src/jloda/gui/find/JListSearcher.java
@@ -1,6 +1,6 @@
 /**
  * JListSearcher.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/JTableSearcher.java b/src/jloda/gui/find/JTableSearcher.java
index e3736f5..710bf58 100644
--- a/src/jloda/gui/find/JTableSearcher.java
+++ b/src/jloda/gui/find/JTableSearcher.java
@@ -1,6 +1,6 @@
 /**
  * JTableSearcher.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/JTreeSearcher.java b/src/jloda/gui/find/JTreeSearcher.java
index e959c13..6d4d288 100644
--- a/src/jloda/gui/find/JTreeSearcher.java
+++ b/src/jloda/gui/find/JTreeSearcher.java
@@ -1,6 +1,6 @@
 /**
  * JTreeSearcher.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/NodeLabelSearcher.java b/src/jloda/gui/find/NodeLabelSearcher.java
index c34ccb8..21531cd 100644
--- a/src/jloda/gui/find/NodeLabelSearcher.java
+++ b/src/jloda/gui/find/NodeLabelSearcher.java
@@ -1,6 +1,6 @@
 /**
  * NodeLabelSearcher.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/SearchActions.java b/src/jloda/gui/find/SearchActions.java
index 811cef3..c95e354 100644
--- a/src/jloda/gui/find/SearchActions.java
+++ b/src/jloda/gui/find/SearchActions.java
@@ -1,6 +1,6 @@
 /**
  * SearchActions.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -61,11 +61,21 @@ public class SearchActions {
      * @param enable
      */
     public void setEnableCritical(boolean enable) {
+        if (enable && searchManager.getSearcher() != null && searchManager.getSearcher().getAdditionalButtons() != null) {
+            for (AbstractButton abstractButton : searchManager.getSearcher().getAdditionalButtons()) {
+                abstractButton.setEnabled(true);
+            }
+        }
         for (AbstractAction action : all) {
             action.setEnabled(enable);
         }
         if (enable)
             updateEnableState();
+        if (!enable && searchManager.getSearcher() != null && searchManager.getSearcher().getAdditionalButtons() != null) {
+            for (AbstractButton abstractButton : searchManager.getSearcher().getAdditionalButtons()) {
+                abstractButton.setEnabled(false);
+            }
+        }
     }
 
     /**
diff --git a/src/jloda/gui/find/SearchManager.java b/src/jloda/gui/find/SearchManager.java
index 057b774..f5cdf4f 100644
--- a/src/jloda/gui/find/SearchManager.java
+++ b/src/jloda/gui/find/SearchManager.java
@@ -1,6 +1,6 @@
 /**
  * SearchManager.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -627,7 +627,7 @@ public class SearchManager implements IDirectableViewer {
                                 if (!oSearcher.isCurrentSelected()) {
                                     changed = true;
                                 }
-                                oSearcher.setCurrentSelected(select);
+                                oSearcher.setCurrentSelected(true);
                                 count++;
                             }
                         }
diff --git a/src/jloda/gui/find/SingleStringSearcher.java b/src/jloda/gui/find/SingleStringSearcher.java
new file mode 100644
index 0000000..e7226f2
--- /dev/null
+++ b/src/jloda/gui/find/SingleStringSearcher.java
@@ -0,0 +1,154 @@
+/*
+ *  Copyright (C) 2015 Daniel H. Huson
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package jloda.gui.find;
+
+import javafx.application.Platform;
+import javafx.beans.property.BooleanProperty;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Collection;
+
+/**
+ * single string searcher
+ * Daniel Huson, 4.2013
+ */
+public class SingleStringSearcher implements IObjectSearcher {
+    private final Component parent;
+    private final String string;
+    private final BooleanProperty selected;
+
+    private boolean isSet = false;
+
+    /**
+     * constructor
+     */
+    public SingleStringSearcher(Component parent, String string, BooleanProperty selected) {
+        this.parent = parent;
+        this.string = string;
+        this.selected = selected;
+    }
+
+
+    @Override
+    public String getName() {
+        return "Alignments";
+    }
+
+    @Override
+    public boolean gotoFirst() {
+        isSet = true;
+        return true;
+    }
+
+    @Override
+    public boolean gotoNext() {
+        isSet = false;
+        return false;
+    }
+
+
+    @Override
+    public boolean isGlobalFindable() {
+        return true;
+    }
+
+    @Override
+    public boolean gotoLast() {
+        isSet = true;
+        return true;
+    }
+
+    @Override
+    public boolean isSelectionFindable() {
+        return false;
+    }
+
+    @Override
+    public boolean gotoPrevious() {
+        isSet = false;
+        return false;
+    }
+
+    @Override
+    public void updateView() {
+    }
+
+    @Override
+    public boolean isCurrentSet() {
+        return isSet;
+    }
+
+    @Override
+    public boolean canFindAll() {
+        return true;
+    }
+
+    @Override
+    public boolean isCurrentSelected() {
+        return isSet && selected.get();
+    }
+
+    @Override
+    public void selectAll(final boolean select) {
+        setCurrentSelected(select);
+    }
+
+    @Override
+    public void setCurrentSelected(final boolean select) {
+        Runnable runnable = new Runnable() {
+            @Override
+            public void run() {
+                selected.set(select);
+            }
+        };
+        if (Platform.isFxApplicationThread())
+            runnable.run();
+        else
+            Platform.runLater(runnable);
+    }
+
+    @Override
+    public Component getParent() {
+        return parent;
+    }
+
+    @Override
+    public String getCurrentLabel() {
+        if (isSet)
+            return string;
+        else
+            return null;
+    }
+
+    @Override
+    public Collection<AbstractButton> getAdditionalButtons() {
+        return null;
+    }
+
+    @Override
+    public void setCurrentLabel(String newLabel) {
+    }
+
+    @Override
+    public int numberOfObjects() {
+        return 1;
+    }
+
+}
diff --git a/src/jloda/gui/find/TableSearcher.java b/src/jloda/gui/find/TableSearcher.java
index cfe7bcb..b812fbe 100644
--- a/src/jloda/gui/find/TableSearcher.java
+++ b/src/jloda/gui/find/TableSearcher.java
@@ -1,6 +1,6 @@
 /**
  * TableSearcher.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/find/TextAreaSearcher.java b/src/jloda/gui/find/TextAreaSearcher.java
index 66933d0..17850ea 100644
--- a/src/jloda/gui/find/TextAreaSearcher.java
+++ b/src/jloda/gui/find/TextAreaSearcher.java
@@ -1,6 +1,6 @@
 /**
  * TextAreaSearcher.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/format/Formatter.java b/src/jloda/gui/format/Formatter.java
index 8980047..67332fc 100644
--- a/src/jloda/gui/format/Formatter.java
+++ b/src/jloda/gui/format/Formatter.java
@@ -1,6 +1,6 @@
 /**
  * Formatter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -61,7 +61,8 @@ public class Formatter implements IDirectableViewer {
 
     private static Formatter instance = null;
 
-    private JComboBox nodeSize, fontName, fontSize, nodeShape, edgeShape, edgeWidth;
+    private JComboBox<String> nodeSize, fontName, fontSize, edgeShape, edgeWidth;
+    private JComboBox<NodeShape> nodeShape;
     private JCheckBox boldFont, italicFont, labels, foregroundColor, backgroundColor, labelForegroundColor,
             labelBackgroundColor;
     private JButton rotateLabelsLeft, rotateLabelsRight;
@@ -535,42 +536,40 @@ public class Formatter implements IDirectableViewer {
         return viewer;
     }
 
-    private JComboBox makeNodeSize() {
-        Object[] possibleValues = {"1", "2", "3", "4", "5", "6", "7", "8", "10"};
-        JComboBox box = new JComboBox(possibleValues);
+    private JComboBox<String> makeNodeSize() {
+        String[] possibleValues = {"1", "2", "3", "4", "5", "6", "7", "8", "10"};
+        JComboBox<String> box = new JComboBox<>(possibleValues);
         box.setEditable(true);
         box.setMinimumSize(box.getPreferredSize());
         box.setAction(actions.getNodeSize());
         return box;
     }
 
-    private JComboBox makeNodeShape() {
-        Object[] possibleValues = {"none", "square", "circle", "triangle", "diamond"};
-        JComboBox box = new JComboBox(possibleValues);
+    private JComboBox<NodeShape> makeNodeShape() {
+        JComboBox<NodeShape> box = new JComboBox<>(NodeShape.values());
         box.setMinimumSize(box.getPreferredSize());
         box.setAction(actions.getNodeShape());
         return box;
     }
 
 
-    private JComboBox makeEdgeShape() {
-        Object[] possibleValues = {"angular", "straight", "curved"};
-        JComboBox box = new JComboBox(possibleValues);
+    private JComboBox<String> makeEdgeShape() {
+        JComboBox<String> box = new JComboBox<>(new String[]{"angular", "straight", "curved"});
         box.setMinimumSize(box.getPreferredSize());
         box.setAction(actions.getEdgeShape());
         return box;
     }
 
-    private JComboBox makeFont() {
-        JComboBox box = new JComboBox(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
+    private JComboBox<String> makeFont() {
+        JComboBox<String> box = new JComboBox<>(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
         box.setAction(actions.getFont());
         box.setMinimumSize(box.getPreferredSize());
         return box;
     }
 
-    private JComboBox makeFontSize() {
-        Object[] possibleValues = {"8", "10", "12", "14", "16", "18", "20", "22", "24", "26", "28", "32", "36", "40", "44"};
-        JComboBox box = new JComboBox(possibleValues);
+    private JComboBox<String> makeFontSize() {
+        String[] possibleValues = {"8", "10", "12", "14", "16", "18", "20", "22", "24", "26", "28", "32", "36", "40", "44"};
+        JComboBox<String> box = new JComboBox<>(possibleValues);
         box.setEditable(true);
         box.setAction(actions.getFontSize());
         box.setMinimumSize(box.getPreferredSize());
diff --git a/src/jloda/gui/format/FormatterActions.java b/src/jloda/gui/format/FormatterActions.java
index cf5831c..0265890 100644
--- a/src/jloda/gui/format/FormatterActions.java
+++ b/src/jloda/gui/format/FormatterActions.java
@@ -1,6 +1,6 @@
 /**
  * FormatterActions.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -22,7 +22,7 @@ package jloda.gui.format;
 import jloda.export.TransferableGraphic;
 import jloda.graphview.EdgeView;
 import jloda.graphview.INodeEdgeFormatable;
-import jloda.graphview.NodeView;
+import jloda.graphview.NodeShape;
 import jloda.gui.director.IDirector;
 import jloda.util.Alert;
 import jloda.util.ResourceManager;
@@ -398,19 +398,13 @@ public class FormatterActions {
         action = new AbstractAction() {
             public void actionPerformed(ActionEvent event) {
                 if (!ignore) {
-                    Object selectedValue = ((JComboBox) event.getSource()).getSelectedItem();
-                    if (selectedValue != null) {
-                        byte shape = -1;
-                        if (selectedValue == "none") shape = 0;
-                        if (selectedValue == "square") shape = NodeView.RECT_NODE;
-                        if (selectedValue == "circle") shape = NodeView.OVAL_NODE;
-                        if (selectedValue == "triangle") shape = NodeView.TRIANGLE_NODE;
-                        if (selectedValue == "diamond") shape = NodeView.DIAMOND_NODE;
-                        viewer.setShapeSelectedNodes(shape);
+                    NodeShape shape = (NodeShape) ((JComboBox) event.getSource()).getSelectedItem();
+                    if (shape != null) {
+                        viewer.setShapeSelectedNodes((byte) shape.ordinal());
                         formatter.fireNodeFormatChanged(viewer.getSelectedNodes());
+                        viewer.repaint();
+                        dir.setDirty(true);
                     }
-                    viewer.repaint();
-                    dir.setDirty(true);
                 }
             }
         };
diff --git a/src/jloda/gui/format/FormatterMenuBar.java b/src/jloda/gui/format/FormatterMenuBar.java
index fd7154d..7c1a85c 100644
--- a/src/jloda/gui/format/FormatterMenuBar.java
+++ b/src/jloda/gui/format/FormatterMenuBar.java
@@ -1,6 +1,6 @@
 /**
  * FormatterMenuBar.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/format/IFormatterListener.java b/src/jloda/gui/format/IFormatterListener.java
index c3b3948..08008cb 100644
--- a/src/jloda/gui/format/IFormatterListener.java
+++ b/src/jloda/gui/format/IFormatterListener.java
@@ -1,6 +1,6 @@
 /**
  * IFormatterListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/message/MessageWindow.java b/src/jloda/gui/message/MessageWindow.java
index 6a4e148..064647e 100644
--- a/src/jloda/gui/message/MessageWindow.java
+++ b/src/jloda/gui/message/MessageWindow.java
@@ -1,6 +1,6 @@
 /**
  * MessageWindow.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/message/MessageWindowActions.java b/src/jloda/gui/message/MessageWindowActions.java
index 242b2b8..c2c65bb 100644
--- a/src/jloda/gui/message/MessageWindowActions.java
+++ b/src/jloda/gui/message/MessageWindowActions.java
@@ -1,6 +1,6 @@
 /**
  * MessageWindowActions.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/gui/message/MessageWindowMenuBar.java b/src/jloda/gui/message/MessageWindowMenuBar.java
index 1a0e57c..5336490 100644
--- a/src/jloda/gui/message/MessageWindowMenuBar.java
+++ b/src/jloda/gui/message/MessageWindowMenuBar.java
@@ -1,6 +1,6 @@
 /**
  * MessageWindowMenuBar.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/phylo/HomoplasyScore.java b/src/jloda/phylo/HomoplasyScore.java
index fb4a8b2..cf4f5e6 100644
--- a/src/jloda/phylo/HomoplasyScore.java
+++ b/src/jloda/phylo/HomoplasyScore.java
@@ -1,6 +1,6 @@
 /**
  * HomoplasyScore.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/phylo/PhyloGraph.java b/src/jloda/phylo/PhyloGraph.java
index d4b9107..61e9b6e 100644
--- a/src/jloda/phylo/PhyloGraph.java
+++ b/src/jloda/phylo/PhyloGraph.java
@@ -1,6 +1,6 @@
 /**
  * PhyloGraph.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -452,7 +452,7 @@ public class PhyloGraph extends Graph {
      */
     public List<Integer> getNode2Taxa(Node v) {
         if (node2taxa.get(v) == null)
-            node2taxa.set(v, new LinkedList<Integer>()); // lazy initialization
+            node2taxa.set(v, new ArrayList<Integer>()); // lazy initialization
         return node2taxa.get(v);
     }
 
@@ -899,7 +899,7 @@ public class PhyloGraph extends Graph {
 
         if (one != null) {
             // determine all nodes and edges that separate S(1) from X-S(1)
-            List<Pair<Node, Edge>> separators = new LinkedList<>(); // each is a pair consisting of a node and edge
+            List<Pair<Node, Edge>> separators = new ArrayList<>(); // each is a pair consisting of a node and edge
             NodeSet seen = new NodeSet(this);
 
             getAllSeparators(splitId, one, null, seen, separators);
@@ -1070,11 +1070,11 @@ public class PhyloGraph extends Graph {
      *
      * @param old2new
      */
-    public void changeLabels(Map old2new) {
+    public void changeLabels(Map<String, String> old2new) {
         for (Node v = getFirstNode(); v != null; v = getNextNode(v)) {
             String label = getLabel(v);
             if (label != null && old2new.containsKey(label))
-                setLabel(v, (String) old2new.get(label));
+                setLabel(v, old2new.get(label));
         }
     }
 
diff --git a/src/jloda/phylo/PhyloGraphView.java b/src/jloda/phylo/PhyloGraphView.java
index 40e2a4d..6560960 100644
--- a/src/jloda/phylo/PhyloGraphView.java
+++ b/src/jloda/phylo/PhyloGraphView.java
@@ -1,6 +1,6 @@
 /**
  * PhyloGraphView.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/phylo/PhyloTree.java b/src/jloda/phylo/PhyloTree.java
index 840c1be..30849c3 100644
--- a/src/jloda/phylo/PhyloTree.java
+++ b/src/jloda/phylo/PhyloTree.java
@@ -1,6 +1,6 @@
 /**
  * PhyloTree.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -16,7 +16,7 @@
  *
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
+ */
 package jloda.phylo;
 
 /**
@@ -27,6 +27,7 @@ package jloda.phylo;
  * @author Daniel Huson
  */
 
+import com.sun.istack.internal.Nullable;
 import jloda.graph.*;
 import jloda.util.Basic;
 import jloda.util.NotOwnerException;
@@ -55,6 +56,7 @@ public class PhyloTree extends PhyloGraph {
     private final boolean cleanLabelsOnWrite;
 
     private String name = null;
+    private double weight = 1;
 
     protected final NodeArray<List<Node>> node2GuideTreeChildren; // keep track of children in LSA tree in network
 
@@ -98,6 +100,7 @@ public class PhyloTree extends PhyloGraph {
                 getNode2GuideTreeChildren().set(oldNode2NewNode.get(v), newChildren);
             }
         }
+        setName(src.getName());
 
         return oldNode2NewNode;
     }
@@ -155,7 +158,7 @@ public class PhyloTree extends PhyloGraph {
      * @return a string representation of the tree in bracket notation
      */
     public String toBracketString() {
-        StringWriter sw = new StringWriter();
+        final StringWriter sw = new StringWriter();
         try {
             write(sw, true);
         } catch (Exception ex) {
@@ -171,7 +174,7 @@ public class PhyloTree extends PhyloGraph {
      * @return a string representation of the tree in bracket notation
      */
     public String toBracketString(boolean showWeights) {
-        StringWriter sw = new StringWriter();
+        final StringWriter sw = new StringWriter();
         try {
             write(sw, showWeights);
         } catch (Exception ex) {
@@ -195,8 +198,8 @@ public class PhyloTree extends PhyloGraph {
      *
      * @return a string representation of the tree in bracket notation
      */
-    public String toString(Map translate) {
-        StringWriter sw = new StringWriter();
+    public String toString(Map<String, String> translate) {
+        final StringWriter sw = new StringWriter();
         try {
             if (translate == null || translate.size() == 0) {
                 this.write(sw, true);
@@ -222,6 +225,33 @@ public class PhyloTree extends PhyloGraph {
     }
 
     /**
+     * writes a tree
+     *
+     * @param writer
+     * @param showWeights
+     * @param translate   if non-null, is used to translate labels
+     * @throws IOException
+     */
+    public void write(final Writer writer, final boolean showWeights, @Nullable final Map<String, String> translate) throws IOException {
+        if (translate == null || translate.size() == 0) {
+            this.write(writer, showWeights);
+
+        } else {
+            PhyloTree tmpTree = new PhyloTree();
+            tmpTree.copy(this);
+            for (Node v = tmpTree.getFirstNode(); v != null; v = v.getNext()) {
+                final String key = tmpTree.getLabel(v);
+                if (key != null) {
+                    final String value = translate.get(key);
+                    if (value != null)
+                        tmpTree.setLabel(v, value);
+                }
+            }
+            tmpTree.write(writer, showWeights);
+        }
+    }
+
+    /**
      * Given a string representation of a tree, returns the tree.
      *
      * @param str      String
@@ -527,7 +557,7 @@ public class PhyloTree extends PhyloGraph {
     }
 
     /**
-     * deletes artificial divertex
+     * deletes divertex
      *
      * @param v Node
      * @return the new edge
@@ -1266,6 +1296,14 @@ public class PhyloTree extends PhyloGraph {
     public NodeArray<List<Node>> getNode2GuideTreeChildren() {
         return node2GuideTreeChildren;
     }
+
+    public double getWeight() {
+        return weight;
+    }
+
+    public void setWeight(double weight) {
+        this.weight = weight;
+    }
 }
 
 // EOF
diff --git a/src/jloda/phylo/PhyloTreeUtils.java b/src/jloda/phylo/PhyloTreeUtils.java
index ec7e00d..056fe70 100644
--- a/src/jloda/phylo/PhyloTreeUtils.java
+++ b/src/jloda/phylo/PhyloTreeUtils.java
@@ -1,6 +1,6 @@
 /**
  * PhyloTreeUtils.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/phylo/PhyloTreeView.java b/src/jloda/phylo/PhyloTreeView.java
index 876e9b1..cd1bf3d 100644
--- a/src/jloda/phylo/PhyloTreeView.java
+++ b/src/jloda/phylo/PhyloTreeView.java
@@ -1,6 +1,6 @@
 /**
  * PhyloTreeView.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -22,6 +22,7 @@ package jloda.phylo;
 import jloda.graph.*;
 import jloda.graphview.EdgeView;
 import jloda.graphview.GraphView;
+import jloda.graphview.NodeShape;
 import jloda.graphview.NodeView;
 import jloda.util.Geometry;
 import jloda.util.NotOwnerException;
@@ -224,12 +225,12 @@ public class PhyloTreeView extends GraphView {
             //setShape(v, NodeView.NONE_NODE);
 
             if (G.getLabel(v) != null && !G.getLabel(v).equals("")) {
-                setShape(v, NodeView.OVAL_NODE);
+                setNodeShape(v, NodeShape.Oval);
                 setLabelLayout(v, NodeView.LAYOUT);
                 setWidth(v, 1);
                 setHeight(v, 1);
             } else
-                setShape(v, NodeView.NONE_NODE);
+                setNodeShape(v, NodeShape.None);
 
         }
         for (Edge e = G.getFirstEdge(); e != null; e = G.getNextEdge(e)) {
@@ -320,11 +321,11 @@ public class PhyloTreeView extends GraphView {
 
             if (hasNodeData) {   // recompute summarized
                 NodeData srcND = (NodeData) srcV.getData();
-                int[] summarized = Arrays.copyOf(srcND.getAssigned(), srcND.getAssigned().length);
+                float[] summarized = Arrays.copyOf(srcND.getAssigned(), srcND.getAssigned().length);
                 for (Node u : below) {
                     for (int i = 0; i < summarized.length; i++) {
-                        final int[] uSummarized = ((NodeData) u.getData()).getSummarized();
-                        final int value = (i < uSummarized.length ? uSummarized[i] : 0);
+                        final float[] uSummarized = ((NodeData) u.getData()).getSummarized();
+                        final float value = (i < uSummarized.length ? uSummarized[i] : 0);
                         summarized[i] += value;
                     }
                 }
diff --git a/src/jloda/phylo/TreeDrawerAngled.java b/src/jloda/phylo/TreeDrawerAngled.java
index 368fd60..b27602c 100644
--- a/src/jloda/phylo/TreeDrawerAngled.java
+++ b/src/jloda/phylo/TreeDrawerAngled.java
@@ -1,6 +1,6 @@
 /**
  * TreeDrawerAngled.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/phylo/TreeDrawerCircular.java b/src/jloda/phylo/TreeDrawerCircular.java
index d6b9caa..edf16c0 100644
--- a/src/jloda/phylo/TreeDrawerCircular.java
+++ b/src/jloda/phylo/TreeDrawerCircular.java
@@ -1,6 +1,6 @@
 /**
  * TreeDrawerCircular.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/phylo/TreeDrawerParallel.java b/src/jloda/phylo/TreeDrawerParallel.java
index e86def8..7f84701 100644
--- a/src/jloda/phylo/TreeDrawerParallel.java
+++ b/src/jloda/phylo/TreeDrawerParallel.java
@@ -1,6 +1,6 @@
 /**
  * TreeDrawerParallel.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/phylo/TreeDrawerRadial.java b/src/jloda/phylo/TreeDrawerRadial.java
index 61cb367..a1218e5 100644
--- a/src/jloda/phylo/TreeDrawerRadial.java
+++ b/src/jloda/phylo/TreeDrawerRadial.java
@@ -1,6 +1,6 @@
 /**
  * TreeDrawerRadial.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/phylo/TreeParseException.java b/src/jloda/phylo/TreeParseException.java
index d7eda78..df51b0c 100644
--- a/src/jloda/phylo/TreeParseException.java
+++ b/src/jloda/phylo/TreeParseException.java
@@ -1,6 +1,6 @@
 /**
  * TreeParseException.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/ApproximateBinaryExpansion.java b/src/jloda/progs/ApproximateBinaryExpansion.java
index 67748ea..338513c 100644
--- a/src/jloda/progs/ApproximateBinaryExpansion.java
+++ b/src/jloda/progs/ApproximateBinaryExpansion.java
@@ -1,6 +1,6 @@
 /**
  * ApproximateBinaryExpansion.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/ApproximateSquareRootOf2.java b/src/jloda/progs/ApproximateSquareRootOf2.java
index 43b34b5..c7c496b 100644
--- a/src/jloda/progs/ApproximateSquareRootOf2.java
+++ b/src/jloda/progs/ApproximateSquareRootOf2.java
@@ -1,6 +1,6 @@
 /**
  * ApproximateSquareRootOf2.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/CoverDigraph.java b/src/jloda/progs/CoverDigraph.java
index 8332b72..c371390 100644
--- a/src/jloda/progs/CoverDigraph.java
+++ b/src/jloda/progs/CoverDigraph.java
@@ -1,6 +1,6 @@
 /**
  * CoverDigraph.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/Date2Number.java b/src/jloda/progs/Date2Number.java
index 44b8556..7aca6f7 100644
--- a/src/jloda/progs/Date2Number.java
+++ b/src/jloda/progs/Date2Number.java
@@ -1,6 +1,6 @@
 /**
  * Date2Number.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/GeneEvolutionSimulator.java b/src/jloda/progs/GeneEvolutionSimulator.java
index 9a2f97b..121d38f 100644
--- a/src/jloda/progs/GeneEvolutionSimulator.java
+++ b/src/jloda/progs/GeneEvolutionSimulator.java
@@ -1,6 +1,6 @@
 /**
  * GeneEvolutionSimulator.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/GraphPather.java b/src/jloda/progs/GraphPather.java
index 3f58bb3..f1a3635 100644
--- a/src/jloda/progs/GraphPather.java
+++ b/src/jloda/progs/GraphPather.java
@@ -1,6 +1,6 @@
 /**
  * GraphPather.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/GraphViewDemo.java b/src/jloda/progs/GraphViewDemo.java
index c9b2711..d9f1b61 100644
--- a/src/jloda/progs/GraphViewDemo.java
+++ b/src/jloda/progs/GraphViewDemo.java
@@ -1,6 +1,6 @@
 /**
  * GraphViewDemo.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/Gunzip.java b/src/jloda/progs/Gunzip.java
index 7782081..2c13260 100644
--- a/src/jloda/progs/Gunzip.java
+++ b/src/jloda/progs/Gunzip.java
@@ -1,6 +1,6 @@
 /**
  * Gunzip.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/ImageProcessor.java b/src/jloda/progs/ImageProcessor.java
index 4fc032b..d489009 100644
--- a/src/jloda/progs/ImageProcessor.java
+++ b/src/jloda/progs/ImageProcessor.java
@@ -1,6 +1,6 @@
 /**
  * ImageProcessor.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/JTableWithRowHeaders.java b/src/jloda/progs/JTableWithRowHeaders.java
index bab8612..5f936fc 100644
--- a/src/jloda/progs/JTableWithRowHeaders.java
+++ b/src/jloda/progs/JTableWithRowHeaders.java
@@ -1,6 +1,6 @@
 /**
  * JTableWithRowHeaders.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/Lines2FastA.java b/src/jloda/progs/Lines2FastA.java
index 117bfa2..f85f26f 100644
--- a/src/jloda/progs/Lines2FastA.java
+++ b/src/jloda/progs/Lines2FastA.java
@@ -1,6 +1,6 @@
 /**
  * Lines2FastA.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/MABlocker.java b/src/jloda/progs/MABlocker.java
index de391e2..63c7ae0 100644
--- a/src/jloda/progs/MABlocker.java
+++ b/src/jloda/progs/MABlocker.java
@@ -1,6 +1,6 @@
 /**
  * MABlocker.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/MASampler.java b/src/jloda/progs/MASampler.java
index 931d7a9..73f1713 100644
--- a/src/jloda/progs/MASampler.java
+++ b/src/jloda/progs/MASampler.java
@@ -1,6 +1,6 @@
 /**
  * MASampler.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/NewMABlocker.java b/src/jloda/progs/NewMABlocker.java
index 67f6c94..6e9483c 100644
--- a/src/jloda/progs/NewMABlocker.java
+++ b/src/jloda/progs/NewMABlocker.java
@@ -1,6 +1,6 @@
 /**
  * NewMABlocker.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/NextMABlocker.java b/src/jloda/progs/NextMABlocker.java
index a4c7749..ef49273 100644
--- a/src/jloda/progs/NextMABlocker.java
+++ b/src/jloda/progs/NextMABlocker.java
@@ -1,6 +1,6 @@
 /**
  * NextMABlocker.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/QuasiMedianClosure.java b/src/jloda/progs/QuasiMedianClosure.java
index 78999bb..740ade7 100644
--- a/src/jloda/progs/QuasiMedianClosure.java
+++ b/src/jloda/progs/QuasiMedianClosure.java
@@ -1,6 +1,6 @@
 /**
  * QuasiMedianClosure.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/QuasiMedianNetwork.java b/src/jloda/progs/QuasiMedianNetwork.java
index e5f2ce9..dae86e6 100644
--- a/src/jloda/progs/QuasiMedianNetwork.java
+++ b/src/jloda/progs/QuasiMedianNetwork.java
@@ -1,6 +1,6 @@
 /**
  * QuasiMedianNetwork.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -22,7 +22,7 @@ package jloda.progs;
 import jloda.export.PDFExportType;
 import jloda.graph.*;
 import jloda.graphview.GraphView;
-import jloda.graphview.NodeView;
+import jloda.graphview.NodeShape;
 import jloda.phylo.PhyloGraph;
 import jloda.phylo.PhyloGraphView;
 import jloda.util.Basic;
@@ -561,7 +561,7 @@ public class QuasiMedianNetwork {
         view.setCanvasColor(Color.WHITE);
         view.setMaintainEdgeLengths(false);
         for (Node v = graph.getFirstNode(); v != null; v = v.getNext()) {
-            view.setShape(v, NodeView.NONE_NODE);
+            view.setNodeShape(v, NodeShape.None);
         }
         for (Edge e = graph.getFirstEdge(); e != null; e = e.getNext()) {
             view.setLabel(e, graph.getLabel(e));
diff --git a/src/jloda/progs/RandomDNAGenerator.java b/src/jloda/progs/RandomDNAGenerator.java
index 47eae91..8e5296b 100644
--- a/src/jloda/progs/RandomDNAGenerator.java
+++ b/src/jloda/progs/RandomDNAGenerator.java
@@ -1,6 +1,6 @@
 /**
  * RandomDNAGenerator.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/RandomizeLines.java b/src/jloda/progs/RandomizeLines.java
index 8040c99..a36c822 100644
--- a/src/jloda/progs/RandomizeLines.java
+++ b/src/jloda/progs/RandomizeLines.java
@@ -1,6 +1,6 @@
 /**
  * RandomizeLines.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/ReadTrimmer.java b/src/jloda/progs/ReadTrimmer.java
index dbe9f4e..3d77512 100644
--- a/src/jloda/progs/ReadTrimmer.java
+++ b/src/jloda/progs/ReadTrimmer.java
@@ -1,6 +1,6 @@
 /**
  * ReadTrimmer.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/SharedGenesDistance.java b/src/jloda/progs/SharedGenesDistance.java
index f99fb07..8fe2152 100644
--- a/src/jloda/progs/SharedGenesDistance.java
+++ b/src/jloda/progs/SharedGenesDistance.java
@@ -1,6 +1,6 @@
 /**
  * SharedGenesDistance.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/Tree2MeganCSV.java b/src/jloda/progs/Tree2MeganCSV.java
index e4d8912..8457f73 100644
--- a/src/jloda/progs/Tree2MeganCSV.java
+++ b/src/jloda/progs/Tree2MeganCSV.java
@@ -1,6 +1,6 @@
 /**
  * Tree2MeganCSV.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/progs/TreeViewDemo.java b/src/jloda/progs/TreeViewDemo.java
index 8947ff0..2d5f1c9 100644
--- a/src/jloda/progs/TreeViewDemo.java
+++ b/src/jloda/progs/TreeViewDemo.java
@@ -1,6 +1,6 @@
 /**
  * TreeViewDemo.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/Alert.java b/src/jloda/util/Alert.java
index d3045d2..79cb5e5 100644
--- a/src/jloda/util/Alert.java
+++ b/src/jloda/util/Alert.java
@@ -1,6 +1,6 @@
 /**
  * Alert.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/ArgsOptions.java b/src/jloda/util/ArgsOptions.java
index c9d33c0..29fc0c8 100644
--- a/src/jloda/util/ArgsOptions.java
+++ b/src/jloda/util/ArgsOptions.java
@@ -1,6 +1,6 @@
 /**
  * ArgsOptions.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -187,7 +187,7 @@ public class ArgsOptions {
         if (!doHelp) {
             if (version != null)
                 System.err.println("Version   " + version);
-            if (authors != null)
+            if (authors != null && license == null)
                 System.err.println("Author(s) " + authors);
             if (license != null)
                 System.err.println(license);
diff --git a/src/jloda/util/Basic.java b/src/jloda/util/Basic.java
index 7802530..cecb272 100644
--- a/src/jloda/util/Basic.java
+++ b/src/jloda/util/Basic.java
@@ -1,6 +1,6 @@
 /**
  * Basic.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -368,6 +368,10 @@ public class Basic {
             public T next() {
                 return (T) array[i++];
             }
+
+            @Override
+            public void remove() {
+            }
         };
     }
 
@@ -920,7 +924,6 @@ public class Basic {
         return toString(array, 0, array.length, separator);
     }
 
-
     /**
      * returns an array of integers as astring
      *
@@ -944,6 +947,46 @@ public class Basic {
     }
 
     /**
+     * returns an array of floats as string
+     *
+     * @param array
+     * @param separator
+     * @return
+     */
+    public static String toString(float[] array, String separator) {
+        return toString(array, 0, array.length, separator, false);
+    }
+
+    /**
+     * returns an array of floats as string
+     *
+     * @param array
+     * @param offset
+     * @param length
+     * @param separator
+     * @param roundToInts
+     * @return
+     */
+    public static String toString(float[] array, int offset, int length, String separator, boolean roundToInts) {
+        final StringBuilder buf = new StringBuilder();
+
+        boolean first = true;
+        length = Math.min(offset + length, array.length);
+        for (int i = offset; i < length; i++) {
+            float x = array[i];
+            if (first)
+                first = false;
+            else
+                buf.append(separator);
+            if (roundToInts)
+                buf.append(Math.round(x));
+            else
+                buf.append(x);
+        }
+        return buf.toString();
+    }
+
+    /**
      * returns an array of integers as a separated string
      *
      * @param array
@@ -1088,13 +1131,13 @@ public class Basic {
 
 
     /**
-     * returns a set of bits as a comma separated string
+     * returns a set a comma separated string
      *
-     * @param bits
+     * @param set
      * @return string representation
      */
-    public static String toString(BitSet bits) {
-        if (bits == null)
+    public static String toString(BitSet set) {
+        if (set == null)
             return "null";
 
         final StringBuilder buf = new StringBuilder();
@@ -1102,7 +1145,7 @@ public class Basic {
         int startRun = 0;
         int inRun = 0;
         boolean first = true;
-        for (int i = bits.nextSetBit(0); i >= 0; i = bits.nextSetBit(i + 1)) {
+        for (int i = set.nextSetBit(0); i >= 0; i = set.nextSetBit(i + 1)) {
             if (first) {
                 first = false;
                 buf.append(i);
@@ -1130,6 +1173,25 @@ public class Basic {
     }
 
     /**
+     * gets members of bit set as as string
+     * @param set
+     * @param separator
+     * @return string
+     */
+    public static String toString(BitSet set, char separator) {
+        StringBuilder buf = new StringBuilder();
+        boolean first = true;
+        for (int i = set.nextSetBit(0); i != -1; i = set.nextSetBit(i + 1)) {
+            if (first)
+                first = false;
+            else
+                buf.append(separator);
+            buf.append(i);
+        }
+        return buf.toString();
+    }
+
+    /**
      * Fetch all resources (i.e. files) that are directly under the specified package structure.
      *
      * @param pckg
@@ -1519,34 +1581,48 @@ public class Basic {
     }
 
     /**
-     * counts the number of occurrences of c in string str
+     * counts the number of occurrences of c in text
      *
-     * @param str
+     * @param text
      * @param c
      * @return count
      */
-    public static int countOccurrences(String str, char c) {
+    public static int countOccurrences(String text, char c) {
         int count = 0;
-        if (str != null) {
-            for (int i = 0; i < str.length(); i++)
-                if (str.charAt(i) == c)
+        if (text != null) {
+            for (int i = 0; i < text.length(); i++)
+                if (text.charAt(i) == c)
                     count++;
         }
         return count;
     }
 
     /**
-     * counts the number of occurrences of c at beginning of string str
+     * counts the number of occurrences of word in text
      *
-     * @param str
+     * @param text
+     * @param word
+     * @return count
+     */
+    public static int countOccurrences(String text, String word) {
+        int count = 0;
+        for (int i = text.indexOf(word); i != -1; i = text.indexOf(word, i + 1))
+            count++;
+        return count;
+    }
+
+    /**
+     * counts the number of occurrences of c at beginning of text
+     *
+     * @param text
      * @param c
      * @return count
      */
-    public static int countLeadingOccurrences(String str, char c) {
+    public static int countLeadingOccurrences(String text, char c) {
         int count = 0;
-        if (str != null) {
-            for (int i = 0; i < str.length(); i++) {
-                if (str.charAt(i) == c)
+        if (text != null) {
+            for (int i = 0; i < text.length(); i++) {
+                if (text.charAt(i) == c)
                     count++;
                 else break;
             }
@@ -1555,16 +1631,16 @@ public class Basic {
     }
 
     /**
-     * counts the number of occurrences of c in byte[] str
+     * counts the number of occurrences of c in byte[] text
      *
-     * @param str
+     * @param text
      * @param c
      * @return count
      */
-    public static int countOccurrences(byte[] str, char c) {
+    public static int countOccurrences(byte[] text, char c) {
         int count = 0;
-        if (str != null) {
-            for (byte aStr : str)
+        if (text != null) {
+            for (byte aStr : text)
                 if (aStr == c)
                     count++;
         }
@@ -2267,6 +2343,32 @@ public class Basic {
     }
 
     /**
+     * returns the last line beginning with query
+     *
+     * @param query
+     * @param text
+     * @return first line
+     */
+    public static String getLastLineStartingWith(String query, String text) {
+        String result = null;
+
+        try (BufferedReader r = new BufferedReader(new StringReader(text))) {
+            String aLine;
+            while ((aLine = r.readLine()) != null) {
+                if (aLine.startsWith(query))
+                    result = aLine;
+            }
+        } catch (IOException e) {
+            Basic.caught(e);
+        }
+        if (result == null)
+            return "";
+        else
+            return result;
+    }
+
+
+    /**
      * returns the first block of a text up to an empty line. Consecutive lines are separated by single spaces
      *
      * @param text
@@ -2343,17 +2445,33 @@ public class Basic {
     }
 
     /**
-     * gets the first word in the given string
+     * gets the first word in the given text
      *
-     * @param string
+     * @param text
      * @return word (delimited by a white space) or empty string, if the first character is a white space
      */
-    public static String getFirstWord(String string) {
-        int i = getIndexOfFirstWhiteSpace(string);
+    public static String getFirstWord(String text) {
+        int i = getIndexOfFirstWhiteSpace(text);
         if (i != -1)
-            return string.substring(0, i);
+            return text.substring(0, i);
         else
-            return string;
+            return text;
+    }
+
+    /**
+     * gets the last word in the given text
+     *
+     * @param text
+     * @return word (delimited by a white space) or empty string, if the last character is a white space
+     */
+    public static String getLastWord(String text) {
+        if (text.length() == 0 || Character.isWhitespace(text.charAt(text.length() - 1)))
+            return "";
+        for (int i = text.length() - 2; i >= 0; i--) {
+            if (Character.isWhitespace(text.charAt(i)))
+                return text.substring(i + 1);
+        }
+        return text;
     }
 
     /**
@@ -2535,6 +2653,21 @@ public class Basic {
      * @param values
      * @return sum
      */
+    public static float getSum(float[] values) {
+        float sum = 0;
+        for (float value : values) {
+            sum += value;
+        }
+        return sum;
+    }
+
+
+    /**
+     * get the sum of values
+     *
+     * @param values
+     * @return sum
+     */
     public static int getSum(Collection<Integer> values) {
         int sum = 0;
         for (Number value : values)
@@ -3095,6 +3228,33 @@ public class Basic {
     }
 
     /**
+     * split string on white space
+     *
+     * @param aLine
+     * @return split string, trimmed
+     */
+    public static String[] splitOnWhiteSpace(String aLine) {
+        ArrayList<String> parts = new ArrayList<>();
+
+        int start = -1;
+        for (int i = 0; i < aLine.length(); i++) {
+            int ch = aLine.charAt(i);
+            if (Character.isWhitespace(ch)) {
+                if (start != -1) {
+                    parts.add(aLine.substring(start, i));
+                    start = -1;
+                }
+            } else {
+                if (start == -1)
+                    start = i;
+            }
+        }
+        if (start != -1)
+            parts.add(aLine.substring(start));
+        return parts.toArray(new String[parts.size()]);
+    }
+
+    /**
      * split string on given characters. Note that results are subsequently trimmed
      *
      * @param aLine
@@ -3236,7 +3396,7 @@ public class Basic {
 
     /**
      * Finds the value of the given enumeration by name, case-insensitive.
-     * Throws an IllegalArgumentException if no match is found.
+     * @return enumeration value or null
      */
     public static <T extends Enum<T>> T valueOfIgnoreCase(Class<T> enumeration, String name) {
         for (T enumValue : enumeration.getEnumConstants()) {
@@ -3244,7 +3404,7 @@ public class Basic {
                 return enumValue;
             }
         }
-        throw new IllegalArgumentException("There is no value with name '" + name + " in Enum " + enumeration.getClass().getName());
+        return null;
     }
 
     /**
@@ -3566,18 +3726,17 @@ public class Basic {
 
 
     /**
-     * return array in reverse order
+     * return list in reverse order
      *
-     * @param strings
-     * @return
+     * @param list
+     * @return list in reverse order
      */
-    public static String[] reverse(Collection<String> strings) {
-        final String[] result = new String[strings.size()];
-        int pos = strings.size();
-        for (String str : strings) {
-            result[--pos] = str;
-        }
-        return result;
+    public static <T> Collection<T> reverse(Collection<T> list) {
+        final ArrayList<T> source = new ArrayList<>(list);
+        final ArrayList<T> target = new ArrayList<>(list.size());
+        for (int i = source.size() - 1; i >= 0; i--)
+            target.add(source.get(i));
+        return target;
     }
 
     /**
@@ -3588,11 +3747,7 @@ public class Basic {
      * @return rank or -1
      */
     public static <T> int getRank(List<T> list, T value) {
-        for (int i = 0; i < list.size(); i++) {
-            if (list.get(i).equals(value))
-                return i;
-        }
-        return -1;
+        return list.indexOf(value);
     }
 
     /**
@@ -3634,6 +3789,30 @@ public class Basic {
      * @return first line or null
      * @throws IOException
      */
+    public static String getFirstLineFromFile(File file, String ignoreLinesThatStartWithThis, int maxLines) {
+        try {
+            int count = 0;
+            try (BufferedReader ins = new BufferedReader(new InputStreamReader(getInputStreamPossiblyZIPorGZIP(file.getPath())))) {
+                String aLine;
+                while ((aLine = ins.readLine()) != null) {
+                    if (!aLine.startsWith(ignoreLinesThatStartWithThis))
+                        return aLine;
+                    if (++count == maxLines)
+                        break;
+                }
+            }
+        } catch (IOException ex) {
+        }
+        return null;
+    }
+
+    /**
+     * gets the first line in a file. File may be zgipped or zipped
+     *
+     * @param file
+     * @return first line or null
+     * @throws IOException
+     */
     public static String[] getFirstLinesFromFile(File file, int count) {
         try {
             String[] lines = new String[count];
@@ -3808,23 +3987,23 @@ public class Basic {
     /**
      * gets next word after given first word
      * @param first
-     * @param aLine
+     * @param text
      * @return next word or null
      */
-    public static String getWordAfter(String first, String aLine) {
-        int start = aLine.indexOf(first);
+    public static String getWordAfter(String first, String text) {
+        int start = text.indexOf(first);
         if (start == -1)
             return null;
         start += first.length();
-        while (start < aLine.length() && Character.isWhitespace(aLine.charAt(start)))
+        while (start < text.length() && Character.isWhitespace(text.charAt(start)))
             start++;
         int finish = start;
-        while (finish < aLine.length() && !Character.isWhitespace(aLine.charAt(finish)))
+        while (finish < text.length() && !Character.isWhitespace(text.charAt(finish)))
             finish++;
-        if (finish < aLine.length())
-            return aLine.substring(start, finish);
+        if (finish < text.length())
+            return text.substring(start, finish);
         else
-            return aLine.substring(start);
+            return text.substring(start);
 
     }
 
@@ -3832,18 +4011,18 @@ public class Basic {
      * gets everything after the first word
      *
      * @param first
-     * @param aLine
+     * @param text
      * @return everything after the given word or null
      */
-    public static String getAfter(String first, String aLine) {
-        int start = aLine.indexOf(first);
+    public static String getTextAfter(String first, String text) {
+        int start = text.indexOf(first);
         if (start == -1)
             return null;
         start += first.length();
-        while (start < aLine.length() && Character.isWhitespace(aLine.charAt(start)))
+        while (start < text.length() && Character.isWhitespace(text.charAt(start)))
             start++;
         int finish = start;
-        return aLine.substring(start);
+        return text.substring(start);
 
     }
 
@@ -3933,6 +4112,56 @@ public class Basic {
         }
         return transposed;
     }
+
+    /**
+     * surrounds word with quotes if it contains character that is not a digit, letter or _
+     *
+     * @param str
+     * @return str, quoted is necessary
+     */
+    public static String quoteIfNecessary(String str) {
+        for (int i = 0; i < str.length(); i++) {
+            if (!Character.isLetterOrDigit(str.charAt(i)) && str.charAt(i) != '_')
+                return "'" + str + "'";
+        }
+        return str;
+    }
+
+    /**
+     * checks that no two of the given files are equal
+     *
+     * @param fileNames (can be null or "")
+     * @return true, if no two files are equal (using File.equals())
+     */
+    public static boolean checkAllFilesDifferent(String... fileNames) {
+        final File[] files = new File[fileNames.length];
+        for (int i = 0; i < fileNames.length; i++) {
+            if (fileNames[i] != null && fileNames[i].length() > 0) {
+                files[i] = new File(fileNames[i]);
+                for (int j = 0; j < i; j++) {
+                    if (files[i] != null && files[i].equals(files[j]))
+                        return false;
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * get the value of an enumeration ignoring case
+     *
+     * @param enumeration
+     * @param string
+     * @param <T>
+     * @return
+     */
+    public static <T extends Enum<T>> T valueOfIgnoreCase(Enum<T> enumeration, String string) {
+        for (T value : enumeration.getDeclaringClass().getEnumConstants()) {
+            if (value.toString().equalsIgnoreCase(string))
+                return value;
+        }
+        return null;
+    }
 }
 
 /**
diff --git a/src/jloda/util/BlastFileFilter.java b/src/jloda/util/BlastFileFilter.java
index 68651d2..6e4e0b8 100644
--- a/src/jloda/util/BlastFileFilter.java
+++ b/src/jloda/util/BlastFileFilter.java
@@ -1,6 +1,6 @@
 /**
  * BlastFileFilter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/Cache.java b/src/jloda/util/Cache.java
index 8086e9d..4ac757d 100644
--- a/src/jloda/util/Cache.java
+++ b/src/jloda/util/Cache.java
@@ -1,6 +1,6 @@
 /**
  * Cache.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/CanceledException.java b/src/jloda/util/CanceledException.java
index af9e181..8ea8baa 100644
--- a/src/jloda/util/CanceledException.java
+++ b/src/jloda/util/CanceledException.java
@@ -1,6 +1,6 @@
 /**
  * CanceledException.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/Colors.java b/src/jloda/util/Colors.java
index d978f6d..04faa94 100644
--- a/src/jloda/util/Colors.java
+++ b/src/jloda/util/Colors.java
@@ -1,6 +1,6 @@
 /**
  * Colors.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/CommandLineOptions.java b/src/jloda/util/CommandLineOptions.java
index 043da18..9f0cef9 100644
--- a/src/jloda/util/CommandLineOptions.java
+++ b/src/jloda/util/CommandLineOptions.java
@@ -1,6 +1,6 @@
 /**
  * CommandLineOptions.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/ConvexHull.java b/src/jloda/util/ConvexHull.java
index 87333c1..a81dbff 100644
--- a/src/jloda/util/ConvexHull.java
+++ b/src/jloda/util/ConvexHull.java
@@ -1,6 +1,6 @@
 /**
  * ConvexHull.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -19,7 +19,7 @@
 */
 package jloda.util;
 /*
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/Counter.java b/src/jloda/util/Counter.java
index 822fbde..162fc87 100644
--- a/src/jloda/util/Counter.java
+++ b/src/jloda/util/Counter.java
@@ -1,6 +1,6 @@
 /**
  * Counter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/Cursors.java b/src/jloda/util/Cursors.java
index 5ec6d53..bb0ec03 100644
--- a/src/jloda/util/Cursors.java
+++ b/src/jloda/util/Cursors.java
@@ -1,6 +1,6 @@
 /**
  * Cursors.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/DNAComplexityMeasure.java b/src/jloda/util/DNAComplexityMeasure.java
index f5d5cbe..52a243d 100644
--- a/src/jloda/util/DNAComplexityMeasure.java
+++ b/src/jloda/util/DNAComplexityMeasure.java
@@ -1,6 +1,6 @@
 /**
  * DNAComplexityMeasure.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/DrawOval.java b/src/jloda/util/DrawOval.java
deleted file mode 100644
index 784e43a..0000000
--- a/src/jloda/util/DrawOval.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/**
- * DrawOval.java 
- * Copyright (C) 2016 Daniel H. Huson
- *
- * (Some files contain contributions from other authors, who are then mentioned separately.)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-package jloda.util;
-
-import javax.swing.*;
-import java.awt.*;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
-import java.awt.geom.AffineTransform;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedList;
-
-/**
- * Draw an oval
- * Daniel Huson, 2014
- */
-public class DrawOval {
-
-    public static void main(String[] args) {
-        final LinkedList<Oval> list = new LinkedList<>();
-        final LinkedList<Point> points = new LinkedList<>();
-
-        final JFrame frame = new JFrame();
-        frame.setSize(500, 500);
-        final JPanel panel = new JPanel() {
-            @Override
-            public void paint(Graphics g0) {
-                Graphics2D g = (Graphics2D) g0;
-                super.paint(g);
-                for (Oval oval : list) {
-                    oval.draw(g);
-                }
-                g.setColor(Color.BLACK);
-                for (Point point : points) {
-                    g.drawRect(point.x - 1, point.y - 1, 2, 2);
-                }
-            }
-        };
-        frame.getContentPane().setLayout(new BorderLayout());
-        frame.getContentPane().add(panel);
-        frame.setVisible(true);
-        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
-        panel.addComponentListener(new ComponentAdapter() {
-            public void componentResized(ComponentEvent e) {
-                super.componentResized(e);
-                panel.repaint();
-            }
-        });
-
-
-        points.add(new Point(105, 100));
-        points.add(new Point(405, 300));
-        points.add(new Point(150, 120));
-
-        list.add(Oval.createOval(points));
-
-        list.add(new Oval(new Point(100, 100), 50, 100, 0));
-
-
-        for (float z = (float) Math.PI; z >= 0f; z -= 0.4f)
-            list.add(new Oval(new Point(300, 300), 120, 10, z));
-
-        list.add(new Oval(new Point(200, 100), 50, 100, 0));
-    }
-
-    public static Point getCenter(Collection<Point> points) {
-        double x = 0;
-        double y = 0;
-        for (Point point : points) {
-            x += point.x;
-            y += point.y;
-        }
-        x /= points.size();
-        y /= points.size();
-        return new Point((int) Math.round(x), (int) Math.round(y));
-
-    }
-
-    public static float getAngleOfMainDirection(Collection<Point> points, Point center) {
-        points = normalize(points, center);
-
-        final Point result = new Point();
-
-        for (Point point : points) {
-            if (point.x < 0) {
-                result.x += -point.x;
-                result.y += -point.y;
-            } else {
-                result.x += point.x;
-                result.y += point.y;
-            }
-        }
-        result.x = (int) ((float) result.x / points.size());
-        result.y = (int) ((float) result.y / points.size());
-        return (float) Geometry.computeAngle(result);
-    }
-
-    private static Collection<Point> normalize(Collection<Point> points, Point center) {
-        ArrayList<Point> result = new ArrayList<>(points.size());
-        for (Point point : points) {
-            result.add(new Point(point.x - center.x, point.y - center.y));
-        }
-        return result;
-    }
-}
-
-class Oval {
-    Point center;
-    int width;
-    int height;
-    float angle;
-
-    public Oval() {
-    }
-
-    public Oval(Point center, int width, int height, float angle) {
-        this.center = center;
-        this.width = width;
-        this.height = height;
-        this.angle = angle;
-    }
-
-    public void draw(Graphics2D gc) {
-        gc.setColor(Color.BLUE);
-        gc.drawRect(0, 0, 100, 100);
-        if (angle != 0.0) {
-            AffineTransform saveTransform = gc.getTransform();
-            gc.rotate(angle, center.getX(), center.getY());
-            gc.drawOval(center.x - width / 2, center.y - height / 2, width, height);
-            gc.setTransform(saveTransform);
-        } else
-            gc.drawOval(center.x - width / 2, center.y - height / 2, width, height);
-    }
-
-    public static Oval createOval(Collection<Point> points) {
-        Oval oval = new Oval();
-        oval.center = DrawOval.getCenter(points);
-        oval.angle = DrawOval.getAngleOfMainDirection(points, oval.center);
-        oval.width = 100;
-        oval.height = 50;
-        System.err.println("Center: " + oval.center);
-        System.err.println("Angle: " + oval.angle);
-        return oval;
-
-    }
-
-}
diff --git a/src/jloda/util/EditDistance.java b/src/jloda/util/EditDistance.java
index e7dbbbc..b58614b 100644
--- a/src/jloda/util/EditDistance.java
+++ b/src/jloda/util/EditDistance.java
@@ -1,6 +1,6 @@
 /**
  * EditDistance.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/FastA.java b/src/jloda/util/FastA.java
index 3b1304f..138a098 100644
--- a/src/jloda/util/FastA.java
+++ b/src/jloda/util/FastA.java
@@ -1,6 +1,6 @@
 /**
  * FastA.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/FastaFileFilter.java b/src/jloda/util/FastaFileFilter.java
index e361770..93dc055 100644
--- a/src/jloda/util/FastaFileFilter.java
+++ b/src/jloda/util/FastaFileFilter.java
@@ -1,6 +1,6 @@
 /**
  * FastaFileFilter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -43,7 +43,6 @@ public class FastaFileFilter extends FileFilterBase implements FilenameFilter {
         return instance;
     }
 
-
     /**
      * constructor
      */
@@ -55,6 +54,16 @@ public class FastaFileFilter extends FileFilterBase implements FilenameFilter {
         add(".fasta");
     }
 
+    public boolean accept (String fileName) {
+        boolean acceptBasedOnSuffix=super.accept(fileName);
+        if(!acceptBasedOnSuffix && isAllowGZipped() && fileName.toLowerCase().endsWith(".gz")) {   // look inside a gzipped file
+            final String[] lines=Basic.getFirstLinesFromFile(new File(fileName),2);
+            return lines!=null && lines[0]!=null && isFastAHeaderLine(lines[0])   && lines[1]!=null && !lines[1].startsWith(">");
+        }
+        else
+            return true;
+    }
+
     /**
      * @return description of file matching the filter
      */
@@ -71,6 +80,16 @@ public class FastaFileFilter extends FileFilterBase implements FilenameFilter {
     public static boolean accept(String fileName, boolean allowGZipped) {
         final FastaFileFilter fastaFileFilter = (new FastaFileFilter());
         fastaFileFilter.setAllowGZipped(allowGZipped);
-        return fastaFileFilter.accept(new File(fileName));
+        return fastaFileFilter.accept(fileName);
+    }
+
+    private static boolean isFastAHeaderLine(String line) {
+        if(line.startsWith("> ")) {
+            return line.length()>2 && Character.isLetterOrDigit(line.charAt(2));
+        } else  if(line.startsWith(">")) {
+            return line.length()>1 && Character.isLetterOrDigit(line.charAt(1));
+        }
+        else
+            return false;
     }
 }
diff --git a/src/jloda/util/FileFilter.java b/src/jloda/util/FileFilter.java
index 85c80d0..ec98cd7 100644
--- a/src/jloda/util/FileFilter.java
+++ b/src/jloda/util/FileFilter.java
@@ -1,6 +1,6 @@
 /**
  * FileFilter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/FileFilterBase.java b/src/jloda/util/FileFilterBase.java
index 234b331..9979b4b 100644
--- a/src/jloda/util/FileFilterBase.java
+++ b/src/jloda/util/FileFilterBase.java
@@ -1,6 +1,6 @@
 /**
  * FileFilterBase.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/FileInputIterator.java b/src/jloda/util/FileInputIterator.java
index fde3ec6..8cfd553 100644
--- a/src/jloda/util/FileInputIterator.java
+++ b/src/jloda/util/FileInputIterator.java
@@ -1,6 +1,6 @@
 /**
  * FileInputIterator.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -252,7 +252,7 @@ public class FileInputIterator implements IFileIterator {
         if (nextLine == null)
             hasNext();
         if (nextLine != null) {
-            String result = nextLine;
+            final String result = nextLine;
             nextLine = null;
             lineNumber++;
             if (progress != null) {
diff --git a/src/jloda/util/FileIterator.java b/src/jloda/util/FileIterator.java
index da7ff48..9e6cc2f 100644
--- a/src/jloda/util/FileIterator.java
+++ b/src/jloda/util/FileIterator.java
@@ -1,6 +1,6 @@
 /**
  * FileIterator.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/GZipUtils.java b/src/jloda/util/GZipUtils.java
index fcd7d78..b500dee 100644
--- a/src/jloda/util/GZipUtils.java
+++ b/src/jloda/util/GZipUtils.java
@@ -1,6 +1,6 @@
 /**
  * GZipUtils.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/Geometry.java b/src/jloda/util/Geometry.java
index 6596c11..625f9ec 100644
--- a/src/jloda/util/Geometry.java
+++ b/src/jloda/util/Geometry.java
@@ -1,6 +1,6 @@
 /**
  * Geometry.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/HeatSpectrum.java b/src/jloda/util/HeatSpectrum.java
index 28aae00..b867260 100644
--- a/src/jloda/util/HeatSpectrum.java
+++ b/src/jloda/util/HeatSpectrum.java
@@ -1,6 +1,6 @@
 /**
  * HeatSpectrum.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/ICloseableIterator.java b/src/jloda/util/ICloseableIterator.java
index 45142b4..868a993 100644
--- a/src/jloda/util/ICloseableIterator.java
+++ b/src/jloda/util/ICloseableIterator.java
@@ -1,6 +1,6 @@
 /**
  * ICloseableIterator.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/IFileIterator.java b/src/jloda/util/IFileIterator.java
index d0cc895..542c3e8 100644
--- a/src/jloda/util/IFileIterator.java
+++ b/src/jloda/util/IFileIterator.java
@@ -1,6 +1,6 @@
 /**
  * ICloseableIterator.java
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  * <p/>
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  * <p/>
diff --git a/src/jloda/util/IViewerWithJComponent.java b/src/jloda/util/IViewerWithJComponent.java
new file mode 100644
index 0000000..c82fe8d
--- /dev/null
+++ b/src/jloda/util/IViewerWithJComponent.java
@@ -0,0 +1,35 @@
+/*
+ *  Copyright (C) 2015 Daniel H. Huson and David J. Bryant
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package jloda.util;
+
+import javax.swing.*;
+
+/**
+ * viewer that can provide a component for image computation
+ * Created by huson on 2/15/17.
+ */
+public interface IViewerWithJComponent {
+    /**
+     * gets component that can be used for exporting image
+     *
+     * @return component
+     */
+    JComponent getComponent();
+}
diff --git a/src/jloda/util/IteratorAdapter.java b/src/jloda/util/IteratorAdapter.java
index b489259..cb47db7 100644
--- a/src/jloda/util/IteratorAdapter.java
+++ b/src/jloda/util/IteratorAdapter.java
@@ -1,6 +1,6 @@
 /**
  * IteratorAdapter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/JointIterators.java b/src/jloda/util/JointIterators.java
new file mode 100644
index 0000000..3a4df81
--- /dev/null
+++ b/src/jloda/util/JointIterators.java
@@ -0,0 +1,63 @@
+/*
+ *  Copyright (C) 2015 Daniel H. Huson and David J. Bryant
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package jloda.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+
+/**
+ * iterator over multiple iterators
+ * Created by huson on 2/7/17.
+ */
+public class JointIterators<T> implements Iterator<T> {
+    private final ArrayList<Iterator<T>> iterators;
+    private Iterator<T> current;
+
+    public JointIterators(Iterator<T>... iterators) {
+        this.iterators = new ArrayList<>(Arrays.asList(iterators));
+        if (this.iterators.size() > 0)
+            current = this.iterators.remove(0);
+
+    }
+
+    @Override
+    public boolean hasNext() {
+        while (current != null) {
+            if (current.hasNext())
+                return true;
+            else if (iterators.size() > 0)
+                current = iterators.remove(0);
+            else {
+                current = null;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public T next() {
+        return current.next();
+    }
+
+    @Override
+    public void remove() {
+    }
+}
diff --git a/src/jloda/util/License.java b/src/jloda/util/License.java
deleted file mode 100644
index d1ff77f..0000000
--- a/src/jloda/util/License.java
+++ /dev/null
@@ -1,353 +0,0 @@
-/**
- * License.java 
- * Copyright (C) 2016 Daniel H. Huson
- *
- * (Some files contain contributions from other authors, who are then mentioned separately.)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-package jloda.util;
-
-import java.io.*;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.NoSuchProviderException;
-import java.security.SignatureException;
-import java.security.spec.InvalidKeySpecException;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * a license data object
- * Daniel Huson, 4.2013
- */
-public class License {
-    public enum Item {Program, User, Email, Organization, Address, City, Country, IPAddress, LicenseType, ExpireDate, Signature}
-
-    public enum Type {
-        Academic, SingleUser, Site, Company, Temporary, NonProfitResearchLab;
-
-        public String getInfo() {
-            switch (this) {
-                default:
-                case Academic:
-                    return "academic research, publication and teaching only.";
-                case SingleUser:
-                    return "only to be used by person specified under 'User'.";
-                case Site:
-                    return "only to be used at the site specified under 'Address' and 'City'.";
-                case Company:
-                    return "only to be used within the company specified under 'Organization'.";
-                case Temporary:
-                    return "only to be used for evaluation or teaching purposes.";
-                case NonProfitResearchLab:
-                    return "non-profit research, publication and teaching only.";
-            }
-        }
-    }
-
-    private final Map<Item, String> item2value = new HashMap<>();
-
-    /**
-     * set a list of name to value pairs
-     *
-     * @param pairs
-     */
-    public void setPairs(java.util.Collection<Pair<String, String>> pairs) {
-        for (Pair<String, String> name2value : pairs) {
-            final Item item = Item.valueOf(name2value.get1());
-            if (item != null) {
-                String value = name2value.get2().trim();
-                if (item == Item.ExpireDate) {
-                    if (value.length() == 0 || value.equals("0")) {
-                        if (item2value.containsKey(item))
-                            item2value.remove(item);
-                    } else {
-                        if (value.equals("1")) // one year
-                        {
-                            value = (new Date((long) (System.currentTimeMillis() + 3.419e+10))).toString();
-                        } else if (value.equals("2")) // two years
-                        {
-                            value = (new Date((long) (System.currentTimeMillis() + 2 * 3.419e+10))).toString();
-                        }
-                        item2value.put(item, value);
-                    }
-                } else
-                    item2value.put(item, value);
-            }
-        }
-    }
-
-
-    /**
-     * string representation
-     *
-     * @return as string
-     */
-    public String toString() {
-        final StringBuilder buf = new StringBuilder();
-        for (Item item : Item.values()) {
-            if (item2value.containsKey(item)) {
-                buf.append(item.toString()).append(": ").append(item2value.get(item)).append("\n");
-            }
-        }
-        return buf.toString();
-    }
-
-    /**
-     * returns the size
-     *
-     * @return size
-     */
-    public int size() {
-        return item2value.size();
-    }
-
-    /**
-     * erase the license info
-     */
-    public void clear() {
-        item2value.clear();
-    }
-
-    /**
-     * string representation
-     *
-     * @return as string
-     */
-    public String toStringWithoutSignature() {
-        StringBuilder buf = new StringBuilder();
-        for (Item item : Item.values()) {
-            if (item != Item.Signature && item2value.containsKey(item)) {
-                String value = item2value.get(item);
-                if (item == Item.LicenseType && !value.contains(" -"))
-                    value = value + " - " + Type.valueOf(value).getInfo();
-                buf.append(item.toString()).append(": ").append(value.trim()).append("\n");
-            }
-        }
-        return buf.toString();
-    }
-
-    /**
-     * put the value for an item
-     *
-     * @param item
-     * @param value
-     */
-    public void put(Item item, String value) {
-        item2value.put(item, value);
-    }
-
-    /**
-     * get the value for an item
-     *
-     * @param item
-     * @return value
-     */
-    public String get(Item item) {
-        return item2value.get(item);
-    }
-
-    /**
-     * gets data as bytes  without the signature (for verifying)
-     *
-     * @return as bytes
-     */
-    public byte[] getBytes() {
-        try {
-            // String str= toStringWithoutSignature();
-            // System.err.println("String:\n"+str);
-            //  System.err.println("Length: "+str.length());
-            //  System.err.println("Hash: "+str.hashCode());
-
-            // replace all non-ascii characters by double ?? before computing score
-            // use ?? because this is what non-ascii characters result in on web page
-            return toStringWithoutSignature().replaceAll("\\P{InBasic_Latin}", "??").getBytes("ISO-8859-1");
-        } catch (UnsupportedEncodingException e) {
-            return toStringWithoutSignature().getBytes();
-        }
-    }
-
-    /**
-     * save to file
-     *
-     * @param fileName
-     * @throws IOException
-     */
-    public void writeToFile(String fileName) throws IOException {
-        try (BufferedWriter w = new BufferedWriter(new FileWriter(fileName))) {
-            w.write(toString());
-        }
-    }
-
-    /**
-     * load from a file
-     *
-     * @param file
-     * @throws IOException
-     */
-    public void loadFromFile(File file) {
-        item2value.clear();
-
-        ICloseableIterator<String> it = null;
-        try {
-            if ((new RTFFileFilter()).accept(file.getParentFile(), file.getName())) {
-                System.err.println("This file appears to be in RTF format, not TXT format, will try to parse. If unsuccessful, please save as a TXT file and let me try again.");
-                final String[] lines = RTFFileFilter.getStrippedLines(file);
-                it = new ICloseableIterator<String>() {
-                    private int i = 0;
-
-                    public void close() throws IOException {
-                    }
-
-                    public long getMaximumProgress() {
-                        return lines.length;
-                    }
-
-                    public long getProgress() {
-                        return i;
-                    }
-
-                    public boolean hasNext() {
-                        return i < lines.length;
-                    }
-
-                    public String next() {
-                        return lines[i++];
-                    }
-
-                    public void remove() {
-
-                    }
-                };
-            } else
-            it = new FileInputIterator(file.getPath());
-
-            boolean inLicense = false;
-            boolean waitForSignature = false; // often the signature token and the actual singature or on different lines, try to fix this
-            while (it.hasNext()) {
-                final String aLine = it.next();
-
-                if (aLine.length() > 0 && !aLine.startsWith("#")) {
-                    if (!inLicense) {
-                        if (aLine.equals("License certificate:") || aLine.equals("Registration details:"))  // the latter for legacy
-                            inLicense = true;
-                    } else {
-                        final int pos = aLine.indexOf(':');
-                        if (pos != -1) {
-                            final String key = aLine.substring(0, pos).trim();
-                            final String value = pos + 1 < aLine.length() ? aLine.substring(pos + 1, aLine.length()).trim() : null;
-                            final Item item = Item.valueOf(key);
-                            item2value.put(item, value);
-                            if (item.equals(Item.Signature)) {
-                                if (value == null && it.hasNext()) // signature appears to be on next line
-                                {
-                                    item2value.put(item, it.next().trim());
-                                }
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-        } catch (Exception ex) {
-        } finally {
-            try {
-                if (it != null)
-                    it.close();
-            } catch (IOException e) {
-            }
-        }
-    }
-
-    /**
-     * verify that signature is valid
-     *
-     * @param signer
-     * @return true, if signature is valid
-     * @throws IOException
-     * @throws NoSuchProviderException
-     * @throws NoSuchAlgorithmException
-     * @throws InvalidKeySpecException
-     * @throws SignatureException
-     * @throws InvalidKeyException
-     */
-    public boolean verifySignature(Signer signer) {
-        try {
-            return signer.verifySignedData(getBytes(), Signer.signatureHexStringToBytes(get(Item.Signature)));
-        } catch (Exception e) {
-        }
-        return false;
-    }
-
-    /**
-     * gets licensed-to header string
-     *
-     * @return string
-     */
-    public String getLicensedTo() {
-        if (item2value.size() > 0) {
-            final String value = item2value.get(Item.LicenseType);
-            if (value != null) {
-                String typeName = Basic.getFirstWord(value);
-                switch (Type.valueOf(typeName)) {
-                    case Academic: {
-                        StringWriter w = new StringWriter();
-                        w.write("Licensed to user: " + item2value.get(Item.User) + ", ");
-                        w.write("Academic institution: " + item2value.get(Item.Organization) + ", ");
-                        w.write("Email: " + item2value.get(Item.Email));
-                        return w.toString();
-                    }
-                    case SingleUser: {
-                        StringWriter w = new StringWriter();
-                        w.write("Licensed to user: " + item2value.get(Item.User) + ", ");
-                        w.write("Organization: " + item2value.get(Item.Organization) + ", ");
-                        w.write("Email: " + item2value.get(Item.Email));
-                        return w.toString();
-                    }
-                    case Site: {
-                        StringWriter w = new StringWriter();
-                        w.write("Licensed to Site: " + item2value.get(Item.City) + ", ");
-                        w.write("Organization: " + item2value.get(Item.Organization) + ", ");
-                        w.write("Email: " + item2value.get(Item.Email));
-                        return w.toString();
-                    }
-                    case Company: {
-                        StringWriter w = new StringWriter();
-                        w.write("Licensed to company: " + item2value.get(Item.Organization) + ", ");
-                        w.write("Contact: " + item2value.get(Item.User) + ", ");
-                        w.write("Email: " + item2value.get(Item.Email));
-                        return w.toString();
-                    }
-                    case Temporary: {
-                        StringWriter w = new StringWriter();
-                        w.write("Temporary license ");
-                        w.write("User: " + item2value.get(Item.User) + ", ");
-                        w.write("Organization: " + item2value.get(Item.Organization));
-                        return w.toString();
-                    }
-                    case NonProfitResearchLab: {
-                        StringWriter w = new StringWriter();
-                        w.write("Non-profit license ");
-                        w.write("User: " + item2value.get(Item.User) + ", ");
-                        w.write("Organization: " + item2value.get(Item.Organization));
-                        return w.toString();
-                    }
-                }
-            }
-        }
-        return "No valid license - for evaluation only";
-    }
-}
diff --git a/src/jloda/util/ListOfLongs.java b/src/jloda/util/ListOfLongs.java
index 7624c33..d7aa41e 100644
--- a/src/jloda/util/ListOfLongs.java
+++ b/src/jloda/util/ListOfLongs.java
@@ -1,6 +1,6 @@
 /**
  * ListOfLongs.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/MenuMnemonics.java b/src/jloda/util/MenuMnemonics.java
index 902257e..79bebbb 100644
--- a/src/jloda/util/MenuMnemonics.java
+++ b/src/jloda/util/MenuMnemonics.java
@@ -1,6 +1,6 @@
 /**
  * MenuMnemonics.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/MultiIterator.java b/src/jloda/util/MultiIterator.java
new file mode 100644
index 0000000..3888d51
--- /dev/null
+++ b/src/jloda/util/MultiIterator.java
@@ -0,0 +1,88 @@
+/*
+ *  Copyright (C) 2015 Daniel H. Huson
+ *
+ *  (Some files contain contributions from other authors, who are then mentioned separately.)
+ *
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program 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 General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package jloda.util;
+
+import java.util.Iterator;
+
+/**
+ * iterator over iterators
+ * Created by huson on 2/17/17.
+ */
+public class MultiIterator<T> implements Iterable<T> {
+    private final Iterator<T>[] iterators;
+
+    /**
+     * constructor
+     *
+     * @param iterables
+     */
+    @SafeVarargs
+    public MultiIterator(Iterable<T>... iterables) {
+        iterators = new Iterator[iterables.length];
+        for (int i = 0; i < iterables.length; i++)
+            iterators[i] = iterables[i].iterator();
+    }
+
+    /**
+     * constructor
+     *
+     * @param iterators
+     */
+    @SafeVarargs
+    public MultiIterator(Iterator<T>... iterators) {
+        this.iterators = iterators;
+    }
+
+    /**
+     * get an iterator over all iterators
+     *
+     * @return iterator
+     */
+    public Iterator<T> iterator() {
+        return new Iterator<T>() {
+            private int which = 0;
+
+            @Override
+            public boolean hasNext() {
+                while (which < iterators.length) {
+                    if (iterators[which].hasNext())
+                        return true;
+                    which++;
+                }
+                return false;
+            }
+
+            @Override
+            public T next() {
+                if (hasNext())
+                    return iterators[which].next();
+                else
+                    return null;
+            }
+
+            @Override
+            public void remove() {
+
+            }
+        };
+    }
+
+
+}
diff --git a/src/jloda/util/MultiLineCellRenderer.java b/src/jloda/util/MultiLineCellRenderer.java
index efcf268..47d8351 100644
--- a/src/jloda/util/MultiLineCellRenderer.java
+++ b/src/jloda/util/MultiLineCellRenderer.java
@@ -1,6 +1,6 @@
 /**
  * MultiLineCellRenderer.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/NexusFileFilter.java b/src/jloda/util/NexusFileFilter.java
index 42bedb4..fdf363d 100644
--- a/src/jloda/util/NexusFileFilter.java
+++ b/src/jloda/util/NexusFileFilter.java
@@ -1,6 +1,6 @@
 /**
  * NexusFileFilter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/NotOwnerException.java b/src/jloda/util/NotOwnerException.java
index dbdd99e..f2aa813 100644
--- a/src/jloda/util/NotOwnerException.java
+++ b/src/jloda/util/NotOwnerException.java
@@ -1,6 +1,6 @@
 /**
  * NotOwnerException.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/Pair.java b/src/jloda/util/Pair.java
index f0bfb2a..58cba06 100644
--- a/src/jloda/util/Pair.java
+++ b/src/jloda/util/Pair.java
@@ -1,6 +1,6 @@
 /**
  * Pair.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -28,17 +28,16 @@ import java.util.Comparator;
  *         Date: 14-May-2004
  */
 public class Pair<S, T> implements Comparable<Pair<S, T>>, Comparator<Pair<S, T>> {
-    S first;
-    T second;
+    private S first;
+    private T second;
 
     public Pair() {
 
     }
 
     public Pair(S first, T second) {
-        setFirst(first);
-        setSecond(second);
-
+        this.first = first;
+        this.second = second;
     }
 
     public S getFirst() {
@@ -61,7 +60,6 @@ public class Pair<S, T> implements Comparable<Pair<S, T>>, Comparator<Pair<S, T>
         return ((Integer) first);
     }
 
-
     public int getSecondInt() {
         return ((Integer) second);
     }
@@ -97,34 +95,47 @@ public class Pair<S, T> implements Comparable<Pair<S, T>>, Comparator<Pair<S, T>
     }
 
     public int hashCode() {
-        if (first == null || second == null)
-            return 0;
-        else
-            return first.hashCode() + 37 * second.hashCode();
+        return (first == null ? 0 : first.hashCode()) + (second == null ? 0 : 37 * second.hashCode());
     }
 
     public int compareTo(Pair<S, T> p) {
-        int value = ((Comparable<S>) this.getFirst()).compareTo(p.getFirst());
+        int value;
+        if (first == null && p.first != null)
+            return -1;
+        if (first != null && p.first == null)
+            return 1;
+        if (first == null) //  && p.first==null
+            value = 0;
+        else
+            value = ((Comparable) first).compareTo(p.getFirst());
         if (value != 0)
             return value;
+
+        if (second == null && p.second != null)
+            return -1;
+        if (second != null && p.second == null)
+            return 1;
+        if (second == null) //  && p.second==null
+            value = 0;
         else
-            return ((Comparable<T>) this.getSecond()).compareTo(p.getSecond());
+            value = ((Comparable) second).compareTo(p.getSecond());
+        return value;
     }
 
     public boolean equals(Object other) {
         boolean good = false;
         if (other instanceof Pair) {
-            Pair p = (Pair) other;
+            final Pair that = (Pair) other;
             if (first == null) {
-                good = (p.first == null);
+                good = (that.first == null);
             } else {
-                good = first.equals(p.first);
+                good = first.equals(that.first);
             }
             if (good) {
                 if (second == null) {
-                    good = (p.second == null);
+                    good = (that.second == null);
                 } else {
-                    good = second.equals(p.second);
+                    good = second.equals(that.second);
                 }
             }
         }
diff --git a/src/jloda/util/PeakMemoryUsageMonitor.java b/src/jloda/util/PeakMemoryUsageMonitor.java
index 9983e6c..ba55e01 100644
--- a/src/jloda/util/PeakMemoryUsageMonitor.java
+++ b/src/jloda/util/PeakMemoryUsageMonitor.java
@@ -1,6 +1,6 @@
 /**
  * PeakMemoryUsageMonitor.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/PhylipUtils.java b/src/jloda/util/PhylipUtils.java
index 006a905..8be75be 100644
--- a/src/jloda/util/PhylipUtils.java
+++ b/src/jloda/util/PhylipUtils.java
@@ -1,6 +1,6 @@
 /**
  * PhylipUtils.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/PluginClassLoader.java b/src/jloda/util/PluginClassLoader.java
index 8977de4..02c61b0 100644
--- a/src/jloda/util/PluginClassLoader.java
+++ b/src/jloda/util/PluginClassLoader.java
@@ -1,6 +1,6 @@
 /**
  * PluginClassLoader.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -47,11 +47,23 @@ public class PluginClassLoader {
     /**
      * get an instance of each class of the given type in the given packages
      *
-     * @param packageNames
      * @param clazz
+     * @param packageNames
      * @return instances
      */
-    public static List<Object> getInstances(String[] packageNames, Class clazz) {
+    public static List<Object> getInstances(Class clazz, String... packageNames) {
+        return getInstances(clazz, null, packageNames);
+    }
+
+    /**
+     * get an instance of each class of the given types in the given packages
+     *
+     * @param clazz1       this must be assignable from the returned class
+     * @param clazz2       if non-null, must also be assignable from the returned class
+     * @param packageNames
+     * @return instances
+     */
+    public static List<Object> getInstances(Class clazz1, Class clazz2, String... packageNames) {
         final List<Object> plugins = new LinkedList<>();
         final LinkedList<String> packageNameQueue = new LinkedList<>();
         packageNameQueue.addAll(Arrays.asList(packageNames));
@@ -66,7 +78,7 @@ public class PluginClassLoader {
                         try {
                             resources[i] = resources[i].substring(0, resources[i].length() - 6);
                             Class c = Basic.classForName(packageName.concat(".").concat(resources[i]));
-                            if (!c.isInterface() && !Modifier.isAbstract(c.getModifiers()) && clazz.isAssignableFrom(c)) {
+                            if (!c.isInterface() && !Modifier.isAbstract(c.getModifiers()) && clazz1.isAssignableFrom(c) && (clazz2 == null || clazz2.isAssignableFrom(c))) {
                                 try {
                                     plugins.add(c.newInstance());
                                 } catch (InstantiationException ex) {
@@ -96,6 +108,17 @@ public class PluginClassLoader {
     }
 
     /**
+     * get an instance of each class of the given type in the given packages
+     *
+     * @param packageNames
+     * @param clazz
+     * @return instances
+     */
+    public static List<Object> getInstances(String[] packageNames, Class clazz) {
+        return getInstances(clazz, null, packageNames);
+    }
+
+    /**
      * get an instance of each class of the given type in the given package, sorted
      *
      * @param packageName
diff --git a/src/jloda/util/PolygonDouble.java b/src/jloda/util/PolygonDouble.java
index 48d2e73..abb3922 100644
--- a/src/jloda/util/PolygonDouble.java
+++ b/src/jloda/util/PolygonDouble.java
@@ -1,6 +1,6 @@
 /**
  * PolygonDouble.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/ProgramProperties.java b/src/jloda/util/ProgramProperties.java
index 0080118..3bfc19f 100644
--- a/src/jloda/util/ProgramProperties.java
+++ b/src/jloda/util/ProgramProperties.java
@@ -1,6 +1,6 @@
 /**
  * ProgramProperties.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -69,6 +69,9 @@ public class ProgramProperties {
     public static final String MULTI_WINDOW_GEOMETRY = "MultiWindowGeometry";
     public static PageFormat pageFormat = null;
     public static final String DEFAULT_FONT = "DefaultFont";
+    public static final String SEARCH_URL = "SearchURL";
+    public static final String defaultSearchURL = "http://www.google.com/search?q=%s";
+
 
     /**
      * load properties from default file
diff --git a/src/jloda/util/ProgressCmdLine.java b/src/jloda/util/ProgressCmdLine.java
index 088a140..48da9c3 100644
--- a/src/jloda/util/ProgressCmdLine.java
+++ b/src/jloda/util/ProgressCmdLine.java
@@ -1,6 +1,6 @@
 /**
  * ProgressCmdLine.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/ProgressListener.java b/src/jloda/util/ProgressListener.java
index fabc77b..05834a1 100644
--- a/src/jloda/util/ProgressListener.java
+++ b/src/jloda/util/ProgressListener.java
@@ -1,6 +1,6 @@
 /**
  * ProgressListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/ProgressPercentage.java b/src/jloda/util/ProgressPercentage.java
index 17f8e4f..4e2aaae 100644
--- a/src/jloda/util/ProgressPercentage.java
+++ b/src/jloda/util/ProgressPercentage.java
@@ -1,6 +1,6 @@
 /**
  * ProgressPercentage.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/ProgressSilent.java b/src/jloda/util/ProgressSilent.java
index c0fa181..8b5a2a1 100644
--- a/src/jloda/util/ProgressSilent.java
+++ b/src/jloda/util/ProgressSilent.java
@@ -1,6 +1,6 @@
 /**
  * ProgressSilent.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/PropertiesListListener.java b/src/jloda/util/PropertiesListListener.java
index 69813a5..4bae91c 100644
--- a/src/jloda/util/PropertiesListListener.java
+++ b/src/jloda/util/PropertiesListListener.java
@@ -1,6 +1,6 @@
 /**
  * PropertiesListListener.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/ProteinComplexityMeasure.java b/src/jloda/util/ProteinComplexityMeasure.java
index f29e381..2906581 100644
--- a/src/jloda/util/ProteinComplexityMeasure.java
+++ b/src/jloda/util/ProteinComplexityMeasure.java
@@ -1,6 +1,6 @@
 /**
  * ProteinComplexityMeasure.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/RTFFileFilter.java b/src/jloda/util/RTFFileFilter.java
index cabbe66..8b5ebbe 100644
--- a/src/jloda/util/RTFFileFilter.java
+++ b/src/jloda/util/RTFFileFilter.java
@@ -1,6 +1,6 @@
 /**
  * RTFFileFilter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/RTree.java b/src/jloda/util/RTree.java
index a436f45..eb3c88d 100644
--- a/src/jloda/util/RTree.java
+++ b/src/jloda/util/RTree.java
@@ -1,6 +1,6 @@
 /**
  * RTree.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/RandomGaussian.java b/src/jloda/util/RandomGaussian.java
index c85ee69..558d6d2 100644
--- a/src/jloda/util/RandomGaussian.java
+++ b/src/jloda/util/RandomGaussian.java
@@ -1,6 +1,6 @@
 /**
  * RandomGaussian.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/RememberingComboBox.java b/src/jloda/util/RememberingComboBox.java
index cdf21d8..239ce95 100644
--- a/src/jloda/util/RememberingComboBox.java
+++ b/src/jloda/util/RememberingComboBox.java
@@ -1,6 +1,6 @@
 /**
  * RememberingComboBox.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/ResourceManager.java b/src/jloda/util/ResourceManager.java
index a0536f6..315a608 100644
--- a/src/jloda/util/ResourceManager.java
+++ b/src/jloda/util/ResourceManager.java
@@ -1,6 +1,6 @@
 /**
  * ResourceManager.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/RunLater.java b/src/jloda/util/RunLater.java
index 53f340a..c429ecd 100644
--- a/src/jloda/util/RunLater.java
+++ b/src/jloda/util/RunLater.java
@@ -1,6 +1,6 @@
 /**
  * RunLater.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/SequenceUtils.java b/src/jloda/util/SequenceUtils.java
index 6e9d6ad..ee9860a 100644
--- a/src/jloda/util/SequenceUtils.java
+++ b/src/jloda/util/SequenceUtils.java
@@ -1,6 +1,6 @@
 /**
  * SequenceUtils.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -485,7 +485,8 @@ public class SequenceUtils {
         {
             int pos = 0;
             for (int i = sequence.length() - 1 - shift; i >= 2; i -= 3) {
-                result[pos++] = getAminoAcidReverse(sequence, i);
+                if (i + 2 < sequence.length())
+                    result[pos++] = getAminoAcidReverse(sequence, i);
             }
         }
         return result;
diff --git a/src/jloda/util/Shapes.java b/src/jloda/util/Shapes.java
new file mode 100644
index 0000000..3dd3590
--- /dev/null
+++ b/src/jloda/util/Shapes.java
@@ -0,0 +1,98 @@
+package jloda.util;
+
+/**
+ * creates some basic shapes
+ * Created by huson on 2/13/17.
+ */
+public class Shapes {
+    /**
+     * create n-pointed star
+     *
+     * @param x
+     * @param y
+     * @param width
+     * @param height
+     * @param n
+     * @return coordinates
+     */
+    public static float[][] createStar(int x, int y, int width, int height, int n) {
+        final float radius = 0.5f * Math.min(width, height);
+        x += radius;
+        y += radius;
+        final float[] xCoordinates = new float[2 * n];
+        final float[] yCoordinates = new float[2 * n];
+        for (int i = 0; i < n; i++) {
+            xCoordinates[2 * i] = x + (float) (radius * Math.sin(i * Math.PI / (0.5 * n)));
+            yCoordinates[2 * i] = y - (float) (radius * Math.cos(i * Math.PI / (0.5 * n)));
+            xCoordinates[2 * i + 1] = x + (float) (0.5f * radius * Math.sin((i + 1.0f / n) * Math.PI / (0.5 * n)));
+            yCoordinates[2 * i + 1] = y - (float) (0.5f * radius * Math.cos((i + 1.0f / n) * Math.PI / (0.5 * n)));
+        }
+        return new float[][]{xCoordinates, yCoordinates};
+    }
+
+    /**
+     * create n-sided regular polygon
+     *
+     * @param x
+     * @param y
+     * @param width
+     * @param height
+     * @param n
+     * @return coordinates
+     */
+    public static float[][] createRegularPolygon(int x, int y, int width, int height, int n) {
+        final float radius = 0.5f * Math.min(width, height);
+        x += radius;
+        y += radius;
+        final float[] xCoordinates = new float[n];
+        final float[] yCoordinates = new float[n];
+        for (int i = 0; i < n; i++) {
+            xCoordinates[i] = x + (float) (radius * Math.cos(i * Math.PI / (0.5 * n)));
+            yCoordinates[i] = y + (float) (radius * Math.sin(i * Math.PI / (0.5 * n)));
+        }
+        return new float[][]{xCoordinates, yCoordinates};
+    }
+
+    /**
+     * create a cross +
+     *
+     * @param x
+     * @param y
+     * @param width
+     * @param height
+     * @return coordinates
+     */
+    public static float[][] createCrossPlus(int x, int y, int width, int height) {
+        final float x1 = x + 0.333f * width;
+        final float x2 = x + 0.666f * width;
+        final float x3 = x + width;
+        final float y1 = y + 0.333f * height;
+        final float y2 = y + 0.666f * height;
+        final float y3 = y + height;
+        return new float[][]{{x3, x2, x2, x1, x1, x, x, x1, x1, x2, x2, x3}, {y1, y1, y, y, y1, y1, y2, y2, y3, y3, y2, y2}};
+    }
+
+    /**
+     * create a cross X
+     *
+     * @param x
+     * @param y
+     * @param width
+     * @param height
+     * @return coordinates
+     */
+    public static float[][] createCrossX(int x, int y, int width, int height) {
+        final float x1 = x + 0.333f * width;
+        final float x2 = x + 0.5f * width;
+        final float x3 = x + 0.666f * width;
+        ;
+        final float x4 = x + width;
+        final float y1 = y + 0.333f * height;
+        final float y2 = y + 0.5f * height;
+        final float y3 = y + 0.666f * height;
+        final float y4 = y + height;
+        return new float[][]{
+                {x4, x3, x2, x1, x, x1, x, x1, x2, x3, x4, x3},
+                {y, y, y1, y, y, y2, y4, y4, y3, y4, y4, y2}};
+    }
+}
diff --git a/src/jloda/util/Signer.java b/src/jloda/util/Signer.java
index 92885ea..a56846e 100644
--- a/src/jloda/util/Signer.java
+++ b/src/jloda/util/Signer.java
@@ -1,6 +1,6 @@
 /**
  * Signer.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/Single.java b/src/jloda/util/Single.java
index e99033c..45a31e9 100644
--- a/src/jloda/util/Single.java
+++ b/src/jloda/util/Single.java
@@ -1,6 +1,6 @@
 /**
  * Single.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/State.java b/src/jloda/util/State.java
index 1a2a945..6e11a7f 100644
--- a/src/jloda/util/State.java
+++ b/src/jloda/util/State.java
@@ -1,6 +1,6 @@
 /**
  * State.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/Statistics.java b/src/jloda/util/Statistics.java
index a7ffae2..aefe0f6 100644
--- a/src/jloda/util/Statistics.java
+++ b/src/jloda/util/Statistics.java
@@ -1,6 +1,6 @@
 /**
  * Statistics.java
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  * <p>
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  * <p>
@@ -62,6 +62,90 @@ public class Statistics {
     }
 
     /**
+     * computes simple statistics for given collection of numbers
+     *
+     * @param data
+     */
+    public Statistics(int[] data) {
+        count = data.length;
+        if (count > 0) {
+            for (Number number : data) {
+                double value = number.doubleValue();
+                sum += value;
+                if (value < min)
+                    min = value;
+                if (value > max)
+                    max = value;
+            }
+            mean = sum / count;
+            if (count > 1) {
+                double sum2 = 0;
+                for (Number number : data) {
+                    double value = number.doubleValue();
+                    sum2 += (value - mean) * (value - mean);
+                }
+                stdDev = Math.sqrt(sum2 / count);
+            }
+        }
+    }
+
+    /**
+     * computes simple statistics for given collection of numbers
+     *
+     * @param data
+     */
+    public Statistics(float[] data) {
+        count = data.length;
+        if (count > 0) {
+            for (Number number : data) {
+                double value = number.doubleValue();
+                sum += value;
+                if (value < min)
+                    min = value;
+                if (value > max)
+                    max = value;
+            }
+            mean = sum / count;
+            if (count > 1) {
+                double sum2 = 0;
+                for (Number number : data) {
+                    double value = number.doubleValue();
+                    sum2 += (value - mean) * (value - mean);
+                }
+                stdDev = Math.sqrt(sum2 / count);
+            }
+        }
+    }
+
+    /**
+     * computes simple statistics for given collection of numbers
+     *
+     * @param data
+     */
+    public Statistics(double[] data) {
+        count = data.length;
+        if (count > 0) {
+            for (Number number : data) {
+                double value = number.doubleValue();
+                sum += value;
+                if (value < min)
+                    min = value;
+                if (value > max)
+                    max = value;
+            }
+            mean = sum / count;
+            if (count > 1) {
+                double sum2 = 0;
+                for (Number number : data) {
+                    double value = number.doubleValue();
+                    sum2 += (value - mean) * (value - mean);
+                }
+                stdDev = Math.sqrt(sum2 / count);
+            }
+        }
+    }
+
+    /**
      * gets string representation of stats
      *
      * @return string
diff --git a/src/jloda/util/StreamGobbler.java b/src/jloda/util/StreamGobbler.java
index 5a01d9e..aa24dfe 100644
--- a/src/jloda/util/StreamGobbler.java
+++ b/src/jloda/util/StreamGobbler.java
@@ -1,6 +1,6 @@
 /**
  * StreamGobbler.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/StringParser.java b/src/jloda/util/StringParser.java
index e22bf10..4785aee 100644
--- a/src/jloda/util/StringParser.java
+++ b/src/jloda/util/StringParser.java
@@ -1,6 +1,6 @@
 /**
  * StringParser.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/Task.java b/src/jloda/util/Task.java
index 3156bf1..e2b74a2 100644
--- a/src/jloda/util/Task.java
+++ b/src/jloda/util/Task.java
@@ -1,6 +1,6 @@
 /**
  * Task.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/TemporaryFileSet.java b/src/jloda/util/TemporaryFileSet.java
index 0b6db29..1bf1814 100644
--- a/src/jloda/util/TemporaryFileSet.java
+++ b/src/jloda/util/TemporaryFileSet.java
@@ -1,6 +1,6 @@
 /**
  * TemporaryFileSet.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/TextFileFilter.java b/src/jloda/util/TextFileFilter.java
index 3be6871..c588d8e 100644
--- a/src/jloda/util/TextFileFilter.java
+++ b/src/jloda/util/TextFileFilter.java
@@ -1,6 +1,6 @@
 /**
  * TextFileFilter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/TextPrinter.java b/src/jloda/util/TextPrinter.java
index 1bda842..f39fe72 100644
--- a/src/jloda/util/TextPrinter.java
+++ b/src/jloda/util/TextPrinter.java
@@ -1,6 +1,6 @@
 /**
  * TextPrinter.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/TextWindow.java b/src/jloda/util/TextWindow.java
index 14cb957..b650baa 100644
--- a/src/jloda/util/TextWindow.java
+++ b/src/jloda/util/TextWindow.java
@@ -1,6 +1,6 @@
 /**
  * TextWindow.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/TimeStamp.java b/src/jloda/util/TimeStamp.java
index 19d7f40..6845825 100644
--- a/src/jloda/util/TimeStamp.java
+++ b/src/jloda/util/TimeStamp.java
@@ -1,6 +1,6 @@
 /**
  * TimeStamp.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/ToolTipHelper.java b/src/jloda/util/ToolTipHelper.java
index a3cfe6d..a16917a 100644
--- a/src/jloda/util/ToolTipHelper.java
+++ b/src/jloda/util/ToolTipHelper.java
@@ -1,6 +1,6 @@
 /**
  * ToolTipHelper.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/Triplet.java b/src/jloda/util/Triplet.java
index 23de798..e17ee2b 100644
--- a/src/jloda/util/Triplet.java
+++ b/src/jloda/util/Triplet.java
@@ -1,6 +1,6 @@
 /**
  * Triplet.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/UsageException.java b/src/jloda/util/UsageException.java
index 68faef4..1184df6 100644
--- a/src/jloda/util/UsageException.java
+++ b/src/jloda/util/UsageException.java
@@ -1,6 +1,6 @@
 /**
  * UsageException.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/lang/Language.java b/src/jloda/util/lang/Language.java
index 21fde54..6ef59a7 100644
--- a/src/jloda/util/lang/Language.java
+++ b/src/jloda/util/lang/Language.java
@@ -1,6 +1,6 @@
 /**
  * Language.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/lang/Translator.java b/src/jloda/util/lang/Translator.java
index 378c19c..10a6616 100644
--- a/src/jloda/util/lang/Translator.java
+++ b/src/jloda/util/lang/Translator.java
@@ -1,6 +1,6 @@
 /**
  * Translator.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/parse/NexusStreamParser.java b/src/jloda/util/parse/NexusStreamParser.java
index 47225f9..e064632 100644
--- a/src/jloda/util/parse/NexusStreamParser.java
+++ b/src/jloda/util/parse/NexusStreamParser.java
@@ -1,6 +1,6 @@
 /**
  * NexusStreamParser.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
@@ -19,29 +19,21 @@
 */
 package jloda.util.parse;
 
-/**
- * @version $Id: NexusStreamParser.java,v 1.16 2010-05-31 04:27:41 huson Exp $
- *
- * @author Daniel Huson
- *
- */
-
-
 import jloda.util.Basic;
 import jloda.util.Colors;
 
 import java.awt.*;
-import java.io.File;
-import java.io.IOException;
-import java.io.Reader;
-import java.io.StringReader;
+import java.io.*;
 import java.util.*;
 import java.util.List;
 
 /**
  * Parser for NexusBlock files
+ * 2003, Daniel Huson
  */
-public class NexusStreamParser extends NexusStreamTokenizer {
+public class NexusStreamParser extends NexusStreamTokenizer implements Closeable {
+    private final Reader reader; // keep a reference only so that we can close the reader...
+
     /**
      * Construct a new NexusStreamParser object
      *
@@ -49,6 +41,7 @@ public class NexusStreamParser extends NexusStreamTokenizer {
      */
     public NexusStreamParser(Reader r) {
         super(r);
+        reader = r;
     }
 
     /**
@@ -1388,7 +1381,7 @@ public class NexusStreamParser extends NexusStreamTokenizer {
         for (String legalToken : legalTokens)
             if (word.equals(legalToken))
                 return legalToken;
-        throw new IOException("line " + lineno() + ": input '" + word + "' does not match any of legal tokens: " + legalTokens);
+        throw new IOException("line " + lineno() + ": input '" + word + "' does not match any of legal tokens: " + Basic.toString(legalTokens, " "));
 
     }
 
@@ -1493,7 +1486,29 @@ public class NexusStreamParser extends NexusStreamTokenizer {
             return Integer.parseInt(value.substring(2), 16);
         else
             throw new NumberFormatException("Not hex: " + value);
+    }
 
+    public void close() throws IOException {
+        reader.close();
+    }
+
+    /**
+     * attempts to skip a block. If successful, returns the name of the block
+     *
+     * @return name of block skipped or null
+     * @throws IOException
+     */
+    public String skipBlock() throws IOException {
+        String blockName = null;
+        while (!peekMatchIgnoreCase("end;")) {
+            if (blockName == null && peekMatchIgnoreCase("begin")) {
+                matchIgnoreCase("begin");
+                blockName = getWordRespectCase();
+                matchIgnoreCase(";");
+            }
+            nextToken();
+        }
+        return blockName;
     }
 }
 
diff --git a/src/jloda/util/parse/NexusStreamTokenizer.java b/src/jloda/util/parse/NexusStreamTokenizer.java
index a3d42a4..bba89e6 100644
--- a/src/jloda/util/parse/NexusStreamTokenizer.java
+++ b/src/jloda/util/parse/NexusStreamTokenizer.java
@@ -1,6 +1,6 @@
 /**
  * NexusStreamTokenizer.java 
- * Copyright (C) 2016 Daniel H. Huson
+ * Copyright (C) 2017 Daniel H. Huson
  *
  * (Some files contain contributions from other authors, who are then mentioned separately.)
  *
diff --git a/src/jloda/util/shapes/TaxaSetShape.java b/src/jloda/util/shapes/TaxaSetShape.java
deleted file mode 100644
index 2d6374e..0000000
--- a/src/jloda/util/shapes/TaxaSetShape.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * TaxaSetShape.java 
- * Copyright (C) 2016 Daniel H. Huson
- *
- * (Some files contain contributions from other authors, who are then mentioned separately.)
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-package jloda.util.shapes;
-
-import java.awt.*;
-import java.awt.geom.AffineTransform;
-import java.awt.geom.PathIterator;
-import java.awt.geom.Point2D;
-import java.awt.geom.Rectangle2D;
-
-/**
- * Created by IntelliJ IDEA.
- * User: kloepper
- * Date: 18.02.2007
- * Time: 21:12:56
- * To change this template use File | Settings | File Templates.
- */
-public class TaxaSetShape implements Shape {
-
-    public boolean contains(double x, double y) {
-        return false;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    public boolean contains(double x, double y, double w, double h) {
-        return false;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    public boolean intersects(double x, double y, double w, double h) {
-        return false;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    public Rectangle getBounds() {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    public boolean contains(Point2D p) {
-        return false;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    public Rectangle2D getBounds2D() {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    public boolean contains(Rectangle2D r) {
-        return false;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    public boolean intersects(Rectangle2D r) {
-        return false;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    public PathIterator getPathIterator(AffineTransform at) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-
-    public PathIterator getPathIterator(AffineTransform at, double flatness) {
-        return null;  //To change body of implemented methods use File | Settings | File Templates.
-    }
-}

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



More information about the debian-med-commit mailing list