inprogress
[jalview.git] / forester / java / src / org / forester / archaeopteryx / TreePanel.java
index fa7484f..68b6376 100644 (file)
@@ -21,7 +21,7 @@
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 //
 // Contact: phylosoft @ gmail . com
 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
 //
 // Contact: phylosoft @ gmail . com
-// WWW: www.phylosoft.org/forester
+// WWW: https://sites.google.com/site/cmzmasek/home/software/forester
 
 package org.forester.archaeopteryx;
 
 
 package org.forester.archaeopteryx;
 
@@ -34,9 +34,9 @@ import java.awt.GradientPaint;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.Point;
-import java.awt.Polygon;
 import java.awt.Rectangle;
 import java.awt.RenderingHints;
 import java.awt.Rectangle;
 import java.awt.RenderingHints;
+import java.awt.Stroke;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.FocusAdapter;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.awt.event.FocusAdapter;
@@ -54,6 +54,7 @@ import java.awt.geom.Arc2D;
 import java.awt.geom.CubicCurve2D;
 import java.awt.geom.Ellipse2D;
 import java.awt.geom.Line2D;
 import java.awt.geom.CubicCurve2D;
 import java.awt.geom.Ellipse2D;
 import java.awt.geom.Line2D;
+import java.awt.geom.Path2D;
 import java.awt.geom.QuadCurve2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
 import java.awt.geom.QuadCurve2D;
 import java.awt.geom.Rectangle2D;
 import java.awt.image.BufferedImage;
@@ -76,6 +77,7 @@ import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Set;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.Set;
+import java.util.SortedSet;
 
 import javax.swing.BorderFactory;
 import javax.swing.JApplet;
 
 import javax.swing.BorderFactory;
 import javax.swing.JApplet;
@@ -89,6 +91,7 @@ import javax.swing.JTextArea;
 import javax.swing.Popup;
 import javax.swing.PopupFactory;
 
 import javax.swing.Popup;
 import javax.swing.PopupFactory;
 
+import org.forester.archaeopteryx.Configuration.EXT_NODE_DATA_RETURN_ON;
 import org.forester.archaeopteryx.ControlPanel.NodeClickAction;
 import org.forester.archaeopteryx.Options.CLADOGRAM_TYPE;
 import org.forester.archaeopteryx.Options.NODE_LABEL_DIRECTION;
 import org.forester.archaeopteryx.ControlPanel.NodeClickAction;
 import org.forester.archaeopteryx.Options.CLADOGRAM_TYPE;
 import org.forester.archaeopteryx.Options.NODE_LABEL_DIRECTION;
@@ -98,18 +101,20 @@ import org.forester.archaeopteryx.phylogeny.data.RenderableVector;
 import org.forester.archaeopteryx.tools.Blast;
 import org.forester.archaeopteryx.tools.ImageLoader;
 import org.forester.io.parsers.phyloxml.PhyloXmlUtil;
 import org.forester.archaeopteryx.tools.Blast;
 import org.forester.archaeopteryx.tools.ImageLoader;
 import org.forester.io.parsers.phyloxml.PhyloXmlUtil;
+import org.forester.io.writers.SequenceWriter;
 import org.forester.phylogeny.Phylogeny;
 import org.forester.phylogeny.PhylogenyMethods;
 import org.forester.phylogeny.PhylogenyMethods.DESCENDANT_SORT_PRIORITY;
 import org.forester.phylogeny.PhylogenyNode;
 import org.forester.phylogeny.Phylogeny;
 import org.forester.phylogeny.PhylogenyMethods;
 import org.forester.phylogeny.PhylogenyMethods.DESCENDANT_SORT_PRIORITY;
 import org.forester.phylogeny.PhylogenyNode;
+import org.forester.phylogeny.data.Accession;
 import org.forester.phylogeny.data.Annotation;
 import org.forester.phylogeny.data.BranchColor;
 import org.forester.phylogeny.data.Confidence;
 import org.forester.phylogeny.data.Event;
 import org.forester.phylogeny.data.Annotation;
 import org.forester.phylogeny.data.BranchColor;
 import org.forester.phylogeny.data.Confidence;
 import org.forester.phylogeny.data.Event;
-import org.forester.phylogeny.data.NodeVisualization;
-import org.forester.phylogeny.data.NodeVisualization.NodeFill;
-import org.forester.phylogeny.data.NodeVisualization.NodeShape;
-import org.forester.phylogeny.data.PhylogenyData;
+import org.forester.phylogeny.data.NodeData.NODE_DATA;
+import org.forester.phylogeny.data.NodeVisualData;
+import org.forester.phylogeny.data.NodeVisualData.NodeFill;
+import org.forester.phylogeny.data.NodeVisualData.NodeShape;
 import org.forester.phylogeny.data.PhylogenyDataUtil;
 import org.forester.phylogeny.data.PropertiesMap;
 import org.forester.phylogeny.data.Property;
 import org.forester.phylogeny.data.PhylogenyDataUtil;
 import org.forester.phylogeny.data.PropertiesMap;
 import org.forester.phylogeny.data.Property;
@@ -123,118 +128,127 @@ import org.forester.util.BasicDescriptiveStatistics;
 import org.forester.util.DescriptiveStatistics;
 import org.forester.util.ForesterConstants;
 import org.forester.util.ForesterUtil;
 import org.forester.util.DescriptiveStatistics;
 import org.forester.util.ForesterConstants;
 import org.forester.util.ForesterUtil;
+import org.forester.util.SequenceAccessionTools;
+import org.forester.util.TaxonomyUtil;
 
 public final class TreePanel extends JPanel implements ActionListener, MouseWheelListener, Printable {
 
 
 public final class TreePanel extends JPanel implements ActionListener, MouseWheelListener, Printable {
 
-    private static final float              PI                                = ( float ) ( Math.PI );
-    private static final double             TWO_PI                            = 2 * Math.PI;
-    private static final float              ONEHALF_PI                        = ( float ) ( 1.5 * Math.PI );
-    private static final float              HALF_PI                           = ( float ) ( Math.PI / 2.0 );
-    private static final float              ANGLE_ROTATION_UNIT               = ( float ) ( Math.PI / 32 );
-    private static final short              OV_BORDER                         = 10;
-    final static Cursor                     CUT_CURSOR                        = Cursor.getPredefinedCursor( Cursor.CROSSHAIR_CURSOR );
-    final static Cursor                     MOVE_CURSOR                       = Cursor.getPredefinedCursor( Cursor.MOVE_CURSOR );
-    final static Cursor                     ARROW_CURSOR                      = Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR );
-    final static Cursor                     HAND_CURSOR                       = Cursor.getPredefinedCursor( Cursor.HAND_CURSOR );
-    final static Cursor                     WAIT_CURSOR                       = Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR );
-    private final static long               serialVersionUID                  = -978349745916505029L;
-    private final static int                EURO_D                            = 10;
-    private final static String             NODE_POPMENU_NODE_CLIENT_PROPERTY = "node";
-    private final static int                MIN_ROOT_LENGTH                   = 3;
-    private final static int                MAX_SUBTREES                      = 100;
-    private final static int                MAX_NODE_FRAMES                   = 10;
-    private final static int                MOVE                              = 20;
-    private final static NumberFormat       FORMATTER_CONFIDENCE;
-    private final static NumberFormat       FORMATTER_BRANCH_LENGTH;
-    private final static int                WIGGLE                            = 2;
-    private final static int                LIMIT_FOR_HQ_RENDERING            = 1000;
-    private final static int                CONFIDENCE_LEFT_MARGIN            = 4;
-    // TODO "rendering_hints" was static before. Need to make sure everything is OK with it not
-    // being static anymore (02/20/2009).
-    private final RenderingHints            _rendering_hints                  = new RenderingHints( RenderingHints.KEY_RENDERING,
-                                                                                                    RenderingHints.VALUE_RENDER_DEFAULT );
-    private File                            _treefile                         = null;
-    private Configuration                   _configuration                    = null;
-    private final NodeFrame[]               _node_frames                      = new NodeFrame[ TreePanel.MAX_NODE_FRAMES ];
-    private int                             _node_frame_index                 = 0;
-    private Phylogeny                       _phylogeny                        = null;
-    private final Phylogeny[]               _sub_phylogenies                  = new Phylogeny[ TreePanel.MAX_SUBTREES ];
-    private final PhylogenyNode[]           _sub_phylogenies_temp_roots       = new PhylogenyNode[ TreePanel.MAX_SUBTREES ];
-    private int                             _subtree_index                    = 0;
-    private MainPanel                       _main_panel                       = null;
-    private Set<Integer>                    _found_nodes                      = null;
-    private PhylogenyNode                   _highlight_node                   = null;
-    private JPopupMenu                      _node_popup_menu                  = null;
-    private JMenuItem                       _node_popup_menu_items[]          = null;
-    private int                             _longest_ext_node_info            = 0;
-    private float                           _x_correction_factor              = 0.0f;
-    private float                           _ov_x_correction_factor           = 0.0f;
-    private float                           _x_distance                       = 0.0f;
-    private float                           _y_distance                       = 0.0f;
-    private PHYLOGENY_GRAPHICS_TYPE         _graphics_type                    = PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR;
-    private double                          _domain_structure_width           = Constants.DOMAIN_STRUCTURE_DEFAULT_WIDTH;
-    private int                             _domain_structure_e_value_thr_exp = Constants.DOMAIN_STRUCTURE_E_VALUE_THR_DEFAULT_EXP;
-    private float                           _last_drag_point_x                = 0;
-    private float                           _last_drag_point_y                = 0;
-    private ControlPanel                    _control_panel                    = null;
-    private int                             _external_node_index              = 0;
-    private final Polygon                   _polygon                          = new Polygon();
-    private final StringBuilder             _sb                               = new StringBuilder();
-    private JColorChooser                   _color_chooser                    = null;
-    private double                          _scale_distance                   = 0.0;
-    private String                          _scale_label                      = null;
-    private final CubicCurve2D              _cubic_curve                      = new CubicCurve2D.Float();
-    private final QuadCurve2D               _quad_curve                       = new QuadCurve2D.Float();
-    private final Line2D                    _line                             = new Line2D.Float();
-    private final Ellipse2D                 _ellipse                          = new Ellipse2D.Float();
-    private final Rectangle2D               _rectangle                        = new Rectangle2D.Float();
-    private Options                         _options                          = null;
-    private float                           _ov_max_width                     = 0;
-    private float                           _ov_max_height                    = 0;
-    private int                             _ov_x_position                    = 0;
-    private int                             _ov_y_position                    = 0;
-    private int                             _ov_y_start                       = 0;
-    private float                           _ov_y_distance                    = 0;
-    private float                           _ov_x_distance                    = 0;
-    private boolean                         _ov_on                            = false;
-    private double                          _urt_starting_angle               = ( float ) ( Math.PI / 2 );
-    private float                           _urt_factor                       = 1;
-    private float                           _urt_factor_ov                    = 1;
-    private final boolean                   _phy_has_branch_lengths;
-    private final Rectangle2D               _ov_rectangle                     = new Rectangle2D.Float();
-    private boolean                         _in_ov_rect                       = false;
-    private boolean                         _in_ov                            = false;
-    private final Rectangle                 _ov_virtual_rectangle             = new Rectangle();
-    final private static double             _180_OVER_PI                      = 180.0 / Math.PI;
-    private static final float              ROUNDED_D                         = 8;
-    private int                             _circ_max_depth;
-    private PhylogenyNode                   _root;
-    final private Arc2D                     _arc                              = new Arc2D.Double();
-    final private HashMap<Integer, Double>  _urt_nodeid_angle_map             = new HashMap<Integer, Double>();
-    final private HashMap<Integer, Integer> _urt_nodeid_index_map             = new HashMap<Integer, Integer>();
-    final private Set<Integer>              _collapsed_external_nodeid_set    = new HashSet<Integer>();
-    HashMap<Integer, Short>                 _nodeid_dist_to_leaf              = new HashMap<Integer, Short>();
-    private AffineTransform                 _at;
-    private double                          _max_distance_to_root             = -1;
-    private int                             _dynamic_hiding_factor            = 0;
-    private boolean                         _edited                           = false;
-    private Popup                           _node_desc_popup;
-    private JTextArea                       _rollover_popup;
-    // private final int                       _box_size;
-    // private final int                       _half_box_size;
-    //private final short                     _skip_counter                     = 0;
-    private final StringBuffer              _popup_buffer                     = new StringBuffer();
-    final private static Font               POPUP_FONT                        = new Font( Configuration.getDefaultFontFamilyName(),
-                                                                                          Font.PLAIN,
-                                                                                          12 );
-    private static final boolean            DRAW_MEAN_COUNTS                  = true;                                                     //TODO remove me later
-    private Sequence                        _query_sequence                   = null;
-    private final FontRenderContext         _frc                              = new FontRenderContext( null,
-                                                                                                       false,
-                                                                                                       false );
+    final static Cursor                  ARROW_CURSOR                                       = Cursor.getPredefinedCursor( Cursor.DEFAULT_CURSOR );
+    final static Cursor                  CUT_CURSOR                                         = Cursor.getPredefinedCursor( Cursor.CROSSHAIR_CURSOR );
+    final static Cursor                  HAND_CURSOR                                        = Cursor.getPredefinedCursor( Cursor.HAND_CURSOR );
+    final static Cursor                  MOVE_CURSOR                                        = Cursor.getPredefinedCursor( Cursor.MOVE_CURSOR );
+    final static Cursor                  WAIT_CURSOR                                        = Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR );
+    final private static double          _180_OVER_PI                                       = 180.0 / Math.PI;
+    private static final float           ANGLE_ROTATION_UNIT                                = ( float ) ( Math.PI / 32 );
+    private final static int             CONFIDENCE_LEFT_MARGIN                             = 4;
+    private final static int             EURO_D                                             = 10;
+    private final static NumberFormat    FORMATTER_BRANCH_LENGTH;
+    private final static NumberFormat    FORMATTER_CONFIDENCE;
+    private static final float           HALF_PI                                            = ( float ) ( Math.PI / 2.0 );
+    private final static int             LIMIT_FOR_HQ_RENDERING                             = 2000;
+    private final static int             MAX_NODE_FRAMES                                    = 10;
+    private final static int             MAX_SUBTREES                                       = 100;
+    private final static int             MIN_ROOT_LENGTH                                    = 3;
+    private final static int             MOVE                                               = 20;
+    private final static String          NODE_POPMENU_NODE_CLIENT_PROPERTY                  = "node";
+    private static final float           ONEHALF_PI                                         = ( float ) ( 1.5 * Math.PI );
+    private static final short           OV_BORDER                                          = 10;
+    private static final float           PI                                                 = ( float ) ( Math.PI );
+    final private static Font            POPUP_FONT                                         = new Font( Configuration.getDefaultFontFamilyName(),
+                                                                                                        Font.PLAIN,
+                                                                                                        12 );
+    private static final float           ROUNDED_D                                          = 8;
+    private final static long            serialVersionUID                                   = -978349745916505029L;
+    private static final BasicStroke     STROKE_005                                         = new BasicStroke( 0.05f );
+    private static final BasicStroke     STROKE_01                                          = new BasicStroke( 0.1f );
+    private static final BasicStroke     STROKE_025                                         = new BasicStroke( 0.25f );
+    private static final BasicStroke     STROKE_05                                          = new BasicStroke( 0.5f );
+    private static final BasicStroke     STROKE_075                                         = new BasicStroke( 0.75f );
+    private static final BasicStroke     STROKE_1                                           = new BasicStroke( 1f );
+    private static final BasicStroke     STROKE_2                                           = new BasicStroke( 2f );
+    private static final double          TWO_PI                                             = 2 * Math.PI;
+    private final static int             WIGGLE                                             = 2;
+    private final static double          OVERVIEW_FOUND_NODE_BOX_SIZE                       = 2;
+    private final static double          OVERVIEW_FOUND_NODE_BOX_SIZE_HALF                  = 1;
+    HashMap<Long, Short>                 _nodeid_dist_to_leaf                               = new HashMap<Long, Short>();
+    final private Arc2D                  _arc                                               = new Arc2D.Double();
+    private AffineTransform              _at;
+    private int                          _circ_max_depth;
+    final private Set<Long>              _collapsed_external_nodeid_set                     = new HashSet<Long>();
+    private JColorChooser                _color_chooser                                     = null;
+    private Configuration                _configuration                                     = null;
+    private ControlPanel                 _control_panel                                     = null;
+    private final CubicCurve2D           _cubic_curve                                       = new CubicCurve2D.Float();
+    private Set<Long>                    _current_external_nodes                            = null;
+    private StringBuilder                _current_external_nodes_data_buffer                = new StringBuilder();
+    private int                          _current_external_nodes_data_buffer_change_counter = 0;
+    private int                          _domain_structure_e_value_thr_exp                  = Constants.DOMAIN_STRUCTURE_E_VALUE_THR_DEFAULT_EXP;
+    private double                       _domain_structure_width                            = Constants.DOMAIN_STRUCTURE_DEFAULT_WIDTH;
+    private int                          _dynamic_hiding_factor                             = 0;
+    private boolean                      _edited                                            = false;
+    private final Ellipse2D              _ellipse                                           = new Ellipse2D.Float();
+    private int                          _external_node_index                               = 0;
+    private Set<Long>                    _found_nodes_0                                     = null;
+    private Set<Long>                    _found_nodes_1                                     = null;
+    private final FontRenderContext      _frc                                               = new FontRenderContext( null,
+                                                                                                                     false,
+                                                                                                                     false );
+    private PHYLOGENY_GRAPHICS_TYPE      _graphics_type                                     = PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR;
+    private PhylogenyNode                _highlight_node                                    = null;
+    private boolean                      _in_ov                                             = false;
+    private boolean                      _in_ov_rect                                        = false;
+    private float                        _last_drag_point_x                                 = 0;
+    private float                        _last_drag_point_y                                 = 0;
+    private final Line2D                 _line                                              = new Line2D.Float();
+    private int                          _longest_ext_node_info                             = 0;
+    private MainPanel                    _main_panel                                        = null;
+    private double                       _max_distance_to_root                              = -1;
+    private Popup                        _node_desc_popup;
+    private int                          _node_frame_index                                  = 0;
+    private final NodeFrame[]            _node_frames                                       = new NodeFrame[ TreePanel.MAX_NODE_FRAMES ];
+    private JPopupMenu                   _node_popup_menu                                   = null;
+    private JMenuItem                    _node_popup_menu_items[]                           = null;
+    private PhylogenyNode[]              _nodes_in_preorder                                 = null;
+    private Options                      _options                                           = null;
+    private float                        _ov_max_height                                     = 0;
+    private float                        _ov_max_width                                      = 0;
+    private boolean                      _ov_on                                             = false;
+    private final Rectangle2D            _ov_rectangle                                      = new Rectangle2D.Float();
+    private final Rectangle              _ov_virtual_rectangle                              = new Rectangle();
+    private float                        _ov_x_correction_factor                            = 0.0f;
+    private float                        _ov_x_distance                                     = 0;
+    private int                          _ov_x_position                                     = 0;
+    private float                        _ov_y_distance                                     = 0;
+    private int                          _ov_y_position                                     = 0;
+    private int                          _ov_y_start                                        = 0;
+    private final boolean                _phy_has_branch_lengths;
+    private Phylogeny                    _phylogeny                                         = null;
+    private final Path2D.Float           _polygon                                           = new Path2D.Float();
+    private final StringBuffer           _popup_buffer                                      = new StringBuffer();
+    private final QuadCurve2D            _quad_curve                                        = new QuadCurve2D.Float();
+    private Sequence                     _query_sequence                                    = null;
+    private final Rectangle2D            _rectangle                                         = new Rectangle2D.Float();
+    private final RenderingHints         _rendering_hints                                   = new RenderingHints( RenderingHints.KEY_RENDERING,
+                                                                                                                  RenderingHints.VALUE_RENDER_DEFAULT );
+    private JTextArea                    _rollover_popup;
+    private PhylogenyNode                _root;
+    private final StringBuilder          _sb                                                = new StringBuilder();
+    private double                       _scale_distance                                    = 0.0;
+    private String                       _scale_label                                       = null;
     // expression values menu:
     // expression values menu:
-    private DescriptiveStatistics           _statistics_for_vector_data;
-    private PhylogenyNode[]                 _nodes_in_preorder                = null;
+    private DescriptiveStatistics        _statistics_for_vector_data;
+    private final Phylogeny[]            _sub_phylogenies                                   = new Phylogeny[ TreePanel.MAX_SUBTREES ];
+    private final PhylogenyNode[]        _sub_phylogenies_temp_roots                        = new PhylogenyNode[ TreePanel.MAX_SUBTREES ];
+    private int                          _subtree_index                                     = 0;
+    private File                         _treefile                                          = null;
+    private float                        _urt_factor                                        = 1;
+    private float                        _urt_factor_ov                                     = 1;
+    final private HashMap<Long, Double>  _urt_nodeid_angle_map                              = new HashMap<Long, Double>();
+    final private HashMap<Long, Integer> _urt_nodeid_index_map                              = new HashMap<Long, Integer>();
+    private double                       _urt_starting_angle                                = ( float ) ( Math.PI / 2 );
+    private float                        _x_correction_factor                               = 0.0f;
+    private float                        _x_distance                                        = 0.0f;
+    private float                        _y_distance                                        = 0.0f;
     //  private Image                           offscreenImage;
     //  private Graphics                        offscreenGraphics;
     //  private Dimension                       offscreenDimension;
     //  private Image                           offscreenImage;
     //  private Graphics                        offscreenGraphics;
     //  private Dimension                       offscreenDimension;
@@ -286,65 +300,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 .getNumberOfDigitsAfterCommaForBranchLengthValues() );
     }
 
                 .getNumberOfDigitsAfterCommaForBranchLengthValues() );
     }
 
-    public void checkForVectorProperties( final Phylogeny phy ) {
-        final DescriptiveStatistics stats = new BasicDescriptiveStatistics();
-        for( final PhylogenyNodeIterator iter = phy.iteratorPreorder(); iter.hasNext(); ) {
-            final PhylogenyNode node = iter.next();
-            if ( node.getNodeData().getProperties() != null ) {
-                final PropertiesMap pm = node.getNodeData().getProperties();
-                final double[] vector = new double[ pm.getProperties().size() ];
-                int counter = 0;
-                for( final String ref : pm.getProperties().keySet() ) {
-                    if ( ref.startsWith( PhyloXmlUtil.VECTOR_PROPERTY_REF ) ) {
-                        final Property p = pm.getProperty( ref );
-                        final String value_str = p.getValue();
-                        final String index_str = ref
-                                .substring( PhyloXmlUtil.VECTOR_PROPERTY_REF.length(), ref.length() );
-                        double d = -100;
-                        try {
-                            d = Double.parseDouble( value_str );
-                        }
-                        catch ( final NumberFormatException e ) {
-                            JOptionPane.showMessageDialog( this, "Could not parse \"" + value_str
-                                    + "\" into a decimal value", "Problem with Vector Data", JOptionPane.ERROR_MESSAGE );
-                            return;
-                        }
-                        int i = -1;
-                        try {
-                            i = Integer.parseInt( index_str );
-                        }
-                        catch ( final NumberFormatException e ) {
-                            JOptionPane.showMessageDialog( this,
-                                                           "Could not parse \"" + index_str
-                                                                   + "\" into index for vector data",
-                                                           "Problem with Vector Data",
-                                                           JOptionPane.ERROR_MESSAGE );
-                            return;
-                        }
-                        if ( i < 0 ) {
-                            JOptionPane.showMessageDialog( this,
-                                                           "Attempt to use negative index for vector data",
-                                                           "Problem with Vector Data",
-                                                           JOptionPane.ERROR_MESSAGE );
-                            return;
-                        }
-                        vector[ i ] = d;
-                        ++counter;
-                        stats.addValue( d );
-                    }
-                }
-                final List<Double> vector_l = new ArrayList<Double>( counter );
-                for( int i = 0; i < counter; ++i ) {
-                    vector_l.add( vector[ i ] );
-                }
-                node.getNodeData().setVector( vector_l );
-            }
-        }
-        if ( stats.getN() > 0 ) {
-            _statistics_for_vector_data = stats;
-        }
-    }
-
+    @Override
     final public void actionPerformed( final ActionEvent e ) {
         boolean done = false;
         final JMenuItem node_popup_menu_item = ( JMenuItem ) e.getSource();
     final public void actionPerformed( final ActionEvent e ) {
         boolean done = false;
         final JMenuItem node_popup_menu_item = ( JMenuItem ) e.getSource();
@@ -364,180 +320,271 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         requestFocusInWindow();
     }
 
         requestFocusInWindow();
     }
 
-    final private void addEmptyNode( final PhylogenyNode node ) {
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            errorMessageNoCutCopyPasteInUnrootedDisplay();
-            return;
-        }
-        final String label = getASimpleTextRepresentationOfANode( node );
-        String msg = "";
-        if ( ForesterUtil.isEmpty( label ) ) {
-            msg = "How to add the new, empty node?";
-        }
-        else {
-            msg = "How to add the new, empty node to node" + label + "?";
-        }
-        final Object[] options = { "As sibling", "As descendant", "Cancel" };
-        final int r = JOptionPane.showOptionDialog( this,
-                                                    msg,
-                                                    "Addition of Empty New Node",
-                                                    JOptionPane.CLOSED_OPTION,
-                                                    JOptionPane.QUESTION_MESSAGE,
-                                                    null,
-                                                    options,
-                                                    options[ 2 ] );
-        boolean add_as_sibling = true;
-        if ( r == 1 ) {
-            add_as_sibling = false;
-        }
-        else if ( r != 0 ) {
-            return;
-        }
-        final Phylogeny phy = new Phylogeny();
-        phy.setRoot( new PhylogenyNode() );
-        phy.setRooted( true );
-        if ( add_as_sibling ) {
-            if ( node.isRoot() ) {
-                JOptionPane.showMessageDialog( this,
-                                               "Cannot add sibling to root",
-                                               "Attempt to add sibling to root",
-                                               JOptionPane.ERROR_MESSAGE );
-                return;
-            }
-            phy.addAsSibling( node );
-        }
-        else {
-            phy.addAsChild( node );
-        }
-        setNodeInPreorderToNull();
-        _phylogeny.externalNodesHaveChanged();
-        _phylogeny.hashIDs();
-        _phylogeny.recalculateNumberOfExternalDescendants( true );
-        resetNodeIdToDistToLeafMap();
-        setEdited( true );
-        repaint();
+    public synchronized Hashtable<String, BufferedImage> getImageMap() {
+        return getMainPanel().getImageMap();
     }
 
     }
 
-    final private void assignGraphicsForBranchWithColorForParentBranch( final PhylogenyNode node,
-                                                                        final boolean is_vertical,
-                                                                        final Graphics g,
-                                                                        final boolean to_pdf,
-                                                                        final boolean to_graphics_file ) {
-        final NodeClickAction action = _control_panel.getActionWhenNodeClicked();
-        if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
-            g.setColor( Color.BLACK );
-        }
-        else if ( ( ( action == NodeClickAction.COPY_SUBTREE ) || ( action == NodeClickAction.CUT_SUBTREE )
-                || ( action == NodeClickAction.DELETE_NODE_OR_SUBTREE ) || ( action == NodeClickAction.PASTE_SUBTREE ) || ( action == NodeClickAction.ADD_NEW_NODE ) )
-                && ( getCutOrCopiedTree() != null )
-                && ( getCopiedAndPastedNodes() != null )
-                && !to_pdf
-                && !to_graphics_file && getCopiedAndPastedNodes().contains( node.getId() ) ) {
-            g.setColor( getTreeColorSet().getFoundColor() );
-        }
-        else if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
-            g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
-        }
-        else if ( to_pdf ) {
-            g.setColor( getTreeColorSet().getBranchColorForPdf() );
-        }
-        else {
-            g.setColor( getTreeColorSet().getBranchColor() );
-        }
+    final public MainPanel getMainPanel() {
+        return _main_panel;
     }
 
     }
 
-    final Color getGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node ) {
-        if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
-            return ( PhylogenyMethods.getBranchColorValue( node ) );
-        }
-        else {
-            return ( getTreeColorSet().getBranchColor() );
-        }
+    /**
+     * Get a pointer to the phylogeny 
+     * 
+     * @return a pointer to the phylogeny
+     */
+    public final Phylogeny getPhylogeny() {
+        return _phylogeny;
     }
 
     }
 
-    final private void blast( final PhylogenyNode node ) {
-        if ( !isCanBlast( node ) ) {
-            JOptionPane.showMessageDialog( this,
-                                           "No sequence information present",
-                                           "Cannot Blast",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
+    @Override
+    final public void mouseWheelMoved( final MouseWheelEvent e ) {
+        final int notches = e.getWheelRotation();
+        if ( inOvVirtualRectangle( e ) ) {
+            if ( !isInOvRect() ) {
+                setInOvRect( true );
+                repaint();
+            }
         }
         }
-        if ( node.getNodeData().isHasSequence() ) {
-            final String query = Blast.obtainQueryForBlast( node );
-            boolean nucleotide = false;
-            if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getType() ) ) {
-                if ( !node.getNodeData().getSequence().getType().toLowerCase().equals( PhyloXmlUtil.SEQ_TYPE_PROTEIN ) ) {
-                    nucleotide = true;
-                }
+        else {
+            if ( isInOvRect() ) {
+                setInOvRect( false );
+                repaint();
+            }
+        }
+        if ( e.isControlDown() ) {
+            if ( notches < 0 ) {
+                getTreeFontSet().increaseFontSize();
+                getControlPanel().displayedPhylogenyMightHaveChanged( true );
             }
             }
-            else if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) {
-                nucleotide = !ForesterUtil.seqIsLikelyToBeAa( node.getNodeData().getSequence().getMolecularSequence() );
+            else {
+                getTreeFontSet().decreaseFontSize( 1, false );
+                getControlPanel().displayedPhylogenyMightHaveChanged( true );
             }
             }
-            if ( !ForesterUtil.isEmpty( query ) ) {
-                JApplet applet = null;
-                if ( isApplet() ) {
-                    applet = obtainApplet();
-                }
-                try {
-                    Blast.openNcbiBlastWeb( query, nucleotide, applet, this );
+        }
+        else if ( e.isShiftDown() ) {
+            if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
+                    || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
+                if ( notches < 0 ) {
+                    for( int i = 0; i < ( -notches ); ++i ) {
+                        setStartingAngle( ( getStartingAngle() % TWO_PI ) + ANGLE_ROTATION_UNIT );
+                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                    }
                 }
                 }
-                catch ( final Exception e ) {
-                    e.printStackTrace();
+                else {
+                    for( int i = 0; i < notches; ++i ) {
+                        setStartingAngle( ( getStartingAngle() % TWO_PI ) - ANGLE_ROTATION_UNIT );
+                        if ( getStartingAngle() < 0 ) {
+                            setStartingAngle( TWO_PI + getStartingAngle() );
+                        }
+                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                    }
                 }
                 }
-                if ( Constants.ALLOW_DDBJ_BLAST ) {
-                    try {
-                        System.out.println( "trying: " + query );
-                        final Blast s = new Blast();
-                        s.ddbjBlast( query );
+            }
+            else {
+                if ( notches < 0 ) {
+                    for( int i = 0; i < ( -notches ); ++i ) {
+                        getControlPanel().zoomInY( Constants.WHEEL_ZOOM_IN_FACTOR );
+                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
                     }
                     }
-                    catch ( final Exception e ) {
-                        e.printStackTrace();
+                }
+                else {
+                    for( int i = 0; i < notches; ++i ) {
+                        getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
+                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
                     }
                 }
             }
         }
                     }
                 }
             }
         }
-    }
-
-    final void calcMaxDepth() {
-        if ( _phylogeny != null ) {
-            _circ_max_depth = PhylogenyMethods.calculateMaxDepth( _phylogeny );
+        else {
+            if ( notches < 0 ) {
+                for( int i = 0; i < ( -notches ); ++i ) {
+                    getControlPanel().zoomInX( Constants.WHEEL_ZOOM_IN_FACTOR,
+                                               Constants.WHEEL_ZOOM_IN_X_CORRECTION_FACTOR );
+                    getControlPanel().zoomInY( Constants.WHEEL_ZOOM_IN_FACTOR );
+                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                }
+            }
+            else {
+                for( int i = 0; i < notches; ++i ) {
+                    getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
+                    getControlPanel().zoomOutX( Constants.WHEEL_ZOOM_OUT_FACTOR,
+                                                Constants.WHEEL_ZOOM_OUT_X_CORRECTION_FACTOR );
+                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                }
+            }
         }
         }
+        requestFocus();
+        requestFocusInWindow();
+        requestFocus();
     }
 
     }
 
-    /**
-     * Calculate the length of the distance between the given node and its
-     * parent.
-     * 
-     * @param node
-     * @param ext_node_x
-     * @factor
-     * @return the distance value
-     */
-    final private float calculateBranchLengthToParent( final PhylogenyNode node, final float factor ) {
-        if ( getControlPanel().isDrawPhylogram() ) {
-            if ( node.getDistanceToParent() < 0.0 ) {
-                return 0.0f;
-            }
-            return ( float ) ( getXcorrectionFactor() * node.getDistanceToParent() );
+    @Override
+    final public void paintComponent( final Graphics g ) {
+        // Dimension currentSize = getSize();
+        //  if ( offscreenImage == null || !currentSize.equals( offscreenDimension ) ) {
+        // call the 'java.awt.Component.createImage(...)' method to get an
+        // image
+        //   offscreenImage = createImage( currentSize.width, currentSize.height );
+        //  offscreenGraphics = offscreenImage.getGraphics();
+        //  offscreenDimension = currentSize;
+        // }
+        // super.paintComponent( g ); //why?
+        //final Graphics2D g2d = ( Graphics2D ) offscreenGraphics;
+        final Graphics2D g2d = ( Graphics2D ) g;
+        g2d.setRenderingHints( _rendering_hints );
+        paintPhylogeny( g2d, false, false, 0, 0, 0, 0 );
+        //g.drawImage( offscreenImage, 0, 0, this );
+    }
+
+    @Override
+    final public int print( final Graphics g, final PageFormat page_format, final int page_index )
+            throws PrinterException {
+        if ( page_index > 0 ) {
+            return ( NO_SUCH_PAGE );
         }
         else {
         }
         else {
-            if ( ( factor == 0 ) || isNonLinedUpCladogram() ) {
-                return getXdistance();
-            }
-            return getXdistance() * factor;
+            final Graphics2D g2d = ( Graphics2D ) g;
+            g2d.translate( page_format.getImageableX(), page_format.getImageableY() );
+            // Turn off double buffering !?
+            paintPhylogeny( g2d, true, false, 0, 0, 0, 0 );
+            // Turn double buffering back on !?
+            return ( PAGE_EXISTS );
         }
     }
 
         }
     }
 
-    final private Color calculateColorForAnnotation( final PhylogenyData ann ) {
-        Color c = getTreeColorSet().getAnnotationColor();
-        if ( getControlPanel().isColorAccordingToAnnotation() && ( getControlPanel().getAnnotationColors() != null ) ) {
-            c = getControlPanel().getAnnotationColors().get( ann.asSimpleText().toString() );
-            if ( c == null ) {
-                c = getTreeColorSet().getAnnotationColor();
+    public final void setEdited( final boolean edited ) {
+        _edited = edited;
+    }
+
+    public synchronized void setImageMap( final Hashtable<String, BufferedImage> image_map ) {
+        getMainPanel().setImageMap( image_map );
+    }
+
+    /**
+     * Set a phylogeny tree.
+     * 
+     * @param t
+     *            an instance of a Phylogeny
+     */
+    public final void setTree( final Phylogeny t ) {
+        setNodeInPreorderToNull();
+        _phylogeny = t;
+    }
+
+    public final void setWaitCursor() {
+        setCursor( WAIT_CURSOR );
+        repaint();
+    }
+
+    @Override
+    public void update( final Graphics g ) {
+        paint( g );
+    }
+
+    final void calcMaxDepth() {
+        if ( _phylogeny != null ) {
+            _circ_max_depth = PhylogenyMethods.calculateMaxDepth( _phylogeny );
+        }
+    }
+
+    /**
+     * Set parameters for printing the displayed tree
+     * 
+     */
+    final void calcParametersForPainting( final int x, final int y, final boolean recalc_longest_ext_node_info ) {
+        // updateStyle(); not needed?
+        if ( ( _phylogeny != null ) && !_phylogeny.isEmpty() ) {
+            initNodeData();
+            if ( recalc_longest_ext_node_info ) {
+                calculateLongestExtNodeInfo();
+                if ( getOptions().isAllowFontSizeChange() ) {
+                    if ( ( getLongestExtNodeInfo() > ( x * 0.6 ) )
+                            && ( getTreeFontSet().getLargeFont().getSize() > 2 + TreeFontSet.FONT_SIZE_CHANGE_STEP ) ) {
+                        while ( ( getLongestExtNodeInfo() > ( x * 0.7 ) )
+                                && ( getTreeFontSet().getLargeFont().getSize() > 2 ) ) {
+                            getMainPanel().getTreeFontSet().decreaseFontSize( getConfiguration().getMinBaseFontSize(),
+                                                                              true );
+                            calculateLongestExtNodeInfo();
+                        }
+                    }
+                    else {
+                        while ( ( getLongestExtNodeInfo() < ( x * 0.6 ) )
+                                && ( getTreeFontSet().getLargeFont().getSize() <= getTreeFontSet().getLargeFontMemory()
+                                        .getSize() - TreeFontSet.FONT_SIZE_CHANGE_STEP ) ) {
+                            getMainPanel().getTreeFontSet().increaseFontSize();
+                            calculateLongestExtNodeInfo();
+                        }
+                    }
+                }
+            }
+            int ext_nodes = _phylogeny.getRoot().getNumberOfExternalNodes();
+            final int max_depth = PhylogenyMethods.calculateMaxDepth( _phylogeny );
+            if ( ext_nodes == 1 ) {
+                ext_nodes = max_depth;
+                if ( ext_nodes < 1 ) {
+                    ext_nodes = 1;
+                }
+            }
+            updateOvSizes();
+            float xdist = 0;
+            float ov_xdist = 0;
+            if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) {
+                xdist = ( float ) ( ( x - getLongestExtNodeInfo() - TreePanel.MOVE ) / ( ext_nodes + 3.0 ) );
+                ov_xdist = ( float ) ( getOvMaxWidth() / ( ext_nodes + 3.0 ) );
+            }
+            else {
+                xdist = ( ( x - getLongestExtNodeInfo() - TreePanel.MOVE ) / ( max_depth + 1 ) );
+                ov_xdist = ( getOvMaxWidth() / ( max_depth + 1 ) );
+            }
+            float ydist = ( float ) ( ( y - TreePanel.MOVE ) / ( ext_nodes * 2.0 ) );
+            if ( xdist < 0.0 ) {
+                xdist = 0.0f;
+            }
+            if ( ov_xdist < 0.0 ) {
+                ov_xdist = 0.0f;
+            }
+            if ( ydist < 0.0 ) {
+                ydist = 0.0f;
+            }
+            setXdistance( xdist );
+            setYdistance( ydist );
+            setOvXDistance( ov_xdist );
+            final double height = _phylogeny.getHeight();
+            if ( height > 0 ) {
+                final float corr = ( float ) ( ( x - TreePanel.MOVE - getLongestExtNodeInfo() - getXdistance() ) / height );
+                setXcorrectionFactor( corr > 0 ? corr : 0 );
+                final float ov_corr = ( float ) ( ( getOvMaxWidth() - getOvXDistance() ) / height );
+                setOvXcorrectionFactor( ov_corr > 0 ? ov_corr : 0 );
+            }
+            else {
+                setXcorrectionFactor( 0 );
+                setOvXcorrectionFactor( 0 );
             }
             }
+            _circ_max_depth = max_depth;
+            setUpUrtFactor();
+            //
+            if ( getOptions().isAllowFontSizeChange() ) {
+                if ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
+                        && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
+                    //                int dynamic_hiding_factor = calcDynamicHidingFactor();
+                    //                if ( dynamic_hiding_factor > 1 ) {
+                    //                    while ( dynamic_hiding_factor > 1
+                    //                            && getTreeFontSet()._fm_large.getHeight() > TreeFontSet.SMALL_FONTS_BASE ) {
+                    //                        getTreeFontSet().decreaseFontSize( 1, true );
+                    //                        dynamic_hiding_factor = calcDynamicHidingFactor();
+                    //                    }
+                    //                }
+                    //                else if ( getTreeFontSet().isDecreasedSizeBySystem() ) {
+                    //                    while ( dynamic_hiding_factor < 1 && getTreeFontSet()._fm_large.getHeight() < 12 ) {
+                    //                        getTreeFontSet().increaseFontSize();
+                    //                        dynamic_hiding_factor = calcDynamicHidingFactor();
+                    //                    }
+                    //                }
+                }
+            }
+            //
         }
         }
-        return c;
     }
 
     final void calculateLongestExtNodeInfo() {
     }
 
     final void calculateLongestExtNodeInfo() {
@@ -565,18 +612,23 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                             .getValue()
                             + " " );
                 }
                             .getValue()
                             + " " );
                 }
-                if ( getControlPanel().isShowGeneNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) {
+                if ( getControlPanel().isShowSeqNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) {
                     sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getName() + " " );
                 }
                     sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getName() + " " );
                 }
-                if ( getControlPanel().isShowGeneSymbols()
+                if ( getControlPanel().isShowSeqSymbols()
                         && ( node.getNodeData().getSequence().getSymbol().length() > 0 ) ) {
                     sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getSymbol() + " " );
                 }
                         && ( node.getNodeData().getSequence().getSymbol().length() > 0 ) ) {
                     sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getSymbol() + " " );
                 }
+                if ( getControlPanel().isShowGeneNames()
+                        && ( node.getNodeData().getSequence().getGeneName().length() > 0 ) ) {
+                    sum += getTreeFontSet()._fm_large
+                            .stringWidth( node.getNodeData().getSequence().getGeneName() + " " );
+                }
                 if ( getControlPanel().isShowAnnotation()
                         && ( node.getNodeData().getSequence().getAnnotations() != null )
                         && !node.getNodeData().getSequence().getAnnotations().isEmpty() ) {
                 if ( getControlPanel().isShowAnnotation()
                         && ( node.getNodeData().getSequence().getAnnotations() != null )
                         && !node.getNodeData().getSequence().getAnnotations().isEmpty() ) {
-                    sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getAnnotation( 0 )
-                            .asSimpleText()
+                    sum += getTreeFontSet()._fm_large.stringWidth( TreePanelUtil.createAnnotationString( node
+                            .getNodeData().getSequence().getAnnotations(), getOptions().isShowAnnotationRefSource() )
                             + " " );
                 }
                 if ( getControlPanel().isShowDomainArchitectures()
                             + " " );
                 }
                 if ( getControlPanel().isShowDomainArchitectures()
@@ -621,21 +673,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    final private float calculateOvBranchLengthToParent( final PhylogenyNode node, final int factor ) {
-        if ( getControlPanel().isDrawPhylogram() ) {
-            if ( node.getDistanceToParent() < 0.0 ) {
-                return 0.0f;
-            }
-            return ( float ) ( getOvXcorrectionFactor() * node.getDistanceToParent() );
-        }
-        else {
-            if ( ( factor == 0 ) || isNonLinedUpCladogram() ) {
-                return getOvXDistance();
-            }
-            return getOvXDistance() * factor;
-        }
-    }
-
     final void calculateScaleDistance() {
         if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
             return;
     final void calculateScaleDistance() {
         if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
             return;
@@ -669,30 +706,111 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     }
 
     final Color calculateTaxonomyBasedColor( final Taxonomy tax ) {
     }
 
     final Color calculateTaxonomyBasedColor( final Taxonomy tax ) {
-        String species = tax.getTaxonomyCode();
-        if ( ForesterUtil.isEmpty( species ) ) {
-            species = tax.getScientificName();
-            if ( ForesterUtil.isEmpty( species ) ) {
-                species = tax.getCommonName();
+        if ( getOptions().isColorByTaxonomicGroup() ) {
+            if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) {
+                boolean ex = false;
+                String group = null;
+                try {
+                    group = TaxonomyUtil.getTaxGroupByTaxCode( tax.getTaxonomyCode() );
+                }
+                catch ( final Exception e ) {
+                    ex = true;
+                }
+                if ( !ex && !ForesterUtil.isEmpty( group ) ) {
+                    final Color c = ForesterUtil.obtainColorDependingOnTaxonomyGroup( group );
+                    if ( c != null ) {
+                        return c;
+                    }
+                }
             }
             }
-        }
-        if ( ForesterUtil.isEmpty( species ) ) {
             return getTreeColorSet().getTaxonomyColor();
         }
             return getTreeColorSet().getTaxonomyColor();
         }
-        // Look in species hash
-        Color c = getControlPanel().getSpeciesColors().get( species );
-        if ( c == null ) {
-            c = AptxUtil.calculateColorFromString( species );
-            getControlPanel().getSpeciesColors().put( species, c );
+        else {
+            if ( ForesterUtil.isEmpty( tax.getTaxonomyCode() ) && ForesterUtil.isEmpty( tax.getScientificName() ) ) {
+                return getTreeColorSet().getTaxonomyColor();
+            }
+            Color c = null;
+            if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) {
+                c = getControlPanel().getSpeciesColors().get( tax.getTaxonomyCode() );
+            }
+            if ( ( c == null ) && !ForesterUtil.isEmpty( tax.getScientificName() ) ) {
+                c = getControlPanel().getSpeciesColors().get( tax.getScientificName() );
+            }
+            if ( c == null ) {
+                if ( !ForesterUtil.isEmpty( tax.getTaxonomyCode() ) ) {
+                    c = TreePanelUtil.calculateColorFromString( tax.getTaxonomyCode(), true );
+                    getControlPanel().getSpeciesColors().put( tax.getTaxonomyCode(), c );
+                }
+                else {
+                    c = TreePanelUtil.calculateColorFromString( tax.getScientificName(), true );
+                    getControlPanel().getSpeciesColors().put( tax.getScientificName(), c );
+                }
+            }
+            return c;
         }
         }
-        return c;
     }
 
     }
 
-    final private void cannotOpenBrowserWarningMessage( final String type_type ) {
-        JOptionPane.showMessageDialog( this,
-                                       "Cannot launch web browser for " + type_type + " data of this node",
-                                       "Cannot launch web browser",
-                                       JOptionPane.WARNING_MESSAGE );
+    void checkForVectorProperties( final Phylogeny phy ) {
+        final DescriptiveStatistics stats = new BasicDescriptiveStatistics();
+        for( final PhylogenyNodeIterator iter = phy.iteratorPreorder(); iter.hasNext(); ) {
+            final PhylogenyNode node = iter.next();
+            if ( node.getNodeData().getProperties() != null ) {
+                final PropertiesMap pm = node.getNodeData().getProperties();
+                final double[] vector = new double[ pm.getProperties().size() ];
+                int counter = 0;
+                for( final String ref : pm.getProperties().keySet() ) {
+                    if ( ref.startsWith( PhyloXmlUtil.VECTOR_PROPERTY_REF ) ) {
+                        final Property p = pm.getProperty( ref );
+                        final String value_str = p.getValue();
+                        final String index_str = ref
+                                .substring( PhyloXmlUtil.VECTOR_PROPERTY_REF.length(), ref.length() );
+                        double d = -100;
+                        try {
+                            d = Double.parseDouble( value_str );
+                        }
+                        catch ( final NumberFormatException e ) {
+                            JOptionPane.showMessageDialog( this, "Could not parse \"" + value_str
+                                    + "\" into a decimal value", "Problem with Vector Data", JOptionPane.ERROR_MESSAGE );
+                            return;
+                        }
+                        int i = -1;
+                        try {
+                            i = Integer.parseInt( index_str );
+                        }
+                        catch ( final NumberFormatException e ) {
+                            JOptionPane.showMessageDialog( this,
+                                                           "Could not parse \"" + index_str
+                                                                   + "\" into index for vector data",
+                                                           "Problem with Vector Data",
+                                                           JOptionPane.ERROR_MESSAGE );
+                            return;
+                        }
+                        if ( i < 0 ) {
+                            JOptionPane.showMessageDialog( this,
+                                                           "Attempt to use negative index for vector data",
+                                                           "Problem with Vector Data",
+                                                           JOptionPane.ERROR_MESSAGE );
+                            return;
+                        }
+                        vector[ i ] = d;
+                        ++counter;
+                        stats.addValue( d );
+                    }
+                }
+                final List<Double> vector_l = new ArrayList<Double>( counter );
+                for( int i = 0; i < counter; ++i ) {
+                    vector_l.add( vector[ i ] );
+                }
+                node.getNodeData().setVector( vector_l );
+            }
+        }
+        if ( stats.getN() > 0 ) {
+            _statistics_for_vector_data = stats;
+        }
+    }
+
+    void clearCurrentExternalNodesDataBuffer() {
+        setCurrentExternalNodesDataBuffer( new StringBuilder() );
     }
 
     /**
     }
 
     /**
@@ -711,7 +829,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
         if ( !node.isExternal() && !node.isRoot() ) {
             final boolean collapse = !node.isCollapse();
         }
         if ( !node.isExternal() && !node.isRoot() ) {
             final boolean collapse = !node.isCollapse();
-            AptxUtil.collapseSubtree( node, collapse );
+            TreePanelUtil.collapseSubtree( node, collapse );
             updateSetOfCollapsedExternalNodes();
             _phylogeny.recalculateNumberOfExternalDescendants( true );
             resetNodeIdToDistToLeafMap();
             updateSetOfCollapsedExternalNodes();
             _phylogeny.recalculateNumberOfExternalDescendants( true );
             resetNodeIdToDistToLeafMap();
@@ -730,7 +848,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             return;
         }
         setWaitCursor();
             return;
         }
         setWaitCursor();
-        AptxUtil.collapseSpeciesSpecificSubtrees( _phylogeny );
+        TreePanelUtil.collapseSpeciesSpecificSubtrees( _phylogeny );
         updateSetOfCollapsedExternalNodes();
         _phylogeny.recalculateNumberOfExternalDescendants( true );
         resetNodeIdToDistToLeafMap();
         updateSetOfCollapsedExternalNodes();
         _phylogeny.recalculateNumberOfExternalDescendants( true );
         resetNodeIdToDistToLeafMap();
@@ -742,79 +860,25 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         repaint();
     }
 
         repaint();
     }
 
-    final private void colorizeSubtree( final Color c, final PhylogenyNode node ) {
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot colorize subtree in unrooted display type",
-                                           "Attempt to colorize subtree in unrooted display",
-                                           JOptionPane.WARNING_MESSAGE );
+    final void colorRank( final String rank ) {
+        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
             return;
         }
             return;
         }
-        _control_panel.setColorBranches( true );
-        if ( _control_panel.getColorBranchesCb() != null ) {
-            _control_panel.getColorBranchesCb().setSelected( true );
-        }
-        for( final PreorderTreeIterator it = new PreorderTreeIterator( node ); it.hasNext(); ) {
-            it.next().getBranchData().setBranchColor( new BranchColor( c ) );
+        setWaitCursor();
+        AptxUtil.removeBranchColors( _phylogeny );
+        final int colorizations = TreePanelUtil.colorPhylogenyAccordingToRanks( _phylogeny, rank, this );
+        if ( colorizations > 0 ) {
+            _control_panel.setColorBranches( true );
+            if ( _control_panel.getUseVisualStylesCb() != null ) {
+                _control_panel.getUseVisualStylesCb().setSelected( true );
+            }
+            if ( _control_panel.getColorAccSpeciesCb() != null ) {
+                _control_panel.getColorAccSpeciesCb().setSelected( false );
+            }
+            _options.setColorLabelsSameAsParentBranch( true );
+            _control_panel.repaint();
         }
         }
-        repaint();
-    }
-
-    final private void colorSubtree( final PhylogenyNode node ) {
-        Color intitial_color = null;
-        if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null )
-                && ( ( ( !node.isRoot() && ( node.getParent().getNumberOfDescendants() < 3 ) ) ) || ( node.isRoot() ) ) ) {
-            intitial_color = PhylogenyMethods.getBranchColorValue( node );
-        }
-        else {
-            intitial_color = getTreeColorSet().getBranchColor();
-        }
-        _color_chooser.setColor( intitial_color );
-        _color_chooser.setPreviewPanel( new JPanel() );
-        final JDialog dialog = JColorChooser
-                .createDialog( this,
-                               "Subtree colorization",
-                               true,
-                               _color_chooser,
-                               new SubtreeColorizationActionListener( _color_chooser, node ),
-                               null );
-        dialog.setVisible( true );
-    }
-
-    final void confColor() {
-        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
-            return;
-        }
-        setWaitCursor();
-        AptxUtil.removeBranchColors( _phylogeny );
-        AptxUtil.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this );
-        _control_panel.setColorBranches( true );
-        if ( _control_panel.getColorBranchesCb() != null ) {
-            _control_panel.getColorBranchesCb().setSelected( true );
-        }
-        setArrowCursor();
-        repaint();
-    }
-
-    final void colorRank( final String rank ) {
-        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
-            return;
-        }
-        setWaitCursor();
-        AptxUtil.removeBranchColors( _phylogeny );
-        final int colorizations = AptxUtil.colorPhylogenyAccordingToRanks( _phylogeny, rank, this );
-        if ( colorizations > 0 ) {
-            _control_panel.setColorBranches( true );
-            if ( _control_panel.getColorBranchesCb() != null ) {
-                _control_panel.getColorBranchesCb().setSelected( true );
-            }
-            if ( _control_panel.getColorAccSpeciesCb() != null ) {
-                _control_panel.getColorAccSpeciesCb().setSelected( false );
-            }
-            _options.setColorLabelsSameAsParentBranch( true );
-            _control_panel.repaint();
-        }
-        setArrowCursor();
+        setArrowCursor();
         repaint();
         if ( colorizations > 0 ) {
             String msg = "Taxonomy colorization via " + rank + " completed:\n";
         repaint();
         if ( colorizations > 0 ) {
             String msg = "Taxonomy colorization via " + rank + " completed:\n";
@@ -824,6 +888,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             else {
                 msg += "colorized one subtree";
             }
             else {
                 msg += "colorized one subtree";
             }
+            setEdited( true );
             JOptionPane.showMessageDialog( this,
                                            msg,
                                            "Taxonomy Colorization Completed (" + rank + ")",
             JOptionPane.showMessageDialog( this,
                                            msg,
                                            "Taxonomy Colorization Completed (" + rank + ")",
@@ -841,1319 +906,2600 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    final private void copySubtree( final PhylogenyNode node ) {
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            errorMessageNoCutCopyPasteInUnrootedDisplay();
+    final void confColor() {
+        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
             return;
         }
             return;
         }
-        setNodeInPreorderToNull();
-        setCutOrCopiedTree( _phylogeny.copy( node ) );
-        final List<PhylogenyNode> nodes = PhylogenyMethods.getAllDescendants( node );
-        final Set<Integer> node_ids = new HashSet<Integer>( nodes.size() );
-        for( final PhylogenyNode n : nodes ) {
-            node_ids.add( n.getId() );
+        setWaitCursor();
+        AptxUtil.removeBranchColors( _phylogeny );
+        TreePanelUtil.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this );
+        _control_panel.setColorBranches( true );
+        if ( _control_panel.getUseVisualStylesCb() != null ) {
+            _control_panel.getUseVisualStylesCb().setSelected( true );
         }
         }
-        node_ids.add( node.getId() );
-        setCopiedAndPastedNodes( node_ids );
+        setArrowCursor();
         repaint();
     }
 
         repaint();
     }
 
-    final private void cutSubtree( final PhylogenyNode node ) {
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            errorMessageNoCutCopyPasteInUnrootedDisplay();
-            return;
+    final void decreaseDomainStructureEvalueThreshold() {
+        if ( _domain_structure_e_value_thr_exp > -20 ) {
+            _domain_structure_e_value_thr_exp -= 1;
         }
         }
-        if ( node.isRoot() ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot cut entire tree as subtree",
-                                           "Attempt to cut entire tree",
-                                           JOptionPane.ERROR_MESSAGE );
-            return;
+    }
+
+    /**
+     * Find the node, if any, at the given location
+     * 
+     * @param x
+     * @param y
+     * @return pointer to the node at x,y, null if not found
+     */
+    final PhylogenyNode findNode( final int x, final int y ) {
+        if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
+            return null;
         }
         }
-        final String label = getASimpleTextRepresentationOfANode( node );
-        final int r = JOptionPane.showConfirmDialog( null,
-                                                     "Cut subtree" + label + "?",
-                                                     "Confirm Cutting of Subtree",
-                                                     JOptionPane.YES_NO_OPTION );
-        if ( r != JOptionPane.OK_OPTION ) {
-            return;
+        final int half_box_size_plus_wiggle = ( getOptions().getDefaultNodeShapeSize() / 2 ) + WIGGLE;
+        for( final PhylogenyNodeIterator iter = _phylogeny.iteratorPostorder(); iter.hasNext(); ) {
+            final PhylogenyNode node = iter.next();
+            if ( ( _phylogeny.isRooted() || !node.isRoot() || ( node.getNumberOfDescendants() > 2 ) )
+                    && ( ( node.getXcoord() - half_box_size_plus_wiggle ) <= x )
+                    && ( ( node.getXcoord() + half_box_size_plus_wiggle ) >= x )
+                    && ( ( node.getYcoord() - half_box_size_plus_wiggle ) <= y )
+                    && ( ( node.getYcoord() + half_box_size_plus_wiggle ) >= y ) ) {
+                return node;
+            }
         }
         }
-        setNodeInPreorderToNull();
-        setCopiedAndPastedNodes( null );
-        setCutOrCopiedTree( _phylogeny.copy( node ) );
-        _phylogeny.deleteSubtree( node, true );
-        _phylogeny.hashIDs();
-        _phylogeny.recalculateNumberOfExternalDescendants( true );
-        resetNodeIdToDistToLeafMap();
-        setEdited( true );
-        repaint();
+        return null;
     }
 
     }
 
-    final private void cycleColors() {
-        getMainPanel().getTreeColorSet().cycleColorScheme();
-        for( final TreePanel tree_panel : getMainPanel().getTreePanels() ) {
-            tree_panel.setBackground( getMainPanel().getTreeColorSet().getBackgroundColor() );
-        }
+    final Configuration getConfiguration() {
+        return _configuration;
     }
 
     }
 
-    final void decreaseDomainStructureEvalueThreshold() {
-        if ( _domain_structure_e_value_thr_exp > -20 ) {
-            _domain_structure_e_value_thr_exp -= 1;
-        }
+    final ControlPanel getControlPanel() {
+        return _control_panel;
     }
 
     }
 
-    final private void decreaseOvSize() {
-        if ( ( getOvMaxWidth() > 20 ) && ( getOvMaxHeight() > 20 ) ) {
-            setOvMaxWidth( getOvMaxWidth() - 5 );
-            setOvMaxHeight( getOvMaxHeight() - 5 );
-            updateOvSettings();
-            getControlPanel().displayedPhylogenyMightHaveChanged( false );
-        }
+    String getCurrentExternalNodesDataBufferAsString() {
+        return _current_external_nodes_data_buffer.toString();
     }
 
     }
 
-    final private void deleteNodeOrSubtree( final PhylogenyNode node ) {
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            errorMessageNoCutCopyPasteInUnrootedDisplay();
-            return;
-        }
-        if ( node.isRoot() ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot delete entire tree",
-                                           "Attempt to delete entire tree",
-                                           JOptionPane.ERROR_MESSAGE );
-            return;
-        }
-        final String label = getASimpleTextRepresentationOfANode( node );
-        final Object[] options = { "Node only", "Entire subtree", "Cancel" };
-        final int r = JOptionPane.showOptionDialog( this,
-                                                    "Delete" + label + "?",
-                                                    "Delete Node/Subtree",
-                                                    JOptionPane.CLOSED_OPTION,
-                                                    JOptionPane.QUESTION_MESSAGE,
-                                                    null,
-                                                    options,
-                                                    options[ 2 ] );
-        setNodeInPreorderToNull();
-        boolean node_only = true;
-        if ( r == 1 ) {
-            node_only = false;
-        }
-        else if ( r != 0 ) {
-            return;
-        }
-        if ( node_only ) {
-            PhylogenyMethods.removeNode( node, _phylogeny );
+    int getCurrentExternalNodesDataBufferChangeCounter() {
+        return _current_external_nodes_data_buffer_change_counter;
+    }
+
+    final int getDomainStructureEvalueThreshold() {
+        return _domain_structure_e_value_thr_exp;
+    }
+
+    final Set<Long> getFoundNodes0() {
+        return _found_nodes_0;
+    }
+
+    final Set<Long> getFoundNodes1() {
+        return _found_nodes_1;
+    }
+
+    final Color getGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node ) {
+        if ( getControlPanel().isUseVisualStyles() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
+            return ( PhylogenyMethods.getBranchColorValue( node ) );
         }
         else {
         }
         else {
-            _phylogeny.deleteSubtree( node, true );
+            return ( getTreeColorSet().getBranchColor() );
         }
         }
-        _phylogeny.externalNodesHaveChanged();
-        _phylogeny.hashIDs();
-        _phylogeny.recalculateNumberOfExternalDescendants( true );
-        resetNodeIdToDistToLeafMap();
-        setEdited( true );
-        repaint();
-    }
-
-    final private void displayNodePopupMenu( final PhylogenyNode node, final int x, final int y ) {
-        makePopupMenus( node );
-        _node_popup_menu.putClientProperty( NODE_POPMENU_NODE_CLIENT_PROPERTY, node );
-        _node_popup_menu.show( this, x, y );
     }
 
     }
 
-    final private void drawArc( final double x,
-                                final double y,
-                                final double width,
-                                final double heigth,
-                                final double start_angle,
-                                final double arc_angle,
-                                final Graphics2D g ) {
-        _arc.setArc( x, y, width, heigth, _180_OVER_PI * start_angle, _180_OVER_PI * arc_angle, Arc2D.OPEN );
-        g.draw( _arc );
+    final int getLongestExtNodeInfo() {
+        return _longest_ext_node_info;
     }
 
     }
 
-    final private void drawLine( final double x1, final double y1, final double x2, final double y2, final Graphics2D g ) {
-        if ( ( x1 == x2 ) && ( y1 == y2 ) ) {
-            return;
+    final Options getOptions() {
+        if ( _options == null ) {
+            _options = getControlPanel().getOptions();
         }
         }
-        _line.setLine( x1, y1, x2, y2 );
-        g.draw( _line );
+        return _options;
     }
 
     }
 
-    final private void drawOval( final double x,
-                                 final double y,
-                                 final double width,
-                                 final double heigth,
-                                 final Graphics2D g ) {
-        _ellipse.setFrame( x, y, width, heigth );
-        g.draw( _ellipse );
+    final Rectangle2D getOvRectangle() {
+        return _ov_rectangle;
     }
 
     }
 
-    final private void drawOvalFilled( final double x,
-                                       final double y,
-                                       final double width,
-                                       final double heigth,
-                                       final Graphics2D g ) {
-        _ellipse.setFrame( x, y, width, heigth );
-        g.fill( _ellipse );
+    final Rectangle getOvVirtualRectangle() {
+        return _ov_virtual_rectangle;
     }
 
     }
 
-    final private void drawRect( final float x, final float y, final float width, final float heigth, final Graphics2D g ) {
-        _rectangle.setFrame( x, y, width, heigth );
-        g.draw( _rectangle );
+    final PHYLOGENY_GRAPHICS_TYPE getPhylogenyGraphicsType() {
+        return _graphics_type;
     }
 
     }
 
-    final private void drawRectFilled( final double x,
-                                       final double y,
-                                       final double width,
-                                       final double heigth,
-                                       final Graphics2D g ) {
-        _rectangle.setFrame( x, y, width, heigth );
-        g.fill( _rectangle );
+    final double getStartingAngle() {
+        return _urt_starting_angle;
     }
 
     }
 
-    final private void drawRectGradient( final double x,
-                                         final double y,
-                                         final double width,
-                                         final double heigth,
-                                         final Graphics2D g,
-                                         final Color color_1,
-                                         final Color color_2,
-                                         final Color color_border ) {
-        _rectangle.setFrame( x, y, width, heigth );
-        g.setPaint( new GradientPaint( ( float ) x,
-                                       ( float ) y,
-                                       color_1,
-                                       ( float ) ( x + width ),
-                                       ( float ) ( y + heigth ),
-                                       color_2,
-                                       false ) );
-        g.fill( _rectangle );
-        if ( color_border != null ) {
-            g.setPaint( color_border );
-            g.draw( _rectangle );
-        }
-    }
-
-    final private void drawOvalGradient( final double x,
-                                         final double y,
-                                         final double width,
-                                         final double heigth,
-                                         final Graphics2D g,
-                                         final Color color_1,
-                                         final Color color_2,
-                                         final Color color_border ) {
-        _ellipse.setFrame( x, y, width, heigth );
-        g.setPaint( new GradientPaint( ( float ) x,
-                                       ( float ) y,
-                                       color_1,
-                                       ( float ) ( x + width ),
-                                       ( float ) ( y + heigth ),
-                                       color_2,
-                                       false ) );
-        g.fill( _ellipse );
-        if ( color_border != null ) {
-            g.setPaint( color_border );
-            g.draw( _ellipse );
-        }
-    }
-
-    final private void errorMessageNoCutCopyPasteInUnrootedDisplay() {
-        JOptionPane.showMessageDialog( this,
-                                       "Cannot cut, copy, paste, add, or delete subtrees/nodes in unrooted display",
-                                       "Attempt to cut/copy/paste/add/delete in unrooted display",
-                                       JOptionPane.ERROR_MESSAGE );
+    DescriptiveStatistics getStatisticsForExpressionValues() {
+        return _statistics_for_vector_data;
     }
 
     /**
     }
 
     /**
-     * Find the node, if any, at the given location
+     * Find a color for this species name.
      * 
      * 
-     * @param x
-     * @param y
-     * @return pointer to the node at x,y, null if not found
+     * @param species
+     * @return the species color
      */
      */
-    final PhylogenyNode findNode( final int x, final int y ) {
-        if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
-            return null;
-        }
-        final int half_box_size_plus_wiggle = getOptions().getDefaultNodeShapeSize() / 2 + WIGGLE;
-        for( final PhylogenyNodeIterator iter = _phylogeny.iteratorPostorder(); iter.hasNext(); ) {
-            final PhylogenyNode node = iter.next();
-            if ( ( _phylogeny.isRooted() || !node.isRoot() || ( node.getNumberOfDescendants() > 2 ) )
-                    && ( ( node.getXcoord() - half_box_size_plus_wiggle ) <= x )
-                    && ( ( node.getXcoord() + half_box_size_plus_wiggle ) >= x )
-                    && ( ( node.getYcoord() - half_box_size_plus_wiggle ) <= y )
-                    && ( ( node.getYcoord() + half_box_size_plus_wiggle ) >= y ) ) {
-                return node;
-            }
-        }
-        return null;
-    }
-
-    final private String getASimpleTextRepresentationOfANode( final PhylogenyNode node ) {
-        final String tax = PhylogenyMethods.getSpecies( node );
-        String label = node.getName();
-        if ( !ForesterUtil.isEmpty( label ) && !ForesterUtil.isEmpty( tax ) ) {
-            label = label + " " + tax;
-        }
-        else if ( !ForesterUtil.isEmpty( tax ) ) {
-            label = tax;
-        }
-        else {
-            label = "";
-        }
-        if ( !ForesterUtil.isEmpty( label ) ) {
-            label = " [" + label + "]";
+    final Color getTaxonomyBasedColor( final PhylogenyNode node ) {
+        if ( node.getNodeData().isHasTaxonomy() ) {
+            return calculateTaxonomyBasedColor( node.getNodeData().getTaxonomy() );
         }
         }
-        return label;
-    }
-
-    final Configuration getConfiguration() {
-        return _configuration;
-    }
-
-    final ControlPanel getControlPanel() {
-        return _control_panel;
-    }
-
-    final private Set<Integer> getCopiedAndPastedNodes() {
-        return getMainPanel().getCopiedAndPastedNodes();
-    }
-
-    final private Phylogeny getCutOrCopiedTree() {
-        return getMainPanel().getCutOrCopiedTree();
+        // return non-colorized color
+        return getTreeColorSet().getTaxonomyColor();
     }
 
     }
 
-    final int getDomainStructureEvalueThreshold() {
-        return _domain_structure_e_value_thr_exp;
+    /**
+     * @return pointer to colorset for tree drawing
+     */
+    final TreeColorSet getTreeColorSet() {
+        return getMainPanel().getTreeColorSet();
     }
 
     }
 
-    final Set<Integer> getFoundNodes() {
-        return _found_nodes;
+    final File getTreeFile() {
+        return _treefile;
     }
 
     }
 
-    final private float getLastDragPointX() {
-        return _last_drag_point_x;
+    final float getXcorrectionFactor() {
+        return _x_correction_factor;
     }
 
     }
 
-    final private float getLastDragPointY() {
-        return _last_drag_point_y;
+    final float getXdistance() {
+        return _x_distance;
     }
 
     }
 
-    final int getLongestExtNodeInfo() {
-        return _longest_ext_node_info;
+    final float getYdistance() {
+        return _y_distance;
     }
 
     }
 
-    final public MainPanel getMainPanel() {
-        return _main_panel;
+    final void increaseDomainStructureEvalueThreshold() {
+        if ( _domain_structure_e_value_thr_exp < 3 ) {
+            _domain_structure_e_value_thr_exp += 1;
+        }
     }
 
     }
 
-    final private short getMaxBranchesToLeaf( final PhylogenyNode node ) {
-        if ( !_nodeid_dist_to_leaf.containsKey( node.getId() ) ) {
-            final short m = PhylogenyMethods.calculateMaxBranchesToLeaf( node );
-            _nodeid_dist_to_leaf.put( node.getId(), m );
-            return m;
+    final void initNodeData() {
+        if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
+            return;
         }
         }
-        else {
-            return _nodeid_dist_to_leaf.get( node.getId() );
+        double max_original_domain_structure_width = 0.0;
+        for( final PhylogenyNode node : _phylogeny.getExternalNodes() ) {
+            if ( node.getNodeData().isHasSequence()
+                    && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
+                RenderableDomainArchitecture rds = null;
+                if ( !( node.getNodeData().getSequence().getDomainArchitecture() instanceof RenderableDomainArchitecture ) ) {
+                    rds = new RenderableDomainArchitecture( node.getNodeData().getSequence().getDomainArchitecture(),
+                                                            getConfiguration() );
+                    node.getNodeData().getSequence().setDomainArchitecture( rds );
+                }
+                else {
+                    rds = ( RenderableDomainArchitecture ) node.getNodeData().getSequence().getDomainArchitecture();
+                }
+                if ( getControlPanel().isShowDomainArchitectures() ) {
+                    final double dsw = rds.getOriginalSize().getWidth();
+                    if ( dsw > max_original_domain_structure_width ) {
+                        max_original_domain_structure_width = dsw;
+                    }
+                }
+            }
         }
         }
-    }
-
-    final private double getMaxDistanceToRoot() {
-        if ( _max_distance_to_root < 0 ) {
-            recalculateMaxDistanceToRoot();
+        if ( getControlPanel().isShowDomainArchitectures() ) {
+            final double ds_factor_width = _domain_structure_width / max_original_domain_structure_width;
+            for( final PhylogenyNode node : _phylogeny.getExternalNodes() ) {
+                if ( node.getNodeData().isHasSequence()
+                        && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
+                    final RenderableDomainArchitecture rds = ( RenderableDomainArchitecture ) node.getNodeData()
+                            .getSequence().getDomainArchitecture();
+                    rds.setRenderingFactorWidth( ds_factor_width );
+                    rds.setParameter( _domain_structure_e_value_thr_exp );
+                }
+            }
         }
         }
-        return _max_distance_to_root;
     }
 
     }
 
-    final Options getOptions() {
-        if ( _options == null ) {
-            _options = getControlPanel().getOptions();
-        }
-        return _options;
+    final boolean inOv( final MouseEvent e ) {
+        return ( ( e.getX() > ( getVisibleRect().x + getOvXPosition() + 1 ) )
+                && ( e.getX() < ( ( getVisibleRect().x + getOvXPosition() + getOvMaxWidth() ) - 1 ) )
+                && ( e.getY() > ( getVisibleRect().y + getOvYPosition() + 1 ) ) && ( e.getY() < ( ( getVisibleRect().y
+                + getOvYPosition() + getOvMaxHeight() ) - 1 ) ) );
     }
 
     }
 
-    final private float getOvMaxHeight() {
-        return _ov_max_height;
+    final boolean inOvRectangle( final MouseEvent e ) {
+        return ( ( e.getX() >= ( getOvRectangle().getX() - 1 ) )
+                && ( e.getX() <= ( getOvRectangle().getX() + getOvRectangle().getWidth() + 1 ) )
+                && ( e.getY() >= ( getOvRectangle().getY() - 1 ) ) && ( e.getY() <= ( getOvRectangle().getY()
+                + getOvRectangle().getHeight() + 1 ) ) );
     }
 
     }
 
-    final private float getOvMaxWidth() {
-        return _ov_max_width;
+    final boolean isApplet() {
+        return getMainPanel() instanceof MainPanelApplets;
     }
 
     }
 
-    final Rectangle2D getOvRectangle() {
-        return _ov_rectangle;
+    final boolean isCanCollapse() {
+        return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
     }
 
     }
 
-    final Rectangle getOvVirtualRectangle() {
-        return _ov_virtual_rectangle;
+    final boolean isCanColorSubtree() {
+        return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
     }
 
     }
 
-    final private float getOvXcorrectionFactor() {
-        return _ov_x_correction_factor;
+    final boolean isCanCopy() {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() );
     }
 
     }
 
-    final private float getOvXDistance() {
-        return _ov_x_distance;
+    final boolean isCanCut( final PhylogenyNode node ) {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() && !node
+                .isRoot() );
     }
 
     }
 
-    final private int getOvXPosition() {
-        return _ov_x_position;
+    final boolean isCanDelete() {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() );
     }
 
     }
 
-    final private float getOvYDistance() {
-        return _ov_y_distance;
+    final boolean isCanPaste() {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable()
+                && ( getCutOrCopiedTree() != null ) && !getCutOrCopiedTree().isEmpty() );
     }
 
     }
 
-    final private int getOvYPosition() {
-        return _ov_y_position;
+    final boolean isCanReroot() {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && ( _subtree_index < 1 ) );
     }
 
     }
 
-    final private int getOvYStart() {
-        return _ov_y_start;
+    final boolean isCanSubtree( final PhylogenyNode node ) {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && !node.isExternal() && ( !node
+                .isRoot() || ( _subtree_index > 0 ) ) );
     }
 
     }
 
-    /**
-     * Get a pointer to the phylogeny 
-     * 
-     * @return a pointer to the phylogeny
-     */
-    public final Phylogeny getPhylogeny() {
-        return _phylogeny;
+    final boolean isCurrentTreeIsSubtree() {
+        return ( _subtree_index > 0 );
     }
 
     }
 
-    final PHYLOGENY_GRAPHICS_TYPE getPhylogenyGraphicsType() {
-        return _graphics_type;
+    final boolean isEdited() {
+        return _edited;
     }
 
     }
 
-    final private double getScaleDistance() {
-        return _scale_distance;
+    final boolean isInOvRect() {
+        return _in_ov_rect;
     }
 
     }
 
-    final private String getScaleLabel() {
-        return _scale_label;
+    final boolean isOvOn() {
+        return _ov_on;
     }
 
     }
 
-    final double getStartingAngle() {
-        return _urt_starting_angle;
+    final boolean isPhyHasBranchLengths() {
+        return _phy_has_branch_lengths;
     }
 
     }
 
-    /**
-     * Find a color for this species name.
-     * 
-     * @param species
-     * @return the species color
-     */
-    final Color getTaxonomyBasedColor( final PhylogenyNode node ) {
-        if ( node.getNodeData().isHasTaxonomy() ) {
-            return calculateTaxonomyBasedColor( node.getNodeData().getTaxonomy() );
+    final void midpointRoot() {
+        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
+            return;
         }
         }
-        // return non-colorized color
-        return getTreeColorSet().getTaxonomyColor();
-    }
-
-    /**
-     * @return pointer to colorset for tree drawing
-     */
-    final TreeColorSet getTreeColorSet() {
-        return getMainPanel().getTreeColorSet();
-    }
-
-    final File getTreeFile() {
-        return _treefile;
-    }
-
-    final private TreeFontSet getTreeFontSet() {
-        return getMainPanel().getTreeFontSet();
-    }
-
-    final private float getUrtFactor() {
-        return _urt_factor;
-    }
-
-    final private float getUrtFactorOv() {
-        return _urt_factor_ov;
-    }
-
-    final float getXcorrectionFactor() {
-        return _x_correction_factor;
-    }
-
-    final float getXdistance() {
-        return _x_distance;
-    }
-
-    final float getYdistance() {
-        return _y_distance;
-    }
-
-    final private void handleClickToAction( final NodeClickAction action, final PhylogenyNode node ) {
-        switch ( action ) {
-            case SHOW_DATA:
-                showNodeFrame( node );
-                break;
-            case COLLAPSE:
-                collapse( node );
-                break;
-            case REROOT:
-                reRoot( node );
-                break;
-            case SUBTREE:
-                subTree( node );
-                break;
-            case SWAP:
-                swap( node );
-                break;
-            case COLOR_SUBTREE:
-                colorSubtree( node );
-                break;
-            case OPEN_SEQ_WEB:
-                openSeqWeb( node );
-                break;
-            case BLAST:
-                blast( node );
-                break;
-            case OPEN_TAX_WEB:
-                openTaxWeb( node );
-                break;
-            case CUT_SUBTREE:
-                cutSubtree( node );
-                break;
-            case COPY_SUBTREE:
-                copySubtree( node );
-                break;
-            case PASTE_SUBTREE:
-                pasteSubtree( node );
-                break;
-            case DELETE_NODE_OR_SUBTREE:
-                deleteNodeOrSubtree( node );
-                break;
-            case ADD_NEW_NODE:
-                addEmptyNode( node );
-                break;
-            case EDIT_NODE_DATA:
-                showNodeEditFrame( node );
-                break;
-            case SORT_DESCENDENTS:
-                sortDescendants( node );
-                break;
-            default:
-                throw new IllegalArgumentException( "unknown action: " + action );
-        }
-    }
-
-    final void increaseDomainStructureEvalueThreshold() {
-        if ( _domain_structure_e_value_thr_exp < 3 ) {
-            _domain_structure_e_value_thr_exp += 1;
-        }
-    }
-
-    final private void increaseOvSize() {
-        if ( ( getOvMaxWidth() < getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect().getWidth() / 2 )
-                && ( getOvMaxHeight() < getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect()
-                        .getHeight() / 2 ) ) {
-            setOvMaxWidth( getOvMaxWidth() + 5 );
-            setOvMaxHeight( getOvMaxHeight() + 5 );
-            updateOvSettings();
-            getControlPanel().displayedPhylogenyMightHaveChanged( false );
-        }
-    }
-
-    final void inferCommonPartOfScientificNames() {
-        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
+        if ( !_phylogeny.isRerootable() ) {
+            JOptionPane.showMessageDialog( this,
+                                           "This is not rerootable",
+                                           "Not rerootable",
+                                           JOptionPane.WARNING_MESSAGE );
             return;
         }
             return;
         }
+        setNodeInPreorderToNull();
         setWaitCursor();
         setWaitCursor();
-        AptxUtil.inferCommonPartOfScientificNames( _phylogeny );
+        PhylogenyMethods.midpointRoot( _phylogeny );
+        resetNodeIdToDistToLeafMap();
         setArrowCursor();
         setArrowCursor();
+        setEdited( true );
         repaint();
     }
 
         repaint();
     }
 
-    final private void init() {
-        _color_chooser = new JColorChooser();
-        _rollover_popup = new JTextArea();
-        _rollover_popup.setFont( POPUP_FONT );
-        resetNodeIdToDistToLeafMap();
-        setTextAntialias();
-        setTreeFile( null );
-        setEdited( false );
-        initializeOvSettings();
-        setStartingAngle( TWO_PI * 3 / 4 );
-        final ImageLoader il = new ImageLoader( this );
-        new Thread( il ).start();
-    }
-
-    final private void initializeOvSettings() {
-        setOvMaxHeight( getConfiguration().getOvMaxHeight() );
-        setOvMaxWidth( getConfiguration().getOvMaxWidth() );
-    }
-
-    final void initNodeData() {
-        if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
-            return;
+    final void mouseClicked( final MouseEvent e ) {
+        if ( getOptions().isShowOverview() && isOvOn() && isInOv() ) {
+            final double w_ratio = getVisibleRect().width / getOvRectangle().getWidth();
+            final double h_ratio = getVisibleRect().height / getOvRectangle().getHeight();
+            double x = ( e.getX() - getVisibleRect().x - getOvXPosition() - ( getOvRectangle().getWidth() / 2.0 ) )
+                    * w_ratio;
+            double y = ( e.getY() - getVisibleRect().y - getOvYPosition() - ( getOvRectangle().getHeight() / 2.0 ) )
+                    * h_ratio;
+            if ( x < 0 ) {
+                x = 0;
+            }
+            if ( y < 0 ) {
+                y = 0;
+            }
+            final double max_x = getWidth() - getVisibleRect().width;
+            final double max_y = getHeight() - getVisibleRect().height;
+            if ( x > max_x ) {
+                x = max_x;
+            }
+            if ( y > max_y ) {
+                y = max_y;
+            }
+            getMainPanel().getCurrentScrollPane().getViewport()
+                    .setViewPosition( new Point( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ) ) );
+            setInOvRect( true );
+            repaint();
         }
         }
-        double max_original_domain_structure_width = 0.0;
-        for( final PhylogenyNode node : _phylogeny.getExternalNodes() ) {
-            if ( node.getNodeData().isHasSequence()
-                    && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
-                RenderableDomainArchitecture rds = null;
-                if ( !( node.getNodeData().getSequence().getDomainArchitecture() instanceof RenderableDomainArchitecture ) ) {
-                    rds = new RenderableDomainArchitecture( node.getNodeData().getSequence().getDomainArchitecture(),
-                                                            getConfiguration() );
-                    node.getNodeData().getSequence().setDomainArchitecture( rds );
+        else {
+            final PhylogenyNode node = findNode( e.getX(), e.getY() );
+            if ( node != null ) {
+                if ( !node.isRoot() && node.getParent().isCollapse() ) {
+                    return;
                 }
                 }
-                else {
-                    rds = ( RenderableDomainArchitecture ) node.getNodeData().getSequence().getDomainArchitecture();
+                _highlight_node = node;
+                // Check if shift key is down
+                if ( ( e.getModifiers() & InputEvent.SHIFT_MASK ) != 0 ) {
+                    // Yes, so add to _found_nodes
+                    if ( getFoundNodes0() == null ) {
+                        setFoundNodes0( new HashSet<Long>() );
+                    }
+                    getFoundNodes0().add( node.getId() );
+                    // Check if control key is down
                 }
                 }
-                if ( getControlPanel().isShowDomainArchitectures() ) {
-                    final double dsw = rds.getOriginalSize().getWidth();
-                    if ( dsw > max_original_domain_structure_width ) {
-                        max_original_domain_structure_width = dsw;
+                else if ( ( e.getModifiers() & InputEvent.CTRL_MASK ) != 0 ) {
+                    // Yes, so pop-up menu
+                    displayNodePopupMenu( node, e.getX(), e.getY() );
+                    // Handle unadorned click
+                }
+                else {
+                    // Check for right mouse button
+                    if ( e.getModifiers() == 4 ) {
+                        displayNodePopupMenu( node, e.getX(), e.getY() );
+                    }
+                    else {
+                        // if not in _found_nodes, clear _found_nodes
+                        handleClickToAction( _control_panel.getActionWhenNodeClicked(), node );
                     }
                 }
             }
                     }
                 }
             }
-        }
-        if ( getControlPanel().isShowDomainArchitectures() ) {
-            final double ds_factor_width = _domain_structure_width / max_original_domain_structure_width;
-            for( final PhylogenyNode node : _phylogeny.getExternalNodes() ) {
-                if ( node.getNodeData().isHasSequence()
-                        && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
-                    final RenderableDomainArchitecture rds = ( RenderableDomainArchitecture ) node.getNodeData()
-                            .getSequence().getDomainArchitecture();
-                    rds.setRenderingFactorWidth( ds_factor_width );
-                    rds.setParameter( _domain_structure_e_value_thr_exp );
-                }
+            else {
+                // no node was clicked
+                _highlight_node = null;
             }
         }
             }
         }
+        repaint();
     }
 
     }
 
-    final boolean inOv( final MouseEvent e ) {
-        return ( ( e.getX() > getVisibleRect().x + getOvXPosition() + 1 )
-                && ( e.getX() < getVisibleRect().x + getOvXPosition() + getOvMaxWidth() - 1 )
-                && ( e.getY() > getVisibleRect().y + getOvYPosition() + 1 ) && ( e.getY() < getVisibleRect().y
-                + getOvYPosition() + getOvMaxHeight() - 1 ) );
-    }
-
-    final boolean inOvRectangle( final MouseEvent e ) {
-        return ( ( e.getX() >= getOvRectangle().getX() - 1 )
-                && ( e.getX() <= getOvRectangle().getX() + getOvRectangle().getWidth() + 1 )
-                && ( e.getY() >= getOvRectangle().getY() - 1 ) && ( e.getY() <= getOvRectangle().getY()
-                + getOvRectangle().getHeight() + 1 ) );
-    }
-
-    final private boolean inOvVirtualRectangle( final int x, final int y ) {
-        return ( ( x >= getOvVirtualRectangle().x - 1 )
-                && ( x <= getOvVirtualRectangle().x + getOvVirtualRectangle().width + 1 )
-                && ( y >= getOvVirtualRectangle().y - 1 ) && ( y <= getOvVirtualRectangle().y
-                + getOvVirtualRectangle().height + 1 ) );
-    }
-
-    final private boolean inOvVirtualRectangle( final MouseEvent e ) {
-        return ( inOvVirtualRectangle( e.getX(), e.getY() ) );
-    }
-
-    final boolean isApplet() {
-        return getMainPanel() instanceof MainPanelApplets;
-    }
-
-    final private boolean isCanBlast( final PhylogenyNode node ) {
-        return ( node.getNodeData().isHasSequence()
-                && ( ( ( node.getNodeData().getSequence().getAccession() != null ) && !ForesterUtil.isEmpty( node
-                        .getNodeData().getSequence().getAccession().getValue() ) )
-                        || !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) || !ForesterUtil
-                        .isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) && Blast
-                .isContainsQueryForBlast( node ) );
+    final void mouseDragInBrowserPanel( final MouseEvent e ) {
+        setCursor( MOVE_CURSOR );
+        final Point scroll_position = getMainPanel().getCurrentScrollPane().getViewport().getViewPosition();
+        scroll_position.x -= ( e.getX() - getLastDragPointX() );
+        scroll_position.y -= ( e.getY() - getLastDragPointY() );
+        if ( scroll_position.x < 0 ) {
+            scroll_position.x = 0;
+        }
+        else {
+            final int max_x = getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getMaximum()
+                    - getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getVisibleAmount();
+            if ( scroll_position.x > max_x ) {
+                scroll_position.x = max_x;
+            }
+        }
+        if ( scroll_position.y < 0 ) {
+            scroll_position.y = 0;
+        }
+        else {
+            final int max_y = getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getMaximum()
+                    - getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getVisibleAmount();
+            if ( scroll_position.y > max_y ) {
+                scroll_position.y = max_y;
+            }
+        }
+        if ( isOvOn() || getOptions().isShowScale() ) {
+            repaint();
+        }
+        getMainPanel().getCurrentScrollPane().getViewport().setViewPosition( scroll_position );
     }
 
     }
 
-    final boolean isCanCollapse() {
-        return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
-    }
-
-    final boolean isCanColorSubtree() {
-        return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
-    }
-
-    final boolean isCanCopy() {
-        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() );
-    }
-
-    final boolean isCanCut( final PhylogenyNode node ) {
-        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() && !node
-                .isRoot() );
-    }
-
-    final boolean isCanDelete() {
-        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() );
-    }
-
-    final private boolean isCanOpenSeqWeb( final PhylogenyNode node ) {
-        if ( node.getNodeData().isHasSequence()
-                && ( node.getNodeData().getSequence().getAccession() != null )
-                && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().getSource() )
-                && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().getValue() )
-                && getConfiguration().isHasWebLink( node.getNodeData().getSequence().getAccession().getSource()
-                        .toLowerCase() ) ) {
-            return true;
+    final void mouseDragInOvRectangle( final MouseEvent e ) {
+        setCursor( HAND_CURSOR );
+        final double w_ratio = getVisibleRect().width / getOvRectangle().getWidth();
+        final double h_ratio = getVisibleRect().height / getOvRectangle().getHeight();
+        final Point scroll_position = getMainPanel().getCurrentScrollPane().getViewport().getViewPosition();
+        double dx = ( ( w_ratio * e.getX() ) - ( w_ratio * getLastDragPointX() ) );
+        double dy = ( ( h_ratio * e.getY() ) - ( h_ratio * getLastDragPointY() ) );
+        scroll_position.x = ForesterUtil.roundToInt( scroll_position.x + dx );
+        scroll_position.y = ForesterUtil.roundToInt( scroll_position.y + dy );
+        if ( scroll_position.x <= 0 ) {
+            scroll_position.x = 0;
+            dx = 0;
         }
         }
-        return false;
-    }
-
-    final private boolean isCanOpenTaxWeb( final PhylogenyNode node ) {
-        if ( node.getNodeData().isHasTaxonomy()
-                && ( ( ( node.getNodeData().getTaxonomy().getIdentifier() != null )
-                        && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getIdentifier().getProvider() )
-                        && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getIdentifier().getValue() ) && getConfiguration()
-                        .isHasWebLink( node.getNodeData().getTaxonomy().getIdentifier().getProvider().toLowerCase() ) )
-                        || ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) )
-                        || ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) )
-                        || ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getCommonName() ) ) || ( ( node
-                        .getNodeData().getTaxonomy().getIdentifier() != null )
-                        && !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getIdentifier().getValue() ) && node
-                        .getNodeData().getTaxonomy().getIdentifier().getValue().startsWith( "http://" ) ) ) ) {
-            return true;
+        else {
+            final int max_x = getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getMaximum()
+                    - getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getVisibleAmount();
+            if ( scroll_position.x >= max_x ) {
+                dx = 0;
+                scroll_position.x = max_x;
+            }
+        }
+        if ( scroll_position.y <= 0 ) {
+            dy = 0;
+            scroll_position.y = 0;
         }
         else {
         }
         else {
-            return false;
+            final int max_y = getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getMaximum()
+                    - getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getVisibleAmount();
+            if ( scroll_position.y >= max_y ) {
+                dy = 0;
+                scroll_position.y = max_y;
+            }
         }
         }
+        repaint();
+        getMainPanel().getCurrentScrollPane().getViewport().setViewPosition( scroll_position );
+        setLastMouseDragPointX( ( float ) ( e.getX() + dx ) );
+        setLastMouseDragPointY( ( float ) ( e.getY() + dy ) );
     }
 
     }
 
-    final boolean isCanPaste() {
-        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable()
-                && ( getCutOrCopiedTree() != null ) && !getCutOrCopiedTree().isEmpty() );
-    }
-
-    final boolean isCanReroot() {
-        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && ( _subtree_index < 1 ) );
-    }
-
-    final boolean isCanSubtree( final PhylogenyNode node ) {
-        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && !node.isExternal() && ( !node
-                .isRoot() || ( _subtree_index > 0 ) ) );
-    }
-
-    final boolean isEdited() {
-        return _edited;
-    }
-
-    final private boolean isInFoundNodes( final PhylogenyNode node ) {
-        return ( ( getFoundNodes() != null ) && getFoundNodes().contains( node.getId() ) );
-    }
-
-    final private boolean isInOv() {
-        return _in_ov;
-    }
-
-    final boolean isInOvRect() {
-        return _in_ov_rect;
-    }
-
-    final private boolean isNodeDataInvisible( final PhylogenyNode node ) {
-        int y_dist = 40;
-        if ( getControlPanel().isShowTaxonomyImages() ) {
-            y_dist = 40 + ( int ) getYdistance();
+    final void mouseMoved( final MouseEvent e ) {
+        requestFocusInWindow();
+        if ( _current_external_nodes != null ) {
+            _current_external_nodes = null;
+            repaint();
         }
         }
-        return ( ( node.getYcoord() < getVisibleRect().getMinY() - y_dist )
-                || ( node.getYcoord() > getVisibleRect().getMaxY() + y_dist ) || ( ( node.getParent() != null ) && ( node
-                .getParent().getXcoord() > getVisibleRect().getMaxX() ) ) );
-    }
-
-    final private boolean isNodeDataInvisibleUnrootedCirc( final PhylogenyNode node ) {
-        return ( ( node.getYcoord() < getVisibleRect().getMinY() - 20 )
-                || ( node.getYcoord() > getVisibleRect().getMaxY() + 20 )
-                || ( node.getXcoord() < getVisibleRect().getMinX() - 20 ) || ( node.getXcoord() > getVisibleRect()
-                .getMaxX() + 20 ) );
-    }
-
-    final private boolean isNonLinedUpCladogram() {
-        return getOptions().getCladogramType() == CLADOGRAM_TYPE.NON_LINED_UP;
-    }
-
-    final boolean isOvOn() {
-        return _ov_on;
-    }
-
-    final boolean isPhyHasBranchLengths() {
-        return _phy_has_branch_lengths;
-    }
-
-    final private boolean isUniformBranchLengthsForCladogram() {
-        return getOptions().getCladogramType() == CLADOGRAM_TYPE.TOTAL_NODE_SUM_DEP;
-    }
-
-    final private void keyPressedCalls( final KeyEvent e ) {
-        if ( isOvOn() && ( getMousePosition() != null ) && ( getMousePosition().getLocation() != null ) ) {
-            if ( inOvVirtualRectangle( getMousePosition().x, getMousePosition().y ) ) {
+        if ( getControlPanel().isNodeDescPopup() ) {
+            if ( _node_desc_popup != null ) {
+                _node_desc_popup.hide();
+                _node_desc_popup = null;
+            }
+        }
+        if ( getOptions().isShowOverview() && isOvOn() ) {
+            if ( inOvVirtualRectangle( e ) ) {
                 if ( !isInOvRect() ) {
                     setInOvRect( true );
                 if ( !isInOvRect() ) {
                     setInOvRect( true );
+                    repaint();
                 }
             }
                 }
             }
-            else if ( isInOvRect() ) {
-                setInOvRect( false );
+            else {
+                if ( isInOvRect() ) {
+                    setInOvRect( false );
+                    repaint();
+                }
             }
         }
             }
         }
-        if ( e.getModifiersEx() == InputEvent.CTRL_DOWN_MASK ) {
-            if ( ( e.getKeyCode() == KeyEvent.VK_DELETE ) || ( e.getKeyCode() == KeyEvent.VK_HOME )
-                    || ( e.getKeyCode() == KeyEvent.VK_F ) ) {
-                getMainPanel().getTreeFontSet().mediumFonts();
-                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true );
-            }
-            else if ( ( e.getKeyCode() == KeyEvent.VK_SUBTRACT ) || ( e.getKeyCode() == KeyEvent.VK_MINUS ) ) {
-                getMainPanel().getTreeFontSet().decreaseFontSize();
-                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true );
-            }
-            else if ( plusPressed( e.getKeyCode() ) ) {
-                getMainPanel().getTreeFontSet().increaseFontSize();
-                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true );
+        if ( inOv( e ) && getOptions().isShowOverview() && isOvOn() ) {
+            if ( !isInOv() ) {
+                setInOv( true );
             }
         }
         else {
             }
         }
         else {
-            if ( ( e.getKeyCode() == KeyEvent.VK_DELETE ) || ( e.getKeyCode() == KeyEvent.VK_HOME )
-                    || ( e.getKeyCode() == KeyEvent.VK_F ) ) {
-                getControlPanel().showWhole();
+            if ( isInOv() ) {
+                setInOv( false );
             }
             }
-            else if ( ( e.getKeyCode() == KeyEvent.VK_UP ) || ( e.getKeyCode() == KeyEvent.VK_DOWN )
-                    || ( e.getKeyCode() == KeyEvent.VK_LEFT ) || ( e.getKeyCode() == KeyEvent.VK_RIGHT ) ) {
-                if ( e.getModifiersEx() == InputEvent.SHIFT_DOWN_MASK ) {
-                    if ( e.getKeyCode() == KeyEvent.VK_UP ) {
-                        getMainPanel().getControlPanel().zoomInY( Constants.WHEEL_ZOOM_IN_FACTOR );
-                        getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
-                    }
-                    else if ( e.getKeyCode() == KeyEvent.VK_DOWN ) {
-                        getMainPanel().getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
-                        getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
-                    }
-                    else if ( e.getKeyCode() == KeyEvent.VK_LEFT ) {
-                        getMainPanel().getControlPanel().zoomOutX( Constants.WHEEL_ZOOM_OUT_FACTOR,
-                                                                   Constants.WHEEL_ZOOM_OUT_X_CORRECTION_FACTOR );
-                        getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
-                    }
-                    else if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) {
-                        getMainPanel().getControlPanel().zoomInX( Constants.WHEEL_ZOOM_IN_FACTOR,
-                                                                  Constants.WHEEL_ZOOM_IN_FACTOR );
-                        getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
-                    }
-                }
-                else {
-                    final int d = 80;
-                    int dx = 0;
-                    int dy = -d;
-                    if ( e.getKeyCode() == KeyEvent.VK_DOWN ) {
-                        dy = d;
-                    }
-                    else if ( e.getKeyCode() == KeyEvent.VK_LEFT ) {
-                        dx = -d;
-                        dy = 0;
-                    }
-                    else if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) {
-                        dx = d;
-                        dy = 0;
-                    }
-                    final Point scroll_position = getMainPanel().getCurrentScrollPane().getViewport().getViewPosition();
-                    scroll_position.x = scroll_position.x + dx;
-                    scroll_position.y = scroll_position.y + dy;
-                    if ( scroll_position.x <= 0 ) {
-                        scroll_position.x = 0;
-                    }
-                    else {
-                        final int max_x = getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getMaximum()
-                                - getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getVisibleAmount();
-                        if ( scroll_position.x >= max_x ) {
-                            scroll_position.x = max_x;
-                        }
-                    }
-                    if ( scroll_position.y <= 0 ) {
-                        scroll_position.y = 0;
-                    }
-                    else {
-                        final int max_y = getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getMaximum()
-                                - getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getVisibleAmount();
-                        if ( scroll_position.y >= max_y ) {
-                            scroll_position.y = max_y;
-                        }
+            final PhylogenyNode node = findNode( e.getX(), e.getY() );
+            if ( ( node != null ) && ( node.isRoot() || !node.getParent().isCollapse() ) ) {
+                if ( ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.GET_EXT_DESC_DATA ) ) {
+                    for( final PhylogenyNode n : node.getAllExternalDescendants() ) {
+                        addToCurrentExternalNodes( n.getId() );
                     }
                     }
+                    setCursor( HAND_CURSOR );
                     repaint();
                     repaint();
-                    getMainPanel().getCurrentScrollPane().getViewport().setViewPosition( scroll_position );
                 }
                 }
-            }
-            else if ( ( e.getKeyCode() == KeyEvent.VK_SUBTRACT ) || ( e.getKeyCode() == KeyEvent.VK_MINUS ) ) {
-                getMainPanel().getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
-                getMainPanel().getControlPanel().zoomOutX( Constants.WHEEL_ZOOM_OUT_FACTOR,
-                                                           Constants.WHEEL_ZOOM_OUT_X_CORRECTION_FACTOR );
-                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
-            }
-            else if ( plusPressed( e.getKeyCode() ) ) {
-                getMainPanel().getControlPanel().zoomInX( Constants.WHEEL_ZOOM_IN_FACTOR,
-                                                          Constants.WHEEL_ZOOM_IN_FACTOR );
-                getMainPanel().getControlPanel().zoomInY( Constants.WHEEL_ZOOM_IN_FACTOR );
-                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
-            }
-            else if ( e.getKeyCode() == KeyEvent.VK_S ) {
-                if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
-                        || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
-                    setStartingAngle( ( getStartingAngle() % TWO_PI ) + ANGLE_ROTATION_UNIT );
-                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                else if ( ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.CUT_SUBTREE )
+                        || ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.COPY_SUBTREE )
+                        || ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.PASTE_SUBTREE )
+                        || ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.DELETE_NODE_OR_SUBTREE )
+                        || ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.REROOT )
+                        || ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.ADD_NEW_NODE ) ) {
+                    setCursor( CUT_CURSOR );
                 }
                 }
-            }
-            else if ( e.getKeyCode() == KeyEvent.VK_A ) {
-                if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
-                        || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
-                    setStartingAngle( ( getStartingAngle() % TWO_PI ) - ANGLE_ROTATION_UNIT );
-                    if ( getStartingAngle() < 0 ) {
-                        setStartingAngle( TWO_PI + getStartingAngle() );
+                else {
+                    setCursor( HAND_CURSOR );
+                    if ( getControlPanel().isNodeDescPopup() ) {
+                        showNodeDataPopup( e, node );
                     }
                     }
-                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
                 }
             }
                 }
             }
-            else if ( e.getKeyCode() == KeyEvent.VK_D ) {
-                boolean selected = false;
-                if ( getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.HORIZONTAL ) {
-                    getOptions().setNodeLabelDirection( NODE_LABEL_DIRECTION.RADIAL );
-                    selected = true;
-                }
-                else {
-                    getOptions().setNodeLabelDirection( NODE_LABEL_DIRECTION.HORIZONTAL );
-                }
-                if ( getMainPanel().getMainFrame() == null ) {
-                    // Must be "E" applet version.
-                    final ArchaeopteryxE ae = ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet();
-                    if ( ae.getlabelDirectionCbmi() != null ) {
-                        ae.getlabelDirectionCbmi().setSelected( selected );
-                    }
-                }
-                else {
-                    getMainPanel().getMainFrame().getlabelDirectionCbmi().setSelected( selected );
-                }
-                repaint();
-            }
-            else if ( e.getKeyCode() == KeyEvent.VK_X ) {
-                switchDisplaygetPhylogenyGraphicsType();
-                repaint();
-            }
-            else if ( e.getKeyCode() == KeyEvent.VK_C ) {
-                cycleColors();
-                repaint();
-            }
-            else if ( getOptions().isShowOverview() && isOvOn() && ( e.getKeyCode() == KeyEvent.VK_O ) ) {
-                MainFrame.cycleOverview( getOptions(), this );
-                repaint();
-            }
-            else if ( getOptions().isShowOverview() && isOvOn() && ( e.getKeyCode() == KeyEvent.VK_I ) ) {
-                increaseOvSize();
-            }
-            else if ( getOptions().isShowOverview() && isOvOn() && ( e.getKeyCode() == KeyEvent.VK_U ) ) {
-                decreaseOvSize();
+            else {
+                setCursor( ARROW_CURSOR );
             }
             }
-            e.consume();
         }
     }
 
         }
     }
 
-    final private void makePopupMenus( final PhylogenyNode node ) {
-        _node_popup_menu = new JPopupMenu();
-        final List<String> clickto_names = _main_panel.getControlPanel().getSingleClickToNames();
-        _node_popup_menu_items = new JMenuItem[ clickto_names.size() ];
-        for( int i = 0; i < clickto_names.size(); i++ ) {
-            final String title = clickto_names.get( i );
-            _node_popup_menu_items[ i ] = new JMenuItem( title );
-            if ( title.equals( Configuration.clickto_options[ Configuration.open_seq_web ][ 0 ] ) ) {
-                _node_popup_menu_items[ i ].setEnabled( isCanOpenSeqWeb( node ) );
+    final void mouseReleasedInBrowserPanel( final MouseEvent e ) {
+        setCursor( ARROW_CURSOR );
+    }
+
+    final void multiplyUrtFactor( final float f ) {
+        _urt_factor *= f;
+    }
+
+    final JApplet obtainApplet() {
+        return ( ( MainPanelApplets ) getMainPanel() ).getApplet();
+    }
+
+    final void paintBranchCircular( final PhylogenyNode p,
+                                    final PhylogenyNode c,
+                                    final Graphics2D g,
+                                    final boolean radial_labels,
+                                    final boolean to_pdf,
+                                    final boolean to_graphics_file ) {
+        final double angle = _urt_nodeid_angle_map.get( c.getId() );
+        final double root_x = _root.getXcoord();
+        final double root_y = _root.getYcoord();
+        final double dx = root_x - p.getXcoord();
+        final double dy = root_y - p.getYcoord();
+        final double parent_radius = Math.sqrt( ( dx * dx ) + ( dy * dy ) );
+        final double arc = ( _urt_nodeid_angle_map.get( p.getId() ) ) - angle;
+        assignGraphicsForBranchWithColorForParentBranch( c, false, g, to_pdf, to_graphics_file );
+        if ( ( c.isFirstChildNode() || c.isLastChildNode() )
+                && ( ( Math.abs( parent_radius * arc ) > 1.5 ) || to_pdf || to_graphics_file ) ) {
+            final double r2 = 2.0 * parent_radius;
+            drawArc( root_x - parent_radius, root_y - parent_radius, r2, r2, ( -angle - arc ), arc, g );
+        }
+        drawLine( c.getXcoord(),
+                  c.getYcoord(),
+                  root_x + ( Math.cos( angle ) * parent_radius ),
+                  root_y + ( Math.sin( angle ) * parent_radius ),
+                  g );
+        paintNodeBox( c.getXcoord(), c.getYcoord(), c, g, to_pdf, to_graphics_file );
+        if ( c.isExternal() ) {
+            final boolean is_in_found_nodes = isInFoundNodes0( c ) || isInFoundNodes1( c )
+                    || isInCurrentExternalNodes( c );
+            if ( ( _dynamic_hiding_factor > 1 ) && !is_in_found_nodes
+                    && ( ( _urt_nodeid_index_map.get( c.getId() ) % _dynamic_hiding_factor ) != 1 ) ) {
+                return;
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.open_tax_web ][ 0 ] ) ) {
-                _node_popup_menu_items[ i ].setEnabled( isCanOpenTaxWeb( node ) );
+            paintNodeDataUnrootedCirc( g, c, to_pdf, to_graphics_file, radial_labels, 0, is_in_found_nodes );
+        }
+    }
+
+    final void paintBranchCircularLite( final PhylogenyNode p, final PhylogenyNode c, final Graphics2D g ) {
+        final double angle = _urt_nodeid_angle_map.get( c.getId() );
+        final double root_x = _root.getXSecondary();
+        final double root_y = _root.getYSecondary();
+        final double dx = root_x - p.getXSecondary();
+        final double dy = root_y - p.getYSecondary();
+        final double arc = ( _urt_nodeid_angle_map.get( p.getId() ) ) - angle;
+        final double parent_radius = Math.sqrt( ( dx * dx ) + ( dy * dy ) );
+        g.setColor( getTreeColorSet().getOvColor() );
+        if ( ( c.isFirstChildNode() || c.isLastChildNode() ) && ( Math.abs( arc ) > 0.02 ) ) {
+            final double r2 = 2.0 * parent_radius;
+            drawArc( root_x - parent_radius, root_y - parent_radius, r2, r2, ( -angle - arc ), arc, g );
+        }
+        drawLine( c.getXSecondary(),
+                  c.getYSecondary(),
+                  root_x + ( Math.cos( angle ) * parent_radius ),
+                  root_y + ( Math.sin( angle ) * parent_radius ),
+                  g );
+        if ( isInFoundNodes( c ) || isInCurrentExternalNodes( c ) ) {
+            g.setColor( getColorForFoundNode( c ) );
+            drawRectFilled( c.getXSecondary() - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF, c.getYSecondary()
+                    - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF, OVERVIEW_FOUND_NODE_BOX_SIZE, OVERVIEW_FOUND_NODE_BOX_SIZE, g );
+        }
+    }
+
+    final void paintCircular( final Phylogeny phy,
+                              final double starting_angle,
+                              final int center_x,
+                              final int center_y,
+                              final int radius,
+                              final Graphics2D g,
+                              final boolean to_pdf,
+                              final boolean to_graphics_file ) {
+        final int circ_num_ext_nodes = phy.getNumberOfExternalNodes() - _collapsed_external_nodeid_set.size();
+        System.out.println( "# collapsed external = " + _collapsed_external_nodeid_set.size() );
+        _root = phy.getRoot();
+        _root.setXcoord( center_x );
+        _root.setYcoord( center_y );
+        final boolean radial_labels = getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL;
+        double current_angle = starting_angle;
+        int i = 0;
+        for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
+            final PhylogenyNode n = it.next();
+            if ( !n.isCollapse() ) {
+                n.setXcoord( ( float ) ( center_x + ( radius * Math.cos( current_angle ) ) ) );
+                n.setYcoord( ( float ) ( center_y + ( radius * Math.sin( current_angle ) ) ) );
+                _urt_nodeid_angle_map.put( n.getId(), current_angle );
+                _urt_nodeid_index_map.put( n.getId(), i++ );
+                current_angle += ( TWO_PI / circ_num_ext_nodes );
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.blast ][ 0 ] ) ) {
-                _node_popup_menu_items[ i ].setEnabled( isCanBlast( node ) );
+            else {
+                //TODO remove me
+                System.out.println( "is collapse" + n.getName() );
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.delete_subtree_or_node ][ 0 ] ) ) {
-                if ( !getOptions().isEditable() ) {
-                    continue;
+        }
+        paintCirculars( phy.getRoot(), phy, center_x, center_y, radius, radial_labels, g, to_pdf, to_graphics_file );
+        paintNodeBox( _root.getXcoord(), _root.getYcoord(), _root, g, to_pdf, to_graphics_file );
+    }
+
+    final void paintCircularLite( final Phylogeny phy,
+                                  final double starting_angle,
+                                  final int center_x,
+                                  final int center_y,
+                                  final int radius,
+                                  final Graphics2D g ) {
+        final int circ_num_ext_nodes = phy.getNumberOfExternalNodes();
+        _root = phy.getRoot();
+        _root.setXSecondary( center_x );
+        _root.setYSecondary( center_y );
+        double current_angle = starting_angle;
+        for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
+            final PhylogenyNode n = it.next();
+            n.setXSecondary( ( float ) ( center_x + ( radius * Math.cos( current_angle ) ) ) );
+            n.setYSecondary( ( float ) ( center_y + ( radius * Math.sin( current_angle ) ) ) );
+            _urt_nodeid_angle_map.put( n.getId(), current_angle );
+            current_angle += ( TWO_PI / circ_num_ext_nodes );
+        }
+        paintCircularsLite( phy.getRoot(), phy, center_x, center_y, radius, g );
+    }
+
+    final void paintPhylogeny( final Graphics2D g,
+                               final boolean to_pdf,
+                               final boolean to_graphics_file,
+                               final int graphics_file_width,
+                               final int graphics_file_height,
+                               final int graphics_file_x,
+                               final int graphics_file_y ) {
+        if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
+            return;
+        }
+        if ( _control_panel.isShowSequenceRelations() ) {
+            _query_sequence = _control_panel.getSelectedQuerySequence();
+        }
+        // Color the background
+        if ( !to_pdf ) {
+            final Rectangle r = getVisibleRect();
+            if ( !getOptions().isBackgroundColorGradient() || getOptions().isPrintBlackAndWhite() ) {
+                g.setColor( getTreeColorSet().getBackgroundColor() );
+                if ( !to_graphics_file ) {
+                    g.fill( r );
                 }
                 }
-                _node_popup_menu_items[ i ].setEnabled( isCanDelete() );
-            }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.cut_subtree ][ 0 ] ) ) {
-                if ( !getOptions().isEditable() ) {
-                    continue;
+                else {
+                    if ( getOptions().isPrintBlackAndWhite() ) {
+                        g.setColor( Color.WHITE );
+                    }
+                    g.fillRect( graphics_file_x, graphics_file_y, graphics_file_width, graphics_file_height );
                 }
                 }
-                _node_popup_menu_items[ i ].setEnabled( isCanCut( node ) );
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.copy_subtree ][ 0 ] ) ) {
-                if ( !getOptions().isEditable() ) {
-                    continue;
+            else {
+                if ( !to_graphics_file ) {
+                    g.setPaint( new GradientPaint( r.x, r.y, getTreeColorSet().getBackgroundColor(), r.x, r.y
+                            + r.height, getTreeColorSet().getBackgroundColorGradientBottom() ) );
+                    g.fill( r );
                 }
                 }
-                _node_popup_menu_items[ i ].setEnabled( isCanCopy() );
-            }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.paste_subtree ][ 0 ] ) ) {
-                if ( !getOptions().isEditable() ) {
-                    continue;
+                else {
+                    g.setPaint( new GradientPaint( graphics_file_x,
+                                                   graphics_file_y,
+                                                   getTreeColorSet().getBackgroundColor(),
+                                                   graphics_file_x,
+                                                   graphics_file_y + graphics_file_height,
+                                                   getTreeColorSet().getBackgroundColorGradientBottom() ) );
+                    g.fillRect( graphics_file_x, graphics_file_y, graphics_file_width, graphics_file_height );
                 }
                 }
-                _node_popup_menu_items[ i ].setEnabled( isCanPaste() );
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.edit_node_data ][ 0 ] ) ) {
-                if ( !getOptions().isEditable() ) {
-                    continue;
-                }
+            setupStroke( g );
+        }
+        else {
+            g.setStroke( new BasicStroke( getOptions().getPrintLineWidth() ) );
+        }
+        if ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
+                && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
+            _external_node_index = 0;
+            // Position starting X of tree
+            if ( !_phylogeny.isRooted() /*|| ( _subtree_index > 0 )*/) {
+                _phylogeny.getRoot().setXcoord( TreePanel.MOVE );
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.add_new_node ][ 0 ] ) ) {
-                if ( !getOptions().isEditable() ) {
-                    continue;
-                }
+            else if ( ( _phylogeny.getRoot().getDistanceToParent() > 0.0 ) && getControlPanel().isDrawPhylogram() ) {
+                _phylogeny.getRoot().setXcoord( ( float ) ( TreePanel.MOVE + ( _phylogeny.getRoot()
+                        .getDistanceToParent() * getXcorrectionFactor() ) ) );
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.reroot ][ 0 ] ) ) {
-                _node_popup_menu_items[ i ].setEnabled( isCanReroot() );
+            else {
+                _phylogeny.getRoot().setXcoord( TreePanel.MOVE + getXdistance() );
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.collapse_uncollapse ][ 0 ] ) ) {
-                _node_popup_menu_items[ i ].setEnabled( ( isCanCollapse() && !node.isExternal() ) );
+            // Position starting Y of tree
+            _phylogeny.getRoot().setYcoord( ( getYdistance() * _phylogeny.getRoot().getNumberOfExternalNodes() )
+                    + ( TreePanel.MOVE / 2.0f ) );
+            final int dynamic_hiding_factor = calcDynamicHidingFactor();
+            if ( getControlPanel().isDynamicallyHideData() ) {
+                if ( dynamic_hiding_factor > 1 ) {
+                    getControlPanel().setDynamicHidingIsOn( true );
+                }
+                else {
+                    getControlPanel().setDynamicHidingIsOn( false );
+                }
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.color_subtree ][ 0 ] ) ) {
-                _node_popup_menu_items[ i ].setEnabled( isCanColorSubtree() );
+            if ( _nodes_in_preorder == null ) {
+                _nodes_in_preorder = new PhylogenyNode[ _phylogeny.getNodeCount() ];
+                int i = 0;
+                for( final PhylogenyNodeIterator it = _phylogeny.iteratorPreorder(); it.hasNext(); ) {
+                    _nodes_in_preorder[ i++ ] = it.next();
+                }
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.subtree ][ 0 ] ) ) {
-                _node_popup_menu_items[ i ].setEnabled( isCanSubtree( node ) );
+            //final PhylogenyNodeIterator it;
+            //for( it = _phylogeny.iteratorPreorder(); it.hasNext(); ) {
+            //    paintNodeRectangular( g, it.next(), to_pdf, getControlPanel().isDynamicallyHideData()
+            //            && ( dynamic_hiding_factor > 1 ), dynamic_hiding_factor, to_graphics_file );
+            //}
+            for( final PhylogenyNode element : _nodes_in_preorder ) {
+                paintNodeRectangular( g, element, to_pdf, getControlPanel().isDynamicallyHideData()
+                        && ( dynamic_hiding_factor > 1 ), dynamic_hiding_factor, to_graphics_file );
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.swap ][ 0 ] ) ) {
-                _node_popup_menu_items[ i ].setEnabled( node.getNumberOfDescendants() == 2 );
+            if ( getOptions().isShowScale() && getControlPanel().isDrawPhylogram() && ( getScaleDistance() > 0.0 ) ) {
+                if ( !( to_graphics_file || to_pdf ) ) {
+                    paintScale( g,
+                                getVisibleRect().x,
+                                getVisibleRect().y + getVisibleRect().height,
+                                to_pdf,
+                                to_graphics_file );
+                }
+                else {
+                    paintScale( g, graphics_file_x, graphics_file_y + graphics_file_height, to_pdf, to_graphics_file );
+                }
             }
             }
-            else if ( title.equals( Configuration.clickto_options[ Configuration.sort_descendents ][ 0 ] ) ) {
-                _node_popup_menu_items[ i ].setEnabled( node.getNumberOfDescendants() > 1 );
+            if ( getOptions().isShowOverview() && isOvOn() && !to_graphics_file && !to_pdf ) {
+                paintPhylogenyLite( g );
+            }
+        }
+        else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+            if ( getControlPanel().getDynamicallyHideData() != null ) {
+                getControlPanel().setDynamicHidingIsOn( false );
+            }
+            final double angle = getStartingAngle();
+            final boolean radial_labels = getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL;
+            _dynamic_hiding_factor = 0;
+            if ( getControlPanel().isDynamicallyHideData() ) {
+                _dynamic_hiding_factor = ( int ) ( ( getTreeFontSet()._fm_large.getHeight() * 1.5 * getPhylogeny()
+                        .getNumberOfExternalNodes() ) / ( TWO_PI * 10 ) );
+            }
+            if ( getControlPanel().getDynamicallyHideData() != null ) {
+                if ( _dynamic_hiding_factor > 1 ) {
+                    getControlPanel().setDynamicHidingIsOn( true );
+                }
+                else {
+                    getControlPanel().setDynamicHidingIsOn( false );
+                }
+            }
+            paintUnrooted( _phylogeny.getRoot(),
+                           angle,
+                           ( float ) ( angle + ( 2 * Math.PI ) ),
+                           radial_labels,
+                           g,
+                           to_pdf,
+                           to_graphics_file );
+            if ( getOptions().isShowScale() ) {
+                if ( !( to_graphics_file || to_pdf ) ) {
+                    paintScale( g,
+                                getVisibleRect().x,
+                                getVisibleRect().y + getVisibleRect().height,
+                                to_pdf,
+                                to_graphics_file );
+                }
+                else {
+                    paintScale( g, graphics_file_x, graphics_file_y + graphics_file_height, to_pdf, to_graphics_file );
+                }
+            }
+            if ( getOptions().isShowOverview() && isOvOn() && !to_graphics_file && !to_pdf ) {
+                g.setColor( getTreeColorSet().getOvColor() );
+                paintUnrootedLite( _phylogeny.getRoot(),
+                                   angle,
+                                   angle + ( 2 * Math.PI ),
+                                   g,
+                                   ( getUrtFactorOv() / ( getVisibleRect().width / getOvMaxWidth() ) ) );
+                paintOvRectangle( g );
+            }
+        }
+        else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) {
+            final int radius = ( int ) ( ( Math.min( getPreferredSize().getWidth(), getPreferredSize().getHeight() ) / 2 ) - ( MOVE + getLongestExtNodeInfo() ) );
+            final int d = radius + MOVE + getLongestExtNodeInfo();
+            _dynamic_hiding_factor = 0;
+            if ( getControlPanel().isDynamicallyHideData() && ( radius > 0 ) ) {
+                _dynamic_hiding_factor = ( int ) ( ( getTreeFontSet()._fm_large.getHeight() * 1.5 * getPhylogeny()
+                        .getNumberOfExternalNodes() ) / ( TWO_PI * radius ) );
+            }
+            if ( getControlPanel().getDynamicallyHideData() != null ) {
+                if ( _dynamic_hiding_factor > 1 ) {
+                    getControlPanel().setDynamicHidingIsOn( true );
+                }
+                else {
+                    getControlPanel().setDynamicHidingIsOn( false );
+                }
+            }
+            paintCircular( _phylogeny, getStartingAngle(), d, d, radius > 0 ? radius : 0, g, to_pdf, to_graphics_file );
+            if ( getOptions().isShowOverview() && isOvOn() && !to_graphics_file && !to_pdf ) {
+                final int radius_ov = ( int ) ( getOvMaxHeight() < getOvMaxWidth() ? getOvMaxHeight() / 2
+                        : getOvMaxWidth() / 2 );
+                double x_scale = 1.0;
+                double y_scale = 1.0;
+                int x_pos = getVisibleRect().x + getOvXPosition();
+                int y_pos = getVisibleRect().y + getOvYPosition();
+                if ( getWidth() > getHeight() ) {
+                    x_scale = ( double ) getHeight() / getWidth();
+                    x_pos = ForesterUtil.roundToInt( x_pos / x_scale );
+                }
+                else {
+                    y_scale = ( double ) getWidth() / getHeight();
+                    y_pos = ForesterUtil.roundToInt( y_pos / y_scale );
+                }
+                _at = g.getTransform();
+                g.scale( x_scale, y_scale );
+                paintCircularLite( _phylogeny,
+                                   getStartingAngle(),
+                                   x_pos + radius_ov,
+                                   y_pos + radius_ov,
+                                   ( int ) ( radius_ov - ( getLongestExtNodeInfo() / ( getVisibleRect().width / getOvRectangle()
+                                           .getWidth() ) ) ),
+                                   g );
+                g.setTransform( _at );
+                paintOvRectangle( g );
             }
             }
-            _node_popup_menu_items[ i ].addActionListener( this );
-            _node_popup_menu.add( _node_popup_menu_items[ i ] );
         }
     }
 
         }
     }
 
-    final void midpointRoot() {
-        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
-            return;
+    final void recalculateMaxDistanceToRoot() {
+        _max_distance_to_root = PhylogenyMethods.calculateMaxDistanceToRoot( getPhylogeny() );
+    }
+
+    /**
+     * Remove all edit-node frames
+     */
+    final void removeAllEditNodeJFrames() {
+        for( int i = 0; i <= ( TreePanel.MAX_NODE_FRAMES - 1 ); i++ ) {
+            if ( _node_frames[ i ] != null ) {
+                _node_frames[ i ].dispose();
+                _node_frames[ i ] = null;
+            }
         }
         }
-        if ( !_phylogeny.isRerootable() ) {
+        _node_frame_index = 0;
+    }
+
+    /**
+     * Remove a node-edit frame.
+     */
+    final void removeEditNodeFrame( final int i ) {
+        _node_frame_index--;
+        _node_frames[ i ] = null;
+        if ( i < _node_frame_index ) {
+            for( int j = 0; j < ( _node_frame_index - 1 ); j++ ) {
+                _node_frames[ j ] = _node_frames[ j + 1 ];
+            }
+            _node_frames[ _node_frame_index ] = null;
+        }
+    }
+
+    final void reRoot( final PhylogenyNode node ) {
+        if ( !getPhylogeny().isRerootable() ) {
             JOptionPane.showMessageDialog( this,
                                            "This is not rerootable",
                                            "Not rerootable",
                                            JOptionPane.WARNING_MESSAGE );
             return;
         }
             JOptionPane.showMessageDialog( this,
                                            "This is not rerootable",
                                            "Not rerootable",
                                            JOptionPane.WARNING_MESSAGE );
             return;
         }
-        setNodeInPreorderToNull();
-        setWaitCursor();
-        PhylogenyMethods.midpointRoot( _phylogeny );
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot reroot in unrooted display type",
+                                           "Attempt to reroot tree in unrooted display",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
+        }
+        getPhylogeny().reRoot( node );
+        getPhylogeny().recalculateNumberOfExternalDescendants( true );
         resetNodeIdToDistToLeafMap();
         resetNodeIdToDistToLeafMap();
-        setArrowCursor();
+        setNodeInPreorderToNull();
+        resetPreferredSize();
+        getMainPanel().adjustJScrollPane();
+        setEdited( true );
         repaint();
         repaint();
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) {
+            getControlPanel().showWhole();
+        }
     }
 
     }
 
-    final void mouseClicked( final MouseEvent e ) {
-        if ( getOptions().isShowOverview() && isOvOn() && isInOv() ) {
-            final double w_ratio = getVisibleRect().width / getOvRectangle().getWidth();
-            final double h_ratio = getVisibleRect().height / getOvRectangle().getHeight();
-            double x = ( e.getX() - getVisibleRect().x - getOvXPosition() - getOvRectangle().getWidth() / 2.0 )
-                    * w_ratio;
-            double y = ( e.getY() - getVisibleRect().y - getOvYPosition() - getOvRectangle().getHeight() / 2.0 )
-                    * h_ratio;
-            if ( x < 0 ) {
-                x = 0;
-            }
-            if ( y < 0 ) {
-                y = 0;
+    final void resetNodeIdToDistToLeafMap() {
+        _nodeid_dist_to_leaf = new HashMap<Long, Short>();
+    }
+
+    final void resetPreferredSize() {
+        if ( ( getPhylogeny() == null ) || getPhylogeny().isEmpty() ) {
+            return;
+        }
+        int x = 0;
+        int y = 0;
+        y = TreePanel.MOVE
+                + ForesterUtil.roundToInt( getYdistance() * getPhylogeny().getRoot().getNumberOfExternalNodes() * 2 );
+        if ( getControlPanel().isDrawPhylogram() ) {
+            x = TreePanel.MOVE
+                    + getLongestExtNodeInfo()
+                    + ForesterUtil
+                            .roundToInt( ( getXcorrectionFactor() * getPhylogeny().getHeight() ) + getXdistance() );
+        }
+        else {
+            if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) {
+                x = TreePanel.MOVE
+                        + getLongestExtNodeInfo()
+                        + ForesterUtil.roundToInt( getXdistance()
+                                * ( getPhylogeny().getRoot().getNumberOfExternalNodes() + 2 ) );
             }
             }
-            final double max_x = getWidth() - getVisibleRect().width;
-            final double max_y = getHeight() - getVisibleRect().height;
-            if ( x > max_x ) {
-                x = max_x;
+            else {
+                x = TreePanel.MOVE
+                        + getLongestExtNodeInfo()
+                        + ForesterUtil.roundToInt( getXdistance()
+                                * ( PhylogenyMethods.calculateMaxDepth( getPhylogeny() ) + 1 ) );
             }
             }
-            if ( y > max_y ) {
-                y = max_y;
+        }
+        setPreferredSize( new Dimension( x, y ) );
+    }
+
+    final void selectNode( final PhylogenyNode node ) {
+        if ( ( getFoundNodes0() != null ) && getFoundNodes0().contains( node.getId() ) ) {
+            getFoundNodes0().remove( node.getId() );
+            getControlPanel().setSearchFoundCountsOnLabel0( getFoundNodes0().size() );
+            if ( getFoundNodes0().size() < 1 ) {
+                getControlPanel().searchReset0();
             }
             }
-            getMainPanel().getCurrentScrollPane().getViewport()
-                    .setViewPosition( new Point( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ) ) );
-            setInOvRect( true );
-            repaint();
         }
         else {
         }
         else {
-            final PhylogenyNode node = findNode( e.getX(), e.getY() );
-            if ( node != null ) {
-                if ( !node.isRoot() && node.getParent().isCollapse() ) {
-                    return;
-                }
-                _highlight_node = node;
-                // Check if shift key is down
-                if ( ( e.getModifiers() & InputEvent.SHIFT_MASK ) != 0 ) {
-                    // Yes, so add to _found_nodes
-                    if ( getFoundNodes() == null ) {
-                        setFoundNodes( new HashSet<Integer>() );
-                    }
-                    getFoundNodes().add( node.getId() );
-                    // Check if control key is down
-                }
-                else if ( ( e.getModifiers() & InputEvent.CTRL_MASK ) != 0 ) {
-                    // Yes, so pop-up menu
-                    displayNodePopupMenu( node, e.getX(), e.getY() );
-                    // Handle unadorned click
-                }
-                else {
-                    // Check for right mouse button
-                    if ( e.getModifiers() == 4 ) {
-                        displayNodePopupMenu( node, e.getX(), e.getY() );
-                    }
+            getControlPanel().getSearchFoundCountsLabel0().setVisible( true );
+            getControlPanel().getSearchResetButton0().setEnabled( true );
+            getControlPanel().getSearchResetButton0().setVisible( true );
+            if ( getFoundNodes0() == null ) {
+                setFoundNodes0( new HashSet<Long>() );
+            }
+            getFoundNodes0().add( node.getId() );
+            getControlPanel().setSearchFoundCountsOnLabel0( getFoundNodes0().size() );
+        }
+    }
+
+    final void setArrowCursor() {
+        setCursor( ARROW_CURSOR );
+        repaint();
+    }
+
+    final void setControlPanel( final ControlPanel atv_control ) {
+        _control_panel = atv_control;
+    }
+
+    void setCurrentExternalNodesDataBuffer( final StringBuilder sb ) {
+        increaseCurrentExternalNodesDataBufferChangeCounter();
+        _current_external_nodes_data_buffer = sb;
+    }
+
+    final void setFoundNodes0( final Set<Long> found_nodes ) {
+        _found_nodes_0 = found_nodes;
+    }
+
+    final void setFoundNodes1( final Set<Long> found_nodes ) {
+        _found_nodes_1 = found_nodes;
+    }
+
+    final void setInOvRect( final boolean in_ov_rect ) {
+        _in_ov_rect = in_ov_rect;
+    }
+
+    final void setLargeFonts() {
+        getTreeFontSet().largeFonts();
+    }
+
+    final void setLastMouseDragPointX( final float x ) {
+        _last_drag_point_x = x;
+    }
+
+    final void setLastMouseDragPointY( final float y ) {
+        _last_drag_point_y = y;
+    }
+
+    final void setLongestExtNodeInfo( final int i ) {
+        _longest_ext_node_info = i;
+    }
+
+    final void setMediumFonts() {
+        getTreeFontSet().mediumFonts();
+    }
+
+    final void setNodeInPreorderToNull() {
+        _nodes_in_preorder = null;
+    }
+
+    final void setOvOn( final boolean ov_on ) {
+        _ov_on = ov_on;
+    }
+
+    final void setPhylogenyGraphicsType( final PHYLOGENY_GRAPHICS_TYPE graphics_type ) {
+        _graphics_type = graphics_type;
+        setTextAntialias();
+    }
+
+    final void setSmallFonts() {
+        getTreeFontSet().smallFonts();
+    }
+
+    final void setStartingAngle( final double starting_angle ) {
+        _urt_starting_angle = starting_angle;
+    }
+
+    void setStatisticsForExpressionValues( final DescriptiveStatistics statistics_for_expression_values ) {
+        _statistics_for_vector_data = statistics_for_expression_values;
+    }
+
+    final void setSuperTinyFonts() {
+        getTreeFontSet().superTinyFonts();
+    }
+
+    final void setTextAntialias() {
+        if ( ( _phylogeny != null ) && !_phylogeny.isEmpty() ) {
+            if ( _phylogeny.getNumberOfExternalNodes() <= LIMIT_FOR_HQ_RENDERING ) {
+                _rendering_hints.put( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY );
+            }
+            else {
+                _rendering_hints.put( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED );
+            }
+        }
+        if ( getMainPanel().getOptions().isAntialiasScreen() ) {
+            _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
+            // try {
+            _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB );
+            // }
+            // catch ( final Throwable e ) {
+            //    _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
+            //}
+        }
+        else {
+            _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF );
+            _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
+        }
+    }
+
+    final void setTinyFonts() {
+        getTreeFontSet().tinyFonts();
+    }
+
+    final void setTreeFile( final File treefile ) {
+        _treefile = treefile;
+    }
+
+    final void setXcorrectionFactor( final float f ) {
+        _x_correction_factor = f;
+    }
+
+    final void setXdistance( final float x ) {
+        _x_distance = x;
+    }
+
+    final void setYdistance( final float y ) {
+        _y_distance = y;
+    }
+
+    final void sortDescendants( final PhylogenyNode node ) {
+        if ( !node.isExternal() ) {
+            DESCENDANT_SORT_PRIORITY pri = DESCENDANT_SORT_PRIORITY.TAXONOMY;
+            if ( ( !getControlPanel().isShowTaxonomyScientificNames() && !getControlPanel().isShowTaxonomyCode() && !getControlPanel()
+                    .isShowTaxonomyCommonNames() ) ) {
+                if ( ( getControlPanel().isShowSequenceAcc() || getControlPanel().isShowSeqNames() || getControlPanel()
+                        .isShowSeqSymbols() ) ) {
+                    pri = DESCENDANT_SORT_PRIORITY.SEQUENCE;
+                }
+                else if ( getControlPanel().isShowNodeNames() ) {
+                    pri = DESCENDANT_SORT_PRIORITY.NODE_NAME;
+                }
+            }
+            PhylogenyMethods.sortNodeDescendents( node, pri );
+            setNodeInPreorderToNull();
+            _phylogeny.externalNodesHaveChanged();
+            _phylogeny.clearHashIdToNodeMap();
+            _phylogeny.recalculateNumberOfExternalDescendants( true );
+            resetNodeIdToDistToLeafMap();
+            setEdited( true );
+        }
+        repaint();
+    }
+
+    final void subTree( final PhylogenyNode node ) {
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot get a sub/super tree in unrooted display",
+                                           "Attempt to get sub/super tree in unrooted display",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
+        }
+        if ( node.isExternal() ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot get a subtree of a external node",
+                                           "Attempt to get subtree of external node",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
+        }
+        if ( node.isRoot() && !isCurrentTreeIsSubtree() ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot get a subtree of the root node",
+                                           "Attempt to get subtree of root node",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
+        }
+        setNodeInPreorderToNull();
+        if ( !node.isExternal() && !node.isRoot() && ( _subtree_index <= ( TreePanel.MAX_SUBTREES - 1 ) ) ) {
+            _sub_phylogenies[ _subtree_index ] = _phylogeny;
+            _sub_phylogenies_temp_roots[ _subtree_index ] = node;
+            ++_subtree_index;
+            _phylogeny = TreePanelUtil.subTree( node, _phylogeny );
+            updateSubSuperTreeButton();
+        }
+        else if ( node.isRoot() && isCurrentTreeIsSubtree() ) {
+            superTree();
+        }
+        _main_panel.getControlPanel().showWhole();
+        repaint();
+    }
+
+    final void superTree() {
+        setNodeInPreorderToNull();
+        final PhylogenyNode temp_root = _sub_phylogenies_temp_roots[ _subtree_index - 1 ];
+        for( final PhylogenyNode n : temp_root.getDescendants() ) {
+            n.setParent( temp_root );
+        }
+        _sub_phylogenies[ _subtree_index ] = null;
+        _sub_phylogenies_temp_roots[ _subtree_index ] = null;
+        _phylogeny = _sub_phylogenies[ --_subtree_index ];
+        updateSubSuperTreeButton();
+    }
+
+    final void swap( final PhylogenyNode node ) {
+        if ( node.isExternal() || ( node.getNumberOfDescendants() < 2 ) ) {
+            return;
+        }
+        if ( node.getNumberOfDescendants() > 2 ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot swap descendants of nodes with more than 2 descendants",
+                                           "Cannot swap descendants",
+                                           JOptionPane.ERROR_MESSAGE );
+            return;
+        }
+        if ( !node.isExternal() ) {
+            node.swapChildren();
+            setNodeInPreorderToNull();
+            _phylogeny.externalNodesHaveChanged();
+            _phylogeny.clearHashIdToNodeMap();
+            _phylogeny.recalculateNumberOfExternalDescendants( true );
+            resetNodeIdToDistToLeafMap();
+            setEdited( true );
+        }
+        repaint();
+    }
+
+    final void taxColor() {
+        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
+            return;
+        }
+        setWaitCursor();
+        TreePanelUtil.colorPhylogenyAccordingToExternalTaxonomy( _phylogeny, this );
+        _control_panel.setColorBranches( true );
+        if ( _control_panel.getUseVisualStylesCb() != null ) {
+            _control_panel.getUseVisualStylesCb().setSelected( true );
+        }
+        setEdited( true );
+        setArrowCursor();
+        repaint();
+    }
+
+    final void updateOvSettings() {
+        switch ( getOptions().getOvPlacement() ) {
+            case LOWER_LEFT:
+                setOvXPosition( OV_BORDER );
+                setOvYPosition( ForesterUtil.roundToInt( getVisibleRect().height - OV_BORDER - getOvMaxHeight() ) );
+                setOvYStart( ForesterUtil.roundToInt( getOvYPosition() + ( getOvMaxHeight() / 2 ) ) );
+                break;
+            case LOWER_RIGHT:
+                setOvXPosition( ForesterUtil.roundToInt( getVisibleRect().width - OV_BORDER - getOvMaxWidth() ) );
+                setOvYPosition( ForesterUtil.roundToInt( getVisibleRect().height - OV_BORDER - getOvMaxHeight() ) );
+                setOvYStart( ForesterUtil.roundToInt( getOvYPosition() + ( getOvMaxHeight() / 2 ) ) );
+                break;
+            case UPPER_RIGHT:
+                setOvXPosition( ForesterUtil.roundToInt( getVisibleRect().width - OV_BORDER - getOvMaxWidth() ) );
+                setOvYPosition( OV_BORDER );
+                setOvYStart( ForesterUtil.roundToInt( OV_BORDER + ( getOvMaxHeight() / 2 ) ) );
+                break;
+            default:
+                setOvXPosition( OV_BORDER );
+                setOvYPosition( OV_BORDER );
+                setOvYStart( ForesterUtil.roundToInt( OV_BORDER + ( getOvMaxHeight() / 2 ) ) );
+                break;
+        }
+    }
+
+    final void updateOvSizes() {
+        if ( ( getWidth() > ( 1.05 * getVisibleRect().width ) ) || ( getHeight() > ( 1.05 * getVisibleRect().height ) ) ) {
+            setOvOn( true );
+            float l = getLongestExtNodeInfo();
+            final float w_ratio = getOvMaxWidth() / getWidth();
+            l *= w_ratio;
+            final int ext_nodes = _phylogeny.getRoot().getNumberOfExternalNodes();
+            setOvYDistance( getOvMaxHeight() / ( 2 * ext_nodes ) );
+            float ov_xdist = 0;
+            if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) {
+                ov_xdist = ( ( getOvMaxWidth() - l ) / ( ext_nodes ) );
+            }
+            else {
+                ov_xdist = ( ( getOvMaxWidth() - l ) / ( PhylogenyMethods.calculateMaxDepth( _phylogeny ) ) );
+            }
+            float ydist = ( float ) ( ( getOvMaxWidth() / ( ext_nodes * 2.0 ) ) );
+            if ( ov_xdist < 0.0 ) {
+                ov_xdist = 0.0f;
+            }
+            if ( ydist < 0.0 ) {
+                ydist = 0.0f;
+            }
+            setOvXDistance( ov_xdist );
+            final double height = _phylogeny.getHeight();
+            if ( height > 0 ) {
+                final float ov_corr = ( float ) ( ( ( getOvMaxWidth() - l ) - getOvXDistance() ) / height );
+                setOvXcorrectionFactor( ov_corr > 0 ? ov_corr : 0 );
+            }
+            else {
+                setOvXcorrectionFactor( 0 );
+            }
+        }
+        else {
+            setOvOn( false );
+        }
+    }
+
+    void updateSetOfCollapsedExternalNodes() {
+        final Phylogeny phy = getPhylogeny();
+        _collapsed_external_nodeid_set.clear();
+        if ( phy != null ) {
+            E: for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
+                final PhylogenyNode ext_node = it.next();
+                PhylogenyNode n = ext_node;
+                while ( !n.isRoot() ) {
+                    if ( n.isCollapse() ) {
+                        _collapsed_external_nodeid_set.add( ext_node.getId() );
+                        ext_node.setCollapse( true );
+                        continue E;
+                    }
+                    n = n.getParent();
+                }
+            }
+        }
+    }
+
+    final void updateSubSuperTreeButton() {
+        if ( _subtree_index < 1 ) {
+            getControlPanel().deactivateButtonToReturnToSuperTree();
+        }
+        else {
+            getControlPanel().activateButtonToReturnToSuperTree( _subtree_index );
+        }
+    }
+
+    final void zoomInDomainStructure() {
+        if ( _domain_structure_width < 2000 ) {
+            _domain_structure_width *= 1.2;
+        }
+    }
+
+    final void zoomOutDomainStructure() {
+        if ( _domain_structure_width > 20 ) {
+            _domain_structure_width *= 0.8;
+        }
+    }
+
+    private void abbreviateScientificName( final String sn ) {
+        final String[] a = sn.split( "\\s+" );
+        _sb.append( a[ 0 ].substring( 0, 1 ) );
+        _sb.append( a[ 1 ].substring( 0, 2 ) );
+        if ( a.length > 2 ) {
+            for( int i = 2; i < a.length; i++ ) {
+                _sb.append( " " );
+                _sb.append( a[ i ] );
+            }
+        }
+    }
+
+    final private void addEmptyNode( final PhylogenyNode node ) {
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+            errorMessageNoCutCopyPasteInUnrootedDisplay();
+            return;
+        }
+        final String label = createASimpleTextRepresentationOfANode( node );
+        String msg = "";
+        if ( ForesterUtil.isEmpty( label ) ) {
+            msg = "How to add the new, empty node?";
+        }
+        else {
+            msg = "How to add the new, empty node to node" + label + "?";
+        }
+        final Object[] options = { "As sibling", "As descendant", "Cancel" };
+        final int r = JOptionPane.showOptionDialog( this,
+                                                    msg,
+                                                    "Addition of Empty New Node",
+                                                    JOptionPane.CLOSED_OPTION,
+                                                    JOptionPane.QUESTION_MESSAGE,
+                                                    null,
+                                                    options,
+                                                    options[ 2 ] );
+        boolean add_as_sibling = true;
+        if ( r == 1 ) {
+            add_as_sibling = false;
+        }
+        else if ( r != 0 ) {
+            return;
+        }
+        final Phylogeny phy = new Phylogeny();
+        phy.setRoot( new PhylogenyNode() );
+        phy.setRooted( true );
+        if ( add_as_sibling ) {
+            if ( node.isRoot() ) {
+                JOptionPane.showMessageDialog( this,
+                                               "Cannot add sibling to root",
+                                               "Attempt to add sibling to root",
+                                               JOptionPane.ERROR_MESSAGE );
+                return;
+            }
+            phy.addAsSibling( node );
+        }
+        else {
+            phy.addAsChild( node );
+        }
+        setNodeInPreorderToNull();
+        _phylogeny.externalNodesHaveChanged();
+        _phylogeny.clearHashIdToNodeMap();
+        _phylogeny.recalculateNumberOfExternalDescendants( true );
+        resetNodeIdToDistToLeafMap();
+        setEdited( true );
+        repaint();
+    }
+
+    final private void addToCurrentExternalNodes( final long i ) {
+        if ( _current_external_nodes == null ) {
+            _current_external_nodes = new HashSet<Long>();
+        }
+        _current_external_nodes.add( i );
+    }
+
+    final private void assignGraphicsForBranchWithColorForParentBranch( final PhylogenyNode node,
+                                                                        final boolean is_vertical,
+                                                                        final Graphics g,
+                                                                        final boolean to_pdf,
+                                                                        final boolean to_graphics_file ) {
+        final NodeClickAction action = _control_panel.getActionWhenNodeClicked();
+        if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
+            g.setColor( Color.BLACK );
+        }
+        else if ( ( ( action == NodeClickAction.COPY_SUBTREE ) || ( action == NodeClickAction.CUT_SUBTREE )
+                || ( action == NodeClickAction.DELETE_NODE_OR_SUBTREE ) || ( action == NodeClickAction.PASTE_SUBTREE ) || ( action == NodeClickAction.ADD_NEW_NODE ) )
+                && ( getCutOrCopiedTree() != null )
+                && ( getCopiedAndPastedNodes() != null )
+                && !to_pdf
+                && !to_graphics_file && getCopiedAndPastedNodes().contains( node.getId() ) ) {
+            g.setColor( getTreeColorSet().getFoundColor0() );
+        }
+        else if ( getControlPanel().isUseVisualStyles() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
+            g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
+        }
+        else if ( to_pdf ) {
+            g.setColor( getTreeColorSet().getBranchColorForPdf() );
+        }
+        else {
+            g.setColor( getTreeColorSet().getBranchColor() );
+        }
+    }
+
+    final private void blast( final PhylogenyNode node ) {
+        if ( !isCanBlast( node ) ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Insufficient information present",
+                                           "Cannot Blast",
+                                           JOptionPane.INFORMATION_MESSAGE );
+            return;
+        }
+        else {
+            final String query = Blast.obtainQueryForBlast( node );
+            System.out.println( "query for BLAST is: " + query );
+            char type = '?';
+            if ( !ForesterUtil.isEmpty( query ) ) {
+                if ( node.getNodeData().isHasSequence() ) {
+                    if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getType() ) ) {
+                        if ( node.getNodeData().getSequence().getType().toLowerCase()
+                                .equals( PhyloXmlUtil.SEQ_TYPE_PROTEIN ) ) {
+                            type = 'p';
+                        }
+                        else {
+                            type = 'n';
+                        }
+                    }
+                    else if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) {
+                        if ( ForesterUtil.seqIsLikelyToBeAa( node.getNodeData().getSequence().getMolecularSequence() ) ) {
+                            type = 'p';
+                        }
+                        else {
+                            type = 'n';
+                        }
+                    }
+                }
+                if ( type == '?' ) {
+                    if ( SequenceAccessionTools.isProteinDbQuery( query ) ) {
+                        type = 'p';
+                    }
                     else {
                     else {
-                        // if not in _found_nodes, clear _found_nodes
-                        handleClickToAction( _control_panel.getActionWhenNodeClicked(), node );
+                        type = 'n';
+                    }
+                }
+                JApplet applet = null;
+                if ( isApplet() ) {
+                    applet = obtainApplet();
+                }
+                try {
+                    Blast.openNcbiBlastWeb( query, type == 'n', applet, this );
+                }
+                catch ( final Exception e ) {
+                    e.printStackTrace();
+                }
+                if ( Constants.ALLOW_DDBJ_BLAST ) {
+                    try {
+                        System.out.println( "trying: " + query );
+                        final Blast s = new Blast();
+                        s.ddbjBlast( query );
+                    }
+                    catch ( final Exception e ) {
+                        e.printStackTrace();
+                    }
+                }
+            }
+        }
+    }
+
+    private final int calcDynamicHidingFactor() {
+        return ( int ) ( 0.5 + ( getTreeFontSet()._fm_large.getHeight() / ( 1.5 * getYdistance() ) ) );
+    }
+
+    /**
+     * Calculate the length of the distance between the given node and its
+     * parent.
+     * 
+     * @param node
+     * @param ext_node_x
+     * @factor
+     * @return the distance value
+     */
+    final private float calculateBranchLengthToParent( final PhylogenyNode node, final float factor ) {
+        if ( getControlPanel().isDrawPhylogram() ) {
+            if ( node.getDistanceToParent() < 0.0 ) {
+                return 0.0f;
+            }
+            return ( float ) ( getXcorrectionFactor() * node.getDistanceToParent() );
+        }
+        else {
+            if ( ( factor == 0 ) || isNonLinedUpCladogram() ) {
+                return getXdistance();
+            }
+            return getXdistance() * factor;
+        }
+    }
+
+    final private Color calculateColorForAnnotation( final SortedSet<Annotation> ann ) {
+        Color c = getTreeColorSet().getAnnotationColor();
+        if ( getControlPanel().isColorAccordingToAnnotation() && ( getControlPanel().getAnnotationColors() != null ) ) {
+            final StringBuilder sb = new StringBuilder();
+            for( final Annotation a : ann ) {
+                sb.append( !ForesterUtil.isEmpty( a.getRefValue() ) ? a.getRefValue() : a.getDesc() );
+            }
+            final String ann_str = sb.toString();
+            if ( !ForesterUtil.isEmpty( ann_str ) ) {
+                c = getControlPanel().getAnnotationColors().get( ann_str );
+                if ( c == null ) {
+                    c = TreePanelUtil.calculateColorFromString( ann_str, false );
+                    getControlPanel().getAnnotationColors().put( ann_str, c );
+                }
+                if ( c == null ) {
+                    c = getTreeColorSet().getAnnotationColor();
+                }
+            }
+        }
+        return c;
+    }
+
+    final private float calculateOvBranchLengthToParent( final PhylogenyNode node, final int factor ) {
+        if ( getControlPanel().isDrawPhylogram() ) {
+            if ( node.getDistanceToParent() < 0.0 ) {
+                return 0.0f;
+            }
+            return ( float ) ( getOvXcorrectionFactor() * node.getDistanceToParent() );
+        }
+        else {
+            if ( ( factor == 0 ) || isNonLinedUpCladogram() ) {
+                return getOvXDistance();
+            }
+            return getOvXDistance() * factor;
+        }
+    }
+
+    final private void cannotOpenBrowserWarningMessage( final String type_type ) {
+        JOptionPane.showMessageDialog( this,
+                                       "Cannot launch web browser for " + type_type + " data of this node",
+                                       "Cannot launch web browser",
+                                       JOptionPane.WARNING_MESSAGE );
+    }
+
+    final private void colorizeSubtree( final Color c,
+                                        final PhylogenyNode node,
+                                        final List<PhylogenyNode> additional_nodes ) {
+        _control_panel.setColorBranches( true );
+        if ( _control_panel.getUseVisualStylesCb() != null ) {
+            _control_panel.getUseVisualStylesCb().setSelected( true );
+        }
+        if ( node != null ) {
+            for( final PreorderTreeIterator it = new PreorderTreeIterator( node ); it.hasNext(); ) {
+                it.next().getBranchData().setBranchColor( new BranchColor( c ) );
+            }
+        }
+        if ( additional_nodes != null ) {
+            for( final PhylogenyNode n : additional_nodes ) {
+                n.getBranchData().setBranchColor( new BranchColor( c ) );
+            }
+        }
+        repaint();
+    }
+
+    final private void colorizeNodes( final Color c,
+                                      final PhylogenyNode node,
+                                      final List<PhylogenyNode> additional_nodes ) {
+        _control_panel.setColorBranches( true );
+        if ( _control_panel.getUseVisualStylesCb() != null ) {
+            _control_panel.getUseVisualStylesCb().setSelected( true );
+        }
+        if ( node != null ) {
+            colorizeNodesHelper( c, node );
+        }
+        if ( additional_nodes != null ) {
+            for( final PhylogenyNode n : additional_nodes ) {
+                colorizeNodesHelper( c, n );
+            }
+        }
+        repaint();
+    }
+
+    private final static void colorizeNodesHelper( final Color c, final PhylogenyNode node ) {
+        if ( node.getNodeData().getNodeVisualData() == null ) {
+            node.getNodeData().setNodeVisualData( new NodeVisualData() );
+        }
+        node.getNodeData().getNodeVisualData().setFontColor( new Color( c.getRed(), c.getGreen(), c.getBlue() ) );
+    }
+
+    final private void colorSubtree( final PhylogenyNode node ) {
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot colorize subtree in unrooted display type",
+                                           "Attempt to colorize subtree in unrooted display",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
+        }
+        _color_chooser.setPreviewPanel( new JPanel() );
+        SubtreeColorizationActionListener al;
+        if ( ( getFoundNodes0() != null ) || ( getFoundNodes1() != null ) ) {
+            final List<PhylogenyNode> additional_nodes = getFoundNodesAsListOfPhylogenyNodes();
+            al = new SubtreeColorizationActionListener( _color_chooser, node, additional_nodes );
+        }
+        else {
+            al = new SubtreeColorizationActionListener( _color_chooser, node );
+        }
+        final JDialog dialog = JColorChooser
+                .createDialog( this, "Subtree colorization", true, _color_chooser, al, null );
+        dialog.setVisible( true );
+    }
+
+    private void colorNodeFont( final PhylogenyNode node ) {
+        _color_chooser.setPreviewPanel( new JPanel() );
+        NodeColorizationActionListener al;
+        if ( ( getFoundNodes0() != null ) || ( getFoundNodes1() != null ) ) {
+            final List<PhylogenyNode> additional_nodes = getFoundNodesAsListOfPhylogenyNodes();
+            al = new NodeColorizationActionListener( _color_chooser, node, additional_nodes );
+        }
+        else {
+            al = new NodeColorizationActionListener( _color_chooser, node );
+        }
+        final JDialog dialog = JColorChooser.createDialog( this, "Node colorization", true, _color_chooser, al, null );
+        dialog.setVisible( true );
+    }
+
+    private void changeNodeFont( final PhylogenyNode node ) {
+        final FontChooser fc = new FontChooser();
+        Font f = null;
+        if ( ( node.getNodeData().getNodeVisualData() != null ) && !node.getNodeData().getNodeVisualData().isEmpty() ) {
+            f = node.getNodeData().getNodeVisualData().getFont();
+        }
+        if ( f != null ) {
+            fc.setFont( f );
+        }
+        else {
+            fc.setFont( getMainPanel().getTreeFontSet().getLargeFont() );
+        }
+        fc.showDialog( this, "Select Font" );
+        if ( ( fc.getFont() != null ) && !ForesterUtil.isEmpty( fc.getFont().getFamily().trim() ) ) {
+            List<PhylogenyNode> nodes = new ArrayList<PhylogenyNode>();
+            if ( ( getFoundNodes0() != null ) || ( getFoundNodes1() != null ) ) {
+                nodes = getFoundNodesAsListOfPhylogenyNodes();
+            }
+            nodes.add( node );
+            for( final PhylogenyNode n : nodes ) {
+                if ( n.getNodeData().getNodeVisualData() == null ) {
+                    n.getNodeData().setNodeVisualData( new NodeVisualData() );
+                }
+                final NodeVisualData vd = n.getNodeData().getNodeVisualData();
+                final Font ff = fc.getFont();
+                vd.setFontName( ff.getFamily().trim() );
+                int s = ff.getSize();
+                if ( s < 0 ) {
+                    s = 0;
+                }
+                if ( s > Byte.MAX_VALUE ) {
+                    s = Byte.MAX_VALUE;
+                }
+                vd.setFontSize( s );
+                vd.setFontStyle( ff.getStyle() );
+            }
+            if ( _control_panel.getUseVisualStylesCb() != null ) {
+                getControlPanel().getUseVisualStylesCb().setSelected( true );
+            }
+        }
+        repaint();
+    }
+
+    final private void copySubtree( final PhylogenyNode node ) {
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+            errorMessageNoCutCopyPasteInUnrootedDisplay();
+            return;
+        }
+        setNodeInPreorderToNull();
+        setCutOrCopiedTree( _phylogeny.copy( node ) );
+        final List<PhylogenyNode> nodes = PhylogenyMethods.getAllDescendants( node );
+        final Set<Long> node_ids = new HashSet<Long>( nodes.size() );
+        for( final PhylogenyNode n : nodes ) {
+            node_ids.add( n.getId() );
+        }
+        node_ids.add( node.getId() );
+        setCopiedAndPastedNodes( node_ids );
+        repaint();
+    }
+
+    final private String createASimpleTextRepresentationOfANode( final PhylogenyNode node ) {
+        final String tax = PhylogenyMethods.getSpecies( node );
+        String label = node.getName();
+        if ( !ForesterUtil.isEmpty( label ) && !ForesterUtil.isEmpty( tax ) ) {
+            label = label + " " + tax;
+        }
+        else if ( !ForesterUtil.isEmpty( tax ) ) {
+            label = tax;
+        }
+        else {
+            label = "";
+        }
+        if ( !ForesterUtil.isEmpty( label ) ) {
+            label = " [" + label + "]";
+        }
+        return label;
+    }
+
+    final private void cutSubtree( final PhylogenyNode node ) {
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+            errorMessageNoCutCopyPasteInUnrootedDisplay();
+            return;
+        }
+        if ( node.isRoot() ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot cut entire tree as subtree",
+                                           "Attempt to cut entire tree",
+                                           JOptionPane.ERROR_MESSAGE );
+            return;
+        }
+        final String label = createASimpleTextRepresentationOfANode( node );
+        final int r = JOptionPane.showConfirmDialog( null,
+                                                     "Cut subtree" + label + "?",
+                                                     "Confirm Cutting of Subtree",
+                                                     JOptionPane.YES_NO_OPTION );
+        if ( r != JOptionPane.OK_OPTION ) {
+            return;
+        }
+        setNodeInPreorderToNull();
+        setCopiedAndPastedNodes( null );
+        setCutOrCopiedTree( _phylogeny.copy( node ) );
+        _phylogeny.deleteSubtree( node, true );
+        _phylogeny.clearHashIdToNodeMap();
+        _phylogeny.recalculateNumberOfExternalDescendants( true );
+        resetNodeIdToDistToLeafMap();
+        setEdited( true );
+        repaint();
+    }
+
+    final private void cycleColors() {
+        getMainPanel().getTreeColorSet().cycleColorScheme();
+        for( final TreePanel tree_panel : getMainPanel().getTreePanels() ) {
+            tree_panel.setBackground( getMainPanel().getTreeColorSet().getBackgroundColor() );
+        }
+    }
+
+    final private void decreaseOvSize() {
+        if ( ( getOvMaxWidth() > 20 ) && ( getOvMaxHeight() > 20 ) ) {
+            setOvMaxWidth( getOvMaxWidth() - 5 );
+            setOvMaxHeight( getOvMaxHeight() - 5 );
+            updateOvSettings();
+            getControlPanel().displayedPhylogenyMightHaveChanged( false );
+        }
+    }
+
+    final private void deleteNodeOrSubtree( final PhylogenyNode node ) {
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+            errorMessageNoCutCopyPasteInUnrootedDisplay();
+            return;
+        }
+        if ( node.isRoot() && ( node.getNumberOfDescendants() != 1 ) ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot delete entire tree",
+                                           "Attempt to delete entire tree",
+                                           JOptionPane.ERROR_MESSAGE );
+            return;
+        }
+        final String label = createASimpleTextRepresentationOfANode( node );
+        final Object[] options = { "Node only", "Entire subtree", "Cancel" };
+        final int r = JOptionPane.showOptionDialog( this,
+                                                    "Delete" + label + "?",
+                                                    "Delete Node/Subtree",
+                                                    JOptionPane.CLOSED_OPTION,
+                                                    JOptionPane.QUESTION_MESSAGE,
+                                                    null,
+                                                    options,
+                                                    options[ 2 ] );
+        setNodeInPreorderToNull();
+        boolean node_only = true;
+        if ( r == 1 ) {
+            node_only = false;
+        }
+        else if ( r != 0 ) {
+            return;
+        }
+        if ( node_only ) {
+            PhylogenyMethods.removeNode( node, _phylogeny );
+        }
+        else {
+            _phylogeny.deleteSubtree( node, true );
+        }
+        _phylogeny.externalNodesHaveChanged();
+        _phylogeny.clearHashIdToNodeMap();
+        _phylogeny.recalculateNumberOfExternalDescendants( true );
+        resetNodeIdToDistToLeafMap();
+        setEdited( true );
+        repaint();
+    }
+
+    final private void displayNodePopupMenu( final PhylogenyNode node, final int x, final int y ) {
+        makePopupMenus( node );
+        _node_popup_menu.putClientProperty( NODE_POPMENU_NODE_CLIENT_PROPERTY, node );
+        _node_popup_menu.show( this, x, y );
+    }
+
+    final private void drawArc( final double x,
+                                final double y,
+                                final double width,
+                                final double heigth,
+                                final double start_angle,
+                                final double arc_angle,
+                                final Graphics2D g ) {
+        _arc.setArc( x, y, width, heigth, _180_OVER_PI * start_angle, _180_OVER_PI * arc_angle, Arc2D.OPEN );
+        g.draw( _arc );
+    }
+
+    final private void drawLine( final double x1, final double y1, final double x2, final double y2, final Graphics2D g ) {
+        if ( ( x1 == x2 ) && ( y1 == y2 ) ) {
+            return;
+        }
+        _line.setLine( x1, y1, x2, y2 );
+        g.draw( _line );
+    }
+
+    final private void drawOval( final double x,
+                                 final double y,
+                                 final double width,
+                                 final double heigth,
+                                 final Graphics2D g ) {
+        _ellipse.setFrame( x, y, width, heigth );
+        g.draw( _ellipse );
+    }
+
+    final private void drawOvalFilled( final double x,
+                                       final double y,
+                                       final double width,
+                                       final double heigth,
+                                       final Graphics2D g ) {
+        _ellipse.setFrame( x, y, width, heigth );
+        g.fill( _ellipse );
+    }
+
+    final private void drawOvalGradient( final double x,
+                                         final double y,
+                                         final double width,
+                                         final double heigth,
+                                         final Graphics2D g,
+                                         final Color color_1,
+                                         final Color color_2,
+                                         final Color color_border ) {
+        _ellipse.setFrame( x, y, width, heigth );
+        g.setPaint( new GradientPaint( ( float ) x,
+                                       ( float ) y,
+                                       color_1,
+                                       ( float ) ( x + width ),
+                                       ( float ) ( y + heigth ),
+                                       color_2,
+                                       false ) );
+        g.fill( _ellipse );
+        if ( color_border != null ) {
+            g.setPaint( color_border );
+            g.draw( _ellipse );
+        }
+    }
+
+    final private void drawRect( final float x, final float y, final float width, final float heigth, final Graphics2D g ) {
+        _rectangle.setFrame( x, y, width, heigth );
+        g.draw( _rectangle );
+    }
+
+    final private void drawRectFilled( final double x,
+                                       final double y,
+                                       final double width,
+                                       final double heigth,
+                                       final Graphics2D g ) {
+        _rectangle.setFrame( x, y, width, heigth );
+        g.fill( _rectangle );
+    }
+
+    final private void drawRectGradient( final double x,
+                                         final double y,
+                                         final double width,
+                                         final double heigth,
+                                         final Graphics2D g,
+                                         final Color color_1,
+                                         final Color color_2,
+                                         final Color color_border ) {
+        _rectangle.setFrame( x, y, width, heigth );
+        g.setPaint( new GradientPaint( ( float ) x,
+                                       ( float ) y,
+                                       color_1,
+                                       ( float ) ( x + width ),
+                                       ( float ) ( y + heigth ),
+                                       color_2,
+                                       false ) );
+        g.fill( _rectangle );
+        if ( color_border != null ) {
+            g.setPaint( color_border );
+            g.draw( _rectangle );
+        }
+    }
+
+    private double drawTaxonomyImage( final double x, final double y, final PhylogenyNode node, final Graphics2D g ) {
+        final List<Uri> us = new ArrayList<Uri>();
+        for( final Taxonomy t : node.getNodeData().getTaxonomies() ) {
+            for( final Uri uri : t.getUris() ) {
+                us.add( uri );
+            }
+        }
+        double offset = 0;
+        for( final Uri uri : us ) {
+            if ( uri != null ) {
+                final String uri_str = uri.getValue().toString().toLowerCase();
+                if ( getImageMap().containsKey( uri_str ) ) {
+                    final BufferedImage bi = getImageMap().get( uri_str );
+                    if ( ( bi != null ) && ( bi.getHeight() > 5 ) && ( bi.getWidth() > 5 ) ) {
+                        double scaling_factor = 1;
+                        if ( getOptions().isAllowMagnificationOfTaxonomyImages()
+                                || ( bi.getHeight() > ( 1.8 * getYdistance() ) ) ) {
+                            scaling_factor = ( 1.8 * getYdistance() ) / bi.getHeight();
+                        }
+                        // y = y - ( 0.9 * getYdistance() );
+                        final double hs = bi.getHeight() * scaling_factor;
+                        double ws = ( bi.getWidth() * scaling_factor ) + offset;
+                        final double my_y = y - ( 0.5 * hs );
+                        final int x_w = ( int ) ( x + ws + 0.5 );
+                        final int y_h = ( int ) ( my_y + hs + 0.5 );
+                        if ( ( ( x_w - x ) > 7 ) && ( ( y_h - my_y ) > 7 ) ) {
+                            g.drawImage( bi,
+                                         ( int ) ( x + 0.5 + offset ),
+                                         ( int ) ( my_y + 0.5 ),
+                                         x_w,
+                                         y_h,
+                                         0,
+                                         0,
+                                         bi.getWidth(),
+                                         bi.getHeight(),
+                                         null );
+                            ws += 8;
+                        }
+                        else {
+                            ws = 0.0;
+                        }
+                        offset = ws;
                     }
                 }
             }
                     }
                 }
             }
-            else {
-                // no node was clicked
-                _highlight_node = null;
+        }
+        return offset;
+    }
+
+    final private void errorMessageNoCutCopyPasteInUnrootedDisplay() {
+        JOptionPane.showMessageDialog( this,
+                                       "Cannot cut, copy, paste, add, or delete subtrees/nodes in unrooted display",
+                                       "Attempt to cut/copy/paste/add/delete in unrooted display",
+                                       JOptionPane.ERROR_MESSAGE );
+    }
+
+    private final Color getColorForFoundNode( final PhylogenyNode n ) {
+        if ( isInCurrentExternalNodes( n ) ) {
+            return getTreeColorSet().getFoundColor0();
+        }
+        else if ( isInFoundNodes0( n ) && !isInFoundNodes1( n ) ) {
+            return getTreeColorSet().getFoundColor0();
+        }
+        else if ( !isInFoundNodes0( n ) && isInFoundNodes1( n ) ) {
+            return getTreeColorSet().getFoundColor1();
+        }
+        else {
+            return getTreeColorSet().getFoundColor0and1();
+        }
+    }
+
+    final private Set<Long> getCopiedAndPastedNodes() {
+        return getMainPanel().getCopiedAndPastedNodes();
+    }
+
+    final private Set<Long> getCurrentExternalNodes() {
+        return _current_external_nodes;
+    }
+
+    final private Phylogeny getCutOrCopiedTree() {
+        return getMainPanel().getCutOrCopiedTree();
+    }
+
+    private List<PhylogenyNode> getFoundNodesAsListOfPhylogenyNodes() {
+        final List<PhylogenyNode> additional_nodes = new ArrayList<PhylogenyNode>();
+        if ( getFoundNodes0() != null ) {
+            for( final Long id : getFoundNodes0() ) {
+                additional_nodes.add( _phylogeny.getNode( id ) );
             }
         }
             }
         }
-        repaint();
+        if ( getFoundNodes1() != null ) {
+            for( final Long id : getFoundNodes1() ) {
+                if ( ( getFoundNodes0() == null ) || !getFoundNodes0().contains( id ) ) {
+                    additional_nodes.add( _phylogeny.getNode( id ) );
+                }
+            }
+        }
+        return additional_nodes;
+    }
+
+    final private float getLastDragPointX() {
+        return _last_drag_point_x;
+    }
+
+    final private float getLastDragPointY() {
+        return _last_drag_point_y;
+    }
+
+    final private short getMaxBranchesToLeaf( final PhylogenyNode node ) {
+        if ( !_nodeid_dist_to_leaf.containsKey( node.getId() ) ) {
+            final short m = PhylogenyMethods.calculateMaxBranchesToLeaf( node );
+            _nodeid_dist_to_leaf.put( node.getId(), m );
+            return m;
+        }
+        else {
+            return _nodeid_dist_to_leaf.get( node.getId() );
+        }
+    }
+
+    final private double getMaxDistanceToRoot() {
+        if ( _max_distance_to_root < 0 ) {
+            recalculateMaxDistanceToRoot();
+        }
+        return _max_distance_to_root;
+    }
+
+    final private float getOvMaxHeight() {
+        return _ov_max_height;
+    }
+
+    final private float getOvMaxWidth() {
+        return _ov_max_width;
+    }
+
+    final private float getOvXcorrectionFactor() {
+        return _ov_x_correction_factor;
+    }
+
+    final private float getOvXDistance() {
+        return _ov_x_distance;
+    }
+
+    final private int getOvXPosition() {
+        return _ov_x_position;
+    }
+
+    final private float getOvYDistance() {
+        return _ov_y_distance;
+    }
+
+    final private int getOvYPosition() {
+        return _ov_y_position;
+    }
+
+    final private int getOvYStart() {
+        return _ov_y_start;
+    }
+
+    final private List<Accession> getPdbAccs( final PhylogenyNode node ) {
+        final List<Accession> pdb_ids = new ArrayList<Accession>();
+        if ( node.getNodeData().isHasSequence() ) {
+            final Sequence seq = node.getNodeData().getSequence();
+            if ( !ForesterUtil.isEmpty( seq.getCrossReferences() ) ) {
+                final SortedSet<Accession> cross_refs = seq.getCrossReferences();
+                for( final Accession acc : cross_refs ) {
+                    if ( acc.getSource().equalsIgnoreCase( "pdb" ) ) {
+                        pdb_ids.add( acc );
+                    }
+                }
+            }
+        }
+        return pdb_ids;
+    }
+
+    final private double getScaleDistance() {
+        return _scale_distance;
+    }
+
+    final private String getScaleLabel() {
+        return _scale_label;
+    }
+
+    final private TreeFontSet getTreeFontSet() {
+        return getMainPanel().getTreeFontSet();
+    }
+
+    final private float getUrtFactor() {
+        return _urt_factor;
+    }
+
+    final private float getUrtFactorOv() {
+        return _urt_factor_ov;
+    }
+
+    final private void handleClickToAction( final NodeClickAction action, final PhylogenyNode node ) {
+        switch ( action ) {
+            case SHOW_DATA:
+                showNodeFrame( node );
+                break;
+            case COLLAPSE:
+                collapse( node );
+                break;
+            case REROOT:
+                reRoot( node );
+                break;
+            case SUBTREE:
+                subTree( node );
+                break;
+            case SWAP:
+                swap( node );
+                break;
+            case COLOR_SUBTREE:
+                colorSubtree( node );
+                break;
+            case COLOR_NODE_FONT:
+                colorNodeFont( node );
+                break;
+            case CHANGE_NODE_FONT:
+                changeNodeFont( node );
+                break;
+            case OPEN_SEQ_WEB:
+                openSeqWeb( node );
+                break;
+            case BLAST:
+                blast( node );
+                break;
+            case OPEN_TAX_WEB:
+                openTaxWeb( node );
+                break;
+            case OPEN_PDB_WEB:
+                openPdbWeb( node );
+                break;
+            case CUT_SUBTREE:
+                cutSubtree( node );
+                break;
+            case COPY_SUBTREE:
+                copySubtree( node );
+                break;
+            case PASTE_SUBTREE:
+                pasteSubtree( node );
+                break;
+            case DELETE_NODE_OR_SUBTREE:
+                deleteNodeOrSubtree( node );
+                break;
+            case ADD_NEW_NODE:
+                addEmptyNode( node );
+                break;
+            case EDIT_NODE_DATA:
+                showNodeEditFrame( node );
+                break;
+            case SELECT_NODES:
+                selectNode( node );
+                break;
+            case SORT_DESCENDENTS:
+                sortDescendants( node );
+                break;
+            case GET_EXT_DESC_DATA:
+                showExtDescNodeData( node );
+                break;
+            default:
+                throw new IllegalArgumentException( "unknown action: " + action );
+        }
+    }
+
+    final private void increaseCurrentExternalNodesDataBufferChangeCounter() {
+        _current_external_nodes_data_buffer_change_counter++;
+    }
+
+    final private void increaseOvSize() {
+        if ( ( getOvMaxWidth() < ( getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect().getWidth() / 2 ) )
+                && ( getOvMaxHeight() < ( getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect()
+                        .getHeight() / 2 ) ) ) {
+            setOvMaxWidth( getOvMaxWidth() + 5 );
+            setOvMaxHeight( getOvMaxHeight() + 5 );
+            updateOvSettings();
+            getControlPanel().displayedPhylogenyMightHaveChanged( false );
+        }
+    }
+
+    final private void init() {
+        _color_chooser = new JColorChooser();
+        _rollover_popup = new JTextArea();
+        _rollover_popup.setFont( POPUP_FONT );
+        resetNodeIdToDistToLeafMap();
+        setTextAntialias();
+        setTreeFile( null );
+        setEdited( false );
+        initializeOvSettings();
+        setStartingAngle( ( TWO_PI * 3 ) / 4 );
+        final ImageLoader il = new ImageLoader( this );
+        new Thread( il ).start();
+    }
+
+    final private void initializeOvSettings() {
+        setOvMaxHeight( getConfiguration().getOvMaxHeight() );
+        setOvMaxWidth( getConfiguration().getOvMaxWidth() );
+    }
+
+    final private boolean inOvVirtualRectangle( final int x, final int y ) {
+        return ( ( x >= ( getOvVirtualRectangle().x - 1 ) )
+                && ( x <= ( getOvVirtualRectangle().x + getOvVirtualRectangle().width + 1 ) )
+                && ( y >= ( getOvVirtualRectangle().y - 1 ) ) && ( y <= ( getOvVirtualRectangle().y
+                + getOvVirtualRectangle().height + 1 ) ) );
+    }
+
+    final private boolean inOvVirtualRectangle( final MouseEvent e ) {
+        return ( inOvVirtualRectangle( e.getX(), e.getY() ) );
     }
 
     }
 
-    final void mouseDragInBrowserPanel( final MouseEvent e ) {
-        setCursor( MOVE_CURSOR );
-        final Point scroll_position = getMainPanel().getCurrentScrollPane().getViewport().getViewPosition();
-        scroll_position.x -= ( e.getX() - getLastDragPointX() );
-        scroll_position.y -= ( e.getY() - getLastDragPointY() );
-        if ( scroll_position.x < 0 ) {
-            scroll_position.x = 0;
-        }
-        else {
-            final int max_x = getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getMaximum()
-                    - getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getVisibleAmount();
-            if ( scroll_position.x > max_x ) {
-                scroll_position.x = max_x;
-            }
-        }
-        if ( scroll_position.y < 0 ) {
-            scroll_position.y = 0;
-        }
-        else {
-            final int max_y = getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getMaximum()
-                    - getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getVisibleAmount();
-            if ( scroll_position.y > max_y ) {
-                scroll_position.y = max_y;
-            }
-        }
-        if ( isOvOn() || getOptions().isShowScale() ) {
-            repaint();
+    final private boolean isCanBlast( final PhylogenyNode node ) {
+        if ( !node.getNodeData().isHasSequence() && ForesterUtil.isEmpty( node.getName() ) ) {
+            return false;
         }
         }
-        getMainPanel().getCurrentScrollPane().getViewport().setViewPosition( scroll_position );
+        return Blast.isContainsQueryForBlast( node );
     }
 
     }
 
-    final void mouseDragInOvRectangle( final MouseEvent e ) {
-        setCursor( HAND_CURSOR );
-        final double w_ratio = getVisibleRect().width / getOvRectangle().getWidth();
-        final double h_ratio = getVisibleRect().height / getOvRectangle().getHeight();
-        final Point scroll_position = getMainPanel().getCurrentScrollPane().getViewport().getViewPosition();
-        double dx = ( w_ratio * e.getX() - w_ratio * getLastDragPointX() );
-        double dy = ( h_ratio * e.getY() - h_ratio * getLastDragPointY() );
-        scroll_position.x = ForesterUtil.roundToInt( scroll_position.x + dx );
-        scroll_position.y = ForesterUtil.roundToInt( scroll_position.y + dy );
-        if ( scroll_position.x <= 0 ) {
-            scroll_position.x = 0;
-            dx = 0;
-        }
-        else {
-            final int max_x = getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getMaximum()
-                    - getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getVisibleAmount();
-            if ( scroll_position.x >= max_x ) {
-                dx = 0;
-                scroll_position.x = max_x;
-            }
+    final private String isCanOpenSeqWeb( final PhylogenyNode node ) {
+        final Accession a = SequenceAccessionTools.obtainAccessorFromDataFields( node );
+        if ( a != null ) {
+            return a.getValue();
         }
         }
-        if ( scroll_position.y <= 0 ) {
-            dy = 0;
-            scroll_position.y = 0;
+        return null;
+    }
+
+    final private boolean isCanOpenTaxWeb( final PhylogenyNode node ) {
+        if ( node.getNodeData().isHasTaxonomy()
+                && ( ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) )
+                        || ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) )
+                        || ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getCommonName() ) ) || ( ( node
+                        .getNodeData().getTaxonomy().getIdentifier() != null ) && !ForesterUtil.isEmpty( node
+                        .getNodeData().getTaxonomy().getIdentifier().getValue() ) ) ) ) {
+            return true;
         }
         else {
         }
         else {
-            final int max_y = getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getMaximum()
-                    - getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getVisibleAmount();
-            if ( scroll_position.y >= max_y ) {
-                dy = 0;
-                scroll_position.y = max_y;
-            }
+            return false;
         }
         }
-        repaint();
-        getMainPanel().getCurrentScrollPane().getViewport().setViewPosition( scroll_position );
-        setLastMouseDragPointX( ( float ) ( e.getX() + dx ) );
-        setLastMouseDragPointY( ( float ) ( e.getY() + dy ) );
     }
 
     }
 
-    final void mouseMoved( final MouseEvent e ) {
-        requestFocusInWindow();
-        if ( getControlPanel().isNodeDescPopup() ) {
-            if ( _node_desc_popup != null ) {
-                _node_desc_popup.hide();
-                _node_desc_popup = null;
-            }
+    final private boolean isInCurrentExternalNodes( final PhylogenyNode node ) {
+        return ( ( getCurrentExternalNodes() != null ) && getCurrentExternalNodes().contains( node.getId() ) );
+    }
+
+    private boolean isInFoundNodes( final PhylogenyNode n ) {
+        return isInFoundNodes0( n ) || isInFoundNodes1( n );
+    }
+
+    final private boolean isInFoundNodes0( final PhylogenyNode node ) {
+        return ( ( getFoundNodes0() != null ) && getFoundNodes0().contains( node.getId() ) );
+    }
+
+    final private boolean isInFoundNodes1( final PhylogenyNode node ) {
+        return ( ( getFoundNodes1() != null ) && getFoundNodes1().contains( node.getId() ) );
+    }
+
+    final private boolean isInOv() {
+        return _in_ov;
+    }
+
+    final private boolean isNodeDataInvisible( final PhylogenyNode node ) {
+        int y_dist = 40;
+        if ( getControlPanel().isShowTaxonomyImages() ) {
+            y_dist = 40 + ( int ) getYdistance();
         }
         }
-        if ( getOptions().isShowOverview() && isOvOn() ) {
-            if ( inOvVirtualRectangle( e ) ) {
+        return ( ( node.getYcoord() < ( getVisibleRect().getMinY() - y_dist ) )
+                || ( node.getYcoord() > ( getVisibleRect().getMaxY() + y_dist ) ) || ( ( node.getParent() != null ) && ( node
+                .getParent().getXcoord() > getVisibleRect().getMaxX() ) ) );
+    }
+
+    final private boolean isNodeDataInvisibleUnrootedCirc( final PhylogenyNode node ) {
+        return ( ( node.getYcoord() < ( getVisibleRect().getMinY() - 20 ) )
+                || ( node.getYcoord() > ( getVisibleRect().getMaxY() + 20 ) )
+                || ( node.getXcoord() < ( getVisibleRect().getMinX() - 20 ) ) || ( node.getXcoord() > ( getVisibleRect()
+                .getMaxX() + 20 ) ) );
+    }
+
+    final private boolean isNonLinedUpCladogram() {
+        return getOptions().getCladogramType() == CLADOGRAM_TYPE.NON_LINED_UP;
+    }
+
+    final private boolean isUniformBranchLengthsForCladogram() {
+        return getOptions().getCladogramType() == CLADOGRAM_TYPE.TOTAL_NODE_SUM_DEP;
+    }
+
+    final private void keyPressedCalls( final KeyEvent e ) {
+        if ( isOvOn() && ( getMousePosition() != null ) && ( getMousePosition().getLocation() != null ) ) {
+            if ( inOvVirtualRectangle( getMousePosition().x, getMousePosition().y ) ) {
                 if ( !isInOvRect() ) {
                     setInOvRect( true );
                 if ( !isInOvRect() ) {
                     setInOvRect( true );
-                    repaint();
                 }
             }
                 }
             }
-            else {
-                if ( isInOvRect() ) {
-                    setInOvRect( false );
-                    repaint();
-                }
+            else if ( isInOvRect() ) {
+                setInOvRect( false );
             }
         }
             }
         }
-        if ( inOv( e ) && getOptions().isShowOverview() && isOvOn() ) {
-            if ( !isInOv() ) {
-                setInOv( true );
+        if ( e.getModifiersEx() == InputEvent.CTRL_DOWN_MASK ) {
+            if ( ( e.getKeyCode() == KeyEvent.VK_DELETE ) || ( e.getKeyCode() == KeyEvent.VK_HOME )
+                    || ( e.getKeyCode() == KeyEvent.VK_F ) ) {
+                getMainPanel().getTreeFontSet().mediumFonts();
+                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            }
+            else if ( ( e.getKeyCode() == KeyEvent.VK_SUBTRACT ) || ( e.getKeyCode() == KeyEvent.VK_MINUS ) ) {
+                getMainPanel().getTreeFontSet().decreaseFontSize( 1, false );
+                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            }
+            else if ( plusPressed( e.getKeyCode() ) ) {
+                getMainPanel().getTreeFontSet().increaseFontSize();
+                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true );
             }
         }
         else {
             }
         }
         else {
-            if ( isInOv() ) {
-                setInOv( false );
+            if ( ( e.getKeyCode() == KeyEvent.VK_DELETE ) || ( e.getKeyCode() == KeyEvent.VK_HOME )
+                    || ( e.getKeyCode() == KeyEvent.VK_F ) ) {
+                getControlPanel().showWhole();
             }
             }
-            final PhylogenyNode node = findNode( e.getX(), e.getY() );
-            if ( ( node != null ) && ( node.isRoot() || !node.getParent().isCollapse() ) ) {
-                // cursor is over a tree node
-                if ( ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.CUT_SUBTREE )
-                        || ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.COPY_SUBTREE )
-                        || ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.PASTE_SUBTREE )
-                        || ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.DELETE_NODE_OR_SUBTREE )
-                        || ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.REROOT )
-                        || ( getControlPanel().getActionWhenNodeClicked() == NodeClickAction.ADD_NEW_NODE ) ) {
-                    setCursor( CUT_CURSOR );
+            else if ( ( e.getKeyCode() == KeyEvent.VK_UP ) || ( e.getKeyCode() == KeyEvent.VK_DOWN )
+                    || ( e.getKeyCode() == KeyEvent.VK_LEFT ) || ( e.getKeyCode() == KeyEvent.VK_RIGHT ) ) {
+                if ( e.getModifiersEx() == InputEvent.SHIFT_DOWN_MASK ) {
+                    if ( e.getKeyCode() == KeyEvent.VK_UP ) {
+                        getMainPanel().getControlPanel().zoomInY( Constants.WHEEL_ZOOM_IN_FACTOR );
+                        getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                    }
+                    else if ( e.getKeyCode() == KeyEvent.VK_DOWN ) {
+                        getMainPanel().getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
+                        getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                    }
+                    else if ( e.getKeyCode() == KeyEvent.VK_LEFT ) {
+                        getMainPanel().getControlPanel().zoomOutX( Constants.WHEEL_ZOOM_OUT_FACTOR,
+                                                                   Constants.WHEEL_ZOOM_OUT_X_CORRECTION_FACTOR );
+                        getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                    }
+                    else if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) {
+                        getMainPanel().getControlPanel().zoomInX( Constants.WHEEL_ZOOM_IN_FACTOR,
+                                                                  Constants.WHEEL_ZOOM_IN_FACTOR );
+                        getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                    }
+                }
+                else {
+                    final int d = 80;
+                    int dx = 0;
+                    int dy = -d;
+                    if ( e.getKeyCode() == KeyEvent.VK_DOWN ) {
+                        dy = d;
+                    }
+                    else if ( e.getKeyCode() == KeyEvent.VK_LEFT ) {
+                        dx = -d;
+                        dy = 0;
+                    }
+                    else if ( e.getKeyCode() == KeyEvent.VK_RIGHT ) {
+                        dx = d;
+                        dy = 0;
+                    }
+                    final Point scroll_position = getMainPanel().getCurrentScrollPane().getViewport().getViewPosition();
+                    scroll_position.x = scroll_position.x + dx;
+                    scroll_position.y = scroll_position.y + dy;
+                    if ( scroll_position.x <= 0 ) {
+                        scroll_position.x = 0;
+                    }
+                    else {
+                        final int max_x = getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getMaximum()
+                                - getMainPanel().getCurrentScrollPane().getHorizontalScrollBar().getVisibleAmount();
+                        if ( scroll_position.x >= max_x ) {
+                            scroll_position.x = max_x;
+                        }
+                    }
+                    if ( scroll_position.y <= 0 ) {
+                        scroll_position.y = 0;
+                    }
+                    else {
+                        final int max_y = getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getMaximum()
+                                - getMainPanel().getCurrentScrollPane().getVerticalScrollBar().getVisibleAmount();
+                        if ( scroll_position.y >= max_y ) {
+                            scroll_position.y = max_y;
+                        }
+                    }
+                    repaint();
+                    getMainPanel().getCurrentScrollPane().getViewport().setViewPosition( scroll_position );
+                }
+            }
+            else if ( ( e.getKeyCode() == KeyEvent.VK_SUBTRACT ) || ( e.getKeyCode() == KeyEvent.VK_MINUS ) ) {
+                getMainPanel().getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
+                getMainPanel().getControlPanel().zoomOutX( Constants.WHEEL_ZOOM_OUT_FACTOR,
+                                                           Constants.WHEEL_ZOOM_OUT_X_CORRECTION_FACTOR );
+                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
+            }
+            else if ( plusPressed( e.getKeyCode() ) ) {
+                getMainPanel().getControlPanel().zoomInX( Constants.WHEEL_ZOOM_IN_FACTOR,
+                                                          Constants.WHEEL_ZOOM_IN_FACTOR );
+                getMainPanel().getControlPanel().zoomInY( Constants.WHEEL_ZOOM_IN_FACTOR );
+                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
+            }
+            else if ( e.getKeyCode() == KeyEvent.VK_S ) {
+                if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
+                        || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
+                    setStartingAngle( ( getStartingAngle() % TWO_PI ) + ANGLE_ROTATION_UNIT );
+                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                }
+            }
+            else if ( e.getKeyCode() == KeyEvent.VK_A ) {
+                if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
+                        || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
+                    setStartingAngle( ( getStartingAngle() % TWO_PI ) - ANGLE_ROTATION_UNIT );
+                    if ( getStartingAngle() < 0 ) {
+                        setStartingAngle( TWO_PI + getStartingAngle() );
+                    }
+                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                }
+            }
+            else if ( e.getKeyCode() == KeyEvent.VK_D ) {
+                boolean selected = false;
+                if ( getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.HORIZONTAL ) {
+                    getOptions().setNodeLabelDirection( NODE_LABEL_DIRECTION.RADIAL );
+                    selected = true;
+                }
+                else {
+                    getOptions().setNodeLabelDirection( NODE_LABEL_DIRECTION.HORIZONTAL );
+                }
+                if ( getMainPanel().getMainFrame() == null ) {
+                    // Must be "E" applet version.
+                    final ArchaeopteryxE ae = ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet();
+                    if ( ae.getlabelDirectionCbmi() != null ) {
+                        ae.getlabelDirectionCbmi().setSelected( selected );
+                    }
                 }
                 else {
                 }
                 else {
-                    setCursor( HAND_CURSOR );
-                    if ( getControlPanel().isNodeDescPopup() ) {
-                        showNodeDataPopup( e, node );
-                    }
+                    getMainPanel().getMainFrame().getlabelDirectionCbmi().setSelected( selected );
                 }
                 }
+                repaint();
             }
             }
-            else {
-                setCursor( ARROW_CURSOR );
+            else if ( e.getKeyCode() == KeyEvent.VK_X ) {
+                switchDisplaygetPhylogenyGraphicsType();
+                repaint();
             }
             }
-        }
-    }
-
-    final void mouseReleasedInBrowserPanel( final MouseEvent e ) {
-        setCursor( ARROW_CURSOR );
-    }
-
-    final public void mouseWheelMoved( final MouseWheelEvent e ) {
-        final int notches = e.getWheelRotation();
-        if ( inOvVirtualRectangle( e ) ) {
-            if ( !isInOvRect() ) {
-                setInOvRect( true );
+            else if ( e.getKeyCode() == KeyEvent.VK_C ) {
+                cycleColors();
                 repaint();
             }
                 repaint();
             }
-        }
-        else {
-            if ( isInOvRect() ) {
-                setInOvRect( false );
+            else if ( getOptions().isShowOverview() && isOvOn() && ( e.getKeyCode() == KeyEvent.VK_O ) ) {
+                MainFrame.cycleOverview( getOptions(), this );
                 repaint();
             }
                 repaint();
             }
-        }
-        if ( e.isControlDown() ) {
-            if ( notches < 0 ) {
-                getTreeFontSet().increaseFontSize();
-                getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            else if ( getOptions().isShowOverview() && isOvOn() && ( e.getKeyCode() == KeyEvent.VK_I ) ) {
+                increaseOvSize();
             }
             }
-            else {
-                getTreeFontSet().decreaseFontSize();
-                getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            else if ( getOptions().isShowOverview() && isOvOn() && ( e.getKeyCode() == KeyEvent.VK_U ) ) {
+                decreaseOvSize();
             }
             }
+            e.consume();
         }
         }
-        else if ( e.isShiftDown() ) {
-            if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
-                    || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
-                if ( notches < 0 ) {
-                    for( int i = 0; i < ( -notches ); ++i ) {
-                        setStartingAngle( ( getStartingAngle() % TWO_PI ) + ANGLE_ROTATION_UNIT );
-                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
-                    }
+    }
+
+    final private void makePopupMenus( final PhylogenyNode node ) {
+        _node_popup_menu = new JPopupMenu();
+        final List<String> clickto_names = _main_panel.getControlPanel().getSingleClickToNames();
+        _node_popup_menu_items = new JMenuItem[ clickto_names.size() ];
+        for( int i = 0; i < clickto_names.size(); i++ ) {
+            final String title = clickto_names.get( i );
+            _node_popup_menu_items[ i ] = new JMenuItem( title );
+            if ( title.equals( Configuration.clickto_options[ Configuration.open_seq_web ][ 0 ] ) ) {
+                final String id = isCanOpenSeqWeb( node );
+                if ( !ForesterUtil.isEmpty( id ) ) {
+                    _node_popup_menu_items[ i ].setText( _node_popup_menu_items[ i ].getText() + " [" + id + "]" );
+                    _node_popup_menu_items[ i ].setEnabled( true );
                 }
                 else {
                 }
                 else {
-                    for( int i = 0; i < notches; ++i ) {
-                        setStartingAngle( ( getStartingAngle() % TWO_PI ) - ANGLE_ROTATION_UNIT );
-                        if ( getStartingAngle() < 0 ) {
-                            setStartingAngle( TWO_PI + getStartingAngle() );
-                        }
-                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
-                    }
+                    _node_popup_menu_items[ i ].setEnabled( false );
                 }
             }
                 }
             }
-            else {
-                if ( notches < 0 ) {
-                    for( int i = 0; i < ( -notches ); ++i ) {
-                        getControlPanel().zoomInY( Constants.WHEEL_ZOOM_IN_FACTOR );
-                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
+            else if ( title.equals( Configuration.clickto_options[ Configuration.open_pdb_web ][ 0 ] ) ) {
+                final List<Accession> accs = getPdbAccs( node );
+                _node_popup_menu_items[ i ] = new JMenuItem( title );
+                if ( !ForesterUtil.isEmpty( accs ) ) {
+                    if ( accs.size() == 1 ) {
+                        _node_popup_menu_items[ i ].setText( _node_popup_menu_items[ i ].getText() + " ["
+                                + TreePanelUtil.pdbAccToString( accs, 0 ) + "]" );
+                        _node_popup_menu_items[ i ].setEnabled( true );
+                    }
+                    else if ( accs.size() == 2 ) {
+                        _node_popup_menu_items[ i ].setText( _node_popup_menu_items[ i ].getText() + " ["
+                                + TreePanelUtil.pdbAccToString( accs, 0 ) + ", "
+                                + TreePanelUtil.pdbAccToString( accs, 1 ) + "]" );
+                        _node_popup_menu_items[ i ].setEnabled( true );
+                    }
+                    else if ( accs.size() == 3 ) {
+                        _node_popup_menu_items[ i ].setText( _node_popup_menu_items[ i ].getText() + " ["
+                                + TreePanelUtil.pdbAccToString( accs, 0 ) + ", "
+                                + TreePanelUtil.pdbAccToString( accs, 1 ) + ", "
+                                + TreePanelUtil.pdbAccToString( accs, 2 ) + "]" );
+                        _node_popup_menu_items[ i ].setEnabled( true );
+                    }
+                    else {
+                        _node_popup_menu_items[ i ].setText( _node_popup_menu_items[ i ].getText() + " ["
+                                + TreePanelUtil.pdbAccToString( accs, 0 ) + ", "
+                                + TreePanelUtil.pdbAccToString( accs, 1 ) + ", "
+                                + TreePanelUtil.pdbAccToString( accs, 2 ) + ", + " + ( accs.size() - 3 ) + " more]" );
+                        _node_popup_menu_items[ i ].setEnabled( true );
                     }
                 }
                 else {
                     }
                 }
                 else {
-                    for( int i = 0; i < notches; ++i ) {
-                        getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
-                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
-                    }
+                    _node_popup_menu_items[ i ].setEnabled( false );
                 }
                 }
+                //
             }
             }
-        }
-        else {
-            if ( notches < 0 ) {
-                for( int i = 0; i < ( -notches ); ++i ) {
-                    getControlPanel().zoomInX( Constants.WHEEL_ZOOM_IN_FACTOR,
-                                               Constants.WHEEL_ZOOM_IN_X_CORRECTION_FACTOR );
-                    getControlPanel().zoomInY( Constants.WHEEL_ZOOM_IN_FACTOR );
-                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
+            else if ( title.equals( Configuration.clickto_options[ Configuration.open_tax_web ][ 0 ] ) ) {
+                _node_popup_menu_items[ i ].setEnabled( isCanOpenTaxWeb( node ) );
+            }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.blast ][ 0 ] ) ) {
+                _node_popup_menu_items[ i ].setEnabled( isCanBlast( node ) );
+            }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.delete_subtree_or_node ][ 0 ] ) ) {
+                if ( !getOptions().isEditable() ) {
+                    continue;
                 }
                 }
+                _node_popup_menu_items[ i ].setEnabled( isCanDelete() );
             }
             }
-            else {
-                for( int i = 0; i < notches; ++i ) {
-                    getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
-                    getControlPanel().zoomOutX( Constants.WHEEL_ZOOM_OUT_FACTOR,
-                                                Constants.WHEEL_ZOOM_OUT_X_CORRECTION_FACTOR );
-                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
+            else if ( title.equals( Configuration.clickto_options[ Configuration.cut_subtree ][ 0 ] ) ) {
+                if ( !getOptions().isEditable() ) {
+                    continue;
+                }
+                _node_popup_menu_items[ i ].setEnabled( isCanCut( node ) );
+            }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.copy_subtree ][ 0 ] ) ) {
+                if ( !getOptions().isEditable() ) {
+                    continue;
+                }
+                _node_popup_menu_items[ i ].setEnabled( isCanCopy() );
+            }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.paste_subtree ][ 0 ] ) ) {
+                if ( !getOptions().isEditable() ) {
+                    continue;
+                }
+                _node_popup_menu_items[ i ].setEnabled( isCanPaste() );
+            }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.edit_node_data ][ 0 ] ) ) {
+                if ( !getOptions().isEditable() ) {
+                    continue;
+                }
+            }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.add_new_node ][ 0 ] ) ) {
+                if ( !getOptions().isEditable() ) {
+                    continue;
                 }
             }
                 }
             }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.reroot ][ 0 ] ) ) {
+                _node_popup_menu_items[ i ].setEnabled( isCanReroot() );
+            }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.collapse_uncollapse ][ 0 ] ) ) {
+                _node_popup_menu_items[ i ].setEnabled( ( isCanCollapse() && !node.isExternal() ) );
+            }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.color_subtree ][ 0 ] ) ) {
+                _node_popup_menu_items[ i ].setEnabled( isCanColorSubtree() );
+            }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.subtree ][ 0 ] ) ) {
+                _node_popup_menu_items[ i ].setEnabled( isCanSubtree( node ) );
+            }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.swap ][ 0 ] ) ) {
+                _node_popup_menu_items[ i ].setEnabled( node.getNumberOfDescendants() == 2 );
+            }
+            else if ( title.equals( Configuration.clickto_options[ Configuration.sort_descendents ][ 0 ] ) ) {
+                _node_popup_menu_items[ i ].setEnabled( node.getNumberOfDescendants() > 1 );
+            }
+            _node_popup_menu_items[ i ].addActionListener( this );
+            _node_popup_menu.add( _node_popup_menu_items[ i ] );
         }
         }
-        requestFocus();
-        requestFocusInWindow();
-        requestFocus();
-    }
-
-    final void multiplyUrtFactor( final float f ) {
-        _urt_factor *= f;
     }
 
     }
 
-    final JApplet obtainApplet() {
-        return ( ( MainPanelApplets ) getMainPanel() ).getApplet();
+    private final String obtainTitleForExtDescNodeData() {
+        switch ( getOptions().getExtDescNodeDataToReturn() ) {
+            case NODE_NAME:
+                return "Node Names";
+            case GENE_NAME:
+                return "Gene Names";
+            case SEQUENCE_NAME:
+                return "Sequence Names";
+            case SEQUENCE_SYMBOL:
+                return "Sequence Symbols";
+            case SEQUENCE_MOL_SEQ:
+                return "Molecular Sequences";
+            case SEQUENCE_MOL_SEQ_FASTA:
+                return "Molecular Sequences (Fasta)";
+            case SEQUENCE_ACC:
+                return "Sequence Accessors";
+            case TAXONOMY_SCIENTIFIC_NAME:
+                return "Scientific Names";
+            case TAXONOMY_CODE:
+                return "Taxonomy Codes";
+            case TAXONOMY_COMM0N_NAME:
+                return "Taxonomy Common Names";
+            case UNKNOWN:
+                return "User Selected Data";
+            default:
+                throw new IllegalArgumentException( "unknown data element: "
+                        + getOptions().getExtDescNodeDataToReturn() );
+        }
     }
 
     }
 
-    final private void openSeqWeb( final PhylogenyNode node ) {
-        if ( !isCanOpenSeqWeb( node ) ) {
-            cannotOpenBrowserWarningMessage( "sequence" );
+    final private void openPdbWeb( final PhylogenyNode node ) {
+        final List<Accession> pdb_ids = getPdbAccs( node );
+        if ( ForesterUtil.isEmpty( pdb_ids ) ) {
+            cannotOpenBrowserWarningMessage( "PDB" );
             return;
         }
             return;
         }
-        String uri_str = null;
-        final Sequence seq = node.getNodeData().getSequence();
-        final String source = seq.getAccession().getSource().toLowerCase();
-        String url;
-        if ( source.toLowerCase().equals( "ncbi" ) ) {
-            url = Constants.NCBI_ALL_DATABASE_SEARCH;
+        final List<String> uri_strs = TreePanelUtil.createUrisForPdbWeb( node, pdb_ids, getConfiguration(), this );
+        if ( !ForesterUtil.isEmpty( uri_strs ) ) {
+            for( final String uri_str : uri_strs ) {
+                try {
+                    AptxUtil.launchWebBrowser( new URI( uri_str ),
+                                               isApplet(),
+                                               isApplet() ? obtainApplet() : null,
+                                               "_aptx_seq" );
+                }
+                catch ( final IOException e ) {
+                    AptxUtil.showErrorMessage( this, e.toString() );
+                    e.printStackTrace();
+                }
+                catch ( final URISyntaxException e ) {
+                    AptxUtil.showErrorMessage( this, e.toString() );
+                    e.printStackTrace();
+                }
+            }
         }
         else {
         }
         else {
-            final WebLink weblink = getConfiguration().getWebLink( source );
-            url = weblink.getUrl().toString();
-        }
-        try {
-            uri_str = url + URLEncoder.encode( seq.getAccession().getValue(), ForesterConstants.UTF8 );
+            cannotOpenBrowserWarningMessage( "PDB" );
         }
         }
-        catch ( final UnsupportedEncodingException e ) {
-            AptxUtil.showErrorMessage( this, e.toString() );
-            e.printStackTrace();
+    }
+
+    final private void openSeqWeb( final PhylogenyNode node ) {
+        if ( ForesterUtil.isEmpty( isCanOpenSeqWeb( node ) ) ) {
+            cannotOpenBrowserWarningMessage( "sequence" );
+            return;
         }
         }
+        final String uri_str = TreePanelUtil.createUriForSeqWeb( node, getConfiguration(), this );
         if ( !ForesterUtil.isEmpty( uri_str ) ) {
             try {
         if ( !ForesterUtil.isEmpty( uri_str ) ) {
             try {
-                JApplet applet = null;
-                if ( isApplet() ) {
-                    applet = obtainApplet();
-                }
-                AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_seq" );
+                AptxUtil.launchWebBrowser( new URI( uri_str ),
+                                           isApplet(),
+                                           isApplet() ? obtainApplet() : null,
+                                           "_aptx_seq" );
             }
             catch ( final IOException e ) {
                 AptxUtil.showErrorMessage( this, e.toString() );
             }
             catch ( final IOException e ) {
                 AptxUtil.showErrorMessage( this, e.toString() );
@@ -2176,32 +3522,34 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
         String uri_str = null;
         final Taxonomy tax = node.getNodeData().getTaxonomy();
         }
         String uri_str = null;
         final Taxonomy tax = node.getNodeData().getTaxonomy();
-        if ( ( tax.getIdentifier() != null ) && !ForesterUtil.isEmpty( tax.getIdentifier().getProvider() )
-                && getConfiguration().isHasWebLink( tax.getIdentifier().getProvider().toLowerCase() ) ) {
-            final String type = tax.getIdentifier().getProvider().toLowerCase();
-            final WebLink weblink = getConfiguration().getWebLink( type );
+        if ( ( tax.getIdentifier() != null ) && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() )
+                && tax.getIdentifier().getValue().startsWith( "http://" ) ) {
             try {
             try {
-                uri_str = weblink.getUrl() + URLEncoder.encode( tax.getIdentifier().getValue(), ForesterConstants.UTF8 );
+                uri_str = new URI( tax.getIdentifier().getValue() ).toString();
             }
             }
-            catch ( final UnsupportedEncodingException e ) {
+            catch ( final URISyntaxException e ) {
                 AptxUtil.showErrorMessage( this, e.toString() );
                 AptxUtil.showErrorMessage( this, e.toString() );
+                uri_str = null;
                 e.printStackTrace();
             }
         }
                 e.printStackTrace();
             }
         }
-        else if ( ( tax.getIdentifier() != null ) && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() )
-                && tax.getIdentifier().getValue().startsWith( "http://" ) ) {
+        else if ( ( tax.getIdentifier() != null )
+                && !ForesterUtil.isEmpty( tax.getIdentifier().getValue() )
+                && !ForesterUtil.isEmpty( tax.getIdentifier().getProvider() )
+                && ( tax.getIdentifier().getProvider().equalsIgnoreCase( "ncbi" ) || tax.getIdentifier().getProvider()
+                        .equalsIgnoreCase( "uniprot" ) ) ) {
             try {
             try {
-                uri_str = new URI( tax.getIdentifier().getValue() ).toString();
+                uri_str = "http://www.uniprot.org/taxonomy/"
+                        + URLEncoder.encode( tax.getIdentifier().getValue(), ForesterConstants.UTF8 );
             }
             }
-            catch ( final URISyntaxException e ) {
+            catch ( final UnsupportedEncodingException e ) {
                 AptxUtil.showErrorMessage( this, e.toString() );
                 AptxUtil.showErrorMessage( this, e.toString() );
-                uri_str = null;
                 e.printStackTrace();
             }
         }
         else if ( !ForesterUtil.isEmpty( tax.getScientificName() ) ) {
             try {
                 e.printStackTrace();
             }
         }
         else if ( !ForesterUtil.isEmpty( tax.getScientificName() ) ) {
             try {
-                uri_str = "http://www.eol.org/search?q="
+                uri_str = "http://www.uniprot.org/taxonomy/?query="
                         + URLEncoder.encode( tax.getScientificName(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
                         + URLEncoder.encode( tax.getScientificName(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
@@ -2221,7 +3569,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
         else if ( !ForesterUtil.isEmpty( tax.getCommonName() ) ) {
             try {
         }
         else if ( !ForesterUtil.isEmpty( tax.getCommonName() ) ) {
             try {
-                uri_str = "http://www.eol.org/search?q="
+                uri_str = "http://www.uniprot.org/taxonomy/?query="
                         + URLEncoder.encode( tax.getCommonName(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
                         + URLEncoder.encode( tax.getCommonName(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
@@ -2231,11 +3579,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
         if ( !ForesterUtil.isEmpty( uri_str ) ) {
             try {
         }
         if ( !ForesterUtil.isEmpty( uri_str ) ) {
             try {
-                JApplet applet = null;
-                if ( isApplet() ) {
-                    applet = obtainApplet();
-                }
-                AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_tax" );
+                AptxUtil.launchWebBrowser( new URI( uri_str ),
+                                           isApplet(),
+                                           isApplet() ? obtainApplet() : null,
+                                           "_aptx_tax" );
             }
             catch ( final IOException e ) {
                 AptxUtil.showErrorMessage( this, e.toString() );
             }
             catch ( final IOException e ) {
                 AptxUtil.showErrorMessage( this, e.toString() );
@@ -2246,68 +3593,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 e.printStackTrace();
             }
         }
                 e.printStackTrace();
             }
         }
-        else {
-            cannotOpenBrowserWarningMessage( "taxonomic" );
-        }
-    }
-
-    final void paintBranchCircular( final PhylogenyNode p,
-                                    final PhylogenyNode c,
-                                    final Graphics2D g,
-                                    final boolean radial_labels,
-                                    final boolean to_pdf,
-                                    final boolean to_graphics_file ) {
-        final double angle = _urt_nodeid_angle_map.get( c.getId() );
-        final double root_x = _root.getXcoord();
-        final double root_y = _root.getYcoord();
-        final double dx = root_x - p.getXcoord();
-        final double dy = root_y - p.getYcoord();
-        final double parent_radius = Math.sqrt( dx * dx + dy * dy );
-        final double arc = ( _urt_nodeid_angle_map.get( p.getId() ) ) - angle;
-        assignGraphicsForBranchWithColorForParentBranch( c, false, g, to_pdf, to_graphics_file );
-        if ( ( c.isFirstChildNode() || c.isLastChildNode() )
-                && ( ( Math.abs( parent_radius * arc ) > 1.5 ) || to_pdf || to_graphics_file ) ) {
-            final double r2 = 2.0 * parent_radius;
-            drawArc( root_x - parent_radius, root_y - parent_radius, r2, r2, ( -angle - arc ), arc, g );
-        }
-        drawLine( c.getXcoord(),
-                  c.getYcoord(),
-                  root_x + ( Math.cos( angle ) * parent_radius ),
-                  root_y + ( Math.sin( angle ) * parent_radius ),
-                  g );
-        paintNodeBox( c.getXcoord(), c.getYcoord(), c, g, to_pdf, to_graphics_file, isInFoundNodes( c ) );
-        if ( c.isExternal() ) {
-            final boolean is_in_found_nodes = isInFoundNodes( c );
-            if ( ( _dynamic_hiding_factor > 1 ) && !is_in_found_nodes
-                    && ( _urt_nodeid_index_map.get( c.getId() ) % _dynamic_hiding_factor != 1 ) ) {
-                return;
-            }
-            paintNodeDataUnrootedCirc( g, c, to_pdf, to_graphics_file, radial_labels, 0, is_in_found_nodes );
-        }
-    }
-
-    final void paintBranchCircularLite( final PhylogenyNode p, final PhylogenyNode c, final Graphics2D g ) {
-        final double angle = _urt_nodeid_angle_map.get( c.getId() );
-        final double root_x = _root.getXSecondary();
-        final double root_y = _root.getYSecondary();
-        final double dx = root_x - p.getXSecondary();
-        final double dy = root_y - p.getYSecondary();
-        final double arc = ( _urt_nodeid_angle_map.get( p.getId() ) ) - angle;
-        final double parent_radius = Math.sqrt( dx * dx + dy * dy );
-        g.setColor( getTreeColorSet().getOvColor() );
-        if ( ( c.isFirstChildNode() || c.isLastChildNode() ) && ( Math.abs( arc ) > 0.02 ) ) {
-            final double r2 = 2.0 * parent_radius;
-            drawArc( root_x - parent_radius, root_y - parent_radius, r2, r2, ( -angle - arc ), arc, g );
-        }
-        drawLine( c.getXSecondary(),
-                  c.getYSecondary(),
-                  root_x + ( Math.cos( angle ) * parent_radius ),
-                  root_y + ( Math.sin( angle ) * parent_radius ),
-                  g );
-        if ( isInFoundNodes( c ) ) {
-            g.setColor( getTreeColorSet().getFoundColor() );
-            drawRectFilled( c.getXSecondary() - 1, c.getYSecondary() - 1, 3, 3, g );
-        }
+        else {
+            cannotOpenBrowserWarningMessage( "taxonomic" );
+        }
     }
 
     final private void paintBranchLength( final Graphics2D g,
     }
 
     final private void paintBranchLength( final Graphics2D g,
@@ -2410,8 +3698,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                     || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
                 if ( !to_graphics_file
                         && !to_pdf
                     || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
                 if ( !to_graphics_file
                         && !to_pdf
-                        && ( ( ( y2 < getVisibleRect().getMinY() - 20 ) && ( y1 < getVisibleRect().getMinY() - 20 ) ) || ( ( y2 > getVisibleRect()
-                                .getMaxY() + 20 ) && ( y1 > getVisibleRect().getMaxY() + 20 ) ) ) ) {
+                        && ( ( ( y2 < ( getVisibleRect().getMinY() - 20 ) ) && ( y1 < ( getVisibleRect().getMinY() - 20 ) ) ) || ( ( y2 > ( getVisibleRect()
+                                .getMaxY() + 20 ) ) && ( y1 > ( getVisibleRect().getMaxY() + 20 ) ) ) ) ) {
                     // Do nothing.
                 }
                 else {
                     // Do nothing.
                 }
                 else {
@@ -2445,7 +3733,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             }
             // draw the horizontal line
             if ( !to_graphics_file && !to_pdf
             }
             // draw the horizontal line
             if ( !to_graphics_file && !to_pdf
-                    && ( ( y2 < getVisibleRect().getMinY() - 20 ) || ( y2 > getVisibleRect().getMaxY() + 20 ) ) ) {
+                    && ( ( y2 < ( getVisibleRect().getMinY() - 20 ) ) || ( y2 > ( getVisibleRect().getMaxY() + 20 ) ) ) ) {
                 return;
             }
             float x1_r = 0;
                 return;
             }
             float x1_r = 0;
@@ -2499,82 +3787,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             }
         }
         if ( node.isExternal() ) {
             }
         }
         if ( node.isExternal() ) {
-            paintNodeBox( x2, y2, node, g, to_pdf, to_graphics_file, isInFoundNodes( node ) );
-        }
-    }
-
-    final void paintCircular( final Phylogeny phy,
-                              final double starting_angle,
-                              final int center_x,
-                              final int center_y,
-                              final int radius,
-                              final Graphics2D g,
-                              final boolean to_pdf,
-                              final boolean to_graphics_file ) {
-        final int circ_num_ext_nodes = phy.getNumberOfExternalNodes() - _collapsed_external_nodeid_set.size();
-        System.out.println( "# collapsed external = " + _collapsed_external_nodeid_set.size() );
-        _root = phy.getRoot();
-        _root.setXcoord( center_x );
-        _root.setYcoord( center_y );
-        final boolean radial_labels = getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL;
-        double current_angle = starting_angle;
-        int i = 0;
-        for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
-            final PhylogenyNode n = it.next();
-            if ( !n.isCollapse() ) {
-                n.setXcoord( ( float ) ( center_x + ( radius * Math.cos( current_angle ) ) ) );
-                n.setYcoord( ( float ) ( center_y + ( radius * Math.sin( current_angle ) ) ) );
-                _urt_nodeid_angle_map.put( n.getId(), current_angle );
-                _urt_nodeid_index_map.put( n.getId(), i++ );
-                current_angle += ( TWO_PI / circ_num_ext_nodes );
-            }
-            else {
-                //TODO remove me
-                System.out.println( "is collapse" + n.getName() );
-            }
-        }
-        paintCirculars( phy.getRoot(), phy, center_x, center_y, radius, radial_labels, g, to_pdf, to_graphics_file );
-        paintNodeBox( _root.getXcoord(), _root.getYcoord(), _root, g, to_pdf, to_graphics_file, isInFoundNodes( _root ) );
-    }
-
-    void updateSetOfCollapsedExternalNodes() {
-        final Phylogeny phy = getPhylogeny();
-        _collapsed_external_nodeid_set.clear();
-        if ( phy != null ) {
-            E: for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
-                final PhylogenyNode ext_node = it.next();
-                PhylogenyNode n = ext_node;
-                while ( !n.isRoot() ) {
-                    if ( n.isCollapse() ) {
-                        _collapsed_external_nodeid_set.add( ext_node.getId() );
-                        ext_node.setCollapse( true );
-                        continue E;
-                    }
-                    n = n.getParent();
-                }
-            }
-        }
-    }
-
-    final void paintCircularLite( final Phylogeny phy,
-                                  final double starting_angle,
-                                  final int center_x,
-                                  final int center_y,
-                                  final int radius,
-                                  final Graphics2D g ) {
-        final int circ_num_ext_nodes = phy.getNumberOfExternalNodes();
-        _root = phy.getRoot();
-        _root.setXSecondary( center_x );
-        _root.setYSecondary( center_y );
-        double current_angle = starting_angle;
-        for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
-            final PhylogenyNode n = it.next();
-            n.setXSecondary( ( float ) ( center_x + radius * Math.cos( current_angle ) ) );
-            n.setYSecondary( ( float ) ( center_y + radius * Math.sin( current_angle ) ) );
-            _urt_nodeid_angle_map.put( n.getId(), current_angle );
-            current_angle += ( TWO_PI / circ_num_ext_nodes );
+            paintNodeBox( x2, y2, node, g, to_pdf, to_graphics_file );
         }
         }
-        paintCircularsLite( phy.getRoot(), phy, center_x, center_y, radius, g );
     }
 
     final private double paintCirculars( final PhylogenyNode n,
     }
 
     final private double paintCirculars( final PhylogenyNode n,
@@ -2608,11 +3822,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             }
             double r = 0;
             if ( !n.isRoot() ) {
             }
             double r = 0;
             if ( !n.isRoot() ) {
-                r = 1 - ( ( ( double ) _circ_max_depth - PhylogenyMethods.calculateDepth( n ) ) / _circ_max_depth );
+                r = 1 - ( ( ( double ) _circ_max_depth - n.calculateDepth() ) / _circ_max_depth );
             }
             final double theta = sum / descs.size();
             }
             final double theta = sum / descs.size();
-            n.setXcoord( ( float ) ( center_x + r * radius * Math.cos( theta ) ) );
-            n.setYcoord( ( float ) ( center_y + r * radius * Math.sin( theta ) ) );
+            n.setXcoord( ( float ) ( center_x + ( r * radius * Math.cos( theta ) ) ) );
+            n.setYcoord( ( float ) ( center_y + ( r * radius * Math.sin( theta ) ) ) );
             _urt_nodeid_angle_map.put( n.getId(), theta );
             for( final PhylogenyNode desc : descs ) {
                 paintBranchCircular( n, desc, g, radial_labels, to_pdf, to_graphics_file );
             _urt_nodeid_angle_map.put( n.getId(), theta );
             for( final PhylogenyNode desc : descs ) {
                 paintBranchCircular( n, desc, g, radial_labels, to_pdf, to_graphics_file );
@@ -2637,11 +3851,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             }
             float r = 0;
             if ( !n.isRoot() ) {
             }
             float r = 0;
             if ( !n.isRoot() ) {
-                r = 1 - ( ( ( float ) _circ_max_depth - PhylogenyMethods.calculateDepth( n ) ) / _circ_max_depth );
+                r = 1 - ( ( ( float ) _circ_max_depth - n.calculateDepth() ) / _circ_max_depth );
             }
             final double theta = _urt_nodeid_angle_map.get( n.getId() );
             }
             final double theta = _urt_nodeid_angle_map.get( n.getId() );
-            n.setXSecondary( ( float ) ( center_x + radius * r * Math.cos( theta ) ) );
-            n.setYSecondary( ( float ) ( center_y + radius * r * Math.sin( theta ) ) );
+            n.setXSecondary( ( float ) ( center_x + ( radius * r * Math.cos( theta ) ) ) );
+            n.setYSecondary( ( float ) ( center_y + ( radius * r * Math.sin( theta ) ) ) );
             for( final PhylogenyNode desc : descs ) {
                 paintBranchCircularLite( n, desc, g );
             }
             for( final PhylogenyNode desc : descs ) {
                 paintBranchCircularLite( n, desc, g );
             }
@@ -2658,12 +3872,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             c = Color.BLACK;
         }
         else if ( is_in_found_nodes ) {
             c = Color.BLACK;
         }
         else if ( is_in_found_nodes ) {
-            c = getTreeColorSet().getFoundColor();
+            c = getColorForFoundNode( node );
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
             c = getTaxonomyBasedColor( node );
         }
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
             c = getTaxonomyBasedColor( node );
         }
-        else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches()
+        else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isUseVisualStyles()
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
             c = PhylogenyMethods.getBranchColorValue( node );
         }
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
             c = PhylogenyMethods.getBranchColorValue( node );
         }
@@ -2677,30 +3891,30 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         else {
             d = ( Math.log10( d ) * _y_distance ) / 2.5;
         }
         else {
             d = ( Math.log10( d ) * _y_distance ) / 2.5;
         }
-        final int box_size = getOptions().getDefaultNodeShapeSize();
+        final int box_size = getOptions().getDefaultNodeShapeSize() + 1;
         if ( d < box_size ) {
             d = box_size;
         }
         if ( d < box_size ) {
             d = box_size;
         }
+        final float xx = node.getXcoord() - ( 2 * box_size );
+        final float xxx = xx > node.getParent().getXcoord() + 1 ? xx : node.getParent().getXcoord() + 1;
         _polygon.reset();
         _polygon.reset();
-        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() - box_size ),
-                           ForesterUtil.roundToInt( node.getYcoord() ) );
-        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ),
-                           ForesterUtil.roundToInt( node.getYcoord() - d ) );
-        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ),
-                           ForesterUtil.roundToInt( node.getYcoord() + d ) );
-        if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) {
+        _polygon.moveTo( xxx, node.getYcoord() );
+        _polygon.lineTo( node.getXcoord() + 1, node.getYcoord() - d );
+        _polygon.lineTo( node.getXcoord() + 1, node.getYcoord() + d );
+        _polygon.closePath();
+        if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.SOLID ) {
             g.setColor( c );
             g.setColor( c );
-            g.fillPolygon( _polygon );
+            g.fill( _polygon );
         }
         }
-        else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.NONE ) {
+        else if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.NONE ) {
             g.setColor( getBackground() );
             g.setColor( getBackground() );
-            g.fillPolygon( _polygon );
+            g.fill( _polygon );
             g.setColor( c );
             g.setColor( c );
-            g.drawPolygon( _polygon );
+            g.draw( _polygon );
         }
         else if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) {
         }
         else if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) {
-            g.setPaint( new GradientPaint( node.getXcoord() - box_size, node.getYcoord(), getBackground(), ( node
-                    .getXcoord() + box_size ), ( float ) ( node.getYcoord() - d ), c, false ) );
+            g.setPaint( new GradientPaint( xxx, node.getYcoord(), getBackground(), node.getXcoord(), ( float ) ( node
+                    .getYcoord() - d ), c, false ) );
             g.fill( _polygon );
             g.setPaint( c );
             g.draw( _polygon );
             g.fill( _polygon );
             g.setPaint( c );
             g.draw( _polygon );
@@ -2708,52 +3922,19 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         paintNodeData( g, node, to_graphics_file, to_pdf, is_in_found_nodes );
     }
 
         paintNodeData( g, node, to_graphics_file, to_pdf, is_in_found_nodes );
     }
 
-    @Override
-    final public void paintComponent( final Graphics g ) {
-        // Dimension currentSize = getSize();
-        //  if ( offscreenImage == null || !currentSize.equals( offscreenDimension ) ) {
-        // call the 'java.awt.Component.createImage(...)' method to get an
-        // image
-        //   offscreenImage = createImage( currentSize.width, currentSize.height );
-        //  offscreenGraphics = offscreenImage.getGraphics();
-        //  offscreenDimension = currentSize;
-        // }
-        // super.paintComponent( g ); //why?
-        //final Graphics2D g2d = ( Graphics2D ) offscreenGraphics;
-        final Graphics2D g2d = ( Graphics2D ) g;
-        g2d.setRenderingHints( _rendering_hints );
-        paintPhylogeny( g2d, false, false, 0, 0, 0, 0 );
-        //g.drawImage( offscreenImage, 0, 0, this );
-    }
-
-    @Override
-    public void update( final Graphics g ) {
-        paint( g );
-    }
-
     final private void paintConfidenceValues( final Graphics2D g,
                                               final PhylogenyNode node,
                                               final boolean to_pdf,
                                               final boolean to_graphics_file ) {
         final List<Confidence> confidences = node.getBranchData().getConfidences();
     final private void paintConfidenceValues( final Graphics2D g,
                                               final PhylogenyNode node,
                                               final boolean to_pdf,
                                               final boolean to_graphics_file ) {
         final List<Confidence> confidences = node.getBranchData().getConfidences();
-        //        if ( confidences.size() == 1 ) {
-        //            final double value = node.getBranchData().getConfidence( 0 ).getValue();
-        //            if ( ( value == Confidence.CONFIDENCE_DEFAULT_VALUE ) || ( value < getOptions().getMinConfidenceValue() ) ) {
-        //                return;
-        //            }
-        //            conf_str = FORMATTER_CONFIDENCE.format( value );
-        //        }
-        //        else if ( confidences.size() > 1 ) {
-        boolean one_ok = false;
         boolean not_first = false;
         Collections.sort( confidences );
         final StringBuilder sb = new StringBuilder();
         boolean not_first = false;
         Collections.sort( confidences );
         final StringBuilder sb = new StringBuilder();
-        String conf_str = "";
         for( final Confidence confidence : confidences ) {
             final double value = confidence.getValue();
             if ( value != Confidence.CONFIDENCE_DEFAULT_VALUE ) {
         for( final Confidence confidence : confidences ) {
             final double value = confidence.getValue();
             if ( value != Confidence.CONFIDENCE_DEFAULT_VALUE ) {
-                if ( value >= getOptions().getMinConfidenceValue() ) {
-                    one_ok = true;
+                if ( value < getOptions().getMinConfidenceValue() ) {
+                    return;
                 }
                 if ( not_first ) {
                     sb.append( "/" );
                 }
                 if ( not_first ) {
                     sb.append( "/" );
@@ -2773,12 +3954,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                     }
                 }
             }
                     }
                 }
             }
-            //}
-            if ( one_ok ) {
-                conf_str = sb.toString();
-            }
         }
         }
-        if ( conf_str.length() > 0 ) {
+        if ( sb.length() > 0 ) {
             final double parent_x = node.getParent().getXcoord();
             double x = node.getXcoord();
             g.setFont( getTreeFontSet().getSmallFont() );
             final double parent_x = node.getParent().getXcoord();
             double x = node.getXcoord();
             g.setFont( getTreeFontSet().getSmallFont() );
@@ -2794,6 +3971,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             else {
                 g.setColor( getTreeColorSet().getConfidenceColor() );
             }
             else {
                 g.setColor( getTreeColorSet().getConfidenceColor() );
             }
+            final String conf_str = sb.toString();
             TreePanel
                     .drawString( conf_str,
                                  parent_x
             TreePanel
                     .drawString( conf_str,
                                  parent_x
@@ -2803,13 +3981,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    final private void paintFoundNode( final int x, final int y, final Graphics2D g ) {
-        final int box_size = getOptions().getDefaultNodeShapeSize();
-        final int half_box_size = getOptions().getDefaultNodeShapeSize() / 2;
-        g.setColor( getTreeColorSet().getFoundColor() );
-        g.fillRect( x - half_box_size, y - half_box_size, box_size, box_size );
-    }
-
     final private void paintGainedAndLostCharacters( final Graphics2D g,
                                                      final PhylogenyNode node,
                                                      final String gained,
     final private void paintGainedAndLostCharacters( final Graphics2D g,
                                                      final PhylogenyNode node,
                                                      final String gained,
@@ -2848,27 +4019,34 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                      final PhylogenyNode node,
                                      final Graphics2D g,
                                      final boolean to_pdf,
                                      final PhylogenyNode node,
                                      final Graphics2D g,
                                      final boolean to_pdf,
-                                     final boolean to_graphics_file,
-                                     final boolean is_in_found_nodes ) {
+                                     final boolean to_graphics_file ) {
         if ( node.isCollapse() ) {
             return;
         }
         // if this node should be highlighted, do so
         if ( ( _highlight_node == node ) && !to_pdf && !to_graphics_file ) {
         if ( node.isCollapse() ) {
             return;
         }
         // if this node should be highlighted, do so
         if ( ( _highlight_node == node ) && !to_pdf && !to_graphics_file ) {
-            g.setColor( getTreeColorSet().getFoundColor() );
+            g.setColor( getTreeColorSet().getFoundColor0() );
             drawOval( x - 8, y - 8, 16, 16, g );
             drawOval( x - 9, y - 8, 17, 17, g );
             drawOval( x - 9, y - 9, 18, 18, g );
         }
             drawOval( x - 8, y - 8, 16, 16, g );
             drawOval( x - 9, y - 8, 17, 17, g );
             drawOval( x - 9, y - 9, 18, 18, g );
         }
-        if ( is_in_found_nodes ) {
-            paintFoundNode( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ), g );
-        }
-        else {
+        if ( ( isInFoundNodes( node ) || isInCurrentExternalNodes( node ) )
+                || ( getOptions().isShowDefaultNodeShapesExternal() && node.isExternal() )
+                || ( getOptions().isShowDefaultNodeShapesInternal() && node.isInternal() )
+                || ( getControlPanel().isEvents() && node.isHasAssignedEvent() && ( node.getNodeData().getEvent()
+                        .isDuplication()
+                        || node.getNodeData().getEvent().isSpeciation() || node.getNodeData().getEvent()
+                        .isSpeciationOrDuplication() ) ) ) {
+            final double box_size = getOptions().getDefaultNodeShapeSize();
+            final double half_box_size = box_size / 2.0;
             Color outline_color = null;
             if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
                 outline_color = Color.BLACK;
             }
             Color outline_color = null;
             if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
                 outline_color = Color.BLACK;
             }
-            else if ( getControlPanel().isEvents() && AptxUtil.isHasAssignedEvent( node ) ) {
+            else if ( isInFoundNodes( node ) || isInCurrentExternalNodes( node ) ) {
+                outline_color = getColorForFoundNode( node );
+            }
+            else if ( getControlPanel().isEvents() && TreePanelUtil.isHasAssignedEvent( node ) ) {
                 final Event event = node.getNodeData().getEvent();
                 if ( event.isDuplication() ) {
                     outline_color = getTreeColorSet().getDuplicationBoxColor();
                 final Event event = node.getNodeData().getEvent();
                 if ( event.isDuplication() ) {
                     outline_color = getTreeColorSet().getDuplicationBoxColor();
@@ -2880,77 +4058,58 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                     outline_color = getTreeColorSet().getDuplicationOrSpeciationColor();
                 }
             }
                     outline_color = getTreeColorSet().getDuplicationOrSpeciationColor();
                 }
             }
-            else if ( getOptions().isTaxonomyColorizeNodeShapes() ) {
-                outline_color = getTaxonomyBasedColor( node );
-            }
             else {
                 outline_color = getGraphicsForNodeBoxWithColorForParentBranch( node );
                 if ( to_pdf && ( outline_color == getTreeColorSet().getBranchColor() ) ) {
                     outline_color = getTreeColorSet().getBranchColorForPdf();
                 }
             }
             else {
                 outline_color = getGraphicsForNodeBoxWithColorForParentBranch( node );
                 if ( to_pdf && ( outline_color == getTreeColorSet().getBranchColor() ) ) {
                     outline_color = getTreeColorSet().getBranchColorForPdf();
                 }
             }
-            final int box_size = getOptions().getDefaultNodeShapeSize();
-            final int half_box_size = box_size / 2;
-            if ( getOptions().isShowDefaultNodeShapes() || ( getControlPanel().isEvents() && node.isHasAssignedEvent() ) ) {
-                if ( getOptions().getDefaultNodeShape() == NodeShape.CIRCLE ) {
-                    if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) {
-                        drawOvalGradient( x - half_box_size,
-                                          y - half_box_size,
-                                          box_size,
-                                          box_size,
-                                          g,
-                                          to_pdf ? Color.WHITE : outline_color,
-                                          to_pdf ? outline_color : getBackground(),
-                                          outline_color );
-                    }
-                    else if ( getOptions().getDefaultNodeFill() == NodeFill.NONE ) {
-                        Color background = getBackground();
-                        if ( to_pdf ) {
-                            background = Color.WHITE;
-                        }
-                        drawOvalGradient( x - half_box_size,
-                                          y - half_box_size,
-                                          box_size,
-                                          box_size,
-                                          g,
-                                          background,
-                                          background,
-                                          outline_color );
-                    }
-                    else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) {
-                        g.setColor( outline_color );
-                        drawOvalFilled( x - half_box_size, y - half_box_size, box_size, box_size, g );
-                    }
+            if ( getOptions().getDefaultNodeShape() == NodeShape.CIRCLE ) {
+                if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) {
+                    drawOvalGradient( x - half_box_size, y - half_box_size, box_size, box_size, g, to_pdf ? Color.WHITE
+                            : outline_color, to_pdf ? outline_color : getBackground(), outline_color );
                 }
                 }
-                else if ( getOptions().getDefaultNodeShape() == NodeVisualization.NodeShape.RECTANGLE ) {
-                    if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.GRADIENT ) {
-                        drawRectGradient( x - half_box_size,
-                                          y - half_box_size,
-                                          box_size,
-                                          box_size,
-                                          g,
-                                          to_pdf ? Color.WHITE : outline_color,
-                                          to_pdf ? outline_color : getBackground(),
-                                          outline_color );
+                else if ( getOptions().getDefaultNodeFill() == NodeFill.NONE ) {
+                    Color background = getBackground();
+                    if ( to_pdf ) {
+                        background = Color.WHITE;
                     }
                     }
-                    else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.NONE ) {
-                        Color background = getBackground();
-                        if ( to_pdf ) {
-                            background = Color.WHITE;
-                        }
-                        drawRectGradient( x - half_box_size,
-                                          y - half_box_size,
-                                          box_size,
-                                          box_size,
-                                          g,
-                                          background,
-                                          background,
-                                          outline_color );
-                    }
-                    else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) {
-                        g.setColor( outline_color );
-                        drawRectFilled( x - half_box_size, y - half_box_size, box_size, box_size, g );
+                    drawOvalGradient( x - half_box_size,
+                                      y - half_box_size,
+                                      box_size,
+                                      box_size,
+                                      g,
+                                      background,
+                                      background,
+                                      outline_color );
+                }
+                else if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.SOLID ) {
+                    g.setColor( outline_color );
+                    drawOvalFilled( x - half_box_size, y - half_box_size, box_size, box_size, g );
+                }
+            }
+            else if ( getOptions().getDefaultNodeShape() == NodeVisualData.NodeShape.RECTANGLE ) {
+                if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.GRADIENT ) {
+                    drawRectGradient( x - half_box_size, y - half_box_size, box_size, box_size, g, to_pdf ? Color.WHITE
+                            : outline_color, to_pdf ? outline_color : getBackground(), outline_color );
+                }
+                else if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.NONE ) {
+                    Color background = getBackground();
+                    if ( to_pdf ) {
+                        background = Color.WHITE;
                     }
                     }
+                    drawRectGradient( x - half_box_size,
+                                      y - half_box_size,
+                                      box_size,
+                                      box_size,
+                                      g,
+                                      background,
+                                      background,
+                                      outline_color );
+                }
+                else if ( getOptions().getDefaultNodeFill() == NodeVisualData.NodeFill.SOLID ) {
+                    g.setColor( outline_color );
+                    drawRectFilled( x - half_box_size, y - half_box_size, box_size, box_size, g );
                 }
             }
         }
                 }
             }
         }
@@ -2973,6 +4132,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         if ( !getControlPanel().isShowInternalData() && !node.isExternal() && !node.isCollapse() ) {
             return;
         }
         if ( !getControlPanel().isShowInternalData() && !node.isExternal() && !node.isCollapse() ) {
             return;
         }
+        _sb.setLength( 0 );
         int x = 0;
         final int half_box_size = getOptions().getDefaultNodeShapeSize() / 2;
         if ( getControlPanel().isShowTaxonomyImages()
         int x = 0;
         final int half_box_size = getOptions().getDefaultNodeShapeSize() / 2;
         if ( getControlPanel().isShowTaxonomyImages()
@@ -2991,12 +4151,21 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             g.setColor( Color.BLACK );
         }
         else if ( is_in_found_nodes ) {
             g.setColor( Color.BLACK );
         }
         else if ( is_in_found_nodes ) {
-            g.setColor( getTreeColorSet().getFoundColor() );
+            g.setColor( getColorForFoundNode( node ) );
+        }
+        else if ( getControlPanel().isUseVisualStyles() && ( node.getNodeData().getNodeVisualData() != null )
+                && ( node.getNodeData().getNodeVisualData().getFontColor() != null ) ) {
+            g.setColor( node.getNodeData().getNodeVisualData().getFontColor() );
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
             g.setColor( getTaxonomyBasedColor( node ) );
         }
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
             g.setColor( getTaxonomyBasedColor( node ) );
         }
-        else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches()
+        else if ( getControlPanel().isColorAccordingToAnnotation()
+                && ( node.getNodeData().isHasSequence() && ( node.getNodeData().getSequence().getAnnotations() != null ) && ( !node
+                        .getNodeData().getSequence().getAnnotations().isEmpty() ) ) ) {
+            g.setColor( calculateColorForAnnotation( node.getNodeData().getSequence().getAnnotations() ) );
+        }
+        else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isUseVisualStyles()
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
             g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
         }
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
             g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
         }
@@ -3006,11 +4175,16 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         else {
             g.setColor( getTreeColorSet().getSequenceColor() );
         }
         else {
             g.setColor( getTreeColorSet().getSequenceColor() );
         }
-        _sb.setLength( 0 );
         if ( node.isCollapse() && ( ( !node.isRoot() && !node.getParent().isCollapse() ) || node.isRoot() ) ) {
         if ( node.isCollapse() && ( ( !node.isRoot() && !node.getParent().isCollapse() ) || node.isRoot() ) ) {
-            _sb.append( " [" );
-            _sb.append( node.getAllExternalDescendants().size() );
-            _sb.append( "]" );
+            if ( _sb.length() > 0 ) {
+                _sb.setLength( 0 );
+                _sb.append( "(" );
+                _sb.append( node.getAllExternalDescendants().size() );
+                _sb.append( ")" );
+            }
+        }
+        else {
+            _sb.setLength( 0 );
         }
         if ( getControlPanel().isShowNodeNames() && ( node.getName().length() > 0 ) ) {
             if ( _sb.length() > 0 ) {
         }
         if ( getControlPanel().isShowNodeNames() && ( node.getName().length() > 0 ) ) {
             if ( _sb.length() > 0 ) {
@@ -3019,13 +4193,19 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             _sb.append( node.getName() );
         }
         if ( node.getNodeData().isHasSequence() ) {
             _sb.append( node.getName() );
         }
         if ( node.getNodeData().isHasSequence() ) {
-            if ( getControlPanel().isShowGeneSymbols() && ( node.getNodeData().getSequence().getSymbol().length() > 0 ) ) {
+            if ( getControlPanel().isShowSeqSymbols() && ( node.getNodeData().getSequence().getSymbol().length() > 0 ) ) {
                 if ( _sb.length() > 0 ) {
                     _sb.append( " " );
                 }
                 _sb.append( node.getNodeData().getSequence().getSymbol() );
             }
                 if ( _sb.length() > 0 ) {
                     _sb.append( " " );
                 }
                 _sb.append( node.getNodeData().getSequence().getSymbol() );
             }
-            if ( getControlPanel().isShowGeneNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) {
+            if ( getControlPanel().isShowGeneNames() && ( node.getNodeData().getSequence().getGeneName().length() > 0 ) ) {
+                if ( _sb.length() > 0 ) {
+                    _sb.append( " " );
+                }
+                _sb.append( node.getNodeData().getSequence().getGeneName() );
+            }
+            if ( getControlPanel().isShowSeqNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) {
                 if ( _sb.length() > 0 ) {
                     _sb.append( " " );
                 }
                 if ( _sb.length() > 0 ) {
                     _sb.append( " " );
                 }
@@ -3048,7 +4228,13 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             }
             _sb.append( propertiesToString( node ) );
         }
             }
             _sb.append( propertiesToString( node ) );
         }
-        g.setFont( getTreeFontSet().getLargeFont() );
+        if ( getControlPanel().isUseVisualStyles() && ( node.getNodeData().getNodeVisualData() != null ) ) {
+            final Font f = node.getNodeData().getNodeVisualData().getFont();
+            g.setFont( f != null ? f : getTreeFontSet().getLargeFont() );
+        }
+        else {
+            g.setFont( getTreeFontSet().getLargeFont() );
+        }
         if ( is_in_found_nodes ) {
             g.setFont( getTreeFontSet().getLargeFont().deriveFont( Font.BOLD ) );
         }
         if ( is_in_found_nodes ) {
             g.setFont( getTreeFontSet().getLargeFont().deriveFont( Font.BOLD ) );
         }
@@ -3098,7 +4284,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                 x += CONFIDENCE_LEFT_MARGIN + confidenceWidth;
                             }
                         }
                                 x += CONFIDENCE_LEFT_MARGIN + confidenceWidth;
                             }
                         }
-                        if ( x + nodeTextBoundsWidth > 0 ) /* we only underline if there is something displayed */
+                        if ( ( x + nodeTextBoundsWidth ) > 0 ) /* we only underline if there is something displayed */
                         {
                             if ( nodeTextBoundsWidth == 0 ) {
                                 nodeTextBoundsWidth -= 3; /* the gap between taxonomy code and node name should not be underlined if nothing comes after it */
                         {
                             if ( nodeTextBoundsWidth == 0 ) {
                                 nodeTextBoundsWidth -= 3; /* the gap between taxonomy code and node name should not be underlined if nothing comes after it */
@@ -3125,155 +4311,59 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         //            + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
         //}
         // COMMENTED_OUT_BY_GUILHEM_END ________________
         //            + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
         //}
         // COMMENTED_OUT_BY_GUILHEM_END ________________
-        if ( getControlPanel().isShowAnnotation() && node.getNodeData().isHasSequence()
-                && ( node.getNodeData().getSequence().getAnnotations() != null )
-                && ( !node.getNodeData().getSequence().getAnnotations().isEmpty() ) ) {
-            if ( _sb.length() > 0 ) {
-                x += getTreeFontSet()._fm_large.stringWidth( _sb.toString() ) + 5;
-            }
-            final Annotation ann = node.getNodeData().getSequence().getAnnotation( 0 );
-            if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
-                g.setColor( Color.BLACK );
-            }
-            else {
-                g.setColor( calculateColorForAnnotation( ann ) );
-            }
-            final String ann_str = ann.asSimpleText().toString();
-            TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + half_box_size, node.getYcoord()
-                    + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
-            _sb.setLength( 0 );
-            _sb.append( ann_str );
-        }
-        if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR )
-                || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE )
-                || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
-            if ( ( getControlPanel().isShowBinaryCharacters() || getControlPanel().isShowBinaryCharacterCounts() )
-                    && node.getNodeData().isHasBinaryCharacters() ) {
-                if ( _sb.length() > 0 ) {
-                    x += getTreeFontSet()._fm_large.stringWidth( _sb.toString() ) + 5;
-                }
-                if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
-                    g.setColor( Color.BLACK );
-                }
-                else {
-                    g.setColor( getTreeColorSet().getBinaryDomainCombinationsColor() );
-                }
-                if ( getControlPanel().isShowBinaryCharacters() ) {
-                    TreePanel.drawString( node.getNodeData().getBinaryCharacters().getPresentCharactersAsStringBuffer()
-                            .toString(), node.getXcoord() + x + 1 + half_box_size, node.getYcoord()
-                            + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
-                    paintGainedAndLostCharacters( g, node, node.getNodeData().getBinaryCharacters()
-                            .getGainedCharactersAsStringBuffer().toString(), node.getNodeData().getBinaryCharacters()
-                            .getLostCharactersAsStringBuffer().toString() );
-                }
-                else {
-                    if ( DRAW_MEAN_COUNTS && node.isInternal() ) {
-                        final List<PhylogenyNode> ec = node.getAllExternalDescendants();
-                        double sum = 0;
-                        int count = 0;
-                        for( final PhylogenyNode phylogenyNode : ec ) {
-                            count++;
-                            if ( phylogenyNode.getNodeData().getBinaryCharacters() != null ) {
-                                sum += phylogenyNode.getNodeData().getBinaryCharacters().getPresentCount();
-                            }
-                        }
-                        final double mean = ForesterUtil.round( sum / count, 1 );
-                        TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount() + " ["
-                                + mean + "]", node.getXcoord() + x + 4 + half_box_size, node.getYcoord()
-                                + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
-                    }
-                    else {
-                        TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount(),
-                                              node.getXcoord() + x + 4 + half_box_size,
-                                              node.getYcoord()
-                                                      + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ),
-                                              g );
-                    }
-                    paintGainedAndLostCharacters( g, node, "+"
-                            + node.getNodeData().getBinaryCharacters().getGainedCount(), "-"
-                            + node.getNodeData().getBinaryCharacters().getLostCount() );
-                }
-            }
-        }
-    }
-
-    private StringBuffer propertiesToString( final PhylogenyNode node ) {
-        final PropertiesMap properties = node.getNodeData().getProperties();
-        final StringBuffer sb = new StringBuffer();
-        boolean first = true;
-        for( final String ref : properties.getPropertyRefs() ) {
-            if ( first ) {
-                first = false;
-            }
-            else {
-                sb.append( " " );
-            }
-            final Property p = properties.getProperty( ref );
-            sb.append( getPartAfterColon( p.getRef() ) );
-            sb.append( "=" );
-            sb.append( p.getValue() );
-            if ( !ForesterUtil.isEmpty( p.getUnit() ) ) {
-                sb.append( getPartAfterColon( p.getUnit() ) );
-            }
-        }
-        return sb;
-    }
-
-    final private static String getPartAfterColon( final String s ) {
-        final int i = s.indexOf( ':' );
-        if ( ( i < 1 ) || ( i == ( s.length() - 1 ) ) ) {
-            return s;
-        }
-        return s.substring( i + 1, s.length() );
-    }
-
-    private double drawTaxonomyImage( final double x, final double y, final PhylogenyNode node, final Graphics2D g ) {
-        final List<Uri> us = new ArrayList<Uri>();
-        for( final Taxonomy t : node.getNodeData().getTaxonomies() ) {
-            for( final Uri uri : t.getUris() ) {
-                us.add( uri );
-            }
-        }
-        double offset = 0;
-        for( final Uri uri : us ) {
-            if ( uri != null ) {
-                final String uri_str = uri.getValue().toString().toLowerCase();
-                if ( getImageMap().containsKey( uri_str ) ) {
-                    final BufferedImage bi = getImageMap().get( uri_str );
-                    if ( ( bi != null ) && ( bi.getHeight() > 5 ) && ( bi.getWidth() > 5 ) ) {
-                        double scaling_factor = 1;
-                        if ( getOptions().isAllowMagnificationOfTaxonomyImages()
-                                || ( bi.getHeight() > ( 1.8 * getYdistance() ) ) ) {
-                            scaling_factor = ( 1.8 * getYdistance() ) / bi.getHeight();
-                        }
-                        // y = y - ( 0.9 * getYdistance() );
-                        final double hs = bi.getHeight() * scaling_factor;
-                        double ws = bi.getWidth() * scaling_factor + offset;
-                        final double my_y = y - ( 0.5 * hs );
-                        final int x_w = ( int ) ( x + ws + 0.5 );
-                        final int y_h = ( int ) ( my_y + hs + 0.5 );
-                        if ( ( x_w - x > 7 ) && ( y_h - my_y > 7 ) ) {
-                            g.drawImage( bi,
-                                         ( int ) ( x + 0.5 + offset ),
-                                         ( int ) ( my_y + 0.5 ),
-                                         x_w,
-                                         y_h,
-                                         0,
-                                         0,
-                                         bi.getWidth(),
-                                         bi.getHeight(),
-                                         null );
-                            ws += 8;
-                        }
-                        else {
-                            ws = 0.0;
-                        }
-                        offset = ws;
-                    }
+        if ( getControlPanel().isShowAnnotation() && node.getNodeData().isHasSequence()
+                && ( node.getNodeData().getSequence().getAnnotations() != null )
+                && ( !node.getNodeData().getSequence().getAnnotations().isEmpty() ) ) {
+            if ( _sb.length() > 0 ) {
+                x += getTreeFontSet()._fm_large.stringWidth( _sb.toString() ) + 5;
+            }
+            final SortedSet<Annotation> ann = node.getNodeData().getSequence().getAnnotations();
+            if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
+                g.setColor( Color.BLACK );
+            }
+            else if ( getControlPanel().isColorAccordingToAnnotation() ) {
+                g.setColor( calculateColorForAnnotation( ann ) );
+            }
+            final String ann_str = TreePanelUtil.createAnnotationString( ann, getOptions().isShowAnnotationRefSource() );
+            TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + half_box_size, node.getYcoord()
+                    + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
+            _sb.setLength( 0 );
+            _sb.append( ann_str );
+        }
+        if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR )
+                || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE )
+                || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
+            if ( ( getControlPanel().isShowBinaryCharacters() || getControlPanel().isShowBinaryCharacterCounts() )
+                    && node.getNodeData().isHasBinaryCharacters() ) {
+                if ( _sb.length() > 0 ) {
+                    x += getTreeFontSet()._fm_large.stringWidth( _sb.toString() ) + 5;
+                }
+                if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
+                    g.setColor( Color.BLACK );
+                }
+                else {
+                    g.setColor( getTreeColorSet().getBinaryDomainCombinationsColor() );
+                }
+                if ( getControlPanel().isShowBinaryCharacters() ) {
+                    TreePanel.drawString( node.getNodeData().getBinaryCharacters().getPresentCharactersAsStringBuffer()
+                            .toString(), node.getXcoord() + x + 1 + half_box_size, node.getYcoord()
+                            + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
+                    paintGainedAndLostCharacters( g, node, node.getNodeData().getBinaryCharacters()
+                            .getGainedCharactersAsStringBuffer().toString(), node.getNodeData().getBinaryCharacters()
+                            .getLostCharactersAsStringBuffer().toString() );
+                }
+                else {
+                    TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount(),
+                                          node.getXcoord() + x + 4 + half_box_size,
+                                          node.getYcoord()
+                                                  + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ),
+                                          g );
+                    paintGainedAndLostCharacters( g, node, "+"
+                            + node.getNodeData().getBinaryCharacters().getGainedCount(), "-"
+                            + node.getNodeData().getBinaryCharacters().getLostCount() );
                 }
             }
         }
                 }
             }
         }
-        return offset;
     }
 
     final private void paintNodeDataUnrootedCirc( final Graphics2D g,
     }
 
     final private void paintNodeDataUnrootedCirc( final Graphics2D g,
@@ -3290,11 +4380,16 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             g.setColor( Color.BLACK );
         }
         else if ( is_in_found_nodes ) {
             g.setColor( Color.BLACK );
         }
         else if ( is_in_found_nodes ) {
-            g.setColor( getTreeColorSet().getFoundColor() );
+            g.setColor( getColorForFoundNode( node ) );
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
             g.setColor( getTaxonomyBasedColor( node ) );
         }
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
             g.setColor( getTaxonomyBasedColor( node ) );
         }
+        else if ( getControlPanel().isColorAccordingToAnnotation()
+                && ( node.getNodeData().isHasSequence() && ( node.getNodeData().getSequence().getAnnotations() != null ) && ( !node
+                        .getNodeData().getSequence().getAnnotations().isEmpty() ) ) ) {
+            g.setColor( calculateColorForAnnotation( node.getNodeData().getSequence().getAnnotations() ) );
+        }
         else {
             g.setColor( getTreeColorSet().getSequenceColor() );
         }
         else {
             g.setColor( getTreeColorSet().getSequenceColor() );
         }
@@ -3360,7 +4455,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 }
                 _sb.append( node.getNodeData().getSequence().getAccession().getValue() );
             }
                 }
                 _sb.append( node.getNodeData().getSequence().getAccession().getValue() );
             }
-            if ( getControlPanel().isShowGeneNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) {
+            if ( getControlPanel().isShowSeqNames() && ( node.getNodeData().getSequence().getName().length() > 0 ) ) {
                 if ( _sb.length() > 0 ) {
                     _sb.append( " " );
                 }
                 if ( _sb.length() > 0 ) {
                     _sb.append( " " );
                 }
@@ -3411,14 +4506,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
 
     final private void paintNodeLite( final Graphics2D g, final PhylogenyNode node ) {
         if ( node.isCollapse() ) {
 
     final private void paintNodeLite( final Graphics2D g, final PhylogenyNode node ) {
         if ( node.isCollapse() ) {
-            if ( ( !node.isRoot() && !node.getParent().isCollapse() ) || node.isRoot() ) {
+            if ( !node.isRoot() && !node.getParent().isCollapse() ) {
                 paintCollapsedNode( g, node, false, false, false );
             }
             return;
         }
                 paintCollapsedNode( g, node, false, false, false );
             }
             return;
         }
-        if ( isInFoundNodes( node ) ) {
-            g.setColor( getTreeColorSet().getFoundColor() );
-            drawRectFilled( node.getXSecondary() - 1, node.getYSecondary() - 1, 3, 3, g );
+        if ( isInFoundNodes( node ) || isInCurrentExternalNodes( node ) ) {
+            g.setColor( getColorForFoundNode( node ) );
+            drawRectFilled( node.getXSecondary() - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF, node.getYSecondary()
+                    - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF, OVERVIEW_FOUND_NODE_BOX_SIZE, OVERVIEW_FOUND_NODE_BOX_SIZE, g );
         }
         float new_x = 0;
         if ( !node.isExternal() && !node.isCollapse() ) {
         }
         float new_x = 0;
         if ( !node.isExternal() && !node.isCollapse() ) {
@@ -3463,9 +4559,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                              final boolean dynamically_hide,
                                              final int dynamic_hiding_factor,
                                              final boolean to_graphics_file ) {
                                              final boolean dynamically_hide,
                                              final int dynamic_hiding_factor,
                                              final boolean to_graphics_file ) {
-        final boolean is_in_found_nodes = isInFoundNodes( node );
+        final boolean is_in_found_nodes = isInFoundNodes( node ) || isInCurrentExternalNodes( node );
         if ( node.isCollapse() ) {
         if ( node.isCollapse() ) {
-            if ( ( !node.isRoot() && !node.getParent().isCollapse() ) || node.isRoot() ) {
+            if ( ( !node.isRoot() && !node.getParent().isCollapse() ) ) {
                 paintCollapsedNode( g, node, to_graphics_file, to_pdf, is_in_found_nodes );
             }
             return;
                 paintCollapsedNode( g, node, to_graphics_file, to_pdf, is_in_found_nodes );
             }
             return;
@@ -3545,12 +4641,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 child_node.setYcoord( y2 );
                 y2 += _y_distance * child_node.getNumberOfExternalNodes();
             }
                 child_node.setYcoord( y2 );
                 y2 += _y_distance * child_node.getNumberOfExternalNodes();
             }
-            paintNodeBox( node.getXcoord(), node.getYcoord(), node, g, to_pdf, to_graphics_file, isInFoundNodes( node ) );
+            paintNodeBox( node.getXcoord(), node.getYcoord(), node, g, to_pdf, to_graphics_file );
         }
         if ( dynamically_hide
                 && !is_in_found_nodes
         }
         if ( dynamically_hide
                 && !is_in_found_nodes
-                && ( ( node.isExternal() && ( _external_node_index % dynamic_hiding_factor != 1 ) ) || ( !node
-                        .isExternal() && ( ( new_x_min < 20 ) || ( _y_distance * node.getNumberOfExternalNodes() < getTreeFontSet()._fm_large
+                && ( ( node.isExternal() && ( ( _external_node_index % dynamic_hiding_factor ) != 1 ) ) || ( !node
+                        .isExternal() && ( ( new_x_min < 20 ) || ( ( _y_distance * node.getNumberOfExternalNodes() ) < getTreeFontSet()._fm_large
                         .getHeight() ) ) ) ) ) {
             return;
         }
                         .getHeight() ) ) ) ) ) {
             return;
         }
@@ -3563,322 +4659,153 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                                     final boolean to_graphics_file,
                                                     final boolean to_pdf ) {
         if ( isNodeDataInvisible( node ) && !to_graphics_file ) {
                                                     final boolean to_graphics_file,
                                                     final boolean to_pdf ) {
         if ( isNodeDataInvisible( node ) && !to_graphics_file ) {
-            return;
-        }
-        if ( ( !getControlPanel().isShowInternalData() && !node.isExternal() ) ) {
-            return;
-        }
-        if ( getControlPanel().isShowDomainArchitectures() && node.getNodeData().isHasSequence()
-                && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
-            RenderableDomainArchitecture rds = null;
-            if ( node.getNodeData().getSequence().getDomainArchitecture() instanceof RenderableDomainArchitecture ) {
-                try {
-                    rds = ( RenderableDomainArchitecture ) node.getNodeData().getSequence().getDomainArchitecture();
-                }
-                catch ( final ClassCastException cce ) {
-                    cce.printStackTrace();
-                }
-                if ( rds != null ) {
-                    rds.setRenderingHeight( 6 );
-                    int x = 0;
-                    if ( getControlPanel().isShowTaxonomyCode()
-                            && ( !ForesterUtil.isEmpty( PhylogenyMethods.getSpecies( node ) ) ) ) {
-                        x += getTreeFontSet()._fm_large_italic.stringWidth( PhylogenyMethods.getSpecies( node ) + " " );
-                    }
-                    if ( getControlPanel().isShowGeneNames()
-                            && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) ) ) {
-                        x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getName() + " " );
-                    }
-                    if ( getControlPanel().isShowGeneSymbols()
-                            && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getSymbol() ) ) ) {
-                        x += getTreeFontSet()._fm_large
-                                .stringWidth( node.getNodeData().getSequence().getSymbol() + " " );
-                    }
-                    if ( getControlPanel().isShowSequenceAcc()
-                            && ( node.getNodeData().getSequence().getAccession() != null ) ) {
-                        x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getAccession()
-                                .toString()
-                                + " " );
-                    }
-                    if ( getControlPanel().isShowNodeNames() && ( node.getName().length() > 0 ) ) {
-                        x += getTreeFontSet()._fm_large.stringWidth( node.getName() + " " );
-                    }
-                    rds.render( node.getXcoord() + x, node.getYcoord() - 3, g, this, to_pdf );
-                }
-            }
-        }
-        //////////////
-        if ( getControlPanel().isShowVectorData() && ( node.getNodeData().getVector() != null )
-                && ( node.getNodeData().getVector().size() > 0 ) && ( getStatisticsForExpressionValues() != null ) ) {
-            final RenderableVector rv = RenderableVector.createInstance( node.getNodeData().getVector(),
-                                                                         getStatisticsForExpressionValues(),
-                                                                         getConfiguration() );
-            if ( rv != null ) {
-                int x = 0;
-                PhylogenyNode my_node = node;
-                if ( !getControlPanel().isDrawPhylogram() ) {
-                    my_node = getPhylogeny().getFirstExternalNode();
-                }
-                if ( getControlPanel().isShowTaxonomyCode() && ( PhylogenyMethods.getSpecies( my_node ).length() > 0 ) ) {
-                    x += getTreeFontSet()._fm_large_italic.stringWidth( PhylogenyMethods.getSpecies( my_node ) + " " );
-                }
-                if ( getControlPanel().isShowNodeNames() && ( my_node.getName().length() > 0 ) ) {
-                    x += getTreeFontSet()._fm_large.stringWidth( my_node.getName() + " " );
-                }
-                rv.render( my_node.getXcoord() + x, node.getYcoord() - 5, g, this, to_pdf );
-            }
-        }
-        //////////////
-    }
-
-    final private void paintOvRectangle( final Graphics2D g ) {
-        final float w_ratio = ( float ) getWidth() / getVisibleRect().width;
-        final float h_ratio = ( float ) getHeight() / getVisibleRect().height;
-        final float x_ratio = ( float ) getWidth() / getVisibleRect().x;
-        final float y_ratio = ( float ) getHeight() / getVisibleRect().y;
-        final float width = getOvMaxWidth() / w_ratio;
-        final float height = getOvMaxHeight() / h_ratio;
-        final float x = getVisibleRect().x + getOvXPosition() + getOvMaxWidth() / x_ratio;
-        final float y = getVisibleRect().y + getOvYPosition() + getOvMaxHeight() / y_ratio;
-        g.setColor( getTreeColorSet().getFoundColor() );
-        getOvRectangle().setRect( x, y, width, height );
-        if ( ( width < 6 ) && ( height < 6 ) ) {
-            drawRectFilled( x, y, 6, 6, g );
-            getOvVirtualRectangle().setRect( x, y, 6, 6 );
-        }
-        else if ( width < 6 ) {
-            drawRectFilled( x, y, 6, height, g );
-            getOvVirtualRectangle().setRect( x, y, 6, height );
-        }
-        else if ( height < 6 ) {
-            drawRectFilled( x, y, width, 6, g );
-            getOvVirtualRectangle().setRect( x, y, width, 6 );
-        }
-        else {
-            drawRect( x, y, width, height, g );
-            if ( isInOvRect() ) {
-                drawRect( x + 1, y + 1, width - 2, height - 2, g );
-            }
-            getOvVirtualRectangle().setRect( x, y, width, height );
-        }
-    }
-
-    final void paintPhylogeny( final Graphics2D g,
-                               final boolean to_pdf,
-                               final boolean to_graphics_file,
-                               final int graphics_file_width,
-                               final int graphics_file_height,
-                               final int graphics_file_x,
-                               final int graphics_file_y ) {
-        if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
-            return;
-        }
-        if ( _control_panel.isShowSequenceRelations() ) {
-            _query_sequence = _control_panel.getSelectedQuerySequence();
-        }
-        // Color the background
-        if ( !to_pdf ) {
-            final Rectangle r = getVisibleRect();
-            if ( !getOptions().isBackgroundColorGradient() || getOptions().isPrintBlackAndWhite() ) {
-                g.setColor( getTreeColorSet().getBackgroundColor() );
-                if ( !to_graphics_file ) {
-                    g.fill( r );
-                }
-                else {
-                    if ( getOptions().isPrintBlackAndWhite() ) {
-                        g.setColor( Color.WHITE );
-                    }
-                    g.fillRect( graphics_file_x, graphics_file_y, graphics_file_width, graphics_file_height );
-                }
-            }
-            else {
-                if ( !to_graphics_file ) {
-                    g.setPaint( new GradientPaint( r.x, r.y, getTreeColorSet().getBackgroundColor(), r.x, r.y
-                            + r.height, getTreeColorSet().getBackgroundColorGradientBottom() ) );
-                    g.fill( r );
-                }
-                else {
-                    g.setPaint( new GradientPaint( graphics_file_x,
-                                                   graphics_file_y,
-                                                   getTreeColorSet().getBackgroundColor(),
-                                                   graphics_file_x,
-                                                   graphics_file_y + graphics_file_height,
-                                                   getTreeColorSet().getBackgroundColorGradientBottom() ) );
-                    g.fillRect( graphics_file_x, graphics_file_y, graphics_file_width, graphics_file_height );
-                }
-            }
-            g.setStroke( new BasicStroke( 1 ) );
-        }
-        else {
-            g.setStroke( new BasicStroke( getOptions().getPrintLineWidth() ) );
-        }
-        if ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
-                && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
-            _external_node_index = 0;
-            // Position starting X of tree
-            if ( !_phylogeny.isRooted() /*|| ( _subtree_index > 0 )*/) {
-                _phylogeny.getRoot().setXcoord( TreePanel.MOVE );
-            }
-            else if ( ( _phylogeny.getRoot().getDistanceToParent() > 0.0 ) && getControlPanel().isDrawPhylogram() ) {
-                _phylogeny.getRoot().setXcoord( ( float ) ( TreePanel.MOVE + ( _phylogeny.getRoot()
-                        .getDistanceToParent() * getXcorrectionFactor() ) ) );
-            }
-            else {
-                _phylogeny.getRoot().setXcoord( TreePanel.MOVE + getXdistance() );
-            }
-            // Position starting Y of tree
-            _phylogeny.getRoot().setYcoord( ( getYdistance() * _phylogeny.getRoot().getNumberOfExternalNodes() )
-                    + ( TreePanel.MOVE / 2.0f ) );
-            final int dynamic_hiding_factor = ( int ) ( getTreeFontSet()._fm_large.getHeight() / ( 1.5 * getYdistance() ) );
-            if ( getControlPanel().isDynamicallyHideData() ) {
-                if ( dynamic_hiding_factor > 1 ) {
-                    getControlPanel().setDynamicHidingIsOn( true );
-                }
-                else {
-                    getControlPanel().setDynamicHidingIsOn( false );
-                }
-            }
-            if ( _nodes_in_preorder == null ) {
-                _nodes_in_preorder = new PhylogenyNode[ _phylogeny.getNodeCount() ];
-                int i = 0;
-                for( final PhylogenyNodeIterator it = _phylogeny.iteratorPreorder(); it.hasNext(); ) {
-                    _nodes_in_preorder[ i++ ] = it.next();
-                }
-            }
-            //final PhylogenyNodeIterator it;
-            //for( it = _phylogeny.iteratorPreorder(); it.hasNext(); ) {
-            //    paintNodeRectangular( g, it.next(), to_pdf, getControlPanel().isDynamicallyHideData()
-            //            && ( dynamic_hiding_factor > 1 ), dynamic_hiding_factor, to_graphics_file );
-            //}
-            for( int i = 0; i < _nodes_in_preorder.length; ++i ) {
-                paintNodeRectangular( g, _nodes_in_preorder[ i ], to_pdf, getControlPanel().isDynamicallyHideData()
-                        && ( dynamic_hiding_factor > 1 ), dynamic_hiding_factor, to_graphics_file );
-            }
-            if ( getOptions().isShowScale() && getControlPanel().isDrawPhylogram() && ( getScaleDistance() > 0.0 ) ) {
-                if ( !( to_graphics_file || to_pdf ) ) {
-                    paintScale( g,
-                                getVisibleRect().x,
-                                getVisibleRect().y + getVisibleRect().height,
-                                to_pdf,
-                                to_graphics_file );
-                }
-                else {
-                    paintScale( g, graphics_file_x, graphics_file_y + graphics_file_height, to_pdf, to_graphics_file );
-                }
-            }
-            if ( getOptions().isShowOverview() && isOvOn() && !to_graphics_file && !to_pdf ) {
-                paintPhylogenyLite( g );
-            }
-        }
-        else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            if ( getControlPanel().getDynamicallyHideData() != null ) {
-                getControlPanel().setDynamicHidingIsOn( false );
-            }
-            final double angle = getStartingAngle();
-            final boolean radial_labels = getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL;
-            _dynamic_hiding_factor = 0;
-            if ( getControlPanel().isDynamicallyHideData() ) {
-                _dynamic_hiding_factor = ( int ) ( ( getTreeFontSet()._fm_large.getHeight() * 1.5 * getPhylogeny()
-                        .getNumberOfExternalNodes() ) / ( TWO_PI * 10 ) );
-            }
-            if ( getControlPanel().getDynamicallyHideData() != null ) {
-                if ( _dynamic_hiding_factor > 1 ) {
-                    getControlPanel().setDynamicHidingIsOn( true );
-                }
-                else {
-                    getControlPanel().setDynamicHidingIsOn( false );
-                }
-            }
-            paintUnrooted( _phylogeny.getRoot(),
-                           angle,
-                           ( float ) ( angle + 2 * Math.PI ),
-                           radial_labels,
-                           g,
-                           to_pdf,
-                           to_graphics_file );
-            if ( getOptions().isShowScale() ) {
-                if ( !( to_graphics_file || to_pdf ) ) {
-                    paintScale( g,
-                                getVisibleRect().x,
-                                getVisibleRect().y + getVisibleRect().height,
-                                to_pdf,
-                                to_graphics_file );
+            return;
+        }
+        if ( ( !getControlPanel().isShowInternalData() && !node.isExternal() ) ) {
+            return;
+        }
+        if ( getControlPanel().isShowDomainArchitectures() && node.getNodeData().isHasSequence()
+                && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
+            RenderableDomainArchitecture rds = null;
+            if ( node.getNodeData().getSequence().getDomainArchitecture() instanceof RenderableDomainArchitecture ) {
+                try {
+                    rds = ( RenderableDomainArchitecture ) node.getNodeData().getSequence().getDomainArchitecture();
                 }
                 }
-                else {
-                    paintScale( g, graphics_file_x, graphics_file_y + graphics_file_height, to_pdf, to_graphics_file );
+                catch ( final ClassCastException cce ) {
+                    cce.printStackTrace();
+                }
+                if ( rds != null ) {
+                    rds.setRenderingHeight( 6 );
+                    int x = 0;
+                    if ( node.getNodeData().isHasTaxonomy() ) {
+                        if ( getControlPanel().isShowTaxonomyCode()
+                                && ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getTaxonomyCode() ) ) ) {
+                            x += getTreeFontSet()._fm_large_italic.stringWidth( node.getNodeData().getTaxonomy()
+                                    .getTaxonomyCode()
+                                    + " " );
+                        }
+                        if ( getControlPanel().isShowTaxonomyScientificNames()
+                                && ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getScientificName() ) ) ) {
+                            x += getTreeFontSet()._fm_large_italic.stringWidth( node.getNodeData().getTaxonomy()
+                                    .getScientificName()
+                                    + " " );
+                        }
+                        if ( getControlPanel().isShowTaxonomyCommonNames()
+                                && ( !ForesterUtil.isEmpty( node.getNodeData().getTaxonomy().getCommonName() ) ) ) {
+                            x += getTreeFontSet()._fm_large_italic.stringWidth( node.getNodeData().getTaxonomy()
+                                    .getCommonName()
+                                    + " " );
+                        }
+                    }
+                    if ( node.getNodeData().isHasSequence() ) {
+                        if ( getControlPanel().isShowSeqNames()
+                                && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) ) ) {
+                            x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getName()
+                                    + " " );
+                        }
+                        if ( getControlPanel().isShowSeqSymbols()
+                                && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getSymbol() ) ) ) {
+                            x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getSymbol()
+                                    + " " );
+                        }
+                        if ( getControlPanel().isShowGeneNames()
+                                && ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getGeneName() ) ) ) {
+                            x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence().getGeneName()
+                                    + " " );
+                        }
+                        if ( getControlPanel().isShowSequenceAcc()
+                                && ( node.getNodeData().getSequence().getAccession() != null ) ) {
+                            x += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getSequence()
+                                    .getAccession().toString()
+                                    + " " );
+                        }
+                        if ( getControlPanel().isShowAnnotation()
+                                && ( node.getNodeData().getSequence().getAnnotations() != null )
+                                && ( !node.getNodeData().getSequence().getAnnotations().isEmpty() ) ) {
+                            x += getTreeFontSet()._fm_large.stringWidth( TreePanelUtil.createAnnotationString( node
+                                    .getNodeData().getSequence().getAnnotations(), getOptions()
+                                    .isShowAnnotationRefSource() )
+                                    + " " );
+                        }
+                    }
+                    if ( getControlPanel().isShowNodeNames() && !ForesterUtil.isEmpty( node.getName() ) ) {
+                        x += getTreeFontSet()._fm_large.stringWidth( node.getName() + " " );
+                    }
+                    rds.render( node.getXcoord() + x, node.getYcoord() - 3, g, this, to_pdf );
                 }
                 }
-            }
-            if ( getOptions().isShowOverview() && isOvOn() && !to_graphics_file && !to_pdf ) {
-                g.setColor( getTreeColorSet().getOvColor() );
-                paintUnrootedLite( _phylogeny.getRoot(),
-                                   angle,
-                                   angle + 2 * Math.PI,
-                                   g,
-                                   ( getUrtFactorOv() / ( getVisibleRect().width / getOvMaxWidth() ) ) );
-                paintOvRectangle( g );
             }
         }
             }
         }
-        else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) {
-            final int radius = ( int ) ( ( Math.min( getPreferredSize().getWidth(), getPreferredSize().getHeight() ) / 2 ) - ( MOVE + getLongestExtNodeInfo() ) );
-            final int d = radius + MOVE + getLongestExtNodeInfo();
-            _dynamic_hiding_factor = 0;
-            if ( getControlPanel().isDynamicallyHideData() && ( radius > 0 ) ) {
-                _dynamic_hiding_factor = ( int ) ( ( getTreeFontSet()._fm_large.getHeight() * 1.5 * getPhylogeny()
-                        .getNumberOfExternalNodes() ) / ( TWO_PI * radius ) );
-            }
-            if ( getControlPanel().getDynamicallyHideData() != null ) {
-                if ( _dynamic_hiding_factor > 1 ) {
-                    getControlPanel().setDynamicHidingIsOn( true );
-                }
-                else {
-                    getControlPanel().setDynamicHidingIsOn( false );
+        //////////////
+        if ( getControlPanel().isShowVectorData() && ( node.getNodeData().getVector() != null )
+                && ( node.getNodeData().getVector().size() > 0 ) && ( getStatisticsForExpressionValues() != null ) ) {
+            final RenderableVector rv = RenderableVector.createInstance( node.getNodeData().getVector(),
+                                                                         getStatisticsForExpressionValues(),
+                                                                         getConfiguration() );
+            if ( rv != null ) {
+                int x = 0;
+                PhylogenyNode my_node = node;
+                if ( !getControlPanel().isDrawPhylogram() ) {
+                    my_node = getPhylogeny().getFirstExternalNode();
                 }
                 }
-            }
-            paintCircular( _phylogeny, getStartingAngle(), d, d, radius > 0 ? radius : 0, g, to_pdf, to_graphics_file );
-            if ( getOptions().isShowOverview() && isOvOn() && !to_graphics_file && !to_pdf ) {
-                final int radius_ov = ( int ) ( getOvMaxHeight() < getOvMaxWidth() ? getOvMaxHeight() / 2
-                        : getOvMaxWidth() / 2 );
-                double x_scale = 1.0;
-                double y_scale = 1.0;
-                int x_pos = getVisibleRect().x + getOvXPosition();
-                int y_pos = getVisibleRect().y + getOvYPosition();
-                if ( getWidth() > getHeight() ) {
-                    x_scale = ( double ) getHeight() / getWidth();
-                    x_pos = ForesterUtil.roundToInt( x_pos / x_scale );
+                if ( getControlPanel().isShowTaxonomyCode() && ( PhylogenyMethods.getSpecies( my_node ).length() > 0 ) ) {
+                    x += getTreeFontSet()._fm_large_italic.stringWidth( PhylogenyMethods.getSpecies( my_node ) + " " );
                 }
                 }
-                else {
-                    y_scale = ( double ) getWidth() / getHeight();
-                    y_pos = ForesterUtil.roundToInt( y_pos / y_scale );
+                if ( getControlPanel().isShowNodeNames() && ( my_node.getName().length() > 0 ) ) {
+                    x += getTreeFontSet()._fm_large.stringWidth( my_node.getName() + " " );
                 }
                 }
-                _at = g.getTransform();
-                g.scale( x_scale, y_scale );
-                paintCircularLite( _phylogeny,
-                                   getStartingAngle(),
-                                   x_pos + radius_ov,
-                                   y_pos + radius_ov,
-                                   ( int ) ( radius_ov - ( getLongestExtNodeInfo() / ( getVisibleRect().width / getOvRectangle()
-                                           .getWidth() ) ) ),
-                                   g );
-                g.setTransform( _at );
-                paintOvRectangle( g );
+                rv.render( my_node.getXcoord() + x, node.getYcoord() - 5, g, this, to_pdf );
             }
         }
             }
         }
+        //////////////
+    }
+
+    final private void paintOvRectangle( final Graphics2D g ) {
+        final float w_ratio = ( ( float ) getWidth() ) / getVisibleRect().width;
+        final float h_ratio = ( ( float ) getHeight() ) / getVisibleRect().height;
+        final float x_ratio = ( ( float ) getWidth() ) / getVisibleRect().x;
+        final float y_ratio = ( ( float ) getHeight() ) / getVisibleRect().y;
+        final float width = getOvMaxWidth() / w_ratio;
+        final float height = getOvMaxHeight() / h_ratio;
+        final float x = getVisibleRect().x + getOvXPosition() + ( getOvMaxWidth() / x_ratio );
+        final float y = getVisibleRect().y + getOvYPosition() + ( getOvMaxHeight() / y_ratio );
+        g.setColor( getTreeColorSet().getFoundColor0() );
+        getOvRectangle().setRect( x, y, width, height );
+        final Stroke s = g.getStroke();
+        g.setStroke( STROKE_1 );
+        if ( ( width < 6 ) && ( height < 6 ) ) {
+            drawRectFilled( x, y, 6, 6, g );
+            getOvVirtualRectangle().setRect( x, y, 6, 6 );
+        }
+        else if ( width < 6 ) {
+            drawRectFilled( x, y, 6, height, g );
+            getOvVirtualRectangle().setRect( x, y, 6, height );
+        }
+        else if ( height < 6 ) {
+            drawRectFilled( x, y, width, 6, g );
+            getOvVirtualRectangle().setRect( x, y, width, 6 );
+        }
+        else {
+            drawRect( x, y, width, height, g );
+            if ( isInOvRect() ) {
+                drawRect( x + 1, y + 1, width - 2, height - 2, g );
+            }
+            getOvVirtualRectangle().setRect( x, y, width, height );
+        }
+        g.setStroke( s );
     }
 
     final private void paintPhylogenyLite( final Graphics2D g ) {
     }
 
     final private void paintPhylogenyLite( final Graphics2D g ) {
-        //System.out.println( getVisibleRect().x + " " + getVisibleRect().y );
         _phylogeny
                 .getRoot()
                 .setXSecondary( ( float ) ( getVisibleRect().x + getOvXPosition() + ( MOVE / ( getVisibleRect().width / getOvRectangle()
                         .getWidth() ) ) ) );
         _phylogeny.getRoot().setYSecondary( ( getVisibleRect().y + getOvYStart() ) );
         _phylogeny
                 .getRoot()
                 .setXSecondary( ( float ) ( getVisibleRect().x + getOvXPosition() + ( MOVE / ( getVisibleRect().width / getOvRectangle()
                         .getWidth() ) ) ) );
         _phylogeny.getRoot().setYSecondary( ( getVisibleRect().y + getOvYStart() ) );
-        //final PhylogenyNodeIterator it;
-        //for( it = _phylogeny.iteratorPreorder(); it.hasNext(); ) {
-        //    paintNodeLite( g, it.next() );
-        //}
-        for( int i = 0; i < _nodes_in_preorder.length; ++i ) {
-            paintNodeLite( g, _nodes_in_preorder[ i ] );
+        final Stroke s = g.getStroke();
+        g.setStroke( STROKE_05 );
+        for( final PhylogenyNode element : _nodes_in_preorder ) {
+            paintNodeLite( g, element );
         }
         }
+        g.setStroke( s );
         paintOvRectangle( g );
     }
 
         paintOvRectangle( g );
     }
 
@@ -3910,7 +4837,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             final double w = PhylogenyMethods.getBranchWidthValue( root );
             drawRectFilled( x1 - d, root.getYcoord() - ( w / 2 ), d, w, g );
         }
             final double w = PhylogenyMethods.getBranchWidthValue( root );
             drawRectFilled( x1 - d, root.getYcoord() - ( w / 2 ), d, w, g );
         }
-        paintNodeBox( x1, root.getYcoord(), root, g, to_pdf, to_graphics_file, isInFoundNodes( root ) );
+        paintNodeBox( x1, root.getYcoord(), root, g, to_pdf, to_graphics_file );
     }
 
     final private void paintScale( final Graphics2D g,
     }
 
     final private void paintScale( final Graphics2D g,
@@ -3930,12 +4857,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         else {
             g.setColor( getTreeColorSet().getBranchLengthColor() );
         }
         else {
             g.setColor( getTreeColorSet().getBranchLengthColor() );
         }
+        final Stroke s = g.getStroke();
+        g.setStroke( STROKE_1 );
         drawLine( x1, y1, x1, y2, g );
         drawLine( x2, y1, x2, y2, g );
         drawLine( x1, y3, x2, y3, g );
         if ( getScaleLabel() != null ) {
             g.drawString( getScaleLabel(), ( x1 + 2 ), y3 - 2 );
         }
         drawLine( x1, y1, x1, y2, g );
         drawLine( x2, y1, x2, y2, g );
         drawLine( x1, y3, x2, y3, g );
         if ( getScaleLabel() != null ) {
             g.drawString( getScaleLabel(), ( x1 + 2 ), y3 - 2 );
         }
+        g.setStroke( s );
     }
 
     final private int paintTaxonomy( final Graphics2D g,
     }
 
     final private int paintTaxonomy( final Graphics2D g,
@@ -3951,12 +4881,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
         else if ( is_in_found_nodes ) {
             g.setFont( getTreeFontSet().getLargeItalicFont().deriveFont( TreeFontSet.BOLD_AND_ITALIC ) );
         }
         else if ( is_in_found_nodes ) {
             g.setFont( getTreeFontSet().getLargeItalicFont().deriveFont( TreeFontSet.BOLD_AND_ITALIC ) );
-            g.setColor( getTreeColorSet().getFoundColor() );
+            g.setColor( getColorForFoundNode( node ) );
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
             g.setColor( getTaxonomyBasedColor( node ) );
         }
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
             g.setColor( getTaxonomyBasedColor( node ) );
         }
-        else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches()
+        else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isUseVisualStyles()
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
             g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
         }
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
             g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
         }
@@ -4043,18 +4973,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    private void abbreviateScientificName( final String sn ) {
-        final String[] a = sn.split( "\\s+" );
-        _sb.append( a[ 0 ].substring( 0, 1 ) );
-        _sb.append( a[ 1 ].substring( 0, 2 ) );
-        if ( a.length > 2 ) {
-            for( int i = 2; i < a.length; i++ ) {
-                _sb.append( " " );
-                _sb.append( a[ i ] );
-            }
-        }
-    }
-
     final private void paintUnrooted( final PhylogenyNode n,
                                       final double low_angle,
                                       final double high_angle,
     final private void paintUnrooted( final PhylogenyNode n,
                                       final double low_angle,
                                       final double high_angle,
@@ -4073,7 +4991,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                        to_graphics_file,
                                        radial_labels,
                                        ( high_angle + low_angle ) / 2,
                                        to_graphics_file,
                                        radial_labels,
                                        ( high_angle + low_angle ) / 2,
-                                       isInFoundNodes( n ) );
+                                       isInFoundNodes( n ) || isInCurrentExternalNodes( n ) );
             return;
         }
         final float num_enclosed = n.getNumberOfExternalNodes();
             return;
         }
         final float num_enclosed = n.getNumberOfExternalNodes();
@@ -4112,19 +5030,19 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             else {
                 length = getUrtFactor();
             }
             else {
                 length = getUrtFactor();
             }
-            final double mid_angle = current_angle + arc_size / 2;
-            final float new_x = ( float ) ( x + Math.cos( mid_angle ) * length );
-            final float new_y = ( float ) ( y + Math.sin( mid_angle ) * length );
+            final double mid_angle = current_angle + ( arc_size / 2 );
+            final float new_x = ( float ) ( x + ( Math.cos( mid_angle ) * length ) );
+            final float new_y = ( float ) ( y + ( Math.sin( mid_angle ) * length ) );
             desc.setXcoord( new_x );
             desc.setYcoord( new_y );
             paintUnrooted( desc, current_angle, current_angle + arc_size, radial_labels, g, to_pdf, to_graphics_file );
             current_angle += arc_size;
             assignGraphicsForBranchWithColorForParentBranch( desc, false, g, to_pdf, to_graphics_file );
             drawLine( x, y, new_x, new_y, g );
             desc.setXcoord( new_x );
             desc.setYcoord( new_y );
             paintUnrooted( desc, current_angle, current_angle + arc_size, radial_labels, g, to_pdf, to_graphics_file );
             current_angle += arc_size;
             assignGraphicsForBranchWithColorForParentBranch( desc, false, g, to_pdf, to_graphics_file );
             drawLine( x, y, new_x, new_y, g );
-            paintNodeBox( new_x, new_y, desc, g, to_pdf, to_graphics_file, isInFoundNodes( desc ) );
+            paintNodeBox( new_x, new_y, desc, g, to_pdf, to_graphics_file );
         }
         if ( n.isRoot() ) {
         }
         if ( n.isRoot() ) {
-            paintNodeBox( n.getXcoord(), n.getYcoord(), n, g, to_pdf, to_graphics_file, isInFoundNodes( n ) );
+            paintNodeBox( n.getXcoord(), n.getYcoord(), n, g, to_pdf, to_graphics_file );
         }
     }
 
         }
     }
 
@@ -4134,8 +5052,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                           final Graphics2D g,
                                           final float urt_ov_factor ) {
         if ( n.isRoot() ) {
                                           final Graphics2D g,
                                           final float urt_ov_factor ) {
         if ( n.isRoot() ) {
-            final int x_pos = ( int ) ( getVisibleRect().x + getOvXPosition() + getOvMaxWidth() / 2 );
-            final int y_pos = ( int ) ( getVisibleRect().y + getOvYPosition() + getOvMaxHeight() / 2 );
+            final int x_pos = ( int ) ( getVisibleRect().x + getOvXPosition() + ( getOvMaxWidth() / 2 ) );
+            final int y_pos = ( int ) ( getVisibleRect().y + getOvYPosition() + ( getOvMaxHeight() / 2 ) );
             n.setXSecondary( x_pos );
             n.setYSecondary( y_pos );
         }
             n.setXSecondary( x_pos );
             n.setYSecondary( y_pos );
         }
@@ -4162,14 +5080,18 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             else {
                 length = urt_ov_factor;
             }
             else {
                 length = urt_ov_factor;
             }
-            final double mid_angle = current_angle + arc_size / 2;
-            final float new_x = ( float ) ( x + Math.cos( mid_angle ) * length );
-            final float new_y = ( float ) ( y + Math.sin( mid_angle ) * length );
+            final double mid_angle = current_angle + ( arc_size / 2 );
+            final float new_x = ( float ) ( x + ( Math.cos( mid_angle ) * length ) );
+            final float new_y = ( float ) ( y + ( Math.sin( mid_angle ) * length ) );
             desc.setXSecondary( new_x );
             desc.setYSecondary( new_y );
             desc.setXSecondary( new_x );
             desc.setYSecondary( new_y );
-            if ( isInFoundNodes( desc ) ) {
-                g.setColor( getTreeColorSet().getFoundColor() );
-                drawRectFilled( desc.getXSecondary() - 1, desc.getYSecondary() - 1, 3, 3, g );
+            if ( isInFoundNodes( desc ) || isInCurrentExternalNodes( desc ) ) {
+                g.setColor( getColorForFoundNode( desc ) );
+                drawRectFilled( desc.getXSecondary() - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF,
+                                desc.getYSecondary() - OVERVIEW_FOUND_NODE_BOX_SIZE_HALF,
+                                OVERVIEW_FOUND_NODE_BOX_SIZE,
+                                OVERVIEW_FOUND_NODE_BOX_SIZE,
+                                g );
                 g.setColor( getTreeColorSet().getOvColor() );
             }
             paintUnrootedLite( desc, current_angle, current_angle + arc_size, g, urt_ov_factor );
                 g.setColor( getTreeColorSet().getOvColor() );
             }
             paintUnrootedLite( desc, current_angle, current_angle + arc_size, g, urt_ov_factor );
@@ -4190,7 +5112,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                            JOptionPane.ERROR_MESSAGE );
             return;
         }
                                            JOptionPane.ERROR_MESSAGE );
             return;
         }
-        final String label = getASimpleTextRepresentationOfANode( getCutOrCopiedTree().getRoot() );
+        final String label = createASimpleTextRepresentationOfANode( getCutOrCopiedTree().getRoot() );
         final Object[] options = { "As sibling", "As descendant", "Cancel" };
         final int r = JOptionPane.showOptionDialog( this,
                                                     "How to paste subtree" + label + "?",
         final Object[] options = { "As sibling", "As descendant", "Cancel" };
         final int r = JOptionPane.showOptionDialog( this,
                                                     "How to paste subtree" + label + "?",
@@ -4209,7 +5131,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
         final Phylogeny buffer_phy = getCutOrCopiedTree().copy();
         buffer_phy.setAllNodesToNotCollapse();
         }
         final Phylogeny buffer_phy = getCutOrCopiedTree().copy();
         buffer_phy.setAllNodesToNotCollapse();
-        buffer_phy.preOrderReId();
+        PhylogenyMethods.preOrderReId( buffer_phy );
         buffer_phy.setRooted( true );
         boolean need_to_show_whole = false;
         if ( paste_as_sibling ) {
         buffer_phy.setRooted( true );
         boolean need_to_show_whole = false;
         if ( paste_as_sibling ) {
@@ -4217,160 +5139,65 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 JOptionPane.showMessageDialog( this,
                                                "Cannot paste sibling to root",
                                                "Attempt to paste sibling to root",
                 JOptionPane.showMessageDialog( this,
                                                "Cannot paste sibling to root",
                                                "Attempt to paste sibling to root",
-                                               JOptionPane.ERROR_MESSAGE );
-                return;
-            }
-            buffer_phy.addAsSibling( node );
-        }
-        else {
-            if ( ( node.getNumberOfExternalNodes() == 1 ) && node.isRoot() ) {
-                need_to_show_whole = true;
-                _phylogeny = buffer_phy;
-            }
-            else {
-                buffer_phy.addAsChild( node );
-            }
-        }
-        if ( getCopiedAndPastedNodes() == null ) {
-            setCopiedAndPastedNodes( new HashSet<Integer>() );
-        }
-        final List<PhylogenyNode> nodes = PhylogenyMethods.obtainAllNodesAsList( buffer_phy );
-        final Set<Integer> node_ids = new HashSet<Integer>( nodes.size() );
-        for( final PhylogenyNode n : nodes ) {
-            node_ids.add( n.getId() );
-        }
-        node_ids.add( node.getId() );
-        getCopiedAndPastedNodes().addAll( node_ids );
-        setNodeInPreorderToNull();
-        _phylogeny.externalNodesHaveChanged();
-        _phylogeny.hashIDs();
-        _phylogeny.recalculateNumberOfExternalDescendants( true );
-        resetNodeIdToDistToLeafMap();
-        setEdited( true );
-        if ( need_to_show_whole ) {
-            getControlPanel().showWhole();
-        }
-        repaint();
-    }
-
-    final public int print( final Graphics g, final PageFormat page_format, final int page_index )
-            throws PrinterException {
-        if ( page_index > 0 ) {
-            return ( NO_SUCH_PAGE );
-        }
-        else {
-            final Graphics2D g2d = ( Graphics2D ) g;
-            g2d.translate( page_format.getImageableX(), page_format.getImageableY() );
-            // Turn off double buffering !?
-            paintPhylogeny( g2d, true, false, 0, 0, 0, 0 );
-            // Turn double buffering back on !?
-            return ( PAGE_EXISTS );
-        }
-    }
-
-    final void recalculateMaxDistanceToRoot() {
-        _max_distance_to_root = PhylogenyMethods.calculateMaxDistanceToRoot( getPhylogeny() );
-    }
-
-    /**
-     * Remove all edit-node frames
-     */
-    final void removeAllEditNodeJFrames() {
-        for( int i = 0; i <= ( TreePanel.MAX_NODE_FRAMES - 1 ); i++ ) {
-            if ( _node_frames[ i ] != null ) {
-                _node_frames[ i ].dispose();
-                _node_frames[ i ] = null;
-            }
-        }
-        _node_frame_index = 0;
-    }
-
-    /**
-     * Remove a node-edit frame.
-     */
-    final void removeEditNodeFrame( final int i ) {
-        _node_frame_index--;
-        _node_frames[ i ] = null;
-        if ( i < _node_frame_index ) {
-            for( int j = 0; j < _node_frame_index - 1; j++ ) {
-                _node_frames[ j ] = _node_frames[ j + 1 ];
-            }
-            _node_frames[ _node_frame_index ] = null;
-        }
-    }
-
-    final void reRoot( final PhylogenyNode node ) {
-        if ( !getPhylogeny().isRerootable() ) {
-            JOptionPane.showMessageDialog( this,
-                                           "This is not rerootable",
-                                           "Not rerootable",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
-        }
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot reroot in unrooted display type",
-                                           "Attempt to reroot tree in unrooted display",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
-        }
-        getPhylogeny().reRoot( node );
-        getPhylogeny().recalculateNumberOfExternalDescendants( true );
-        resetNodeIdToDistToLeafMap();
-        setNodeInPreorderToNull();
-        resetPreferredSize();
-        getMainPanel().adjustJScrollPane();
-        repaint();
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) {
-            getControlPanel().showWhole();
-        }
-    }
-
-    final void resetNodeIdToDistToLeafMap() {
-        _nodeid_dist_to_leaf = new HashMap<Integer, Short>();
-    }
-
-    final void resetPreferredSize() {
-        if ( ( getPhylogeny() == null ) || getPhylogeny().isEmpty() ) {
-            return;
-        }
-        int x = 0;
-        int y = 0;
-        y = TreePanel.MOVE
-                + ForesterUtil.roundToInt( getYdistance() * getPhylogeny().getRoot().getNumberOfExternalNodes() * 2 );
-        if ( getControlPanel().isDrawPhylogram() ) {
-            x = TreePanel.MOVE
-                    + getLongestExtNodeInfo()
-                    + ForesterUtil
-                            .roundToInt( ( getXcorrectionFactor() * getPhylogeny().getHeight() ) + getXdistance() );
+                                               JOptionPane.ERROR_MESSAGE );
+                return;
+            }
+            buffer_phy.addAsSibling( node );
         }
         else {
         }
         else {
-            if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) {
-                x = TreePanel.MOVE
-                        + getLongestExtNodeInfo()
-                        + ForesterUtil.roundToInt( getXdistance()
-                                * ( getPhylogeny().getRoot().getNumberOfExternalNodes() + 2 ) );
+            if ( ( node.getNumberOfExternalNodes() == 1 ) && node.isRoot() ) {
+                need_to_show_whole = true;
+                _phylogeny = buffer_phy;
             }
             else {
             }
             else {
-                x = TreePanel.MOVE
-                        + getLongestExtNodeInfo()
-                        + ForesterUtil.roundToInt( getXdistance()
-                                * ( PhylogenyMethods.calculateMaxDepth( getPhylogeny() ) + 1 ) );
+                buffer_phy.addAsChild( node );
             }
         }
             }
         }
-        setPreferredSize( new Dimension( x, y ) );
-    }
-
-    public final void setArrowCursor() {
-        setCursor( ARROW_CURSOR );
+        if ( getCopiedAndPastedNodes() == null ) {
+            setCopiedAndPastedNodes( new HashSet<Long>() );
+        }
+        final List<PhylogenyNode> nodes = PhylogenyMethods.obtainAllNodesAsList( buffer_phy );
+        final Set<Long> node_ids = new HashSet<Long>( nodes.size() );
+        for( final PhylogenyNode n : nodes ) {
+            node_ids.add( n.getId() );
+        }
+        node_ids.add( node.getId() );
+        getCopiedAndPastedNodes().addAll( node_ids );
+        setNodeInPreorderToNull();
+        _phylogeny.externalNodesHaveChanged();
+        _phylogeny.clearHashIdToNodeMap();
+        _phylogeny.recalculateNumberOfExternalDescendants( true );
+        resetNodeIdToDistToLeafMap();
+        setEdited( true );
+        if ( need_to_show_whole ) {
+            getControlPanel().showWhole();
+        }
         repaint();
     }
 
         repaint();
     }
 
-    final void setControlPanel( final ControlPanel atv_control ) {
-        _control_panel = atv_control;
+    private final StringBuffer propertiesToString( final PhylogenyNode node ) {
+        final PropertiesMap properties = node.getNodeData().getProperties();
+        final StringBuffer sb = new StringBuffer();
+        boolean first = true;
+        for( final String ref : properties.getPropertyRefs() ) {
+            if ( first ) {
+                first = false;
+            }
+            else {
+                sb.append( " " );
+            }
+            final Property p = properties.getProperty( ref );
+            sb.append( TreePanelUtil.getPartAfterColon( p.getRef() ) );
+            sb.append( "=" );
+            sb.append( p.getValue() );
+            if ( !ForesterUtil.isEmpty( p.getUnit() ) ) {
+                sb.append( TreePanelUtil.getPartAfterColon( p.getUnit() ) );
+            }
+        }
+        return sb;
     }
 
     }
 
-    final private void setCopiedAndPastedNodes( final Set<Integer> nodeIds ) {
+    final private void setCopiedAndPastedNodes( final Set<Long> nodeIds ) {
         getMainPanel().setCopiedAndPastedNodes( nodeIds );
     }
 
         getMainPanel().setCopiedAndPastedNodes( nodeIds );
     }
 
@@ -4378,42 +5205,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         getMainPanel().setCutOrCopiedTree( cut_or_copied_tree );
     }
 
         getMainPanel().setCutOrCopiedTree( cut_or_copied_tree );
     }
 
-    public final void setEdited( final boolean edited ) {
-        _edited = edited;
-    }
-
-    final void setFoundNodes( final Set<Integer> found_nodes ) {
-        _found_nodes = found_nodes;
-    }
-
     final private void setInOv( final boolean in_ov ) {
         _in_ov = in_ov;
     }
 
     final private void setInOv( final boolean in_ov ) {
         _in_ov = in_ov;
     }
 
-    final void setInOvRect( final boolean in_ov_rect ) {
-        _in_ov_rect = in_ov_rect;
-    }
-
-    final void setLargeFonts() {
-        getTreeFontSet().largeFonts();
-    }
-
-    final void setLastMouseDragPointX( final float x ) {
-        _last_drag_point_x = x;
-    }
-
-    final void setLastMouseDragPointY( final float y ) {
-        _last_drag_point_y = y;
-    }
-
-    final void setLongestExtNodeInfo( final int i ) {
-        _longest_ext_node_info = i;
-    }
-
-    final void setMediumFonts() {
-        getTreeFontSet().mediumFonts();
-    }
-
     final private void setOvMaxHeight( final float ov_max_height ) {
         _ov_max_height = ov_max_height;
     }
     final private void setOvMaxHeight( final float ov_max_height ) {
         _ov_max_height = ov_max_height;
     }
@@ -4422,10 +5217,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         _ov_max_width = ov_max_width;
     }
 
         _ov_max_width = ov_max_width;
     }
 
-    final void setOvOn( final boolean ov_on ) {
-        _ov_on = ov_on;
-    }
-
     final private void setOvXcorrectionFactor( final float f ) {
         _ov_x_correction_factor = f;
     }
     final private void setOvXcorrectionFactor( final float f ) {
         _ov_x_correction_factor = f;
     }
@@ -4450,72 +5241,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         _ov_y_start = ov_y_start;
     }
 
         _ov_y_start = ov_y_start;
     }
 
-    /**
-     * Set parameters for printing the displayed tree
-     * 
-     * @param x
-     * @param y
-     */
-    public final void setParametersForPainting( final int x, final int y, final boolean recalc_longest_ext_node_info ) {
-        // updateStyle(); not needed?
-        if ( ( _phylogeny != null ) && !_phylogeny.isEmpty() ) {
-            initNodeData();
-            if ( recalc_longest_ext_node_info ) {
-                calculateLongestExtNodeInfo();
-            }
-            int ext_nodes = _phylogeny.getRoot().getNumberOfExternalNodes();
-            final int max_depth = PhylogenyMethods.calculateMaxDepth( _phylogeny );
-            if ( ext_nodes == 1 ) {
-                ext_nodes = max_depth;
-                if ( ext_nodes < 1 ) {
-                    ext_nodes = 1;
-                }
-            }
-            updateOvSizes();
-            float xdist = 0;
-            float ov_xdist = 0;
-            if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) {
-                xdist = ( float ) ( ( x - getLongestExtNodeInfo() - TreePanel.MOVE ) / ( ext_nodes + 3.0 ) );
-                ov_xdist = ( float ) ( getOvMaxWidth() / ( ext_nodes + 3.0 ) );
-            }
-            else {
-                xdist = ( ( x - getLongestExtNodeInfo() - TreePanel.MOVE ) / ( max_depth + 1 ) );
-                ov_xdist = ( getOvMaxWidth() / ( max_depth + 1 ) );
-            }
-            float ydist = ( float ) ( ( y - TreePanel.MOVE ) / ( ext_nodes * 2.0 ) );
-            if ( xdist < 0.0 ) {
-                xdist = 0.0f;
-            }
-            if ( ov_xdist < 0.0 ) {
-                ov_xdist = 0.0f;
-            }
-            if ( ydist < 0.0 ) {
-                ydist = 0.0f;
-            }
-            setXdistance( xdist );
-            setYdistance( ydist );
-            setOvXDistance( ov_xdist );
-            final double height = _phylogeny.getHeight();
-            if ( height > 0 ) {
-                final float corr = ( float ) ( ( x - TreePanel.MOVE - getLongestExtNodeInfo() - getXdistance() ) / height );
-                setXcorrectionFactor( corr > 0 ? corr : 0 );
-                final float ov_corr = ( float ) ( ( getOvMaxWidth() - getOvXDistance() ) / height );
-                setOvXcorrectionFactor( ov_corr > 0 ? ov_corr : 0 );
-            }
-            else {
-                setXcorrectionFactor( 0 );
-                setOvXcorrectionFactor( 0 );
-            }
-            _circ_max_depth = max_depth;
-            setUpUrtFactor();
-        }
-    }
-
-    final void setPhylogenyGraphicsType( final PHYLOGENY_GRAPHICS_TYPE graphics_type ) {
-        _graphics_type = graphics_type;
-        setTextAntialias();
-    }
-
     final private void setScaleDistance( final double scale_distance ) {
         _scale_distance = scale_distance;
     }
     final private void setScaleDistance( final double scale_distance ) {
         _scale_distance = scale_distance;
     }
@@ -4524,75 +5249,30 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         _scale_label = scale_label;
     }
 
         _scale_label = scale_label;
     }
 
-    final void setSmallFonts() {
-        getTreeFontSet().smallFonts();
-    }
-
-    final void setStartingAngle( final double starting_angle ) {
-        _urt_starting_angle = starting_angle;
-    }
-
-    final void setSuperTinyFonts() {
-        getTreeFontSet().superTinyFonts();
-    }
-
-    final void setTextAntialias() {
-        if ( ( _phylogeny != null ) && !_phylogeny.isEmpty() ) {
-            if ( _phylogeny.getNumberOfExternalNodes() <= LIMIT_FOR_HQ_RENDERING ) {
-                _rendering_hints.put( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY );
-            }
-            else {
-                _rendering_hints.put( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED );
-            }
+    private final void setupStroke( final Graphics2D g ) {
+        if ( getYdistance() < 0.001 ) {
+            g.setStroke( STROKE_005 );
         }
         }
-        if ( getMainPanel().getOptions().isAntialiasScreen() ) {
-            if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR 
-            && !getMainPanel().getOptions().isShowDefaultNodeShapes()       
-            && ( getControlPanel() != null && !getControlPanel().isShowDomainArchitectures() )
-            
-            ) {
-                _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
-            }
-            else {
-                _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
-            }
-            try {
-                _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING,
-                                      RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB );
-            }
-            catch ( final Throwable e ) {
-                _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
-            }
+        else if ( getYdistance() < 0.01 ) {
+            g.setStroke( STROKE_01 );
+        }
+        else if ( getYdistance() < 0.5 ) {
+            g.setStroke( STROKE_025 );
+        }
+        else if ( getYdistance() < 1 ) {
+            g.setStroke( STROKE_05 );
+        }
+        else if ( getYdistance() < 2 ) {
+            g.setStroke( STROKE_075 );
+        }
+        else if ( getYdistance() < 20 ) {
+            g.setStroke( STROKE_1 );
         }
         else {
         }
         else {
-            _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF );
-            _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
+            g.setStroke( STROKE_2 );
         }
     }
 
         }
     }
 
-    final void setTinyFonts() {
-        getTreeFontSet().tinyFonts();
-    }
-
-    /**
-     * Set a phylogeny tree.
-     * 
-     * @param t
-     *            an instance of a Phylogeny
-     */
-    public final void setTree( final Phylogeny t ) {
-        setNodeInPreorderToNull();
-        _phylogeny = t;
-    }
-
-    final void setNodeInPreorderToNull() {
-        _nodes_in_preorder = null;
-    }
-
-    final void setTreeFile( final File treefile ) {
-        _treefile = treefile;
-    }
-
     final private void setUpUrtFactor() {
         final int d = getVisibleRect().width < getVisibleRect().height ? getVisibleRect().width
                 : getVisibleRect().height;
     final private void setUpUrtFactor() {
         final int d = getVisibleRect().width < getVisibleRect().height ? getVisibleRect().width
                 : getVisibleRect().height;
@@ -4619,37 +5299,203 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         _urt_factor_ov = urt_factor_ov;
     }
 
         _urt_factor_ov = urt_factor_ov;
     }
 
-    public final void setWaitCursor() {
-        setCursor( WAIT_CURSOR );
-        repaint();
-    }
-
-    final void setXcorrectionFactor( final float f ) {
-        _x_correction_factor = f;
-    }
-
-    final void setXdistance( final float x ) {
-        _x_distance = x;
-    }
-
-    final void setYdistance( final float y ) {
-        _y_distance = y;
+    private void showExtDescNodeData( final PhylogenyNode node ) {
+        final List<String> data = new ArrayList<String>();
+        final List<PhylogenyNode> nodes = node.getAllExternalDescendants();
+        if ( ( getFoundNodes0() != null ) || ( getFoundNodes1() != null ) ) {
+            for( final PhylogenyNode n : getFoundNodesAsListOfPhylogenyNodes() ) {
+                if ( !nodes.contains( n ) ) {
+                    nodes.add( n );
+                }
+            }
+        }
+        for( final PhylogenyNode n : nodes ) {
+            switch ( getOptions().getExtDescNodeDataToReturn() ) {
+                case NODE_NAME:
+                    if ( !ForesterUtil.isEmpty( n.getName() ) ) {
+                        data.add( n.getName() );
+                    }
+                    break;
+                case SEQUENCE_NAME:
+                    if ( n.getNodeData().isHasSequence()
+                            && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) {
+                        data.add( n.getNodeData().getSequence().getName() );
+                    }
+                    break;
+                case GENE_NAME:
+                    if ( n.getNodeData().isHasSequence()
+                            && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getGeneName() ) ) {
+                        data.add( n.getNodeData().getSequence().getGeneName() );
+                    }
+                    break;
+                case SEQUENCE_SYMBOL:
+                    if ( n.getNodeData().isHasSequence()
+                            && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getSymbol() ) ) {
+                        data.add( n.getNodeData().getSequence().getSymbol() );
+                    }
+                    break;
+                case SEQUENCE_MOL_SEQ:
+                    if ( n.getNodeData().isHasSequence()
+                            && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getMolecularSequence() ) ) {
+                        data.add( n.getNodeData().getSequence().getMolecularSequence() );
+                    }
+                    break;
+                case SEQUENCE_MOL_SEQ_FASTA:
+                    final StringBuilder sb = new StringBuilder();
+                    if ( n.getNodeData().isHasSequence()
+                            && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getMolecularSequence() ) ) {
+                        final StringBuilder ann = new StringBuilder();
+                        if ( !ForesterUtil.isEmpty( n.getName() ) ) {
+                            ann.append( n.getName() );
+                            ann.append( "|" );
+                        }
+                        if ( !ForesterUtil.isEmpty( n.getNodeData().getSequence().getSymbol() ) ) {
+                            ann.append( "SYM=" );
+                            ann.append( n.getNodeData().getSequence().getSymbol() );
+                            ann.append( "|" );
+                        }
+                        if ( !ForesterUtil.isEmpty( n.getNodeData().getSequence().getName() ) ) {
+                            ann.append( "NAME=" );
+                            ann.append( n.getNodeData().getSequence().getName() );
+                            ann.append( "|" );
+                        }
+                        if ( !ForesterUtil.isEmpty( n.getNodeData().getSequence().getGeneName() ) ) {
+                            ann.append( "GN=" );
+                            ann.append( n.getNodeData().getSequence().getGeneName() );
+                            ann.append( "|" );
+                        }
+                        if ( n.getNodeData().getSequence().getAccession() != null ) {
+                            ann.append( "ACC=" );
+                            ann.append( n.getNodeData().getSequence().getAccession().asText() );
+                            ann.append( "|" );
+                        }
+                        if ( n.getNodeData().isHasTaxonomy() ) {
+                            if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
+                                ann.append( "TAXID=" );
+                                ann.append( n.getNodeData().getTaxonomy().getTaxonomyCode() );
+                                ann.append( "|" );
+                            }
+                            if ( !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) {
+                                ann.append( "SN=" );
+                                ann.append( n.getNodeData().getTaxonomy().getScientificName() );
+                                ann.append( "|" );
+                            }
+                        }
+                        String ann_str;
+                        if ( ann.charAt( ann.length() - 1 ) == '|' ) {
+                            ann_str = ann.substring( 0, ann.length() - 1 );
+                        }
+                        else {
+                            ann_str = ann.toString();
+                        }
+                        sb.append( SequenceWriter.toFasta( ann_str, n.getNodeData().getSequence()
+                                .getMolecularSequence(), 60 ) );
+                        data.add( sb.toString() );
+                    }
+                    break;
+                case SEQUENCE_ACC:
+                    if ( n.getNodeData().isHasSequence() && ( n.getNodeData().getSequence().getAccession() != null )
+                            && !ForesterUtil.isEmpty( n.getNodeData().getSequence().getAccession().toString() ) ) {
+                        data.add( n.getNodeData().getSequence().getAccession().toString() );
+                    }
+                    break;
+                case TAXONOMY_SCIENTIFIC_NAME:
+                    if ( n.getNodeData().isHasTaxonomy()
+                            && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getScientificName() ) ) {
+                        data.add( n.getNodeData().getTaxonomy().getScientificName() );
+                    }
+                    break;
+                case TAXONOMY_COMM0N_NAME:
+                    if ( n.getNodeData().isHasTaxonomy()
+                            && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getCommonName() ) ) {
+                        data.add( n.getNodeData().getTaxonomy().getCommonName() );
+                    }
+                    break;
+                case TAXONOMY_CODE:
+                    if ( n.getNodeData().isHasTaxonomy()
+                            && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
+                        data.add( n.getNodeData().getTaxonomy().getTaxonomyCode() );
+                    }
+                    break;
+                case UNKNOWN:
+                    TreePanelUtil.showExtDescNodeDataUserSelectedHelper( getControlPanel(), n, data );
+                    break;
+                default:
+                    throw new IllegalArgumentException( "unknown data element: "
+                            + getOptions().getExtDescNodeDataToReturn() );
+            }
+        } // for loop
+        final StringBuilder sb = new StringBuilder();
+        final int size = TreePanelUtil.makeSB( data, getOptions(), sb );
+        if ( ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE )
+                || ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.BUFFER_ONLY ) ) {
+            if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE ) {
+                System.out.println( sb );
+            }
+            if ( sb.length() < 1 ) {
+                clearCurrentExternalNodesDataBuffer();
+            }
+            else {
+                setCurrentExternalNodesDataBuffer( sb );
+            }
+        }
+        else if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.WINODW ) {
+            if ( sb.length() < 1 ) {
+                TreePanelUtil.showInformationMessage( this, "No Appropriate Data (" + obtainTitleForExtDescNodeData()
+                        + ")", "Descendants of selected node do not contain selected data" );
+                clearCurrentExternalNodesDataBuffer();
+            }
+            else {
+                setCurrentExternalNodesDataBuffer( sb );
+                String title;
+                if ( ( getFoundNodes0() != null ) && !getFoundNodes0().isEmpty() ) {
+                    title = ( getOptions().getExtDescNodeDataToReturn() == NODE_DATA.UNKNOWN ? "Data"
+                            : obtainTitleForExtDescNodeData() )
+                            + " for "
+                            + data.size()
+                            + " nodes, unique entries: "
+                            + size;
+                }
+                else {
+                    title = ( getOptions().getExtDescNodeDataToReturn() == NODE_DATA.UNKNOWN ? "Data"
+                            : obtainTitleForExtDescNodeData() )
+                            + " for "
+                            + data.size()
+                            + "/"
+                            + node.getNumberOfExternalNodes()
+                            + " external descendats of node "
+                            + node
+                            + ", unique entries: " + size;
+                }
+                final String s = sb.toString().trim();
+                if ( getMainPanel().getMainFrame() == null ) {
+                    // Must be "E" applet version.
+                    final ArchaeopteryxE ae = ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet();
+                    ae.showTextFrame( s, title );
+                }
+                else {
+                    getMainPanel().getMainFrame().showTextFrame( s, title );
+                }
+            }
+        }
     }
 
     final private void showNodeDataPopup( final MouseEvent e, final PhylogenyNode node ) {
         try {
             if ( ( node.getName().length() > 0 )
     }
 
     final private void showNodeDataPopup( final MouseEvent e, final PhylogenyNode node ) {
         try {
             if ( ( node.getName().length() > 0 )
-                    || ( node.getNodeData().isHasTaxonomy() && !isTaxonomyEmpty( node.getNodeData().getTaxonomy() ) )
-                    || ( node.getNodeData().isHasSequence() && !isSequenceEmpty( node.getNodeData().getSequence() ) )
-                    || ( node.getNodeData().isHasDate() ) || ( node.getNodeData().isHasDistribution() )
-                    || node.getBranchData().isHasConfidences() ) {
+                    || ( node.getNodeData().isHasTaxonomy() && !TreePanelUtil.isTaxonomyEmpty( node.getNodeData()
+                            .getTaxonomy() ) )
+                    || ( node.getNodeData().isHasSequence() && !TreePanelUtil.isSequenceEmpty( node.getNodeData()
+                            .getSequence() ) ) || ( node.getNodeData().isHasDate() )
+                    || ( node.getNodeData().isHasDistribution() ) || node.getBranchData().isHasConfidences() ) {
                 _popup_buffer.setLength( 0 );
                 short lines = 0;
                 if ( node.getName().length() > 0 ) {
                     lines++;
                     _popup_buffer.append( node.getName() );
                 }
                 _popup_buffer.setLength( 0 );
                 short lines = 0;
                 if ( node.getName().length() > 0 ) {
                     lines++;
                     _popup_buffer.append( node.getName() );
                 }
-                if ( node.getNodeData().isHasTaxonomy() && !isTaxonomyEmpty( node.getNodeData().getTaxonomy() ) ) {
+                if ( node.getNodeData().isHasTaxonomy()
+                        && !TreePanelUtil.isTaxonomyEmpty( node.getNodeData().getTaxonomy() ) ) {
                     lines++;
                     boolean enc_data = false;
                     final Taxonomy tax = node.getNodeData().getTaxonomy();
                     lines++;
                     boolean enc_data = false;
                     final Taxonomy tax = node.getNodeData().getTaxonomy();
@@ -4731,7 +5577,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                         }
                     }
                 }
                         }
                     }
                 }
-                if ( node.getNodeData().isHasSequence() && !isSequenceEmpty( node.getNodeData().getSequence() ) ) {
+                if ( node.getNodeData().isHasSequence()
+                        && !TreePanelUtil.isSequenceEmpty( node.getNodeData().getSequence() ) ) {
                     lines++;
                     boolean enc_data = false;
                     if ( _popup_buffer.length() > 0 ) {
                     lines++;
                     boolean enc_data = false;
                     if ( _popup_buffer.length() > 0 ) {
@@ -4759,6 +5606,17 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                         _popup_buffer.append( "]" );
                         enc_data = true;
                     }
                         _popup_buffer.append( "]" );
                         enc_data = true;
                     }
+                    if ( !ForesterUtil.isEmpty( seq.getGeneName() ) ) {
+                        if ( enc_data ) {
+                            _popup_buffer.append( " [" );
+                        }
+                        else {
+                            _popup_buffer.append( "[" );
+                        }
+                        _popup_buffer.append( seq.getGeneName() );
+                        _popup_buffer.append( "]" );
+                        enc_data = true;
+                    }
                     if ( !ForesterUtil.isEmpty( seq.getName() ) ) {
                         if ( enc_data ) {
                             _popup_buffer.append( " " );
                     if ( !ForesterUtil.isEmpty( seq.getName() ) ) {
                         if ( enc_data ) {
                             _popup_buffer.append( " " );
@@ -4810,11 +5668,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                     for( final String ref : properties.getPropertyRefs() ) {
                         _popup_buffer.append( "\n" );
                         final Property p = properties.getProperty( ref );
                     for( final String ref : properties.getPropertyRefs() ) {
                         _popup_buffer.append( "\n" );
                         final Property p = properties.getProperty( ref );
-                        _popup_buffer.append( getPartAfterColon( p.getRef() ) );
+                        _popup_buffer.append( TreePanelUtil.getPartAfterColon( p.getRef() ) );
                         _popup_buffer.append( "=" );
                         _popup_buffer.append( p.getValue() );
                         if ( !ForesterUtil.isEmpty( p.getUnit() ) ) {
                         _popup_buffer.append( "=" );
                         _popup_buffer.append( p.getValue() );
                         if ( !ForesterUtil.isEmpty( p.getUnit() ) ) {
-                            _popup_buffer.append( getPartAfterColon( p.getUnit() ) );
+                            _popup_buffer.append( TreePanelUtil.getPartAfterColon( p.getUnit() ) );
                         }
                     }
                 }
                         }
                     }
                 }
@@ -4823,8 +5681,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                         _rollover_popup
                                 .setBorder( BorderFactory.createLineBorder( getTreeColorSet().getBranchColor() ) );
                         _rollover_popup.setBackground( getTreeColorSet().getBackgroundColor() );
                         _rollover_popup
                                 .setBorder( BorderFactory.createLineBorder( getTreeColorSet().getBranchColor() ) );
                         _rollover_popup.setBackground( getTreeColorSet().getBackgroundColor() );
-                        if ( isInFoundNodes( node ) ) {
-                            _rollover_popup.setForeground( getTreeColorSet().getFoundColor() );
+                        if ( isInFoundNodes0( node ) && !isInFoundNodes1( node ) ) {
+                            _rollover_popup.setForeground( getTreeColorSet().getFoundColor0() );
+                        }
+                        else if ( !isInFoundNodes0( node ) && isInFoundNodes1( node ) ) {
+                            _rollover_popup.setForeground( getTreeColorSet().getFoundColor1() );
+                        }
+                        else if ( isInFoundNodes0( node ) && isInFoundNodes1( node ) ) {
+                            _rollover_popup.setForeground( getTreeColorSet().getFoundColor0and1() );
                         }
                         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
                             _rollover_popup.setForeground( getTaxonomyBasedColor( node ) );
                         }
                         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
                             _rollover_popup.setForeground( getTaxonomyBasedColor( node ) );
@@ -4873,123 +5737,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    final void subTree( final PhylogenyNode node ) {
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot get a sub/super tree in unrooted display",
-                                           "Attempt to get sub/super tree in unrooted display",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
-        }
-        if ( node.isExternal() ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot get a subtree of a external node",
-                                           "Attempt to get subtree of external node",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
-        }
-        if ( node.isRoot() && !isCurrentTreeIsSubtree() ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot get a subtree of the root node",
-                                           "Attempt to get subtree of root node",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
-        }
-        setNodeInPreorderToNull();
-        if ( !node.isExternal() && !node.isRoot() && ( _subtree_index <= ( TreePanel.MAX_SUBTREES - 1 ) ) ) {
-            _sub_phylogenies[ _subtree_index ] = _phylogeny;
-            _sub_phylogenies_temp_roots[ _subtree_index ] = node;
-            ++_subtree_index;
-            _phylogeny = subTree( node, _phylogeny );
-            updateSubSuperTreeButton();
-        }
-        else if ( node.isRoot() && isCurrentTreeIsSubtree() ) {
-            superTree();
-        }
-        _main_panel.getControlPanel().showWhole();
-        repaint();
-    }
-
-    final boolean isCurrentTreeIsSubtree() {
-        return ( _subtree_index > 0 );
-    }
-
-    final private static Phylogeny subTree( final PhylogenyNode new_root, final Phylogeny source_phy ) {
-        final Phylogeny new_phy = new Phylogeny();
-        new_phy.setRooted( true );
-        new_phy.setName( source_phy.getName() );
-        new_phy.setDescription( source_phy.getDescription() );
-        new_phy.setType( source_phy.getType() );
-        new_phy.setDistanceUnit( source_phy.getDistanceUnit() );
-        new_phy.setConfidence( source_phy.getConfidence() );
-        new_phy.setIdentifier( source_phy.getIdentifier() );
-        new_phy.setRoot( new_root.copyNodeDataShallow() );
-        int i = 0;
-        for( final PhylogenyNode n : new_root.getDescendants() ) {
-            new_phy.getRoot().setChildNode( i++, n );
-        }
-        return new_phy;
-    }
-
-    final void superTree() {
-        setNodeInPreorderToNull();
-        final PhylogenyNode temp_root = _sub_phylogenies_temp_roots[ _subtree_index - 1 ];
-        for( final PhylogenyNode n : temp_root.getDescendants() ) {
-            n.setParent( temp_root );
-        }
-        _sub_phylogenies[ _subtree_index ] = null;
-        _sub_phylogenies_temp_roots[ _subtree_index ] = null;
-        _phylogeny = _sub_phylogenies[ --_subtree_index ];
-        updateSubSuperTreeButton();
-    }
-
-    final void swap( final PhylogenyNode node ) {
-        if ( node.isExternal() || ( node.getNumberOfDescendants() < 2 ) ) {
-            return;
-        }
-        if ( node.getNumberOfDescendants() > 2 ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot swap descendants of nodes with more than 2 descendants",
-                                           "Cannot swap descendants",
-                                           JOptionPane.ERROR_MESSAGE );
-            return;
-        }
-        if ( !node.isExternal() ) {
-            node.swapChildren();
-            setNodeInPreorderToNull();
-            _phylogeny.externalNodesHaveChanged();
-            _phylogeny.hashIDs();
-            _phylogeny.recalculateNumberOfExternalDescendants( true );
-            resetNodeIdToDistToLeafMap();
-            setEdited( true );
-        }
-        repaint();
-    }
-
-    final void sortDescendants( final PhylogenyNode node ) {
-        if ( !node.isExternal() ) {
-            DESCENDANT_SORT_PRIORITY pri = DESCENDANT_SORT_PRIORITY.TAXONOMY;
-            if ( ( !getControlPanel().isShowTaxonomyScientificNames() && !getControlPanel().isShowTaxonomyCode() && !getControlPanel()
-                    .isShowTaxonomyCommonNames() ) ) {
-                if ( ( getControlPanel().isShowSequenceAcc() || getControlPanel().isShowGeneNames() || getControlPanel()
-                        .isShowGeneSymbols() ) ) {
-                    pri = DESCENDANT_SORT_PRIORITY.SEQUENCE;
-                }
-                else if ( getControlPanel().isShowNodeNames() ) {
-                    pri = DESCENDANT_SORT_PRIORITY.NODE_NAME;
-                }
-            }
-            PhylogenyMethods.sortNodeDescendents( node, pri );
-            setNodeInPreorderToNull();
-            _phylogeny.externalNodesHaveChanged();
-            _phylogeny.hashIDs();
-            _phylogeny.recalculateNumberOfExternalDescendants( true );
-            resetNodeIdToDistToLeafMap();
-            setEdited( true );
-        }
-        repaint();
-    }
-
     final private void switchDisplaygetPhylogenyGraphicsType() {
         switch ( getPhylogenyGraphicsType() ) {
             case RECTANGULAR:
     final private void switchDisplaygetPhylogenyGraphicsType() {
         switch ( getPhylogenyGraphicsType() ) {
             case RECTANGULAR:
@@ -5051,159 +5798,68 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    final void taxColor() {
-        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
-            return;
-        }
-        setWaitCursor();
-        AptxUtil.colorPhylogenyAccordingToExternalTaxonomy( _phylogeny, this );
-        _control_panel.setColorBranches( true );
-        if ( _control_panel.getColorBranchesCb() != null ) {
-            _control_panel.getColorBranchesCb().setSelected( true );
-        }
-        setArrowCursor();
-        repaint();
-    }
-
-    final void updateOvSettings() {
-        switch ( getOptions().getOvPlacement() ) {
-            case LOWER_LEFT:
-                setOvXPosition( OV_BORDER );
-                setOvYPosition( ForesterUtil.roundToInt( getVisibleRect().height - OV_BORDER - getOvMaxHeight() ) );
-                setOvYStart( ForesterUtil.roundToInt( getOvYPosition() + ( getOvMaxHeight() / 2 ) ) );
-                break;
-            case LOWER_RIGHT:
-                setOvXPosition( ForesterUtil.roundToInt( getVisibleRect().width - OV_BORDER - getOvMaxWidth() ) );
-                setOvYPosition( ForesterUtil.roundToInt( getVisibleRect().height - OV_BORDER - getOvMaxHeight() ) );
-                setOvYStart( ForesterUtil.roundToInt( getOvYPosition() + ( getOvMaxHeight() / 2 ) ) );
-                break;
-            case UPPER_RIGHT:
-                setOvXPosition( ForesterUtil.roundToInt( getVisibleRect().width - OV_BORDER - getOvMaxWidth() ) );
-                setOvYPosition( OV_BORDER );
-                setOvYStart( ForesterUtil.roundToInt( OV_BORDER + ( getOvMaxHeight() / 2 ) ) );
-                break;
-            default:
-                setOvXPosition( OV_BORDER );
-                setOvYPosition( OV_BORDER );
-                setOvYStart( ForesterUtil.roundToInt( OV_BORDER + ( getOvMaxHeight() / 2 ) ) );
-                break;
-        }
-    }
-
-    final void updateOvSizes() {
-        if ( ( getWidth() > 1.05 * getVisibleRect().width ) || ( getHeight() > 1.05 * getVisibleRect().height ) ) {
-            setOvOn( true );
-            float l = getLongestExtNodeInfo();
-            final float w_ratio = getOvMaxWidth() / getWidth();
-            l *= w_ratio;
-            final int ext_nodes = _phylogeny.getRoot().getNumberOfExternalNodes();
-            setOvYDistance( getOvMaxHeight() / ( 2 * ext_nodes ) );
-            float ov_xdist = 0;
-            if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) {
-                ov_xdist = ( ( getOvMaxWidth() - l ) / ( ext_nodes ) );
-            }
-            else {
-                ov_xdist = ( ( getOvMaxWidth() - l ) / ( PhylogenyMethods.calculateMaxDepth( _phylogeny ) ) );
-            }
-            float ydist = ( float ) ( ( getOvMaxWidth() / ( ext_nodes * 2.0 ) ) );
-            if ( ov_xdist < 0.0 ) {
-                ov_xdist = 0.0f;
-            }
-            if ( ydist < 0.0 ) {
-                ydist = 0.0f;
-            }
-            setOvXDistance( ov_xdist );
-            final double height = _phylogeny.getHeight();
-            if ( height > 0 ) {
-                final float ov_corr = ( float ) ( ( ( getOvMaxWidth() - l ) - getOvXDistance() ) / height );
-                setOvXcorrectionFactor( ov_corr > 0 ? ov_corr : 0 );
-            }
-            else {
-                setOvXcorrectionFactor( 0 );
-            }
-        }
-        else {
-            setOvOn( false );
-        }
-    }
-
-    final void updateSubSuperTreeButton() {
-        if ( _subtree_index < 1 ) {
-            getControlPanel().deactivateButtonToReturnToSuperTree();
-        }
-        else {
-            getControlPanel().activateButtonToReturnToSuperTree( _subtree_index );
-        }
-    }
-
-    final void zoomInDomainStructure() {
-        if ( _domain_structure_width < 2000 ) {
-            _domain_structure_width *= 1.2;
-        }
-    }
-
-    final void zoomOutDomainStructure() {
-        if ( _domain_structure_width > 20 ) {
-            _domain_structure_width *= 0.8;
-        }
-    }
-
-    final private static void drawString( final int i, final double x, final double y, final Graphics2D g ) {
-        g.drawString( String.valueOf( i ), ( int ) ( x + 0.5 ), ( int ) ( y + 0.5 ) );
-    }
-
     final private static void drawString( final String str, final double x, final double y, final Graphics2D g ) {
         g.drawString( str, ( int ) ( x + 0.5 ), ( int ) ( y + 0.5 ) );
     }
 
     final private static void drawString( final String str, final double x, final double y, final Graphics2D g ) {
         g.drawString( str, ( int ) ( x + 0.5 ), ( int ) ( y + 0.5 ) );
     }
 
-    final private static boolean isSequenceEmpty( final Sequence seq ) {
-        return ( seq.getAccession() == null ) && ForesterUtil.isEmpty( seq.getName() )
-                && ForesterUtil.isEmpty( seq.getSymbol() );
-    }
-
-    final private static boolean isTaxonomyEmpty( final Taxonomy tax ) {
-        return ( ( tax.getIdentifier() == null ) && ForesterUtil.isEmpty( tax.getTaxonomyCode() )
-                && ForesterUtil.isEmpty( tax.getCommonName() ) && ForesterUtil.isEmpty( tax.getScientificName() ) && tax
-                .getSynonyms().isEmpty() );
-    }
-
     final private static boolean plusPressed( final int key_code ) {
         return ( ( key_code == KeyEvent.VK_ADD ) || ( key_code == KeyEvent.VK_PLUS )
                 || ( key_code == KeyEvent.VK_EQUALS ) || ( key_code == KeyEvent.VK_SEMICOLON ) || ( key_code == KeyEvent.VK_1 ) );
     }
 
     final private static boolean plusPressed( final int key_code ) {
         return ( ( key_code == KeyEvent.VK_ADD ) || ( key_code == KeyEvent.VK_PLUS )
                 || ( key_code == KeyEvent.VK_EQUALS ) || ( key_code == KeyEvent.VK_SEMICOLON ) || ( key_code == KeyEvent.VK_1 ) );
     }
 
-    void setStatisticsForExpressionValues( final DescriptiveStatistics statistics_for_expression_values ) {
-        _statistics_for_vector_data = statistics_for_expression_values;
-    }
-
-    DescriptiveStatistics getStatisticsForExpressionValues() {
-        return _statistics_for_vector_data;
-    }
-
     final private class SubtreeColorizationActionListener implements ActionListener {
 
     final private class SubtreeColorizationActionListener implements ActionListener {
 
-        JColorChooser _chooser;
-        PhylogenyNode _node;
+        List<PhylogenyNode> _additional_nodes = null;
+        JColorChooser       _chooser          = null;
+        PhylogenyNode       _node             = null;
 
         SubtreeColorizationActionListener( final JColorChooser chooser, final PhylogenyNode node ) {
             _chooser = chooser;
             _node = node;
         }
 
 
         SubtreeColorizationActionListener( final JColorChooser chooser, final PhylogenyNode node ) {
             _chooser = chooser;
             _node = node;
         }
 
+        SubtreeColorizationActionListener( final JColorChooser chooser,
+                                           final PhylogenyNode node,
+                                           final List<PhylogenyNode> additional_nodes ) {
+            _chooser = chooser;
+            _node = node;
+            _additional_nodes = additional_nodes;
+        }
+
         @Override
         public void actionPerformed( final ActionEvent e ) {
             final Color c = _chooser.getColor();
             if ( c != null ) {
         @Override
         public void actionPerformed( final ActionEvent e ) {
             final Color c = _chooser.getColor();
             if ( c != null ) {
-                colorizeSubtree( c, _node );
+                colorizeSubtree( c, _node, _additional_nodes );
             }
         }
     }
 
             }
         }
     }
 
-    public synchronized void setImageMap( final Hashtable<String, BufferedImage> image_map ) {
-        getMainPanel().setImageMap( image_map );
-    }
+    final private class NodeColorizationActionListener implements ActionListener {
 
 
-    public synchronized Hashtable<String, BufferedImage> getImageMap() {
-        return getMainPanel().getImageMap();
+        List<PhylogenyNode> _additional_nodes = null;
+        JColorChooser       _chooser          = null;
+        PhylogenyNode       _node             = null;
+
+        NodeColorizationActionListener( final JColorChooser chooser, final PhylogenyNode node ) {
+            _chooser = chooser;
+            _node = node;
+        }
+
+        NodeColorizationActionListener( final JColorChooser chooser,
+                                        final PhylogenyNode node,
+                                        final List<PhylogenyNode> additional_nodes ) {
+            _chooser = chooser;
+            _node = node;
+            _additional_nodes = additional_nodes;
+        }
+
+        @Override
+        public void actionPerformed( final ActionEvent e ) {
+            final Color c = _chooser.getColor();
+            if ( c != null ) {
+                colorizeNodes( c, _node, _additional_nodes );
+            }
+        }
     }
 }
     }
 }