in progress
[jalview.git] / forester / java / src / org / forester / archaeopteryx / TreePanel.java
index c55449b..907a20f 100644 (file)
@@ -76,6 +76,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,21 +90,29 @@ 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.Options.PHYLOGENY_GRAPHICS_TYPE;
 import org.forester.archaeopteryx.phylogeny.data.RenderableDomainArchitecture;
 import org.forester.archaeopteryx.phylogeny.data.RenderableVector;
 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.Options.PHYLOGENY_GRAPHICS_TYPE;
 import org.forester.archaeopteryx.phylogeny.data.RenderableDomainArchitecture;
 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.phylogeny.Phylogeny;
 import org.forester.phylogeny.PhylogenyMethods;
 import org.forester.io.parsers.phyloxml.PhyloXmlUtil;
 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.Annotation;
 import org.forester.phylogeny.data.BranchColor;
 import org.forester.phylogeny.data.Confidence;
 import org.forester.phylogeny.data.Event;
 import org.forester.phylogeny.PhylogenyNode;
 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.PhylogenyData;
+import org.forester.phylogeny.data.NodeData.NODE_DATA;
+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.PhylogenyDataUtil;
 import org.forester.phylogeny.data.PropertiesMap;
 import org.forester.phylogeny.data.Property;
 import org.forester.phylogeny.data.Sequence;
 import org.forester.phylogeny.data.PropertiesMap;
 import org.forester.phylogeny.data.Property;
 import org.forester.phylogeny.data.Sequence;
@@ -116,6 +125,7 @@ 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.SequenceIdParser;
 
 public final class TreePanel extends JPanel implements ActionListener, MouseWheelListener, Printable {
 
 
 public final class TreePanel extends JPanel implements ActionListener, MouseWheelListener, Printable {
 
@@ -134,15 +144,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     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                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                BOX_SIZE                          = 4;
-    private final static int                HALF_BOX_SIZE                     = TreePanel.BOX_SIZE / 2;
     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                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                HALF_BOX_SIZE_PLUS_WIGGLE         = HALF_BOX_SIZE + WIGGLE;
     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
     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
@@ -204,11 +211,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     final private static double             _180_OVER_PI                      = 180.0 / Math.PI;
     private static final float              ROUNDED_D                         = 8;
     private int                             _circ_max_depth;
     final private static double             _180_OVER_PI                      = 180.0 / Math.PI;
     private static final float              ROUNDED_D                         = 8;
     private int                             _circ_max_depth;
-    private int                             _circ_num_ext_nodes;
     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>();
     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;
     HashMap<Integer, Short>                 _nodeid_dist_to_leaf              = new HashMap<Integer, Short>();
     private AffineTransform                 _at;
     private double                          _max_distance_to_root             = -1;
@@ -216,12 +223,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     private boolean                         _edited                           = false;
     private Popup                           _node_desc_popup;
     private JTextArea                       _rollover_popup;
     private boolean                         _edited                           = false;
     private Popup                           _node_desc_popup;
     private JTextArea                       _rollover_popup;
-    //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 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,
     private Sequence                        _query_sequence                   = null;
     private final FontRenderContext         _frc                              = new FontRenderContext( null,
                                                                                                        false,
@@ -263,7 +268,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         _main_panel = tjp;
         _configuration = configuration;
         _phylogeny = t;
         _main_panel = tjp;
         _configuration = configuration;
         _phylogeny = t;
-        _phy_has_branch_lengths = ForesterUtil.isHasAtLeastOneBranchLengthLargerThanZero( _phylogeny );
+        _phy_has_branch_lengths = AptxUtil.isHasAtLeastOneBranchLengthLargerThanZero( _phylogeny );
         init();
         // if ( !_phylogeny.isEmpty() ) {
         _phylogeny.recalculateNumberOfExternalDescendants( true );
         init();
         // if ( !_phylogeny.isEmpty() ) {
         _phylogeny.recalculateNumberOfExternalDescendants( true );
@@ -280,6 +285,26 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 .getNumberOfDigitsAfterCommaForBranchLengthValues() );
     }
 
                 .getNumberOfDigitsAfterCommaForBranchLengthValues() );
     }
 
+    @Override
+    final public void actionPerformed( final ActionEvent e ) {
+        boolean done = false;
+        final JMenuItem node_popup_menu_item = ( JMenuItem ) e.getSource();
+        for( int index = 0; ( index < _node_popup_menu_items.length ) && !done; index++ ) {
+            // NOTE: index corresponds to the indices of click-to options
+            // in the control panel.
+            if ( node_popup_menu_item == _node_popup_menu_items[ index ] ) {
+                // Set this as the new default click-to action
+                _main_panel.getControlPanel().setClickToAction( index );
+                final PhylogenyNode node = ( PhylogenyNode ) _node_popup_menu
+                        .getClientProperty( NODE_POPMENU_NODE_CLIENT_PROPERTY );
+                handleClickToAction( _control_panel.getActionWhenNodeClicked(), node );
+                done = true;
+            }
+        }
+        repaint();
+        requestFocusInWindow();
+    }
+
     public void checkForVectorProperties( final Phylogeny phy ) {
         final DescriptiveStatistics stats = new BasicDescriptiveStatistics();
         for( final PhylogenyNodeIterator iter = phy.iteratorPreorder(); iter.hasNext(); ) {
     public void checkForVectorProperties( final Phylogeny phy ) {
         final DescriptiveStatistics stats = new BasicDescriptiveStatistics();
         for( final PhylogenyNodeIterator iter = phy.iteratorPreorder(); iter.hasNext(); ) {
@@ -339,194 +364,250 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    final public void actionPerformed( final ActionEvent e ) {
-        int index;
-        boolean done = false;
-        final JMenuItem node_popup_menu_item = ( JMenuItem ) e.getSource();
-        for( index = 0; ( index < _node_popup_menu_items.length ) && !done; index++ ) {
-            // NOTE: index corresponds to the indices of click-to options
-            // in the control panel.
-            if ( node_popup_menu_item == _node_popup_menu_items[ index ] ) {
-                // Set this as the new default click-to action
-                _main_panel.getControlPanel().setClickToAction( index );
-                final PhylogenyNode node = ( PhylogenyNode ) _node_popup_menu
-                        .getClientProperty( NODE_POPMENU_NODE_CLIENT_PROPERTY );
-                handleClickToAction( _control_panel.getActionWhenNodeClicked(), node );
-                done = true;
-            }
-        }
-        repaint();
-        requestFocusInWindow();
+    public synchronized Hashtable<String, BufferedImage> getImageMap() {
+        return getMainPanel().getImageMap();
     }
 
     }
 
-    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?";
+    final public MainPanel getMainPanel() {
+        return _main_panel;
+    }
+
+    /**
+     * Get a pointer to the phylogeny 
+     * 
+     * @return a pointer to the phylogeny
+     */
+    public final Phylogeny getPhylogeny() {
+        return _phylogeny;
+    }
+
+    @Override
+    final public void mouseWheelMoved( final MouseWheelEvent e ) {
+        final int notches = e.getWheelRotation();
+        if ( inOvVirtualRectangle( e ) ) {
+            if ( !isInOvRect() ) {
+                setInOvRect( true );
+                repaint();
+            }
         }
         else {
         }
         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;
+            if ( isInOvRect() ) {
+                setInOvRect( false );
+                repaint();
+            }
         }
         }
-        else if ( r != 0 ) {
-            return;
+        if ( e.isControlDown() ) {
+            if ( notches < 0 ) {
+                getTreeFontSet().increaseFontSize();
+                getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            }
+            else {
+                getTreeFontSet().decreaseFontSize();
+                getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            }
         }
         }
-        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;
+        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 );
+                    }
+                }
+                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 );
+                    }
+                }
+            }
+            else {
+                if ( notches < 0 ) {
+                    for( int i = 0; i < ( -notches ); ++i ) {
+                        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().displayedPhylogenyMightHaveChanged( false );
+                    }
+                }
             }
             }
-            phy.addAsSibling( node );
         }
         else {
         }
         else {
-            phy.addAsChild( node );
+            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 );
+                }
+            }
         }
         }
-        _phylogeny.externalNodesHaveChanged();
-        _phylogeny.hashIDs();
-        _phylogeny.recalculateNumberOfExternalDescendants( true );
-        resetNodeIdToDistToLeafMap();
-        setEdited( true );
-        repaint();
+        requestFocus();
+        requestFocusInWindow();
+        requestFocus();
     }
 
     }
 
-    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() );
-        }
+    @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 );
     }
 
     }
 
-    final void assignGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node, final Graphics g ) {
-        if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
-            g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
+    @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 {
-            g.setColor( getTreeColorSet().getBranchColor() );
+            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 void blast( final PhylogenyNode node ) {
-        if ( !isCanBlast( node ) ) {
-            JOptionPane.showMessageDialog( this,
-                                           "No sequence information present",
-                                           "Cannot Blast",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
-        }
-        if ( node.getNodeData().isHasSequence() ) {
-            String name = "";
-            if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getName() ) ) {
-                name = node.getNodeData().getSequence().getName();
-            }
-            else if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getSymbol() ) ) {
-                name = node.getNodeData().getSequence().getSymbol();
-            }
-            else if ( node.getNodeData().getSequence().getAccession() != null ) {
-                name = node.getNodeData().getSequence().getAccession().getValue();
-            }
-            if ( !ForesterUtil.isEmpty( name ) ) {
-                try {
-                    System.out.println( "trying: " + name );
-                    final Blast s = new Blast();
-                    s.go( name );
-                }
-                catch ( final Exception e ) {
-                    e.printStackTrace();
-                }
-            }
-        }
+    public final void setArrowCursor() {
+        setCursor( ARROW_CURSOR );
+        repaint();
     }
 
     }
 
-    final void calcMaxDepth() {
-        if ( _phylogeny != null ) {
-            _circ_max_depth = PhylogenyMethods.calculateMaxDepth( _phylogeny );
-        }
+    public final void setEdited( final boolean edited ) {
+        _edited = edited;
+    }
+
+    public synchronized void setImageMap( final Hashtable<String, BufferedImage> image_map ) {
+        getMainPanel().setImageMap( image_map );
     }
 
     /**
     }
 
     /**
-     * Calculate the length of the distance between the given node and its
-     * parent.
+     * Set parameters for printing the displayed tree
      * 
      * 
-     * @param node
-     * @param ext_node_x
-     * @factor
-     * @return the distance value
+     * @param x
+     * @param y
      */
      */
-    final private float calculateBranchLengthToParent( final PhylogenyNode node, final float factor ) {
-        if ( getControlPanel().isDrawPhylogram() ) {
-            if ( node.getDistanceToParent() < 0.0 ) {
-                return 0.0f;
+    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();
             }
             }
-            return ( float ) ( getXcorrectionFactor() * node.getDistanceToParent() );
-        }
-        else {
-            if ( ( factor == 0 ) || isNonLinedUpCladogram() ) {
-                return getXdistance();
+            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;
+                }
             }
             }
-            return getXdistance() * factor;
+            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 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();
-            }
+    /**
+     * 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 );
         }
         }
-        return c;
     }
 
     final void calculateLongestExtNodeInfo() {
         if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
             return;
         }
     }
 
     final void calculateLongestExtNodeInfo() {
         if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
             return;
         }
-        int longest = 20;
+        int max_length = ForesterUtil.roundToInt( ( getSize().getWidth() - MOVE )
+                * Constants.EXT_NODE_INFO_LENGTH_MAX_RATIO );
+        if ( max_length < 40 ) {
+            max_length = 40;
+        }
+        int longest = 30;
         for( final PhylogenyNode node : _phylogeny.getExternalNodes() ) {
             int sum = 0;
             if ( node.isCollapse() ) {
         for( final PhylogenyNode node : _phylogeny.getExternalNodes() ) {
             int sum = 0;
             if ( node.isCollapse() ) {
@@ -556,6 +637,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                             .asSimpleText()
                             + " " );
                 }
                             .asSimpleText()
                             + " " );
                 }
+                if ( getControlPanel().isShowDomainArchitectures()
+                        && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
+                    sum += ( ( RenderableDomainArchitecture ) node.getNodeData().getSequence().getDomainArchitecture() )
+                            .getRenderingSize().getWidth();
+                }
             }
             if ( node.getNodeData().isHasTaxonomy() ) {
                 final Taxonomy tax = node.getNodeData().getTaxonomy();
             }
             if ( node.getNodeData().isHasTaxonomy() ) {
                 final Taxonomy tax = node.getNodeData().getTaxonomy();
@@ -570,46 +656,29 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                     sum += getTreeFontSet()._fm_large_italic.stringWidth( tax.getCommonName() + " ()" );
                 }
             }
                     sum += getTreeFontSet()._fm_large_italic.stringWidth( tax.getCommonName() + " ()" );
                 }
             }
+            if ( getControlPanel().isShowProperties() && node.getNodeData().isHasProperties() ) {
+                sum += getTreeFontSet()._fm_large.stringWidth( propertiesToString( node ).toString() );
+            }
             if ( getControlPanel().isShowBinaryCharacters() && node.getNodeData().isHasBinaryCharacters() ) {
                 sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getBinaryCharacters()
                         .getGainedCharactersAsStringBuffer().toString() );
             }
             if ( getControlPanel().isShowBinaryCharacters() && node.getNodeData().isHasBinaryCharacters() ) {
                 sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getBinaryCharacters()
                         .getGainedCharactersAsStringBuffer().toString() );
             }
-            if ( getControlPanel().isShowDomainArchitectures() && node.getNodeData().isHasSequence()
-                    && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
-                sum += ( ( RenderableDomainArchitecture ) node.getNodeData().getSequence().getDomainArchitecture() )
-                        .getRenderingSize().getWidth();
-            }
-            if ( sum >= Constants.EXT_NODE_INFO_LENGTH_MAX ) {
-                setLongestExtNodeInfo( Constants.EXT_NODE_INFO_LENGTH_MAX );
+            if ( sum >= max_length ) {
+                setLongestExtNodeInfo( max_length );
                 return;
             }
             if ( sum > longest ) {
                 longest = sum;
             }
         }
                 return;
             }
             if ( sum > longest ) {
                 longest = sum;
             }
         }
-        if ( longest >= Constants.EXT_NODE_INFO_LENGTH_MAX ) {
-            setLongestExtNodeInfo( Constants.EXT_NODE_INFO_LENGTH_MAX );
+        if ( longest >= max_length ) {
+            setLongestExtNodeInfo( max_length );
         }
         else {
             setLongestExtNodeInfo( longest );
         }
     }
 
         }
         else {
             setLongestExtNodeInfo( longest );
         }
     }
 
-    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;
@@ -656,19 +725,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         // Look in species hash
         Color c = getControlPanel().getSpeciesColors().get( species );
         if ( c == null ) {
         // Look in species hash
         Color c = getControlPanel().getSpeciesColors().get( species );
         if ( c == null ) {
-            c = Util.calculateColorFromString( species );
+            c = AptxUtil.calculateColorFromString( species );
             getControlPanel().getSpeciesColors().put( species, c );
         }
         return c;
     }
 
             getControlPanel().getSpeciesColors().put( species, 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 );
-    }
-
     /**
      * Collapse the tree from the given node
      * 
     /**
      * Collapse the tree from the given node
      * 
@@ -685,10 +747,13 @@ 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();
-            Util.collapseSubtree( node, collapse );
+            AptxUtil.collapseSubtree( node, collapse );
+            updateSetOfCollapsedExternalNodes();
             _phylogeny.recalculateNumberOfExternalDescendants( true );
             resetNodeIdToDistToLeafMap();
             calculateLongestExtNodeInfo();
             _phylogeny.recalculateNumberOfExternalDescendants( true );
             resetNodeIdToDistToLeafMap();
             calculateLongestExtNodeInfo();
+            setNodeInPreorderToNull();
+            _control_panel.displayedPhylogenyMightHaveChanged( true );
             resetPreferredSize();
             updateOvSizes();
             _main_panel.adjustJScrollPane();
             resetPreferredSize();
             updateOvSizes();
             _main_panel.adjustJScrollPane();
@@ -701,53 +766,61 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             return;
         }
         setWaitCursor();
             return;
         }
         setWaitCursor();
-        Util.collapseSpeciesSpecificSubtrees( _phylogeny );
+        AptxUtil.collapseSpeciesSpecificSubtrees( _phylogeny );
+        updateSetOfCollapsedExternalNodes();
         _phylogeny.recalculateNumberOfExternalDescendants( true );
         resetNodeIdToDistToLeafMap();
         calculateLongestExtNodeInfo();
         _phylogeny.recalculateNumberOfExternalDescendants( true );
         resetNodeIdToDistToLeafMap();
         calculateLongestExtNodeInfo();
+        setNodeInPreorderToNull();
         resetPreferredSize();
         _main_panel.adjustJScrollPane();
         setArrowCursor();
         repaint();
     }
 
         resetPreferredSize();
         _main_panel.adjustJScrollPane();
         setArrowCursor();
         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 = 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();
         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 );
+        if ( colorizations > 0 ) {
+            String msg = "Taxonomy colorization via " + rank + " completed:\n";
+            if ( colorizations > 1 ) {
+                msg += "colorized " + colorizations + " subtrees";
+            }
+            else {
+                msg += "colorized one subtree";
+            }
+            JOptionPane.showMessageDialog( this,
+                                           msg,
+                                           "Taxonomy Colorization Completed (" + rank + ")",
+                                           JOptionPane.INFORMATION_MESSAGE );
         }
         else {
         }
         else {
-            intitial_color = getTreeColorSet().getBranchColor();
+            String msg = "Could not taxonomy colorize any subtree via " + rank + ".\n";
+            msg += "Possible solutions (given that suitable taxonomic information is present):\n";
+            msg += "select a different rank (e.g. phylum, genus, ...)\n";
+            msg += "  and/or\n";
+            msg += "execute:\n";
+            msg += "1. \"" + MainFrameApplication.OBTAIN_DETAILED_TAXONOMIC_INFORMATION + "\" (Tools)\n";
+            msg += "2. \"" + MainFrameApplication.INFER_ANCESTOR_TAXONOMIES + "\" (Analysis)";
+            JOptionPane.showMessageDialog( this, msg, "Taxonomy Colorization Failed", JOptionPane.WARNING_MESSAGE );
         }
         }
-        _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() {
     }
 
     final void confColor() {
@@ -755,7 +828,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             return;
         }
         setWaitCursor();
             return;
         }
         setWaitCursor();
-        Util.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this );
+        AptxUtil.removeBranchColors( _phylogeny );
+        AptxUtil.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this );
         _control_panel.setColorBranches( true );
         if ( _control_panel.getColorBranchesCb() != null ) {
             _control_panel.getColorBranchesCb().setSelected( true );
         _control_panel.setColorBranches( true );
         if ( _control_panel.getColorBranchesCb() != null ) {
             _control_panel.getColorBranchesCb().setSelected( true );
@@ -764,1228 +838,2296 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         repaint();
     }
 
         repaint();
     }
 
-    final private void copySubtree( final PhylogenyNode node ) {
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            errorMessageNoCutCopyPasteInUnrootedDisplay();
-            return;
-        }
-        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() );
+    final void decreaseDomainStructureEvalueThreshold() {
+        if ( _domain_structure_e_value_thr_exp > -20 ) {
+            _domain_structure_e_value_thr_exp -= 1;
         }
         }
-        node_ids.add( node.getId() );
-        setCopiedAndPastedNodes( node_ids );
-        repaint();
     }
 
     }
 
-    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;
+    /**
+     * 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;
+            }
         }
         }
-        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 );
-        }
+    final int getDomainStructureEvalueThreshold() {
+        return _domain_structure_e_value_thr_exp;
     }
 
     }
 
-    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 Set<Integer> getFoundNodes() {
+        return _found_nodes;
+    }
+
+    final Color getGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node ) {
+        if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
+            return ( PhylogenyMethods.getBranchColorValue( node ) );
         }
         }
-        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 ] );
-        boolean node_only = true;
-        if ( r == 1 ) {
-            node_only = false;
+        else {
+            return ( getTreeColorSet().getBranchColor() );
         }
         }
-        else if ( r != 0 ) {
-            return;
-        }
-        if ( node_only ) {
-            PhylogenyMethods.removeNode( node, _phylogeny );
-        }
-        else {
-            _phylogeny.deleteSubtree( node, true );
-        }
-        _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 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;
-        }
-        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;
-            }
+    final Color getTaxonomyBasedColor( final PhylogenyNode node ) {
+        if ( node.getNodeData().isHasTaxonomy() ) {
+            return calculateTaxonomyBasedColor( node.getNodeData().getTaxonomy() );
         }
         }
-        return null;
+        // return non-colorized color
+        return getTreeColorSet().getTaxonomyColor();
     }
 
     }
 
-    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 + "]";
-        }
-        return label;
+    /**
+     * @return pointer to colorset for tree drawing
+     */
+    final TreeColorSet getTreeColorSet() {
+        return getMainPanel().getTreeColorSet();
     }
 
     }
 
-    final Configuration getConfiguration() {
-        return _configuration;
+    final File getTreeFile() {
+        return _treefile;
     }
 
     }
 
-    final ControlPanel getControlPanel() {
-        return _control_panel;
+    final float getXcorrectionFactor() {
+        return _x_correction_factor;
     }
 
     }
 
-    final private Set<Integer> getCopiedAndPastedNodes() {
-        return getMainPanel().getCopiedAndPastedNodes();
+    final float getXdistance() {
+        return _x_distance;
     }
 
     }
 
-    final private Phylogeny getCutOrCopiedTree() {
-        return getMainPanel().getCutOrCopiedTree();
+    final float getYdistance() {
+        return _y_distance;
     }
 
     }
 
-    final int getDomainStructureEvalueThreshold() {
-        return _domain_structure_e_value_thr_exp;
+    final void increaseDomainStructureEvalueThreshold() {
+        if ( _domain_structure_e_value_thr_exp < 3 ) {
+            _domain_structure_e_value_thr_exp += 1;
+        }
     }
 
     }
 
-    final Set<Integer> getFoundNodes() {
-        return _found_nodes;
+    final void initNodeData() {
+        if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
+            return;
+        }
+        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;
+                    }
+                }
+            }
+        }
+        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 );
+                }
+            }
+        }
     }
 
     }
 
-    final private float getLastDragPointX() {
-        return _last_drag_point_x;
+    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 getLastDragPointY() {
-        return _last_drag_point_y;
+    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 int getLongestExtNodeInfo() {
-        return _longest_ext_node_info;
+    final boolean isApplet() {
+        return getMainPanel() instanceof MainPanelApplets;
     }
 
     }
 
-    final public MainPanel getMainPanel() {
-        return _main_panel;
+    final boolean isCanCollapse() {
+        return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
     }
 
     }
 
-    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 boolean isCanColorSubtree() {
+        return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
     }
 
     }
 
-    final private double getMaxDistanceToRoot() {
-        if ( _max_distance_to_root < 0 ) {
-            recalculateMaxDistanceToRoot();
-        }
-        return _max_distance_to_root;
+    final boolean isCanCopy() {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() );
     }
 
     }
 
-    final Options getOptions() {
-        if ( _options == null ) {
-            _options = getControlPanel().getOptions();
-        }
-        return _options;
+    final boolean isCanCut( final PhylogenyNode node ) {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() && !node
+                .isRoot() );
     }
 
     }
 
-    final private float getOvMaxHeight() {
-        return _ov_max_height;
+    final boolean isCanDelete() {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() );
     }
 
     }
 
-    final private float getOvMaxWidth() {
-        return _ov_max_width;
+    final boolean isCanPaste() {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable()
+                && ( getCutOrCopiedTree() != null ) && !getCutOrCopiedTree().isEmpty() );
     }
 
     }
 
-    final Rectangle2D getOvRectangle() {
-        return _ov_rectangle;
+    final boolean isCanReroot() {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && ( _subtree_index < 1 ) );
     }
 
     }
 
-    final Rectangle getOvVirtualRectangle() {
-        return _ov_virtual_rectangle;
+    final boolean isCanSubtree( final PhylogenyNode node ) {
+        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && !node.isExternal() && ( !node
+                .isRoot() || ( _subtree_index > 0 ) ) );
     }
 
     }
 
-    final private float getOvXcorrectionFactor() {
-        return _ov_x_correction_factor;
+    final boolean isCurrentTreeIsSubtree() {
+        return ( _subtree_index > 0 );
     }
 
     }
 
-    final private float getOvXDistance() {
-        return _ov_x_distance;
+    final boolean isEdited() {
+        return _edited;
     }
 
     }
 
-    final private int getOvXPosition() {
-        return _ov_x_position;
+    final boolean isInOvRect() {
+        return _in_ov_rect;
     }
 
     }
 
-    final private float getOvYDistance() {
-        return _ov_y_distance;
+    final boolean isOvOn() {
+        return _ov_on;
     }
 
     }
 
-    final private int getOvYPosition() {
-        return _ov_y_position;
-    }
-
-    final private int getOvYStart() {
-        return _ov_y_start;
-    }
-
-    /**
-     * Get a pointer to the phylogeny 
-     * 
-     * @return a pointer to the phylogeny
-     */
-    final Phylogeny getPhylogeny() {
-        return _phylogeny;
-    }
-
-    final PHYLOGENY_GRAPHICS_TYPE getPhylogenyGraphicsType() {
-        return _graphics_type;
-    }
-
-    final private double getScaleDistance() {
-        return _scale_distance;
+    final boolean isPhyHasBranchLengths() {
+        return _phy_has_branch_lengths;
     }
 
     }
 
-    final private String getScaleLabel() {
-        return _scale_label;
+    final void midpointRoot() {
+        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
+            return;
+        }
+        if ( !_phylogeny.isRerootable() ) {
+            JOptionPane.showMessageDialog( this,
+                                           "This is not rerootable",
+                                           "Not rerootable",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
+        }
+        setNodeInPreorderToNull();
+        setWaitCursor();
+        PhylogenyMethods.midpointRoot( _phylogeny );
+        resetNodeIdToDistToLeafMap();
+        setArrowCursor();
+        repaint();
     }
 
     }
 
-    final double getStartingAngle() {
-        return _urt_starting_angle;
+    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();
+        }
+        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() );
+                    }
+                    else {
+                        // if not in _found_nodes, clear _found_nodes
+                        handleClickToAction( _control_panel.getActionWhenNodeClicked(), node );
+                    }
+                }
+            }
+            else {
+                // no node was clicked
+                _highlight_node = null;
+            }
+        }
+        repaint();
     }
 
     }
 
-    /**
-     * 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 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;
         }
         }
-        // return non-colorized color
-        return getTreeColorSet().getTaxonomyColor();
+        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 );
     }
 
     }
 
-    /**
-     * @return pointer to colorset for tree drawing
-     */
-    final TreeColorSet getTreeColorSet() {
-        return getMainPanel().getTreeColorSet();
+    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;
+            }
+        }
+        if ( scroll_position.y <= 0 ) {
+            dy = 0;
+            scroll_position.y = 0;
+        }
+        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;
+            }
+        }
+        repaint();
+        getMainPanel().getCurrentScrollPane().getViewport().setViewPosition( scroll_position );
+        setLastMouseDragPointX( ( float ) ( e.getX() + dx ) );
+        setLastMouseDragPointY( ( float ) ( e.getY() + dy ) );
     }
 
     }
 
-    final File getTreeFile() {
-        return _treefile;
+    final void mouseMoved( final MouseEvent e ) {
+        requestFocusInWindow();
+        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 );
+                    repaint();
+                }
+            }
+            else {
+                if ( isInOvRect() ) {
+                    setInOvRect( false );
+                    repaint();
+                }
+            }
+        }
+        if ( inOv( e ) && getOptions().isShowOverview() && isOvOn() ) {
+            if ( !isInOv() ) {
+                setInOv( true );
+            }
+        }
+        else {
+            if ( isInOv() ) {
+                setInOv( false );
+            }
+            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 {
+                    setCursor( HAND_CURSOR );
+                    if ( getControlPanel().isNodeDescPopup() ) {
+                        showNodeDataPopup( e, node );
+                    }
+                }
+            }
+            else {
+                setCursor( ARROW_CURSOR );
+            }
+        }
     }
 
     }
 
-    final private TreeFontSet getTreeFontSet() {
-        return getMainPanel().getTreeFontSet();
+    final void mouseReleasedInBrowserPanel( final MouseEvent e ) {
+        setCursor( ARROW_CURSOR );
     }
 
     }
 
-    final private float getUrtFactor() {
-        return _urt_factor;
+    final void multiplyUrtFactor( final float f ) {
+        _urt_factor *= f;
     }
 
     }
 
-    final private float getUrtFactorOv() {
-        return _urt_factor_ov;
+    final JApplet obtainApplet() {
+        return ( ( MainPanelApplets ) getMainPanel() ).getApplet();
     }
 
     }
 
-    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;
-            default:
-                throw new IllegalArgumentException( "unknown action: " + action );
+    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 );
         }
         }
-    }
-
-    final void increaseDomainStructureEvalueThreshold() {
-        if ( _domain_structure_e_value_thr_exp < 3 ) {
-            _domain_structure_e_value_thr_exp += 1;
+        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 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 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 );
         }
         }
-    }
-
-    final void inferCommonPartOfScientificNames() {
-        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
-            return;
+        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 );
         }
         }
-        setWaitCursor();
-        Util.inferCommonPartOfScientificNames( _phylogeny );
-        setArrowCursor();
-        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 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 ) );
     }
 
     }
 
-    final private void initializeOvSettings() {
-        setOvMaxHeight( getConfiguration().getOvMaxHeight() );
-        setOvMaxWidth( getConfiguration().getOvMaxWidth() );
+    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 initNodeData() {
+    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 ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
             return;
         }
-        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 );
+        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 {
                 }
                 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;
+                    if ( getOptions().isPrintBlackAndWhite() ) {
+                        g.setColor( Color.WHITE );
                     }
                     }
+                    g.fillRect( graphics_file_x, graphics_file_y, graphics_file_width, graphics_file_height );
                 }
             }
                 }
             }
-        }
-        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 {
+                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( final PhylogenyNode element : _nodes_in_preorder ) {
+                paintNodeRectangular( g, element, 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 );
+                }
+                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 );
+            }
         }
     }
 
         }
     }
 
-    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().getSymbol() ) ) );
-    }
-
-    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 void recalculateMaxDistanceToRoot() {
+        _max_distance_to_root = PhylogenyMethods.calculateMaxDistanceToRoot( getPhylogeny() );
     }
 
     }
 
-    final boolean isCanDelete() {
-        return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() );
+    /**
+     * 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;
     }
 
     }
 
-    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;
+    /**
+     * 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;
         }
         }
-        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;
+    final void reRoot( final PhylogenyNode node ) {
+        if ( !getPhylogeny().isRerootable() ) {
+            JOptionPane.showMessageDialog( this,
+                                           "This is not rerootable",
+                                           "Not rerootable",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
         }
         }
-        else {
-            return false;
+        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 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 void resetNodeIdToDistToLeafMap() {
+        _nodeid_dist_to_leaf = new HashMap<Integer, Short>();
     }
 
     }
 
-    final private boolean isInFoundNodes( final PhylogenyNode node ) {
-        return ( ( getFoundNodes() != null ) && getFoundNodes().contains( node.getId() ) );
-    }
+    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 ) );
+            }
+            else {
+                x = TreePanel.MOVE
+                        + getLongestExtNodeInfo()
+                        + ForesterUtil.roundToInt( getXdistance()
+                                * ( PhylogenyMethods.calculateMaxDepth( getPhylogeny() ) + 1 ) );
+            }
+        }
+        setPreferredSize( new Dimension( x, y ) );
+    }
 
 
-    final private boolean isInOv() {
-        return _in_ov;
+    final void selectNode( final PhylogenyNode node ) {
+        if ( ( getFoundNodes() != null ) && getFoundNodes().contains( node.getId() ) ) {
+            getFoundNodes().remove( node.getId() );
+            getControlPanel().setSearchFoundCountsOnLabel( getFoundNodes().size() );
+            if ( getFoundNodes().size() < 1 ) {
+                getControlPanel().searchReset();
+            }
+        }
+        else {
+            getControlPanel().getSearchFoundCountsLabel().setVisible( true );
+            getControlPanel().getSearchResetButton().setEnabled( true );
+            getControlPanel().getSearchResetButton().setVisible( true );
+            if ( getFoundNodes() == null ) {
+                setFoundNodes( new HashSet<Integer>() );
+            }
+            getFoundNodes().add( node.getId() );
+            getControlPanel().setSearchFoundCountsOnLabel( getFoundNodes().size() );
+        }
     }
 
     }
 
-    final boolean isInOvRect() {
-        return _in_ov_rect;
+    final void setControlPanel( final ControlPanel atv_control ) {
+        _control_panel = atv_control;
     }
 
     }
 
-    final private boolean isNodeDataInvisible( final PhylogenyNode node ) {
-        int y_dist = 40;
-        if ( getControlPanel().isShowTaxonomyImages() ) {
-            y_dist = 40 + ( int ) getYdistance();
-        }
-        return ( ( node.getYcoord() < getVisibleRect().getMinY() - y_dist )
-                || ( node.getYcoord() > getVisibleRect().getMaxY() + y_dist ) || ( ( node.getParent() != null ) && ( node
-                .getParent().getXcoord() > getVisibleRect().getMaxX() ) ) );
+    final void setFoundNodes( final Set<Integer> found_nodes ) {
+        _found_nodes = found_nodes;
     }
 
     }
 
-    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 void setInOvRect( final boolean in_ov_rect ) {
+        _in_ov_rect = in_ov_rect;
     }
 
     }
 
-    final private boolean isNonLinedUpCladogram() {
-        return getOptions().getCladogramType() == CLADOGRAM_TYPE.NON_LINED_UP;
+    final void setLargeFonts() {
+        getTreeFontSet().largeFonts();
     }
 
     }
 
-    final boolean isOvOn() {
-        return _ov_on;
+    final void setLastMouseDragPointX( final float x ) {
+        _last_drag_point_x = x;
     }
 
     }
 
-    final boolean isPhyHasBranchLengths() {
-        return _phy_has_branch_lengths;
+    final void setLastMouseDragPointY( final float y ) {
+        _last_drag_point_y = y;
     }
 
     }
 
-    final private boolean isUniformBranchLengthsForCladogram() {
-        return getOptions().getCladogramType() == CLADOGRAM_TYPE.TOTAL_NODE_SUM_DEP;
+    final void setLongestExtNodeInfo( final int i ) {
+        _longest_ext_node_info = i;
     }
 
     }
 
-    final private void keyPressedCalls( final KeyEvent e ) {
-        if ( isOvOn() && ( getMousePosition() != null ) && ( getMousePosition().getLocation() != null ) ) {
-            if ( inOvVirtualRectangle( getMousePosition().x, getMousePosition().y ) ) {
-                if ( !isInOvRect() ) {
-                    setInOvRect( true );
-                }
+    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 if ( isInOvRect() ) {
-                setInOvRect( false );
+            else {
+                _rendering_hints.put( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED );
             }
         }
             }
         }
-        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 );
+        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 if ( ( e.getKeyCode() == KeyEvent.VK_SUBTRACT ) || ( e.getKeyCode() == KeyEvent.VK_MINUS ) ) {
-                getMainPanel().getTreeFontSet().decreaseFontSize();
-                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            else {
+                _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
             }
             }
-            else if ( plusPressed( e.getKeyCode() ) ) {
-                getMainPanel().getTreeFontSet().increaseFontSize();
-                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            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 {
             }
         }
         else {
-            if ( ( e.getKeyCode() == KeyEvent.VK_DELETE ) || ( e.getKeyCode() == KeyEvent.VK_HOME )
-                    || ( e.getKeyCode() == KeyEvent.VK_F ) ) {
-                getControlPanel().showWhole();
-            }
-            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 );
+            _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().isShowGeneNames() || getControlPanel()
+                        .isShowGeneSymbols() ) ) {
+                    pri = DESCENDANT_SORT_PRIORITY.SEQUENCE;
                 }
                 }
-            }
-            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 ( getControlPanel().isShowNodeNames() ) {
+                    pri = DESCENDANT_SORT_PRIORITY.NODE_NAME;
                 }
             }
                 }
             }
-            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();
-            }
-            e.consume();
+            PhylogenyMethods.sortNodeDescendents( node, pri );
+            setNodeInPreorderToNull();
+            _phylogeny.externalNodesHaveChanged();
+            _phylogeny.clearHashIdToNodeMap();
+            _phylogeny.recalculateNumberOfExternalDescendants( true );
+            resetNodeIdToDistToLeafMap();
+            setEdited( true );
         }
         }
+        repaint();
     }
 
     }
 
-    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 ) );
-            }
-            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 ] ) ) {
-                if ( Constants.__RELEASE || Constants.__SNAPSHOT_RELEASE ) {
-                    continue;
-                }
-                _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 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() );
-            }
-            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 ) );
-            }
-            _node_popup_menu_items[ i ].addActionListener( this );
-            _node_popup_menu.add( _node_popup_menu_items[ i ] );
+    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 void midpointRoot() {
-        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
+    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;
         }
             return;
         }
-        if ( !_phylogeny.isRerootable() ) {
+        if ( node.getNumberOfDescendants() > 2 ) {
             JOptionPane.showMessageDialog( this,
             JOptionPane.showMessageDialog( this,
-                                           "This is not rerootable",
-                                           "Not rerootable",
-                                           JOptionPane.WARNING_MESSAGE );
+                                           "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();
             return;
         }
         setWaitCursor();
-        PhylogenyMethods.midpointRoot( _phylogeny );
-        resetNodeIdToDistToLeafMap();
+        AptxUtil.colorPhylogenyAccordingToExternalTaxonomy( _phylogeny, this );
+        _control_panel.setColorBranches( true );
+        if ( _control_panel.getColorBranchesCb() != null ) {
+            _control_panel.getColorBranchesCb().setSelected( true );
+        }
         setArrowCursor();
         repaint();
     }
 
         setArrowCursor();
         repaint();
     }
 
-    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;
+    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 ) );
             }
             }
-            if ( y < 0 ) {
-                y = 0;
+            else {
+                ov_xdist = ( ( getOvMaxWidth() - l ) / ( PhylogenyMethods.calculateMaxDepth( _phylogeny ) ) );
             }
             }
-            final double max_x = getWidth() - getVisibleRect().width;
-            final double max_y = getHeight() - getVisibleRect().height;
-            if ( x > max_x ) {
-                x = max_x;
+            float ydist = ( float ) ( ( getOvMaxWidth() / ( ext_nodes * 2.0 ) ) );
+            if ( ov_xdist < 0.0 ) {
+                ov_xdist = 0.0f;
             }
             }
-            if ( y > max_y ) {
-                y = max_y;
+            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 );
             }
             }
-            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;
+            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();
                 }
                 }
-                _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>() );
+            }
+        }
+    }
+
+    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 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 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';
+                        }
                     }
                     }
-                    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() );
+                if ( type == '?' ) {
+                    if ( SequenceIdParser.isProtein( 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();
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 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.getRef() ) ? a.getRef() : a.getDesc() );
+            }
+            final String ann_str = sb.toString();
+            if ( !ForesterUtil.isEmpty( ann_str ) ) {
+                c = getControlPanel().getAnnotationColors().get( ann_str );
+                if ( c == null ) {
+                    c = AptxUtil.calculateColorFromString( ann_str );
+                    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 ) {
+        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;
+        }
+        _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 ) );
+        }
+        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 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<Integer> node_ids = new HashSet<Integer>( 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() ) {
+            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;
-            }
         }
         }
-        repaint();
+        return offset;
     }
 
     }
 
-    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;
+    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 );
+    }
+
+    final private Set<Integer> getCopiedAndPastedNodes() {
+        return getMainPanel().getCopiedAndPastedNodes();
+    }
+
+    final private Phylogeny getCutOrCopiedTree() {
+        return getMainPanel().getCutOrCopiedTree();
+    }
+
+    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 {
         }
         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;
+            return _nodeid_dist_to_leaf.get( node.getId() );
         }
         }
-        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 private double getMaxDistanceToRoot() {
+        if ( _max_distance_to_root < 0 ) {
+            recalculateMaxDistanceToRoot();
         }
         }
-        if ( isOvOn() || getOptions().isShowScale() ) {
-            repaint();
+        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 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 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 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 );
         }
         }
-        getMainPanel().getCurrentScrollPane().getViewport().setViewPosition( scroll_position );
     }
 
     }
 
-    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;
+    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 );
         }
         }
-        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 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 private boolean isCanBlast( final PhylogenyNode node ) {
+        if ( !node.getNodeData().isHasSequence() && ForesterUtil.isEmpty( node.getName() ) ) {
+            return false;
         }
         }
-        if ( scroll_position.y <= 0 ) {
-            dy = 0;
-            scroll_position.y = 0;
+        return Blast.isContainsQueryForBlast( node );
+    }
+
+    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;
         }
         }
-        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;
+    }
+
+    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 {
+            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 isInFoundNodes( final PhylogenyNode node ) {
+        return ( ( getFoundNodes() != null ) && getFoundNodes().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();
+                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 {
                 }
                 else {
-                    setCursor( HAND_CURSOR );
-                    if ( getControlPanel().isNodeDescPopup() ) {
-                        showNodeDataPopup( e, node );
+                    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 {
-                setCursor( ARROW_CURSOR );
+            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 );
             }
             }
-        }
-    }
-
-    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 ( 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 {
+                    getMainPanel().getMainFrame().getlabelDirectionCbmi().setSelected( selected );
+                }
                 repaint();
             }
                 repaint();
             }
-        }
-        else {
-            if ( isInOvRect() ) {
-                setInOvRect( false );
+            else if ( e.getKeyCode() == KeyEvent.VK_X ) {
+                switchDisplaygetPhylogenyGraphicsType();
                 repaint();
             }
                 repaint();
             }
-        }
-        if ( e.isControlDown() ) {
-            if ( notches < 0 ) {
-                getTreeFontSet().increaseFontSize();
-                getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            else if ( e.getKeyCode() == KeyEvent.VK_C ) {
+                cycleColors();
+                repaint();
             }
             }
-            else {
-                getTreeFontSet().decreaseFontSize();
-                getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            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();
             }
             }
+            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 ] ) ) {
+                _node_popup_menu_items[ i ].setEnabled( isCanOpenSeqWeb( node ) );
+            }
+            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;
                 }
                 }
-                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( isCanDelete() );
+            }
+            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 ( 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.copy_subtree ][ 0 ] ) ) {
+                if ( !getOptions().isEditable() ) {
+                    continue;
                 }
                 }
-                else {
-                    for( int i = 0; i < notches; ++i ) {
-                        getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
-                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
-                    }
+                _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 ( 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.edit_node_data ][ 0 ] ) ) {
+                if ( !getOptions().isEditable() ) {
+                    continue;
                 }
             }
                 }
             }
-            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.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 SEQUENCE_NAME:
+                return "Sequence Names";
+            case SEQUENCE_SYMBOL:
+                return "Sequence Symbols";
+            case SEQUENCE_MOL_SEQ:
+                return "Molecular Sequences";
+            case SEQUENCE_ACC:
+                return "Sequence Accessors";
+            case TAXONOMY_SCIENTIFIC_NAME:
+                return "Scientific Names";
+            case TAXONOMY_CODE:
+                return "Taxonomy Codes";
+            case UNKNOWN:
+                return "User Selected Data";
+            default:
+                throw new IllegalArgumentException( "unknown data element: "
+                        + getOptions().getExtDescNodeDataToReturn() );
+        }
     }
 
     final private void openSeqWeb( final PhylogenyNode node ) {
     }
 
     final private void openSeqWeb( final PhylogenyNode node ) {
@@ -2008,7 +3150,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             uri_str = url + URLEncoder.encode( seq.getAccession().getValue(), ForesterConstants.UTF8 );
         }
         catch ( final UnsupportedEncodingException e ) {
             uri_str = url + URLEncoder.encode( seq.getAccession().getValue(), ForesterConstants.UTF8 );
         }
         catch ( final UnsupportedEncodingException e ) {
-            Util.showErrorMessage( this, e.toString() );
+            AptxUtil.showErrorMessage( this, e.toString() );
             e.printStackTrace();
         }
         if ( !ForesterUtil.isEmpty( uri_str ) ) {
             e.printStackTrace();
         }
         if ( !ForesterUtil.isEmpty( uri_str ) ) {
@@ -2017,14 +3159,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 if ( isApplet() ) {
                     applet = obtainApplet();
                 }
                 if ( isApplet() ) {
                     applet = obtainApplet();
                 }
-                Util.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_seq" );
+                AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_seq" );
             }
             catch ( final IOException e ) {
             }
             catch ( final IOException e ) {
-                Util.showErrorMessage( this, e.toString() );
+                AptxUtil.showErrorMessage( this, e.toString() );
                 e.printStackTrace();
             }
             catch ( final URISyntaxException e ) {
                 e.printStackTrace();
             }
             catch ( final URISyntaxException e ) {
-                Util.showErrorMessage( this, e.toString() );
+                AptxUtil.showErrorMessage( this, e.toString() );
                 e.printStackTrace();
             }
         }
                 e.printStackTrace();
             }
         }
@@ -2048,7 +3190,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 uri_str = weblink.getUrl() + URLEncoder.encode( tax.getIdentifier().getValue(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
                 uri_str = weblink.getUrl() + URLEncoder.encode( tax.getIdentifier().getValue(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
-                Util.showErrorMessage( this, e.toString() );
+                AptxUtil.showErrorMessage( this, e.toString() );
                 e.printStackTrace();
             }
         }
                 e.printStackTrace();
             }
         }
@@ -2058,7 +3200,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 uri_str = new URI( tax.getIdentifier().getValue() ).toString();
             }
             catch ( final URISyntaxException e ) {
                 uri_str = new URI( tax.getIdentifier().getValue() ).toString();
             }
             catch ( final URISyntaxException e ) {
-                Util.showErrorMessage( this, e.toString() );
+                AptxUtil.showErrorMessage( this, e.toString() );
                 uri_str = null;
                 e.printStackTrace();
             }
                 uri_str = null;
                 e.printStackTrace();
             }
@@ -2069,7 +3211,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                         + URLEncoder.encode( tax.getScientificName(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
                         + URLEncoder.encode( tax.getScientificName(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
-                Util.showErrorMessage( this, e.toString() );
+                AptxUtil.showErrorMessage( this, e.toString() );
                 e.printStackTrace();
             }
         }
                 e.printStackTrace();
             }
         }
@@ -2079,7 +3221,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                         + URLEncoder.encode( tax.getTaxonomyCode(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
                         + URLEncoder.encode( tax.getTaxonomyCode(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
-                Util.showErrorMessage( this, e.toString() );
+                AptxUtil.showErrorMessage( this, e.toString() );
                 e.printStackTrace();
             }
         }
                 e.printStackTrace();
             }
         }
@@ -2089,7 +3231,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                         + URLEncoder.encode( tax.getCommonName(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
                         + URLEncoder.encode( tax.getCommonName(), ForesterConstants.UTF8 );
             }
             catch ( final UnsupportedEncodingException e ) {
-                Util.showErrorMessage( this, e.toString() );
+                AptxUtil.showErrorMessage( this, e.toString() );
                 e.printStackTrace();
             }
         }
                 e.printStackTrace();
             }
         }
@@ -2099,14 +3241,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 if ( isApplet() ) {
                     applet = obtainApplet();
                 }
                 if ( isApplet() ) {
                     applet = obtainApplet();
                 }
-                Util.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_tax" );
+                AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_tax" );
             }
             catch ( final IOException e ) {
             }
             catch ( final IOException e ) {
-                Util.showErrorMessage( this, e.toString() );
+                AptxUtil.showErrorMessage( this, e.toString() );
                 e.printStackTrace();
             }
             catch ( final URISyntaxException e ) {
                 e.printStackTrace();
             }
             catch ( final URISyntaxException e ) {
-                Util.showErrorMessage( this, e.toString() );
+                AptxUtil.showErrorMessage( this, e.toString() );
                 e.printStackTrace();
             }
         }
                 e.printStackTrace();
             }
         }
@@ -2115,65 +3257,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    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 );
-        }
-    }
-
     final private void paintBranchLength( final Graphics2D g,
                                           final PhylogenyNode node,
                                           final boolean to_pdf,
     final private void paintBranchLength( final Graphics2D g,
                                           final PhylogenyNode node,
                                           final boolean to_pdf,
@@ -2245,7 +3328,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     final private void paintBranchRectangular( final Graphics2D g,
                                                final float x1,
                                                final float x2,
     final private void paintBranchRectangular( final Graphics2D g,
                                                final float x1,
                                                final float x2,
-                                               float y1,
+                                               final float y1,
                                                final float y2,
                                                final PhylogenyNode node,
                                                final boolean to_pdf,
                                                final float y2,
                                                final PhylogenyNode node,
                                                final boolean to_pdf,
@@ -2266,131 +3349,87 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             g.draw( _cubic_curve );
         }
         else {
             g.draw( _cubic_curve );
         }
         else {
-            float x2a = x2;
-            float x1a = x1;
-            // draw the vertical line
-            boolean draw_horizontal = true;
+            final float x2a = x2;
+            final float x1a = x1;
             float y2_r = 0;
             if ( node.isFirstChildNode() || node.isLastChildNode()
                     || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE )
                     || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
             float y2_r = 0;
             if ( node.isFirstChildNode() || node.isLastChildNode()
                     || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE )
                     || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
-                boolean draw_vertical = true;
-                final PhylogenyNode parent = node.getParent();
-                if ( ( ( getOptions().isShowNodeBoxes() && !to_pdf && !to_graphics_file ) || ( ( getControlPanel()
-                        .isEvents() ) && ( parent != null ) && parent.isHasAssignedEvent() ) )
-                        && ( _phylogeny.isRooted() || !( ( parent != null ) && parent.isRoot() ) )
-                        && !( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() && !parent
-                                .isDuplication() ) ) {
-                    if ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE )
-                            && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
-                        if ( Math.abs( y2 - y1 ) <= TreePanel.HALF_BOX_SIZE ) {
-                            draw_vertical = false;
-                        }
-                        else {
-                            if ( y1 < y2 ) {
-                                y1 += TreePanel.HALF_BOX_SIZE;
-                            }
-                            else {
-                                if ( !to_pdf ) {
-                                    y1 -= TreePanel.HALF_BOX_SIZE + 1;
-                                }
-                                else {
-                                    y1 -= TreePanel.HALF_BOX_SIZE;
-                                }
-                            }
-                        }
-                    }
-                    if ( ( x2 - x1 ) <= TreePanel.HALF_BOX_SIZE ) {
-                        draw_horizontal = false;
-                    }
-                    else if ( !draw_vertical ) {
-                        x1a += TreePanel.HALF_BOX_SIZE;
-                    }
-                    if ( ( ( x2 - x1a ) > TreePanel.HALF_BOX_SIZE )
-                            && !( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() && !node
-                                    .isDuplication() ) ) {
-                        x2a -= TreePanel.HALF_BOX_SIZE;
-                    }
+                if ( !to_graphics_file
+                        && !to_pdf
+                        && ( ( ( y2 < ( getVisibleRect().getMinY() - 20 ) ) && ( y1 < ( getVisibleRect().getMinY() - 20 ) ) ) || ( ( y2 > ( getVisibleRect()
+                                .getMaxY() + 20 ) ) && ( y1 > ( getVisibleRect().getMaxY() + 20 ) ) ) ) ) {
+                    // Do nothing.
                 }
                 }
-                if ( draw_vertical ) {
-                    if ( !to_graphics_file
-                            && !to_pdf
-                            && ( ( ( y2 < getVisibleRect().getMinY() - 20 ) && ( y1 < getVisibleRect().getMinY() - 20 ) ) || ( ( y2 > getVisibleRect()
-                                    .getMaxY() + 20 ) && ( y1 > getVisibleRect().getMaxY() + 20 ) ) ) ) {
-                        // Do nothing.
-                    }
-                    else {
-                        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
-                            float x2c = x1 + EURO_D;
-                            if ( x2c > x2a ) {
-                                x2c = x2a;
-                            }
-                            drawLine( x1, y1, x2c, y2, g );
+                else {
+                    if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
+                        float x2c = x1 + EURO_D;
+                        if ( x2c > x2a ) {
+                            x2c = x2a;
                         }
                         }
-                        else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
-                            if ( y2 > y1 ) {
-                                y2_r = y2 - ROUNDED_D;
-                                if ( y2_r < y1 ) {
-                                    y2_r = y1;
-                                }
-                                drawLine( x1, y1, x1, y2_r, g );
-                            }
-                            else {
-                                y2_r = y2 + ROUNDED_D;
-                                if ( y2_r > y1 ) {
-                                    y2_r = y1;
-                                }
-                                drawLine( x1, y1, x1, y2_r, g );
+                        drawLine( x1, y1, x2c, y2, g );
+                    }
+                    else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
+                        if ( y2 > y1 ) {
+                            y2_r = y2 - ROUNDED_D;
+                            if ( y2_r < y1 ) {
+                                y2_r = y1;
                             }
                             }
+                            drawLine( x1, y1, x1, y2_r, g );
                         }
                         else {
                         }
                         else {
-                            drawLine( x1, y1, x1, y2, g );
+                            y2_r = y2 + ROUNDED_D;
+                            if ( y2_r > y1 ) {
+                                y2_r = y1;
+                            }
+                            drawLine( x1, y1, x1, y2_r, g );
                         }
                     }
                         }
                     }
+                    else {
+                        drawLine( x1, y1, x1, y2, g );
+                    }
                 }
             }
             // 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;
-            if ( draw_horizontal ) {
-                if ( !getControlPanel().isWidthBranches() || ( PhylogenyMethods.getBranchWidthValue( node ) == 1 ) ) {
-                    if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
-                        x1_r = x1a + ROUNDED_D;
-                        if ( x1_r < x2a ) {
-                            drawLine( x1_r, y2, x2a, y2, g );
-                        }
-                    }
-                    else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
-                        final float x1c = x1a + EURO_D;
-                        if ( x1c < x2a ) {
-                            drawLine( x1c, y2, x2a, y2, g );
-                        }
+            if ( !getControlPanel().isWidthBranches() || ( PhylogenyMethods.getBranchWidthValue( node ) == 1 ) ) {
+                if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
+                    x1_r = x1a + ROUNDED_D;
+                    if ( x1_r < x2a ) {
+                        drawLine( x1_r, y2, x2a, y2, g );
                     }
                     }
-                    else {
-                        drawLine( x1a, y2, x2a, y2, g );
+                }
+                else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
+                    final float x1c = x1a + EURO_D;
+                    if ( x1c < x2a ) {
+                        drawLine( x1c, y2, x2a, y2, g );
                     }
                 }
                 else {
                     }
                 }
                 else {
-                    final double w = PhylogenyMethods.getBranchWidthValue( node );
-                    if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
-                        x1_r = x1a + ROUNDED_D;
-                        if ( x1_r < x2a ) {
-                            drawRectFilled( x1_r, y2 - ( w / 2 ), x2a - x1_r, w, g );
-                        }
-                    }
-                    else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
-                        final float x1c = x1a + EURO_D;
-                        if ( x1c < x2a ) {
-                            drawRectFilled( x1c, y2 - ( w / 2 ), x2a - x1c, w, g );
-                        }
+                    drawLine( x1a, y2, x2a, y2, g );
+                }
+            }
+            else {
+                final double w = PhylogenyMethods.getBranchWidthValue( node );
+                if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
+                    x1_r = x1a + ROUNDED_D;
+                    if ( x1_r < x2a ) {
+                        drawRectFilled( x1_r, y2 - ( w / 2 ), x2a - x1_r, w, g );
                     }
                     }
-                    else {
-                        drawRectFilled( x1a, y2 - ( w / 2 ), x2a - x1a, w, g );
+                }
+                else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
+                    final float x1c = x1a + EURO_D;
+                    if ( x1c < x2a ) {
+                        drawRectFilled( x1c, y2 - ( w / 2 ), x2a - x1c, w, g );
                     }
                 }
                     }
                 }
+                else {
+                    drawRectFilled( x1a, y2 - ( w / 2 ), x2a - x1a, w, g );
+                }
             }
             if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
                 if ( x1_r > x2a ) {
             }
             if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
                 if ( x1_r > x2a ) {
@@ -2406,55 +3445,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 g.draw( _arc );
             }
         }
                 g.draw( _arc );
             }
         }
-        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 ) {
-        _circ_num_ext_nodes = phy.getNumberOfExternalNodes();
-        _root = phy.getRoot();
-        _root.setXcoord( center_x );
-        _root.setYcoord( center_y );
-        paintNodeBox( _root.getXcoord(), _root.getYcoord(), _root, g, to_pdf, to_graphics_file, isInFoundNodes( _root ) );
-        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();
-            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 );
-        }
-        paintCirculars( phy.getRoot(), phy, center_x, center_y, radius, radial_labels, 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 ) {
-        _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 );
+        if ( node.isExternal() ) {
+            paintNodeBox( x2, y2, node, g, to_pdf, to_graphics_file, isInFoundNodes( node ) );
         }
         }
-        paintCircularsLite( phy.getRoot(), phy, center_x, center_y, radius, g );
     }
 
     final private double paintCirculars( final PhylogenyNode n,
     }
 
     final private double paintCirculars( final PhylogenyNode n,
@@ -2466,9 +3459,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                          final Graphics2D g,
                                          final boolean to_pdf,
                                          final boolean to_graphics_file ) {
                                          final Graphics2D g,
                                          final boolean to_pdf,
                                          final boolean to_graphics_file ) {
-        if ( n.isExternal() ) {
+        if ( n.isExternal() || n.isCollapse() ) { //~~circ collapse
             if ( !_urt_nodeid_angle_map.containsKey( n.getId() ) ) {
             if ( !_urt_nodeid_angle_map.containsKey( n.getId() ) ) {
-                System.out.println( "no " + n + ", fucker!" );//TODO
+                System.out.println( "no " + n + " =====>>>>>>> ERROR!" );//TODO
             }
             return _urt_nodeid_angle_map.get( n.getId() );
         }
             }
             return _urt_nodeid_angle_map.get( n.getId() );
         }
@@ -2488,11 +3481,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 );
@@ -2517,11 +3510,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 );
             }
@@ -2533,21 +3526,22 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                            final boolean to_graphics_file,
                                            final boolean to_pdf,
                                            final boolean is_in_found_nodes ) {
                                            final boolean to_graphics_file,
                                            final boolean to_pdf,
                                            final boolean is_in_found_nodes ) {
+        Color c = null;
         if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
         if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
-            g.setColor( Color.BLACK );
+            c = Color.BLACK;
         }
         else if ( is_in_found_nodes ) {
         }
         else if ( is_in_found_nodes ) {
-            g.setColor( getTreeColorSet().getFoundColor() );
+            c = getTreeColorSet().getFoundColor();
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
-            g.setColor( getTaxonomyBasedColor( node ) );
+            c = getTaxonomyBasedColor( node );
         }
         else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches()
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
         }
         else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches()
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
-            g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
+            c = PhylogenyMethods.getBranchColorValue( node );
         }
         else {
         }
         else {
-            g.setColor( getTreeColorSet().getCollapseFillColor() );
+            c = getTreeColorSet().getCollapseFillColor();
         }
         double d = node.getAllExternalDescendants().size();
         if ( d > 1000 ) {
         }
         double d = node.getAllExternalDescendants().size();
         if ( d > 1000 ) {
@@ -2556,77 +3550,80 @@ 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;
         }
-        if ( d < BOX_SIZE ) {
-            d = BOX_SIZE;
+        final int box_size = getOptions().getDefaultNodeShapeSize();
+        if ( d < box_size ) {
+            d = box_size;
         }
         _polygon.reset();
         }
         _polygon.reset();
-        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() - TreePanel.BOX_SIZE ),
+        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() - box_size ),
                            ForesterUtil.roundToInt( node.getYcoord() ) );
                            ForesterUtil.roundToInt( node.getYcoord() ) );
-        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + TreePanel.BOX_SIZE ),
+        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ),
                            ForesterUtil.roundToInt( node.getYcoord() - d ) );
                            ForesterUtil.roundToInt( node.getYcoord() - d ) );
-        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + TreePanel.BOX_SIZE ),
+        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ),
                            ForesterUtil.roundToInt( node.getYcoord() + d ) );
                            ForesterUtil.roundToInt( node.getYcoord() + d ) );
-        g.fillPolygon( _polygon );
+        if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) {
+            g.setColor( c );
+            g.fillPolygon( _polygon );
+        }
+        else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.NONE ) {
+            g.setColor( getBackground() );
+            g.fillPolygon( _polygon );
+            g.setColor( c );
+            g.drawPolygon( _polygon );
+        }
+        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.fill( _polygon );
+            g.setPaint( c );
+            g.draw( _polygon );
+        }
         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 private void paintConfidenceValues( final Graphics2D g,
                                               final PhylogenyNode node,
                                               final boolean to_pdf,
                                               final boolean to_graphics_file ) {
-        String conf_str = "";
         final List<Confidence> confidences = node.getBranchData().getConfidences();
         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();
-            for( final Confidence confidence : confidences ) {
-                final double value = confidence.getValue();
-                if ( value != Confidence.CONFIDENCE_DEFAULT_VALUE ) {
-                    if ( value >= getOptions().getMinConfidenceValue() ) {
-                        one_ok = true;
-                    }
-                    if ( not_first ) {
-                        sb.append( "/" );
-                    }
-                    else {
-                        not_first = true;
+        //        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();
+        String conf_str = "";
+        for( final Confidence confidence : confidences ) {
+            final double value = confidence.getValue();
+            if ( value != Confidence.CONFIDENCE_DEFAULT_VALUE ) {
+                if ( value >= getOptions().getMinConfidenceValue() ) {
+                    one_ok = true;
+                }
+                if ( not_first ) {
+                    sb.append( "/" );
+                }
+                else {
+                    not_first = true;
+                }
+                sb.append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( value, getOptions()
+                        .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) );
+                if ( getOptions().isShowConfidenceStddev() ) {
+                    if ( confidence.getStandardDeviation() != Confidence.CONFIDENCE_DEFAULT_VALUE ) {
+                        sb.append( "(" );
+                        sb.append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( confidence.getStandardDeviation(),
+                                                                                    getOptions()
+                                                                                            .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) );
+                        sb.append( ")" );
                     }
                     }
-                    sb.append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( value, getOptions()
-                            .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) );
                 }
             }
                 }
             }
+            //}
             if ( one_ok ) {
                 conf_str = sb.toString();
             }
             if ( one_ok ) {
                 conf_str = sb.toString();
             }
@@ -2657,8 +3654,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     }
 
     final private void paintFoundNode( final int x, final int y, final Graphics2D g ) {
     }
 
     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.setColor( getTreeColorSet().getFoundColor() );
-        g.fillRect( x - TreePanel.HALF_BOX_SIZE, y - TreePanel.HALF_BOX_SIZE, TreePanel.BOX_SIZE, TreePanel.BOX_SIZE );
+        g.fillRect( x - half_box_size, y - half_box_size, box_size, box_size );
     }
 
     final private void paintGainedAndLostCharacters( final Graphics2D g,
     }
 
     final private void paintGainedAndLostCharacters( final Graphics2D g,
@@ -2715,33 +3714,93 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             paintFoundNode( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ), g );
         }
         else {
             paintFoundNode( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ), g );
         }
         else {
+            Color outline_color = null;
             if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
             if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
-                g.setColor( Color.BLACK );
+                outline_color = Color.BLACK;
             }
             }
-            else if ( getControlPanel().isEvents() && Util.isHasAssignedEvent( node ) ) {
+            else if ( getControlPanel().isEvents() && AptxUtil.isHasAssignedEvent( node ) ) {
                 final Event event = node.getNodeData().getEvent();
                 if ( event.isDuplication() ) {
                 final Event event = node.getNodeData().getEvent();
                 if ( event.isDuplication() ) {
-                    g.setColor( getTreeColorSet().getDuplicationBoxColor() );
+                    outline_color = getTreeColorSet().getDuplicationBoxColor();
                 }
                 else if ( event.isSpeciation() ) {
                 }
                 else if ( event.isSpeciation() ) {
-                    g.setColor( getTreeColorSet().getSpecBoxColor() );
+                    outline_color = getTreeColorSet().getSpecBoxColor();
                 }
                 else if ( event.isSpeciationOrDuplication() ) {
                 }
                 else if ( event.isSpeciationOrDuplication() ) {
-                    g.setColor( getTreeColorSet().getDuplicationOrSpeciationColor() );
+                    outline_color = getTreeColorSet().getDuplicationOrSpeciationColor();
                 }
             }
                 }
             }
-            else {
-                assignGraphicsForNodeBoxWithColorForParentBranch( node, g );
+            else if ( getOptions().isTaxonomyColorizeNodeShapes() ) {
+                outline_color = getTaxonomyBasedColor( node );
             }
             }
-            if ( ( getOptions().isShowNodeBoxes() && !to_pdf && !to_graphics_file )
-                    || ( getControlPanel().isEvents() && node.isHasAssignedEvent() ) ) {
-                if ( to_pdf || to_graphics_file ) {
-                    if ( node.isDuplication() || !getOptions().isPrintBlackAndWhite() ) {
-                        drawOvalFilled( x - HALF_BOX_SIZE, y - HALF_BOX_SIZE, BOX_SIZE, BOX_SIZE, g );
+            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 );
                     }
                 }
                     }
                 }
-                else {
-                    drawRectFilled( x - HALF_BOX_SIZE, y - HALF_BOX_SIZE, BOX_SIZE, BOX_SIZE, g );
+                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() == 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 );
+                    }
                 }
             }
         }
                 }
             }
         }
@@ -2758,20 +3817,21 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         if ( getOptions().isShowBranchLengthValues()
                 && ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR )
                         || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) )
         if ( getOptions().isShowBranchLengthValues()
                 && ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR )
                         || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) )
-                && ( !node.isRoot() ) && ( node.getDistanceToParent() != PhylogenyNode.DISTANCE_DEFAULT ) ) {
+                && ( !node.isRoot() ) && ( node.getDistanceToParent() != PhylogenyDataUtil.BRANCH_LENGTH_DEFAULT ) ) {
             paintBranchLength( g, node, to_pdf, to_graphics_file );
         }
         if ( !getControlPanel().isShowInternalData() && !node.isExternal() && !node.isCollapse() ) {
             return;
         }
         int x = 0;
             paintBranchLength( g, node, to_pdf, to_graphics_file );
         }
         if ( !getControlPanel().isShowInternalData() && !node.isExternal() && !node.isCollapse() ) {
             return;
         }
         int x = 0;
+        final int half_box_size = getOptions().getDefaultNodeShapeSize() / 2;
         if ( getControlPanel().isShowTaxonomyImages()
                 && ( getImageMap() != null )
                 && !getImageMap().isEmpty()
                 && node.getNodeData().isHasTaxonomy()
                 && ( ( node.getNodeData().getTaxonomy().getUris() != null ) && !node.getNodeData().getTaxonomy()
                         .getUris().isEmpty() ) ) {
         if ( getControlPanel().isShowTaxonomyImages()
                 && ( getImageMap() != null )
                 && !getImageMap().isEmpty()
                 && node.getNodeData().isHasTaxonomy()
                 && ( ( node.getNodeData().getTaxonomy().getUris() != null ) && !node.getNodeData().getTaxonomy()
                         .getUris().isEmpty() ) ) {
-            x += drawTaxonomyImage( node.getXcoord() + 2 + TreePanel.HALF_BOX_SIZE, node.getYcoord(), node, g );
+            x += drawTaxonomyImage( node.getXcoord() + 2 + half_box_size, node.getYcoord(), node, g );
         }
         if ( ( getControlPanel().isShowTaxonomyCode() || getControlPanel().isShowTaxonomyScientificNames() || getControlPanel()
                 .isShowTaxonomyCommonNames() ) && node.getNodeData().isHasTaxonomy() ) {
         }
         if ( ( getControlPanel().isShowTaxonomyCode() || getControlPanel().isShowTaxonomyScientificNames() || getControlPanel()
                 .isShowTaxonomyCommonNames() ) && node.getNodeData().isHasTaxonomy() ) {
@@ -2786,6 +3846,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         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 if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches()
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
             g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
         else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches()
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
             g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
@@ -2832,6 +3897,12 @@ 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().isShowProperties() && node.getNodeData().isHasProperties() ) {
+            if ( _sb.length() > 0 ) {
+                _sb.append( " " );
+            }
+            _sb.append( propertiesToString( node ) );
+        }
         g.setFont( getTreeFontSet().getLargeFont() );
         if ( is_in_found_nodes ) {
             g.setFont( getTreeFontSet().getLargeFont().deriveFont( Font.BOLD ) );
         g.setFont( getTreeFontSet().getLargeFont() );
         if ( is_in_found_nodes ) {
             g.setFont( getTreeFontSet().getLargeFont().deriveFont( Font.BOLD ) );
@@ -2840,7 +3911,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         if ( !node.isExternal() && ( node.getNumberOfDescendants() == 1 ) ) {
             down_shift_factor = 1;
         }
         if ( !node.isExternal() && ( node.getNumberOfDescendants() == 1 ) ) {
             down_shift_factor = 1;
         }
-        final double pos_x = node.getXcoord() + x + 2 + TreePanel.HALF_BOX_SIZE;
+        final double pos_x = node.getXcoord() + x + 2 + half_box_size;
         final double pos_y = ( node.getYcoord() + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ) );
         final String sb_str = _sb.toString();
         // GUILHEM_BEG ______________
         final double pos_y = ( node.getYcoord() + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ) );
         final String sb_str = _sb.toString();
         // GUILHEM_BEG ______________
@@ -2865,7 +3936,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                             && seqRelation.getType().equals( getControlPanel().getSequenceRelationTypeBox()
                                     .getSelectedItem() );
                     if ( fGotRelationWithQuery ) { // we will underline the text to show that this sequence is ortholog to the query
                             && seqRelation.getType().equals( getControlPanel().getSequenceRelationTypeBox()
                                     .getSelectedItem() );
                     if ( fGotRelationWithQuery ) { // we will underline the text to show that this sequence is ortholog to the query
-                        final double linePosX = node.getXcoord() + 2 + TreePanel.HALF_BOX_SIZE;
+                        final double linePosX = node.getXcoord() + 2 + half_box_size;
                         final String sConfidence = ( !getControlPanel().isShowSequenceRelationConfidence() || ( seqRelation
                                 .getConfidence() == null ) ) ? null : " (" + seqRelation.getConfidence().getValue()
                                 + ")";
                         final String sConfidence = ( !getControlPanel().isShowSequenceRelationConfidence() || ( seqRelation
                                 .getConfidence() == null ) ) ? null : " (" + seqRelation.getConfidence().getValue()
                                 + ")";
@@ -2882,7 +3953,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 */
@@ -2915,15 +3986,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             if ( _sb.length() > 0 ) {
                 x += getTreeFontSet()._fm_large.stringWidth( _sb.toString() ) + 5;
             }
             if ( _sb.length() > 0 ) {
                 x += getTreeFontSet()._fm_large.stringWidth( _sb.toString() ) + 5;
             }
-            final Annotation ann = node.getNodeData().getSequence().getAnnotation( 0 );
+            final SortedSet<Annotation> ann = node.getNodeData().getSequence().getAnnotations();
             if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
                 g.setColor( Color.BLACK );
             }
             if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
                 g.setColor( Color.BLACK );
             }
-            else {
+            else if ( getControlPanel().isColorAccordingToAnnotation() ) {
                 g.setColor( calculateColorForAnnotation( ann ) );
             }
                 g.setColor( calculateColorForAnnotation( ann ) );
             }
-            final String ann_str = ann.asSimpleText().toString();
-            TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + TreePanel.HALF_BOX_SIZE, node.getYcoord()
+            final String ann_str = createAnnotationString( ann );
+            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 );
                     + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
             _sb.setLength( 0 );
             _sb.append( ann_str );
@@ -2944,35 +4015,18 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 }
                 if ( getControlPanel().isShowBinaryCharacters() ) {
                     TreePanel.drawString( node.getNodeData().getBinaryCharacters().getPresentCharactersAsStringBuffer()
                 }
                 if ( getControlPanel().isShowBinaryCharacters() ) {
                     TreePanel.drawString( node.getNodeData().getBinaryCharacters().getPresentCharactersAsStringBuffer()
-                            .toString(), node.getXcoord() + x + 1 + TreePanel.HALF_BOX_SIZE, node.getYcoord()
+                            .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 {
                             + ( 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 + TreePanel.HALF_BOX_SIZE, node.getYcoord()
-                                + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
-                    }
-                    else {
-                        TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount(),
-                                              node.getXcoord() + x + 4 + TreePanel.HALF_BOX_SIZE,
-                                              node.getYcoord()
-                                                      + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ),
-                                              g );
-                    }
+                    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() );
                     paintGainedAndLostCharacters( g, node, "+"
                             + node.getNodeData().getBinaryCharacters().getGainedCount(), "-"
                             + node.getNodeData().getBinaryCharacters().getLostCount() );
@@ -2981,53 +4035,20 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    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 );
+    private String createAnnotationString( final SortedSet<Annotation> ann ) {
+        final StringBuilder sb = new StringBuilder();
+        boolean first = true;
+        for( final Annotation a : ann ) {
+            if ( !first ) {
+                sb.append( "|" );
             }
             }
-        }
-        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 {
+                first = false;
             }
             }
+            sb.append( a.asSimpleText() );
         }
         }
-        return offset;
+        final String ann_str = sb.toString();
+        return ann_str;
     }
 
     final private void paintNodeDataUnrootedCirc( final Graphics2D g,
     }
 
     final private void paintNodeDataUnrootedCirc( final Graphics2D g,
@@ -3049,6 +4070,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         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() );
         }
@@ -3228,7 +4254,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             ++_external_node_index;
         }
         // Confidence values
             ++_external_node_index;
         }
         // Confidence values
-        if ( getControlPanel().isShowBootstrapValues()
+        if ( getControlPanel().isShowConfidenceValues()
                 && !node.isExternal()
                 && !node.isRoot()
                 && ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED )
                 && !node.isExternal()
                 && !node.isRoot()
                 && ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED )
@@ -3299,11 +4325,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 ) );
         }
         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;
         }
@@ -3322,278 +4349,116 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             return;
         }
         if ( getControlPanel().isShowDomainArchitectures() && node.getNodeData().isHasSequence()
             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();
-                    return;
-                }
-                rds.setRenderingHeight( 6 );
-                int x = 0;
-                if ( getControlPanel().isShowTaxonomyCode() && ( PhylogenyMethods.getSpecies( node ).length() > 0 ) ) {
-                    x += getTreeFontSet()._fm_large_italic.stringWidth( PhylogenyMethods.getSpecies( node ) + " " );
-                }
-                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() );
-            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 ( _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() ];
-                System.out.println( "total nodes: " + _nodes_in_preorder.length );
-                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 );
+                && ( node.getNodeData().getSequence().getDomainArchitecture() != null ) ) {
+            RenderableDomainArchitecture rds = null;
+            if ( node.getNodeData().getSequence().getDomainArchitecture() instanceof RenderableDomainArchitecture ) {
+                try {
+                    rds = ( RenderableDomainArchitecture ) node.getNodeData().getSequence().getDomainArchitecture();
                 }
                 }
-            }
-            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 );
+                catch ( final ClassCastException cce ) {
+                    cce.printStackTrace();
                 }
                 }
-                else {
-                    paintScale( g, graphics_file_x, graphics_file_y + graphics_file_height, to_pdf, to_graphics_file );
+                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().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() && !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().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 );
         }
     }
 
         }
     }
 
@@ -3608,8 +4473,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         //for( it = _phylogeny.iteratorPreorder(); it.hasNext(); ) {
         //    paintNodeLite( g, it.next() );
         //}
         //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 ] );
+        for( final PhylogenyNode element : _nodes_in_preorder ) {
+            paintNodeLite( g, element );
         }
         paintOvRectangle( g );
     }
         }
         paintOvRectangle( g );
     }
@@ -3698,7 +4563,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         else {
             g.setColor( getTreeColorSet().getTaxonomyColor() );
         }
         else {
             g.setColor( getTreeColorSet().getTaxonomyColor() );
         }
-        final double start_x = node.getXcoord() + 3 + TreePanel.HALF_BOX_SIZE + x_shift;
+        final double start_x = node.getXcoord() + 3 + ( getOptions().getDefaultNodeShapeSize() / 2 ) + x_shift;
         final double start_y = node.getYcoord()
                 + ( getTreeFontSet()._fm_large.getAscent() / ( node.getNumberOfDescendants() == 1 ? 1 : 3.0 ) );
         _sb.setLength( 0 );
         final double start_y = node.getYcoord()
                 + ( getTreeFontSet()._fm_large.getAscent() / ( node.getNumberOfDescendants() == 1 ? 1 : 3.0 ) );
         _sb.setLength( 0 );
@@ -3775,18 +4640,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,
@@ -3797,7 +4650,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         if ( n.isRoot() ) {
             n.setXcoord( getWidth() / 2 );
             n.setYcoord( getHeight() / 2 );
         if ( n.isRoot() ) {
             n.setXcoord( getWidth() / 2 );
             n.setYcoord( getHeight() / 2 );
-            paintNodeBox( n.getXcoord(), n.getYcoord(), n, g, to_pdf, to_graphics_file, isInFoundNodes( n ) );
         }
         if ( n.isExternal() ) {
             paintNodeDataUnrootedCirc( g,
         }
         if ( n.isExternal() ) {
             paintNodeDataUnrootedCirc( g,
@@ -3845,16 +4697,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 );
             desc.setXcoord( new_x );
             desc.setYcoord( new_y );
-            paintNodeBox( new_x, new_y, desc, g, to_pdf, to_graphics_file, isInFoundNodes( desc ) );
             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 );
             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 ) );
+        }
+        if ( n.isRoot() ) {
+            paintNodeBox( n.getXcoord(), n.getYcoord(), n, g, to_pdf, to_graphics_file, isInFoundNodes( n ) );
         }
     }
 
         }
     }
 
@@ -3864,8 +4719,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 );
         }
@@ -3892,9 +4747,9 @@ 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 );
             if ( isInFoundNodes( desc ) ) {
             desc.setXSecondary( new_x );
             desc.setYSecondary( new_y );
             if ( isInFoundNodes( desc ) ) {
@@ -3910,193 +4765,99 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
 
     final private void pasteSubtree( final PhylogenyNode node ) {
         if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
 
     final private void pasteSubtree( final PhylogenyNode node ) {
         if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            errorMessageNoCutCopyPasteInUnrootedDisplay();
-            return;
-        }
-        if ( ( getCutOrCopiedTree() == null ) || getCutOrCopiedTree().isEmpty() ) {
-            JOptionPane.showMessageDialog( this,
-                                           "No tree in buffer (need to copy or cut a subtree first)",
-                                           "Attempt to paste with empty buffer",
-                                           JOptionPane.ERROR_MESSAGE );
-            return;
-        }
-        final String label = getASimpleTextRepresentationOfANode( getCutOrCopiedTree().getRoot() );
-        final Object[] options = { "As sibling", "As descendant", "Cancel" };
-        final int r = JOptionPane.showOptionDialog( this,
-                                                    "How to paste subtree" + label + "?",
-                                                    "Paste Subtree",
-                                                    JOptionPane.CLOSED_OPTION,
-                                                    JOptionPane.QUESTION_MESSAGE,
-                                                    null,
-                                                    options,
-                                                    options[ 2 ] );
-        boolean paste_as_sibling = true;
-        if ( r == 1 ) {
-            paste_as_sibling = false;
-        }
-        else if ( r != 0 ) {
-            return;
-        }
-        final Phylogeny buffer_phy = getCutOrCopiedTree().copy();
-        buffer_phy.setAllNodesToNotCollapse();
-        buffer_phy.preOrderReId();
-        buffer_phy.setRooted( true );
-        boolean need_to_show_whole = false;
-        if ( paste_as_sibling ) {
-            if ( node.isRoot() ) {
-                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 );
-        _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 );
+            errorMessageNoCutCopyPasteInUnrootedDisplay();
             return;
         }
             return;
         }
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+        if ( ( getCutOrCopiedTree() == null ) || getCutOrCopiedTree().isEmpty() ) {
             JOptionPane.showMessageDialog( this,
             JOptionPane.showMessageDialog( this,
-                                           "Cannot reroot in unrooted display type",
-                                           "Attempt to reroot tree in unrooted display",
-                                           JOptionPane.WARNING_MESSAGE );
+                                           "No tree in buffer (need to copy or cut a subtree first)",
+                                           "Attempt to paste with empty buffer",
+                                           JOptionPane.ERROR_MESSAGE );
             return;
         }
             return;
         }
-        getPhylogeny().reRoot( node );
-        getPhylogeny().recalculateNumberOfExternalDescendants( true );
-        resetNodeIdToDistToLeafMap();
-        _nodes_in_preorder = null;
-        resetPreferredSize();
-        getMainPanel().adjustJScrollPane();
-        repaint();
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) {
-            getControlPanel().showWhole();
+        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 + "?",
+                                                    "Paste Subtree",
+                                                    JOptionPane.CLOSED_OPTION,
+                                                    JOptionPane.QUESTION_MESSAGE,
+                                                    null,
+                                                    options,
+                                                    options[ 2 ] );
+        boolean paste_as_sibling = true;
+        if ( r == 1 ) {
+            paste_as_sibling = false;
         }
         }
-    }
-
-    final void resetNodeIdToDistToLeafMap() {
-        _nodeid_dist_to_leaf = new HashMap<Integer, Short>();
-    }
-
-    final void resetPreferredSize() {
-        if ( ( getPhylogeny() == null ) || getPhylogeny().isEmpty() ) {
+        else if ( r != 0 ) {
             return;
         }
             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() );
+        final Phylogeny buffer_phy = getCutOrCopiedTree().copy();
+        buffer_phy.setAllNodesToNotCollapse();
+        PhylogenyMethods.preOrderReId( buffer_phy );
+        buffer_phy.setRooted( true );
+        boolean need_to_show_whole = false;
+        if ( paste_as_sibling ) {
+            if ( node.isRoot() ) {
+                JOptionPane.showMessageDialog( this,
+                                               "Cannot paste sibling to root",
+                                               "Attempt to paste sibling to root",
+                                               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 ) );
-    }
-
-    final void setArrowCursor() {
-        setCursor( ARROW_CURSOR );
+        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.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( getPartAfterColon( p.getRef() ) );
+            sb.append( "=" );
+            sb.append( p.getValue() );
+            if ( !ForesterUtil.isEmpty( p.getUnit() ) ) {
+                sb.append( getPartAfterColon( p.getUnit() ) );
+            }
+        }
+        return sb;
     }
 
     final private void setCopiedAndPastedNodes( final Set<Integer> nodeIds ) {
     }
 
     final private void setCopiedAndPastedNodes( final Set<Integer> nodeIds ) {
@@ -4107,42 +4868,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         getMainPanel().setCutOrCopiedTree( cut_or_copied_tree );
     }
 
         getMainPanel().setCutOrCopiedTree( cut_or_copied_tree );
     }
 
-    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;
     }
@@ -4151,10 +4880,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;
     }
@@ -4176,141 +4901,15 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     }
 
     final private void setOvYStart( final int ov_y_start ) {
     }
 
     final private void setOvYStart( final int ov_y_start ) {
-        _ov_y_start = ov_y_start;
-    }
-
-    /**
-     * Set parameters for printing the displayed tree
-     * 
-     * @param x
-     * @param y
-     */
-    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 setScaleLabel( final String 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 );
-            }
-        }
-        if ( getMainPanel().getOptions().isAntialiasScreen() ) {
-            if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR ) {
-                _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 {
-            _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();
+        _ov_y_start = ov_y_start;
     }
 
     }
 
-    /**
-     * Set a phylogeny tree.
-     * 
-     * @param t
-     *            an instance of a Phylogeny
-     */
-    final void setTree( final Phylogeny t ) {
-        _phylogeny = t;
+    final private void setScaleDistance( final double scale_distance ) {
+        _scale_distance = scale_distance;
     }
 
     }
 
-    final void setTreeFile( final File treefile ) {
-        _treefile = treefile;
+    final private void setScaleLabel( final String scale_label ) {
+        _scale_label = scale_label;
     }
 
     final private void setUpUrtFactor() {
     }
 
     final private void setUpUrtFactor() {
@@ -4339,21 +4938,96 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         _urt_factor_ov = urt_factor_ov;
     }
 
         _urt_factor_ov = urt_factor_ov;
     }
 
-    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>();
+        for( final PhylogenyNode n : node.getAllExternalDescendants() ) {
+            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 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_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_CODE:
+                    if ( n.getNodeData().isHasTaxonomy()
+                            && !ForesterUtil.isEmpty( n.getNodeData().getTaxonomy().getTaxonomyCode() ) ) {
+                        data.add( n.getNodeData().getTaxonomy().getTaxonomyCode() );
+                    }
+                    break;
+                case UNKNOWN:
+                    AptxUtil.showExtDescNodeDataUserSelectedHelper( getControlPanel(), n, data );
+                    break;
+                default:
+                    throw new IllegalArgumentException( "unknown data element: "
+                            + getOptions().getExtDescNodeDataToReturn() );
+            }
+        } // for loop
+        if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.CONSOLE ) {
+            for( final String d : data ) {
+                if ( !ForesterUtil.isEmpty( d ) ) {
+                    System.out.println( d );
+                }
+            }
+        }
+        else if ( getConfiguration().getExtNodeDataReturnOn() == EXT_NODE_DATA_RETURN_ON.WINODW ) {
+            final StringBuilder sb = new StringBuilder();
+            for( final String d : data ) {
+                if ( !ForesterUtil.isEmpty( d ) ) {
+                    sb.append( d );
+                    sb.append( "\n" );
+                }
+            }
+            if ( sb.length() < 1 ) {
+                AptxUtil.showInformationMessage( this,
+                                                 "No Appropriate Data (" + obtainTitleForExtDescNodeData() + ")",
+                                                 "Descendants of selected node do not contain selected data" );
+            }
+            else {
+                final String title = "External Descendants "
+                        + ( getOptions().getExtDescNodeDataToReturn() == NODE_DATA.UNKNOWN ? "Data"
+                                : obtainTitleForExtDescNodeData() ) + " (" + data.size() + "/"
+                        + node.getNumberOfExternalNodes() + ") For Node " + node;
+                if ( getMainPanel().getMainFrame() == null ) {
+                    // Must be "E" applet version.
+                    final ArchaeopteryxE ae = ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet();
+                    final String s = sb.toString().trim();
+                    ae.showTextFrame( s, title );
+                    ae.setCurrentExternalNodesDataBuffer( s );
+                }
+                else {
+                    getMainPanel().getMainFrame().showTextFrame( sb.toString(), title );
+                }
+            }
+        }
     }
 
     final private void showNodeDataPopup( final MouseEvent e, final PhylogenyNode node ) {
     }
 
     final private void showNodeDataPopup( final MouseEvent e, final PhylogenyNode node ) {
@@ -4516,6 +5190,26 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                 .append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( confidence.getValue(),
                                                                                           getOptions()
                                                                                                   .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) );
                                 .append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( confidence.getValue(),
                                                                                           getOptions()
                                                                                                   .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) );
+                        if ( confidence.getStandardDeviation() != Confidence.CONFIDENCE_DEFAULT_VALUE ) {
+                            _popup_buffer.append( " (sd=" );
+                            _popup_buffer.append( FORMATTER_CONFIDENCE.format( ForesterUtil.round( confidence
+                                    .getStandardDeviation(), getOptions()
+                                    .getNumberOfDigitsAfterCommaForConfidenceValues() ) ) );
+                            _popup_buffer.append( ")" );
+                        }
+                    }
+                }
+                if ( node.getNodeData().isHasProperties() ) {
+                    final PropertiesMap properties = node.getNodeData().getProperties();
+                    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( "=" );
+                        _popup_buffer.append( p.getValue() );
+                        if ( !ForesterUtil.isEmpty( p.getUnit() ) ) {
+                            _popup_buffer.append( getPartAfterColon( p.getUnit() ) );
+                        }
                     }
                 }
                 if ( _popup_buffer.length() > 0 ) {
                     }
                 }
                 if ( _popup_buffer.length() > 0 ) {
@@ -4573,81 +5267,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;
-        }
-        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() {
-        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() ) {
-            _phylogeny.swapChildren( node );
-        }
-        repaint();
-    }
-
     final private void switchDisplaygetPhylogenyGraphicsType() {
         switch ( getPhylogenyGraphicsType() ) {
             case RECTANGULAR:
     final private void switchDisplaygetPhylogenyGraphicsType() {
         switch ( getPhylogenyGraphicsType() ) {
             case RECTANGULAR:
@@ -4709,103 +5328,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    final void taxColor() {
-        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
-            return;
-        }
-        setWaitCursor();
-        Util.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 int i, final double x, final double y, final Graphics2D g ) {
         g.drawString( String.valueOf( i ), ( int ) ( x + 0.5 ), ( int ) ( y + 0.5 ) );
     }
@@ -4814,6 +5336,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         g.drawString( str, ( int ) ( x + 0.5 ), ( int ) ( y + 0.5 ) );
     }
 
         g.drawString( str, ( int ) ( x + 0.5 ), ( int ) ( y + 0.5 ) );
     }
 
+    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() );
+    }
+
     final private static boolean isSequenceEmpty( final Sequence seq ) {
         return ( seq.getAccession() == null ) && ForesterUtil.isEmpty( seq.getName() )
                 && ForesterUtil.isEmpty( seq.getSymbol() );
     final private static boolean isSequenceEmpty( final Sequence seq ) {
         return ( seq.getAccession() == null ) && ForesterUtil.isEmpty( seq.getName() )
                 && ForesterUtil.isEmpty( seq.getSymbol() );
@@ -4830,12 +5360,21 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 || ( key_code == KeyEvent.VK_EQUALS ) || ( key_code == KeyEvent.VK_SEMICOLON ) || ( key_code == KeyEvent.VK_1 ) );
     }
 
                 || ( 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 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 private class SubtreeColorizationActionListener implements ActionListener {
     }
 
     final private class SubtreeColorizationActionListener implements ActionListener {
@@ -4856,12 +5395,4 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             }
         }
     }
             }
         }
     }
-
-    synchronized void setImageMap( final Hashtable<String, BufferedImage> image_map ) {
-        getMainPanel().setImageMap( image_map );
-    }
-
-    synchronized Hashtable<String, BufferedImage> getImageMap() {
-        return getMainPanel().getImageMap();
-    }
 }
 }