in progress
authorcmzmasek@gmail.com <cmzmasek@gmail.com@ca865154-3058-d1c3-3e42-d8f55a55bdbd>
Thu, 29 Nov 2012 01:40:07 +0000 (01:40 +0000)
committercmzmasek@gmail.com <cmzmasek@gmail.com@ca865154-3058-d1c3-3e42-d8f55a55bdbd>
Thu, 29 Nov 2012 01:40:07 +0000 (01:40 +0000)
forester/java/src/org/forester/archaeopteryx/Configuration.java
forester/java/src/org/forester/archaeopteryx/ControlPanel.java
forester/java/src/org/forester/archaeopteryx/TreePanel.java

index d232fdd..ad38502 100644 (file)
@@ -150,6 +150,7 @@ public final class Configuration {
     final static int                        edit_node_data                                         = 14;
     final static int                        sort_descendents                                       = 15;
     final static int                        get_ext_desc_data                                      = 16;
+    final static int                        select_nodes                                           = 17;
     // ---------------------------
     // Display options for trees
     // ---------------------------
@@ -178,7 +179,7 @@ public final class Configuration {
             { "Open Sequence Web", "display" }, { "Open Taxonomy Web", "display" }, { "Blast", "display" },
             { "Cut Subtree", "display" }, { "Copy Subtree", "display" }, { "Paste Subtree", "display" },
             { "Delete Subtree/Node", "display" }, { "Add New Node", "display" }, { "Edit Node Data", "display" },
-            { "Sort Descendants", "display" }, { "Return", "display" }                            };
+            { "Sort Descendants", "display" }, { "Return", "display" }, { "Select Node(s)", "display" } };
     // This option is selected in the dropdown
     int                                     default_clickto                                        = Configuration.display_node_data;
     // --------------
@@ -415,6 +416,9 @@ public final class Configuration {
         else if ( name.equals( "edit_node_data" ) ) {
             index = Configuration.edit_node_data;
         }
+        else if ( name.equals( "select_nodes" ) ) {
+            index = Configuration.select_nodes;
+        }
         else if ( name.equals( "display_node_popup" ) ) {
             ForesterUtil.printWarningMessage( Constants.PRG_NAME,
                                               "configuration key [display_node_popup] is deprecated" );
index d7df705..1dee33f 100644 (file)
@@ -134,6 +134,7 @@ final class ControlPanel extends JPanel implements ActionListener {
     private int                  _paste_subtree_item;
     private int                  _add_new_node_item;
     private int                  _edit_node_data_item;
+    private int                  _select_nodes_item;
     private int                  _get_ext_desc_data;
     private int                  _blast_item;
     // zooming and quick tree manipulation buttons:
@@ -1195,6 +1196,9 @@ final class ControlPanel extends JPanel implements ActionListener {
         else if ( action == _edit_node_data_item ) {
             setActionWhenNodeClicked( NodeClickAction.EDIT_NODE_DATA );
         }
+        else if ( action == _select_nodes_item ) {
+            setActionWhenNodeClicked( NodeClickAction.SELECT_NODES );
+        }
         else if ( action == _get_ext_desc_data ) {
             setActionWhenNodeClicked( NodeClickAction.GET_EXT_DESC_DATA );
         }
@@ -1483,6 +1487,15 @@ final class ControlPanel extends JPanel implements ActionListener {
                 }
                 cb_index++;
             }
+            if ( _configuration.doDisplayClickToOption( Configuration.select_nodes ) ) {
+                _select_nodes_item = cb_index;
+                addClickToOption( Configuration.select_nodes,
+                                  _configuration.getClickToTitle( Configuration.select_nodes ) );
+                if ( default_option == Configuration.select_nodes ) {
+                    selected_index = cb_index;
+                }
+                cb_index++;
+            }
         }
         // Set default selection and its action
         _click_to_combobox.setSelectedIndex( selected_index );
@@ -2010,6 +2023,7 @@ final class ControlPanel extends JPanel implements ActionListener {
         PASTE_SUBTREE,
         ADD_NEW_NODE,
         EDIT_NODE_DATA,
+        SELECT_NODES,
         SORT_DESCENDENTS,
         GET_EXT_DESC_DATA,
         BLAST;
index 924eae9..fb1316b 100644 (file)
@@ -288,6 +288,26 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 .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(); ) {
@@ -347,220 +367,238 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
-    @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 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 = 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 public MainPanel getMainPanel() {
+        return _main_panel;
     }
 
-    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() );
-        }
+    /**
+     * Get a pointer to the phylogeny 
+     * 
+     * @return a pointer to the phylogeny
+     */
+    public final Phylogeny getPhylogeny() {
+        return _phylogeny;
     }
 
-    final Color getGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node ) {
-        if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
-            return ( PhylogenyMethods.getBranchColorValue( node ) );
+    @Override
+    final public void mouseWheelMoved( final MouseWheelEvent e ) {
+        final int notches = e.getWheelRotation();
+        if ( inOvVirtualRectangle( e ) ) {
+            if ( !isInOvRect() ) {
+                setInOvRect( true );
+                repaint();
+            }
         }
         else {
-            return ( getTreeColorSet().getBranchColor() );
+            if ( isInOvRect() ) {
+                setInOvRect( false );
+                repaint();
+            }
         }
-    }
-
-    final private void blast( final PhylogenyNode node ) {
-        if ( !isCanBlast( node ) ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Insufficient information present",
-                                           "Cannot Blast",
-                                           JOptionPane.INFORMATION_MESSAGE );
-            return;
+        if ( e.isControlDown() ) {
+            if ( notches < 0 ) {
+                getTreeFontSet().increaseFontSize();
+                getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            }
+            else {
+                getTreeFontSet().decreaseFontSize();
+                getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            }
         }
-        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 ( 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 if ( !ForesterUtil.isEmpty( node.getNodeData().getSequence().getMolecularSequence() ) ) {
-                        if ( ForesterUtil.seqIsLikelyToBeAa( node.getNodeData().getSequence().getMolecularSequence() ) ) {
-                            type = 'p';
-                        }
-                        else {
-                            type = 'n';
+                }
+                else {
+                    for( int i = 0; i < notches; ++i ) {
+                        setStartingAngle( ( getStartingAngle() % TWO_PI ) - ANGLE_ROTATION_UNIT );
+                        if ( getStartingAngle() < 0 ) {
+                            setStartingAngle( TWO_PI + getStartingAngle() );
                         }
+                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
                     }
                 }
-                if ( type == '?' ) {
-                    if ( SequenceIdParser.isProtein( query ) ) {
-                        type = 'p';
-                    }
-                    else {
-                        type = 'n';
+            }
+            else {
+                if ( notches < 0 ) {
+                    for( int i = 0; i < ( -notches ); ++i ) {
+                        getControlPanel().zoomInY( Constants.WHEEL_ZOOM_IN_FACTOR );
+                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
                     }
                 }
-                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();
+                else {
+                    for( int i = 0; i < notches; ++i ) {
+                        getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
+                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
                     }
                 }
             }
         }
-    }
-
-    final void calcMaxDepth() {
-        if ( _phylogeny != null ) {
-            _circ_max_depth = PhylogenyMethods.calculateMaxDepth( _phylogeny );
+        else {
+            if ( notches < 0 ) {
+                for( int i = 0; i < ( -notches ); ++i ) {
+                    getControlPanel().zoomInX( Constants.WHEEL_ZOOM_IN_FACTOR,
+                                               Constants.WHEEL_ZOOM_IN_X_CORRECTION_FACTOR );
+                    getControlPanel().zoomInY( Constants.WHEEL_ZOOM_IN_FACTOR );
+                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                }
+            }
+            else {
+                for( int i = 0; i < notches; ++i ) {
+                    getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
+                    getControlPanel().zoomOutX( Constants.WHEEL_ZOOM_OUT_FACTOR,
+                                                Constants.WHEEL_ZOOM_OUT_X_CORRECTION_FACTOR );
+                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
+                }
+            }
         }
+        requestFocus();
+        requestFocusInWindow();
+        requestFocus();
     }
 
-    /**
-     * Calculate the length of the distance between the given node and its
-     * parent.
+    @Override
+    final public void paintComponent( final Graphics g ) {
+        // Dimension currentSize = getSize();
+        //  if ( offscreenImage == null || !currentSize.equals( offscreenDimension ) ) {
+        // call the 'java.awt.Component.createImage(...)' method to get an
+        // image
+        //   offscreenImage = createImage( currentSize.width, currentSize.height );
+        //  offscreenGraphics = offscreenImage.getGraphics();
+        //  offscreenDimension = currentSize;
+        // }
+        // super.paintComponent( g ); //why?
+        //final Graphics2D g2d = ( Graphics2D ) offscreenGraphics;
+        final Graphics2D g2d = ( Graphics2D ) g;
+        g2d.setRenderingHints( _rendering_hints );
+        paintPhylogeny( g2d, false, false, 0, 0, 0, 0 );
+        //g.drawImage( offscreenImage, 0, 0, this );
+    }
+
+    @Override
+    final public int print( final Graphics g, final PageFormat page_format, final int page_index )
+            throws PrinterException {
+        if ( page_index > 0 ) {
+            return ( NO_SUCH_PAGE );
+        }
+        else {
+            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 );
+        }
+    }
+
+    public final void setArrowCursor() {
+        setCursor( ARROW_CURSOR );
+        repaint();
+    }
+
+    public final void setEdited( final boolean edited ) {
+        _edited = edited;
+    }
+
+    public synchronized void setImageMap( final Hashtable<String, BufferedImage> image_map ) {
+        getMainPanel().setImageMap( image_map );
+    }
+
+    /**
+     * 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() {
@@ -644,21 +682,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
-    final private float calculateOvBranchLengthToParent( final PhylogenyNode node, final int factor ) {
-        if ( getControlPanel().isDrawPhylogram() ) {
-            if ( node.getDistanceToParent() < 0.0 ) {
-                return 0.0f;
-            }
-            return ( float ) ( getOvXcorrectionFactor() * node.getDistanceToParent() );
-        }
-        else {
-            if ( ( factor == 0 ) || isNonLinedUpCladogram() ) {
-                return getOvXDistance();
-            }
-            return getOvXDistance() * factor;
-        }
-    }
-
     final void calculateScaleDistance() {
         if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
             return;
@@ -711,13 +734,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         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
      * 
@@ -765,60 +781,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         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 );
-            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 void confColor() {
-        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
-            return;
-        }
-        setWaitCursor();
-        AptxUtil.removeBranchColors( _phylogeny );
-        AptxUtil.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this );
-        _control_panel.setColorBranches( true );
-        if ( _control_panel.getColorBranchesCb() != null ) {
-            _control_panel.getColorBranchesCb().setSelected( true );
-        }
-        setArrowCursor();
-        repaint();
-    }
-
     final void colorRank( final String rank ) {
         if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
             return;
@@ -864,228 +826,25 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
-    final private void copySubtree( final PhylogenyNode node ) {
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            errorMessageNoCutCopyPasteInUnrootedDisplay();
+    final void confColor() {
+        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
             return;
         }
-        setNodeInPreorderToNull();
-        setCutOrCopiedTree( _phylogeny.copy( node ) );
-        final List<PhylogenyNode> nodes = PhylogenyMethods.getAllDescendants( node );
-        final Set<Integer> node_ids = new HashSet<Integer>( nodes.size() );
-        for( final PhylogenyNode n : nodes ) {
-            node_ids.add( n.getId() );
+        setWaitCursor();
+        AptxUtil.removeBranchColors( _phylogeny );
+        AptxUtil.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this );
+        _control_panel.setColorBranches( true );
+        if ( _control_panel.getColorBranchesCb() != null ) {
+            _control_panel.getColorBranchesCb().setSelected( true );
         }
-        node_ids.add( node.getId() );
-        setCopiedAndPastedNodes( node_ids );
+        setArrowCursor();
         repaint();
     }
 
-    final private void cutSubtree( final PhylogenyNode node ) {
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            errorMessageNoCutCopyPasteInUnrootedDisplay();
-            return;
+    final void decreaseDomainStructureEvalueThreshold() {
+        if ( _domain_structure_e_value_thr_exp > -20 ) {
+            _domain_structure_e_value_thr_exp -= 1;
         }
-        if ( node.isRoot() ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot cut entire tree as subtree",
-                                           "Attempt to cut entire tree",
-                                           JOptionPane.ERROR_MESSAGE );
-            return;
-        }
-        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 void decreaseDomainStructureEvalueThreshold() {
-        if ( _domain_structure_e_value_thr_exp > -20 ) {
-            _domain_structure_e_value_thr_exp -= 1;
-        }
-    }
-
-    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 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 );
-        }
-    }
-
-    final private void drawOvalGradient( final double x,
-                                         final double y,
-                                         final double width,
-                                         final double heigth,
-                                         final Graphics2D g,
-                                         final Color color_1,
-                                         final Color color_2,
-                                         final Color color_border ) {
-        _ellipse.setFrame( x, y, width, heigth );
-        g.setPaint( new GradientPaint( ( float ) x,
-                                       ( float ) y,
-                                       color_1,
-                                       ( float ) ( x + width ),
-                                       ( float ) ( y + heigth ),
-                                       color_2,
-                                       false ) );
-        g.fill( _ellipse );
-        if ( color_border != null ) {
-            g.setPaint( color_border );
-            g.draw( _ellipse );
-        }
-    }
-
-    final private void errorMessageNoCutCopyPasteInUnrootedDisplay() {
-        JOptionPane.showMessageDialog( this,
-                                       "Cannot cut, copy, paste, add, or delete subtrees/nodes in unrooted display",
-                                       "Attempt to cut/copy/paste/add/delete in unrooted display",
-                                       JOptionPane.ERROR_MESSAGE );
     }
 
     /**
@@ -1113,24 +872,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         return null;
     }
 
-    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 Configuration getConfiguration() {
         return _configuration;
     }
@@ -1139,14 +880,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         return _control_panel;
     }
 
-    final private Set<Integer> getCopiedAndPastedNodes() {
-        return getMainPanel().getCopiedAndPastedNodes();
-    }
-
-    final private Phylogeny getCutOrCopiedTree() {
-        return getMainPanel().getCutOrCopiedTree();
-    }
-
     final int getDomainStructureEvalueThreshold() {
         return _domain_structure_e_value_thr_exp;
     }
@@ -1155,38 +888,17 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         return _found_nodes;
     }
 
-    final private float getLastDragPointX() {
-        return _last_drag_point_x;
-    }
-
-    final private float getLastDragPointY() {
-        return _last_drag_point_y;
-    }
-
-    final int getLongestExtNodeInfo() {
-        return _longest_ext_node_info;
-    }
-
-    final public MainPanel getMainPanel() {
-        return _main_panel;
-    }
-
-    final private short getMaxBranchesToLeaf( final PhylogenyNode node ) {
-        if ( !_nodeid_dist_to_leaf.containsKey( node.getId() ) ) {
-            final short m = PhylogenyMethods.calculateMaxBranchesToLeaf( node );
-            _nodeid_dist_to_leaf.put( node.getId(), m );
-            return m;
+    final Color getGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node ) {
+        if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
+            return ( PhylogenyMethods.getBranchColorValue( node ) );
         }
         else {
-            return _nodeid_dist_to_leaf.get( node.getId() );
+            return ( getTreeColorSet().getBranchColor() );
         }
     }
 
-    final private double getMaxDistanceToRoot() {
-        if ( _max_distance_to_root < 0 ) {
-            recalculateMaxDistanceToRoot();
-        }
-        return _max_distance_to_root;
+    final int getLongestExtNodeInfo() {
+        return _longest_ext_node_info;
     }
 
     final Options getOptions() {
@@ -1196,14 +908,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         return _options;
     }
 
-    final private float getOvMaxHeight() {
-        return _ov_max_height;
-    }
-
-    final private float getOvMaxWidth() {
-        return _ov_max_width;
-    }
-
     final Rectangle2D getOvRectangle() {
         return _ov_rectangle;
     }
@@ -1212,55 +916,18 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         return _ov_virtual_rectangle;
     }
 
-    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;
-    }
-
-    /**
-     * Get a pointer to the phylogeny 
-     * 
-     * @return a pointer to the phylogeny
-     */
-    public final Phylogeny getPhylogeny() {
-        return _phylogeny;
-    }
-
     final PHYLOGENY_GRAPHICS_TYPE getPhylogenyGraphicsType() {
         return _graphics_type;
     }
 
-    final private double getScaleDistance() {
-        return _scale_distance;
-    }
-
-    final private String getScaleLabel() {
-        return _scale_label;
-    }
-
     final double getStartingAngle() {
         return _urt_starting_angle;
     }
 
+    DescriptiveStatistics getStatisticsForExpressionValues() {
+        return _statistics_for_vector_data;
+    }
+
     /**
      * Find a color for this species name.
      * 
@@ -1286,18 +953,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         return _treefile;
     }
 
-    final private TreeFontSet getTreeFontSet() {
-        return getMainPanel().getTreeFontSet();
-    }
-
-    final private float getUrtFactor() {
-        return _urt_factor;
-    }
-
-    final private float getUrtFactorOv() {
-        return _urt_factor_ov;
-    }
-
     final float getXcorrectionFactor() {
         return _x_correction_factor;
     }
@@ -1310,197 +965,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         return _y_distance;
     }
 
-    final private void handleClickToAction( final NodeClickAction action, final PhylogenyNode node ) {
-        switch ( action ) {
-            case SHOW_DATA:
-                showNodeFrame( node );
-                break;
-            case COLLAPSE:
-                collapse( node );
-                break;
-            case REROOT:
-                reRoot( node );
-                break;
-            case SUBTREE:
-                subTree( node );
-                break;
-            case SWAP:
-                swap( node );
-                break;
-            case COLOR_SUBTREE:
-                colorSubtree( node );
-                break;
-            case OPEN_SEQ_WEB:
-                openSeqWeb( node );
-                break;
-            case BLAST:
-                blast( node );
-                break;
-            case OPEN_TAX_WEB:
-                openTaxWeb( node );
-                break;
-            case CUT_SUBTREE:
-                cutSubtree( node );
-                break;
-            case COPY_SUBTREE:
-                copySubtree( node );
-                break;
-            case PASTE_SUBTREE:
-                pasteSubtree( node );
-                break;
-            case DELETE_NODE_OR_SUBTREE:
-                deleteNodeOrSubtree( node );
-                break;
-            case ADD_NEW_NODE:
-                addEmptyNode( node );
-                break;
-            case EDIT_NODE_DATA:
-                showNodeEditFrame( node );
-                break;
-            case SORT_DESCENDENTS:
-                sortDescendants( node );
-                break;
-            case GET_EXT_DESC_DATA:
-                showExtDescNodeData( node );
-                break;
-            default:
-                throw new IllegalArgumentException( "unknown action: " + action );
-        }
-    }
-
-    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 );
-                }
-            }
-        }
-    }
-
-    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 void increaseDomainStructureEvalueThreshold() {
         if ( _domain_structure_e_value_thr_exp < 3 ) {
             _domain_structure_e_value_thr_exp += 1;
         }
     }
 
-    final private void increaseOvSize() {
-        if ( ( getOvMaxWidth() < ( getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect().getWidth() / 2 ) )
-                && ( getOvMaxHeight() < ( getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect()
-                        .getHeight() / 2 ) ) ) {
-            setOvMaxWidth( getOvMaxWidth() + 5 );
-            setOvMaxHeight( getOvMaxHeight() + 5 );
-            updateOvSettings();
-            getControlPanel().displayedPhylogenyMightHaveChanged( false );
-        }
-    }
-
     final void inferCommonPartOfScientificNames() {
         if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
             return;
@@ -1511,25 +981,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         repaint();
     }
 
-    final private void init() {
-        _color_chooser = new JColorChooser();
-        _rollover_popup = new JTextArea();
-        _rollover_popup.setFont( POPUP_FONT );
-        resetNodeIdToDistToLeafMap();
-        setTextAntialias();
-        setTreeFile( null );
-        setEdited( false );
-        initializeOvSettings();
-        setStartingAngle( ( TWO_PI * 3 ) / 4 );
-        final ImageLoader il = new ImageLoader( this );
-        new Thread( il ).start();
-    }
-
-    final private void initializeOvSettings() {
-        setOvMaxHeight( getConfiguration().getOvMaxHeight() );
-        setOvMaxWidth( getConfiguration().getOvMaxWidth() );
-    }
-
     final void initNodeData() {
         if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
             return;
@@ -1583,28 +1034,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 + 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 ) {
-        if ( !node.getNodeData().isHasSequence() && ForesterUtil.isEmpty( node.getName() ) ) {
-            return false;
-        }
-        return Blast.isContainsQueryForBlast( node );
-    }
-
     final boolean isCanCollapse() {
         return ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED );
     }
@@ -1626,37 +1059,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable() );
     }
 
-    final private boolean isCanOpenSeqWeb( final PhylogenyNode node ) {
-        if ( node.getNodeData().isHasSequence()
-                && ( node.getNodeData().getSequence().getAccession() != null )
-                && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().getSource() )
-                && !ForesterUtil.isEmpty( node.getNodeData().getSequence().getAccession().getValue() )
-                && getConfiguration().isHasWebLink( node.getNodeData().getSequence().getAccession().getSource()
-                        .toLowerCase() ) ) {
-            return true;
-        }
-        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;
-        }
-    }
-
     final boolean isCanPaste() {
         return ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) && getOptions().isEditable()
                 && ( getCutOrCopiedTree() != null ) && !getCutOrCopiedTree().isEmpty() );
@@ -1671,43 +1073,18 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 .isRoot() || ( _subtree_index > 0 ) ) );
     }
 
-    final boolean isEdited() {
-        return _edited;
-    }
-
-    final private boolean isInFoundNodes( final PhylogenyNode node ) {
-        return ( ( getFoundNodes() != null ) && getFoundNodes().contains( node.getId() ) );
+    final boolean isCurrentTreeIsSubtree() {
+        return ( _subtree_index > 0 );
     }
 
-    final private boolean isInOv() {
-        return _in_ov;
+    final boolean isEdited() {
+        return _edited;
     }
 
     final boolean isInOvRect() {
         return _in_ov_rect;
     }
 
-    final private boolean isNodeDataInvisible( final PhylogenyNode node ) {
-        int y_dist = 40;
-        if ( getControlPanel().isShowTaxonomyImages() ) {
-            y_dist = 40 + ( int ) getYdistance();
-        }
-        return ( ( node.getYcoord() < ( getVisibleRect().getMinY() - y_dist ) )
-                || ( node.getYcoord() > ( getVisibleRect().getMaxY() + y_dist ) ) || ( ( node.getParent() != null ) && ( node
-                .getParent().getXcoord() > getVisibleRect().getMaxX() ) ) );
-    }
-
-    final private boolean isNodeDataInvisibleUnrootedCirc( final PhylogenyNode node ) {
-        return ( ( node.getYcoord() < ( getVisibleRect().getMinY() - 20 ) )
-                || ( node.getYcoord() > ( getVisibleRect().getMaxY() + 20 ) )
-                || ( node.getXcoord() < ( getVisibleRect().getMinX() - 20 ) ) || ( node.getXcoord() > ( getVisibleRect()
-                .getMaxX() + 20 ) ) );
-    }
-
-    final private boolean isNonLinedUpCladogram() {
-        return getOptions().getCladogramType() == CLADOGRAM_TYPE.NON_LINED_UP;
-    }
-
     final boolean isOvOn() {
         return _ov_on;
     }
@@ -1716,331 +1093,87 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         return _phy_has_branch_lengths;
     }
 
-    final private boolean isUniformBranchLengthsForCladogram() {
-        return getOptions().getCladogramType() == CLADOGRAM_TYPE.TOTAL_NODE_SUM_DEP;
+    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 private void keyPressedCalls( final KeyEvent e ) {
-        if ( isOvOn() && ( getMousePosition() != null ) && ( getMousePosition().getLocation() != null ) ) {
-            if ( inOvVirtualRectangle( getMousePosition().x, getMousePosition().y ) ) {
-                if ( !isInOvRect() ) {
-                    setInOvRect( true );
-                }
-            }
-            else if ( isInOvRect() ) {
-                setInOvRect( false );
+    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 ( 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 ( y < 0 ) {
+                y = 0;
             }
-            else if ( ( e.getKeyCode() == KeyEvent.VK_SUBTRACT ) || ( e.getKeyCode() == KeyEvent.VK_MINUS ) ) {
-                getMainPanel().getTreeFontSet().decreaseFontSize();
-                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            final double max_x = getWidth() - getVisibleRect().width;
+            final double max_y = getHeight() - getVisibleRect().height;
+            if ( x > max_x ) {
+                x = max_x;
             }
-            else if ( plusPressed( e.getKeyCode() ) ) {
-                getMainPanel().getTreeFontSet().increaseFontSize();
-                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            if ( y > max_y ) {
+                y = max_y;
             }
+            getMainPanel().getCurrentScrollPane().getViewport()
+                    .setViewPosition( new Point( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ) ) );
+            setInOvRect( true );
+            repaint();
         }
         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 );
+            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 {
-                    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;
+                    // Check for right mouse button
+                    if ( e.getModifiers() == 4 ) {
+                        displayNodePopupMenu( node, e.getX(), e.getY() );
                     }
                     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 not in _found_nodes, clear _found_nodes
+                        handleClickToAction( _control_panel.getActionWhenNodeClicked(), node );
                     }
-                    repaint();
-                    getMainPanel().getCurrentScrollPane().getViewport().setViewPosition( scroll_position );
                 }
             }
-            else if ( ( e.getKeyCode() == KeyEvent.VK_SUBTRACT ) || ( e.getKeyCode() == KeyEvent.VK_MINUS ) ) {
-                getMainPanel().getControlPanel().zoomOutY( Constants.WHEEL_ZOOM_OUT_FACTOR );
-                getMainPanel().getControlPanel().zoomOutX( Constants.WHEEL_ZOOM_OUT_FACTOR,
-                                                           Constants.WHEEL_ZOOM_OUT_X_CORRECTION_FACTOR );
-                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
-            }
-            else if ( plusPressed( e.getKeyCode() ) ) {
-                getMainPanel().getControlPanel().zoomInX( Constants.WHEEL_ZOOM_IN_FACTOR,
-                                                          Constants.WHEEL_ZOOM_IN_FACTOR );
-                getMainPanel().getControlPanel().zoomInY( Constants.WHEEL_ZOOM_IN_FACTOR );
-                getMainPanel().getControlPanel().displayedPhylogenyMightHaveChanged( false );
-            }
-            else if ( e.getKeyCode() == KeyEvent.VK_S ) {
-                if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
-                        || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
-                    setStartingAngle( ( getStartingAngle() % TWO_PI ) + ANGLE_ROTATION_UNIT );
-                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
-                }
-            }
-            else if ( e.getKeyCode() == KeyEvent.VK_A ) {
-                if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
-                        || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
-                    setStartingAngle( ( getStartingAngle() % TWO_PI ) - ANGLE_ROTATION_UNIT );
-                    if ( getStartingAngle() < 0 ) {
-                        setStartingAngle( TWO_PI + getStartingAngle() );
-                    }
-                    getControlPanel().displayedPhylogenyMightHaveChanged( false );
-                }
-            }
-            else if ( e.getKeyCode() == KeyEvent.VK_D ) {
-                boolean selected = false;
-                if ( getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.HORIZONTAL ) {
-                    getOptions().setNodeLabelDirection( NODE_LABEL_DIRECTION.RADIAL );
-                    selected = true;
-                }
-                else {
-                    getOptions().setNodeLabelDirection( NODE_LABEL_DIRECTION.HORIZONTAL );
-                }
-                if ( getMainPanel().getMainFrame() == null ) {
-                    // Must be "E" applet version.
-                    final ArchaeopteryxE ae = ( ArchaeopteryxE ) ( ( MainPanelApplets ) getMainPanel() ).getApplet();
-                    if ( ae.getlabelDirectionCbmi() != null ) {
-                        ae.getlabelDirectionCbmi().setSelected( selected );
-                    }
-                }
-                else {
-                    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();
-        }
-    }
-
-    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;
-                }
-                _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() && !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 ] );
-        }
-    }
-
-    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 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;
+            else {
+                // no node was clicked
+                _highlight_node = null;
             }
         }
         repaint();
@@ -2147,122 +1280,1848 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             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 );
+            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 void mouseReleasedInBrowserPanel( final MouseEvent e ) {
+        setCursor( ARROW_CURSOR );
+    }
+
+    final void multiplyUrtFactor( final float f ) {
+        _urt_factor *= f;
+    }
+
+    final JApplet obtainApplet() {
+        return ( ( MainPanelApplets ) getMainPanel() ).getApplet();
+    }
+
+    final void paintBranchCircular( final PhylogenyNode p,
+                                    final PhylogenyNode c,
+                                    final Graphics2D g,
+                                    final boolean radial_labels,
+                                    final boolean to_pdf,
+                                    final boolean to_graphics_file ) {
+        final double angle = _urt_nodeid_angle_map.get( c.getId() );
+        final double root_x = _root.getXcoord();
+        final double root_y = _root.getYcoord();
+        final double dx = root_x - p.getXcoord();
+        final double dy = root_y - p.getYcoord();
+        final double parent_radius = Math.sqrt( ( dx * dx ) + ( dy * dy ) );
+        final double arc = ( _urt_nodeid_angle_map.get( p.getId() ) ) - angle;
+        assignGraphicsForBranchWithColorForParentBranch( c, false, g, to_pdf, to_graphics_file );
+        if ( ( c.isFirstChildNode() || c.isLastChildNode() )
+                && ( ( Math.abs( parent_radius * arc ) > 1.5 ) || to_pdf || to_graphics_file ) ) {
+            final double r2 = 2.0 * parent_radius;
+            drawArc( root_x - parent_radius, root_y - parent_radius, r2, r2, ( -angle - arc ), arc, g );
+        }
+        drawLine( c.getXcoord(),
+                  c.getYcoord(),
+                  root_x + ( Math.cos( angle ) * parent_radius ),
+                  root_y + ( Math.sin( angle ) * parent_radius ),
+                  g );
+        paintNodeBox( c.getXcoord(), c.getYcoord(), c, g, to_pdf, to_graphics_file, 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 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 void paintCircularLite( final Phylogeny phy,
+                                  final double starting_angle,
+                                  final int center_x,
+                                  final int center_y,
+                                  final int radius,
+                                  final Graphics2D g ) {
+        final int circ_num_ext_nodes = phy.getNumberOfExternalNodes();
+        _root = phy.getRoot();
+        _root.setXSecondary( center_x );
+        _root.setYSecondary( center_y );
+        double current_angle = starting_angle;
+        for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
+            final PhylogenyNode n = it.next();
+            n.setXSecondary( ( float ) ( center_x + ( radius * Math.cos( current_angle ) ) ) );
+            n.setYSecondary( ( float ) ( center_y + ( radius * Math.sin( current_angle ) ) ) );
+            _urt_nodeid_angle_map.put( n.getId(), current_angle );
+            current_angle += ( TWO_PI / circ_num_ext_nodes );
+        }
+        paintCircularsLite( phy.getRoot(), phy, center_x, center_y, radius, g );
+    }
+
+    final void paintPhylogeny( final Graphics2D g,
+                               final boolean to_pdf,
+                               final boolean to_graphics_file,
+                               final int graphics_file_width,
+                               final int graphics_file_height,
+                               final int graphics_file_x,
+                               final int graphics_file_y ) {
+        if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
+            return;
+        }
+        if ( _control_panel.isShowSequenceRelations() ) {
+            _query_sequence = _control_panel.getSelectedQuerySequence();
+        }
+        // Color the background
+        if ( !to_pdf ) {
+            final Rectangle r = getVisibleRect();
+            if ( !getOptions().isBackgroundColorGradient() || getOptions().isPrintBlackAndWhite() ) {
+                g.setColor( getTreeColorSet().getBackgroundColor() );
+                if ( !to_graphics_file ) {
+                    g.fill( r );
+                }
+                else {
+                    if ( getOptions().isPrintBlackAndWhite() ) {
+                        g.setColor( Color.WHITE );
+                    }
+                    g.fillRect( graphics_file_x, graphics_file_y, graphics_file_width, graphics_file_height );
+                }
+            }
+            else {
+                if ( !to_graphics_file ) {
+                    g.setPaint( new GradientPaint( r.x, r.y, getTreeColorSet().getBackgroundColor(), r.x, r.y
+                            + r.height, getTreeColorSet().getBackgroundColorGradientBottom() ) );
+                    g.fill( r );
+                }
+                else {
+                    g.setPaint( new GradientPaint( graphics_file_x,
+                                                   graphics_file_y,
+                                                   getTreeColorSet().getBackgroundColor(),
+                                                   graphics_file_x,
+                                                   graphics_file_y + graphics_file_height,
+                                                   getTreeColorSet().getBackgroundColorGradientBottom() ) );
+                    g.fillRect( graphics_file_x, graphics_file_y, graphics_file_width, graphics_file_height );
+                }
+            }
+            g.setStroke( new BasicStroke( 1 ) );
+        }
+        else {
+            g.setStroke( new BasicStroke( getOptions().getPrintLineWidth() ) );
+        }
+        if ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
+                && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
+            _external_node_index = 0;
+            // Position starting X of tree
+            if ( !_phylogeny.isRooted() /*|| ( _subtree_index > 0 )*/) {
+                _phylogeny.getRoot().setXcoord( TreePanel.MOVE );
+            }
+            else if ( ( _phylogeny.getRoot().getDistanceToParent() > 0.0 ) && getControlPanel().isDrawPhylogram() ) {
+                _phylogeny.getRoot().setXcoord( ( float ) ( TreePanel.MOVE + ( _phylogeny.getRoot()
+                        .getDistanceToParent() * getXcorrectionFactor() ) ) );
+            }
+            else {
+                _phylogeny.getRoot().setXcoord( TreePanel.MOVE + getXdistance() );
+            }
+            // Position starting Y of tree
+            _phylogeny.getRoot().setYcoord( ( getYdistance() * _phylogeny.getRoot().getNumberOfExternalNodes() )
+                    + ( TreePanel.MOVE / 2.0f ) );
+            final int dynamic_hiding_factor = ( int ) ( getTreeFontSet()._fm_large.getHeight() / ( 1.5 * getYdistance() ) );
+            if ( getControlPanel().isDynamicallyHideData() ) {
+                if ( dynamic_hiding_factor > 1 ) {
+                    getControlPanel().setDynamicHidingIsOn( true );
+                }
+                else {
+                    getControlPanel().setDynamicHidingIsOn( false );
+                }
+            }
+            if ( _nodes_in_preorder == null ) {
+                _nodes_in_preorder = new PhylogenyNode[ _phylogeny.getNodeCount() ];
+                int i = 0;
+                for( final PhylogenyNodeIterator it = _phylogeny.iteratorPreorder(); it.hasNext(); ) {
+                    _nodes_in_preorder[ i++ ] = it.next();
+                }
+            }
+            //final PhylogenyNodeIterator it;
+            //for( it = _phylogeny.iteratorPreorder(); it.hasNext(); ) {
+            //    paintNodeRectangular( g, it.next(), to_pdf, getControlPanel().isDynamicallyHideData()
+            //            && ( dynamic_hiding_factor > 1 ), dynamic_hiding_factor, to_graphics_file );
+            //}
+            for( 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 void recalculateMaxDistanceToRoot() {
+        _max_distance_to_root = PhylogenyMethods.calculateMaxDistanceToRoot( getPhylogeny() );
+    }
+
+    /**
+     * Remove all edit-node frames
+     */
+    final void removeAllEditNodeJFrames() {
+        for( int i = 0; i <= ( TreePanel.MAX_NODE_FRAMES - 1 ); i++ ) {
+            if ( _node_frames[ i ] != null ) {
+                _node_frames[ i ].dispose();
+                _node_frames[ i ] = null;
+            }
+        }
+        _node_frame_index = 0;
+    }
+
+    /**
+     * Remove a node-edit frame.
+     */
+    final void removeEditNodeFrame( final int i ) {
+        _node_frame_index--;
+        _node_frames[ i ] = null;
+        if ( i < _node_frame_index ) {
+            for( int j = 0; j < ( _node_frame_index - 1 ); j++ ) {
+                _node_frames[ j ] = _node_frames[ j + 1 ];
+            }
+            _node_frames[ _node_frame_index ] = null;
+        }
+    }
+
+    final void reRoot( final PhylogenyNode node ) {
+        if ( !getPhylogeny().isRerootable() ) {
+            JOptionPane.showMessageDialog( this,
+                                           "This is not rerootable",
+                                           "Not rerootable",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
+        }
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot reroot in unrooted display type",
+                                           "Attempt to reroot tree in unrooted display",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
+        }
+        getPhylogeny().reRoot( node );
+        getPhylogeny().recalculateNumberOfExternalDescendants( true );
+        resetNodeIdToDistToLeafMap();
+        setNodeInPreorderToNull();
+        resetPreferredSize();
+        getMainPanel().adjustJScrollPane();
+        repaint();
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) {
+            getControlPanel().showWhole();
+        }
+    }
+
+    final void resetNodeIdToDistToLeafMap() {
+        _nodeid_dist_to_leaf = new HashMap<Integer, Short>();
+    }
+
+    final void resetPreferredSize() {
+        if ( ( getPhylogeny() == null ) || getPhylogeny().isEmpty() ) {
+            return;
+        }
+        int x = 0;
+        int y = 0;
+        y = TreePanel.MOVE
+                + ForesterUtil.roundToInt( getYdistance() * getPhylogeny().getRoot().getNumberOfExternalNodes() * 2 );
+        if ( getControlPanel().isDrawPhylogram() ) {
+            x = TreePanel.MOVE
+                    + getLongestExtNodeInfo()
+                    + ForesterUtil
+                            .roundToInt( ( getXcorrectionFactor() * getPhylogeny().getHeight() ) + getXdistance() );
+        }
+        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 void selectNode( final PhylogenyNode node ) {
+        if ( ( getFoundNodes() != null ) && getFoundNodes().contains( node.getId() ) ) {
+            getFoundNodes().remove( node.getId() );
+        }
+        else {
+            if ( getFoundNodes() == null ) {
+                setFoundNodes( new HashSet<Integer>() );
+            }
+            getFoundNodes().add( node.getId() );
+        }
+    }
+
+    final void setControlPanel( final ControlPanel atv_control ) {
+        _control_panel = atv_control;
+    }
+
+    final void setFoundNodes( final Set<Integer> found_nodes ) {
+        _found_nodes = found_nodes;
+    }
+
+    final void setInOvRect( final boolean in_ov_rect ) {
+        _in_ov_rect = in_ov_rect;
+    }
+
+    final void setLargeFonts() {
+        getTreeFontSet().largeFonts();
+    }
+
+    final void setLastMouseDragPointX( final float x ) {
+        _last_drag_point_x = x;
+    }
+
+    final void setLastMouseDragPointY( final float y ) {
+        _last_drag_point_y = y;
+    }
+
+    final void setLongestExtNodeInfo( final int i ) {
+        _longest_ext_node_info = i;
+    }
+
+    final void setMediumFonts() {
+        getTreeFontSet().mediumFonts();
+    }
+
+    final void setNodeInPreorderToNull() {
+        _nodes_in_preorder = null;
+    }
+
+    final void setOvOn( final boolean ov_on ) {
+        _ov_on = ov_on;
+    }
+
+    final void setPhylogenyGraphicsType( final PHYLOGENY_GRAPHICS_TYPE graphics_type ) {
+        _graphics_type = graphics_type;
+        setTextAntialias();
+    }
+
+    final void setSmallFonts() {
+        getTreeFontSet().smallFonts();
+    }
+
+    final void setStartingAngle( final double starting_angle ) {
+        _urt_starting_angle = starting_angle;
+    }
+
+    void setStatisticsForExpressionValues( final DescriptiveStatistics statistics_for_expression_values ) {
+        _statistics_for_vector_data = statistics_for_expression_values;
+    }
+
+    final void setSuperTinyFonts() {
+        getTreeFontSet().superTinyFonts();
+    }
+
+    final void setTextAntialias() {
+        if ( ( _phylogeny != null ) && !_phylogeny.isEmpty() ) {
+            if ( _phylogeny.getNumberOfExternalNodes() <= LIMIT_FOR_HQ_RENDERING ) {
+                _rendering_hints.put( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY );
+            }
+            else {
+                _rendering_hints.put( RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED );
+            }
+        }
+        if ( getMainPanel().getOptions().isAntialiasScreen() ) {
+            if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR )
+                    && !getMainPanel().getOptions().isShowDefaultNodeShapes()
+                    && ( ( getControlPanel() != null ) && !getControlPanel().isShowDomainArchitectures() ) ) {
+                _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
+            }
+            else {
+                _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
+            }
+            try {
+                _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING,
+                                      RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB );
+            }
+            catch ( final Throwable e ) {
+                _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
+            }
+        }
+        else {
+            _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 ( getControlPanel().isShowNodeNames() ) {
+                    pri = DESCENDANT_SORT_PRIORITY.NODE_NAME;
+                }
+            }
+            PhylogenyMethods.sortNodeDescendents( node, pri );
+            setNodeInPreorderToNull();
+            _phylogeny.externalNodesHaveChanged();
+            _phylogeny.clearHashIdToNodeMap();
+            _phylogeny.recalculateNumberOfExternalDescendants( true );
+            resetNodeIdToDistToLeafMap();
+            setEdited( true );
+        }
+        repaint();
+    }
+
+    final void subTree( final PhylogenyNode node ) {
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot get a sub/super tree in unrooted display",
+                                           "Attempt to get sub/super tree in unrooted display",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
+        }
+        if ( node.isExternal() ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot get a subtree of a external node",
+                                           "Attempt to get subtree of external node",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
+        }
+        if ( node.isRoot() && !isCurrentTreeIsSubtree() ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot get a subtree of the root node",
+                                           "Attempt to get subtree of root node",
+                                           JOptionPane.WARNING_MESSAGE );
+            return;
+        }
+        setNodeInPreorderToNull();
+        if ( !node.isExternal() && !node.isRoot() && ( _subtree_index <= ( TreePanel.MAX_SUBTREES - 1 ) ) ) {
+            _sub_phylogenies[ _subtree_index ] = _phylogeny;
+            _sub_phylogenies_temp_roots[ _subtree_index ] = node;
+            ++_subtree_index;
+            _phylogeny = subTree( node, _phylogeny );
+            updateSubSuperTreeButton();
+        }
+        else if ( node.isRoot() && isCurrentTreeIsSubtree() ) {
+            superTree();
+        }
+        _main_panel.getControlPanel().showWhole();
+        repaint();
+    }
+
+    final void superTree() {
+        setNodeInPreorderToNull();
+        final PhylogenyNode temp_root = _sub_phylogenies_temp_roots[ _subtree_index - 1 ];
+        for( final PhylogenyNode n : temp_root.getDescendants() ) {
+            n.setParent( temp_root );
+        }
+        _sub_phylogenies[ _subtree_index ] = null;
+        _sub_phylogenies_temp_roots[ _subtree_index ] = null;
+        _phylogeny = _sub_phylogenies[ --_subtree_index ];
+        updateSubSuperTreeButton();
+    }
+
+    final void swap( final PhylogenyNode node ) {
+        if ( node.isExternal() || ( node.getNumberOfDescendants() < 2 ) ) {
+            return;
+        }
+        if ( node.getNumberOfDescendants() > 2 ) {
+            JOptionPane.showMessageDialog( this,
+                                           "Cannot swap descendants of nodes with more than 2 descendants",
+                                           "Cannot swap descendants",
+                                           JOptionPane.ERROR_MESSAGE );
+            return;
+        }
+        if ( !node.isExternal() ) {
+            node.swapChildren();
+            setNodeInPreorderToNull();
+            _phylogeny.externalNodesHaveChanged();
+            _phylogeny.clearHashIdToNodeMap();
+            _phylogeny.recalculateNumberOfExternalDescendants( true );
+            resetNodeIdToDistToLeafMap();
+            setEdited( true );
+        }
+        repaint();
+    }
+
+    final void taxColor() {
+        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
+            return;
+        }
+        setWaitCursor();
+        AptxUtil.colorPhylogenyAccordingToExternalTaxonomy( _phylogeny, this );
+        _control_panel.setColorBranches( true );
+        if ( _control_panel.getColorBranchesCb() != null ) {
+            _control_panel.getColorBranchesCb().setSelected( true );
+        }
+        setArrowCursor();
+        repaint();
+    }
+
+    final void updateOvSettings() {
+        switch ( getOptions().getOvPlacement() ) {
+            case LOWER_LEFT:
+                setOvXPosition( OV_BORDER );
+                setOvYPosition( ForesterUtil.roundToInt( getVisibleRect().height - OV_BORDER - getOvMaxHeight() ) );
+                setOvYStart( ForesterUtil.roundToInt( getOvYPosition() + ( getOvMaxHeight() / 2 ) ) );
+                break;
+            case LOWER_RIGHT:
+                setOvXPosition( ForesterUtil.roundToInt( getVisibleRect().width - OV_BORDER - getOvMaxWidth() ) );
+                setOvYPosition( ForesterUtil.roundToInt( getVisibleRect().height - OV_BORDER - getOvMaxHeight() ) );
+                setOvYStart( ForesterUtil.roundToInt( getOvYPosition() + ( getOvMaxHeight() / 2 ) ) );
+                break;
+            case UPPER_RIGHT:
+                setOvXPosition( ForesterUtil.roundToInt( getVisibleRect().width - OV_BORDER - getOvMaxWidth() ) );
+                setOvYPosition( OV_BORDER );
+                setOvYStart( ForesterUtil.roundToInt( OV_BORDER + ( getOvMaxHeight() / 2 ) ) );
+                break;
+            default:
+                setOvXPosition( OV_BORDER );
+                setOvYPosition( OV_BORDER );
+                setOvYStart( ForesterUtil.roundToInt( OV_BORDER + ( getOvMaxHeight() / 2 ) ) );
+                break;
+        }
+    }
+
+    final void updateOvSizes() {
+        if ( ( getWidth() > ( 1.05 * getVisibleRect().width ) ) || ( getHeight() > ( 1.05 * getVisibleRect().height ) ) ) {
+            setOvOn( true );
+            float l = getLongestExtNodeInfo();
+            final float w_ratio = getOvMaxWidth() / getWidth();
+            l *= w_ratio;
+            final int ext_nodes = _phylogeny.getRoot().getNumberOfExternalNodes();
+            setOvYDistance( getOvMaxHeight() / ( 2 * ext_nodes ) );
+            float ov_xdist = 0;
+            if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) {
+                ov_xdist = ( ( getOvMaxWidth() - l ) / ( ext_nodes ) );
+            }
+            else {
+                ov_xdist = ( ( getOvMaxWidth() - l ) / ( PhylogenyMethods.calculateMaxDepth( _phylogeny ) ) );
+            }
+            float ydist = ( float ) ( ( getOvMaxWidth() / ( ext_nodes * 2.0 ) ) );
+            if ( ov_xdist < 0.0 ) {
+                ov_xdist = 0.0f;
+            }
+            if ( ydist < 0.0 ) {
+                ydist = 0.0f;
+            }
+            setOvXDistance( ov_xdist );
+            final double height = _phylogeny.getHeight();
+            if ( height > 0 ) {
+                final float ov_corr = ( float ) ( ( ( getOvMaxWidth() - l ) - getOvXDistance() ) / height );
+                setOvXcorrectionFactor( ov_corr > 0 ? ov_corr : 0 );
+            }
+            else {
+                setOvXcorrectionFactor( 0 );
+            }
+        }
+        else {
+            setOvOn( false );
+        }
+    }
+
+    void updateSetOfCollapsedExternalNodes() {
+        final Phylogeny phy = getPhylogeny();
+        _collapsed_external_nodeid_set.clear();
+        if ( phy != null ) {
+            E: for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
+                final PhylogenyNode ext_node = it.next();
+                PhylogenyNode n = ext_node;
+                while ( !n.isRoot() ) {
+                    if ( n.isCollapse() ) {
+                        _collapsed_external_nodeid_set.add( ext_node.getId() );
+                        ext_node.setCollapse( true );
+                        continue E;
+                    }
+                    n = n.getParent();
+                }
+            }
+        }
+    }
+
+    final void updateSubSuperTreeButton() {
+        if ( _subtree_index < 1 ) {
+            getControlPanel().deactivateButtonToReturnToSuperTree();
+        }
+        else {
+            getControlPanel().activateButtonToReturnToSuperTree( _subtree_index );
+        }
+    }
+
+    final void zoomInDomainStructure() {
+        if ( _domain_structure_width < 2000 ) {
+            _domain_structure_width *= 1.2;
+        }
+    }
+
+    final void zoomOutDomainStructure() {
+        if ( _domain_structure_width > 20 ) {
+            _domain_structure_width *= 0.8;
+        }
+    }
+
+    private void abbreviateScientificName( final String sn ) {
+        final String[] a = sn.split( "\\s+" );
+        _sb.append( a[ 0 ].substring( 0, 1 ) );
+        _sb.append( a[ 1 ].substring( 0, 2 ) );
+        if ( a.length > 2 ) {
+            for( int i = 2; i < a.length; i++ ) {
+                _sb.append( " " );
+                _sb.append( a[ i ] );
+            }
+        }
+    }
+
+    final private void addEmptyNode( final PhylogenyNode node ) {
+        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
+            errorMessageNoCutCopyPasteInUnrootedDisplay();
+            return;
+        }
+        final String label = createASimpleTextRepresentationOfANode( node );
+        String msg = "";
+        if ( ForesterUtil.isEmpty( label ) ) {
+            msg = "How to add the new, empty node?";
+        }
+        else {
+            msg = "How to add the new, empty node to node" + label + "?";
+        }
+        final Object[] options = { "As sibling", "As descendant", "Cancel" };
+        final int r = JOptionPane.showOptionDialog( this,
+                                                    msg,
+                                                    "Addition of Empty New Node",
+                                                    JOptionPane.CLOSED_OPTION,
+                                                    JOptionPane.QUESTION_MESSAGE,
+                                                    null,
+                                                    options,
+                                                    options[ 2 ] );
+        boolean add_as_sibling = true;
+        if ( r == 1 ) {
+            add_as_sibling = false;
+        }
+        else if ( r != 0 ) {
+            return;
+        }
+        final Phylogeny phy = new Phylogeny();
+        phy.setRoot( new PhylogenyNode() );
+        phy.setRooted( true );
+        if ( add_as_sibling ) {
+            if ( node.isRoot() ) {
+                JOptionPane.showMessageDialog( this,
+                                               "Cannot add sibling to root",
+                                               "Attempt to add sibling to root",
+                                               JOptionPane.ERROR_MESSAGE );
+                return;
+            }
+            phy.addAsSibling( node );
+        }
+        else {
+            phy.addAsChild( node );
+        }
+        setNodeInPreorderToNull();
+        _phylogeny.externalNodesHaveChanged();
+        _phylogeny.clearHashIdToNodeMap();
+        _phylogeny.recalculateNumberOfExternalDescendants( true );
+        resetNodeIdToDistToLeafMap();
+        setEdited( true );
+        repaint();
+    }
+
+    final private void 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';
+                        }
+                    }
+                }
+                if ( type == '?' ) {
+                    if ( SequenceIdParser.isProtein( query ) ) {
+                        type = 'p';
+                    }
+                    else {
+                        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 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();
+            }
+        }
+        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;
+                    }
+                }
+            }
+        }
+        return offset;
+    }
+
+    final private void errorMessageNoCutCopyPasteInUnrootedDisplay() {
+        JOptionPane.showMessageDialog( this,
+                                       "Cannot cut, copy, paste, add, or delete subtrees/nodes in unrooted display",
+                                       "Attempt to cut/copy/paste/add/delete in unrooted display",
+                                       JOptionPane.ERROR_MESSAGE );
+    }
+
+    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 {
+            return _nodeid_dist_to_leaf.get( node.getId() );
+        }
+    }
+
+    final private double getMaxDistanceToRoot() {
+        if ( _max_distance_to_root < 0 ) {
+            recalculateMaxDistanceToRoot();
+        }
+        return _max_distance_to_root;
+    }
+
+    final private float getOvMaxHeight() {
+        return _ov_max_height;
+    }
+
+    final private float getOvMaxWidth() {
+        return _ov_max_width;
+    }
+
+    final private float getOvXcorrectionFactor() {
+        return _ov_x_correction_factor;
+    }
+
+    final private float getOvXDistance() {
+        return _ov_x_distance;
+    }
+
+    final private int getOvXPosition() {
+        return _ov_x_position;
+    }
+
+    final private float getOvYDistance() {
+        return _ov_y_distance;
+    }
+
+    final private int getOvYPosition() {
+        return _ov_y_position;
+    }
+
+    final private int getOvYStart() {
+        return _ov_y_start;
+    }
+
+    final private 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 );
+        }
+    }
+
+    final private void increaseOvSize() {
+        if ( ( getOvMaxWidth() < ( getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect().getWidth() / 2 ) )
+                && ( getOvMaxHeight() < ( getMainPanel().getCurrentScrollPane().getViewport().getVisibleRect()
+                        .getHeight() / 2 ) ) ) {
+            setOvMaxWidth( getOvMaxWidth() + 5 );
+            setOvMaxHeight( getOvMaxHeight() + 5 );
+            updateOvSettings();
+            getControlPanel().displayedPhylogenyMightHaveChanged( false );
+        }
+    }
+
+    final private void init() {
+        _color_chooser = new JColorChooser();
+        _rollover_popup = new JTextArea();
+        _rollover_popup.setFont( POPUP_FONT );
+        resetNodeIdToDistToLeafMap();
+        setTextAntialias();
+        setTreeFile( null );
+        setEdited( false );
+        initializeOvSettings();
+        setStartingAngle( ( TWO_PI * 3 ) / 4 );
+        final ImageLoader il = new ImageLoader( this );
+        new Thread( il ).start();
+    }
+
+    final private void initializeOvSettings() {
+        setOvMaxHeight( getConfiguration().getOvMaxHeight() );
+        setOvMaxWidth( getConfiguration().getOvMaxWidth() );
+    }
+
+    final private boolean inOvVirtualRectangle( final int x, final int y ) {
+        return ( ( x >= ( getOvVirtualRectangle().x - 1 ) )
+                && ( x <= ( getOvVirtualRectangle().x + getOvVirtualRectangle().width + 1 ) )
+                && ( y >= ( getOvVirtualRectangle().y - 1 ) ) && ( y <= ( getOvVirtualRectangle().y
+                + getOvVirtualRectangle().height + 1 ) ) );
+    }
+
+    final private boolean inOvVirtualRectangle( final MouseEvent e ) {
+        return ( inOvVirtualRectangle( e.getX(), e.getY() ) );
+    }
+
+    final private boolean isCanBlast( final PhylogenyNode node ) {
+        if ( !node.getNodeData().isHasSequence() && ForesterUtil.isEmpty( node.getName() ) ) {
+            return false;
+        }
+        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;
+        }
+        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;
+        }
+    }
+
+    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();
+        }
+        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 );
+                }
+            }
+            else if ( isInOvRect() ) {
+                setInOvRect( false );
+            }
+        }
+        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 {
+            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 );
+                }
+            }
+            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 {
-                    setCursor( HAND_CURSOR );
-                    if ( getControlPanel().isNodeDescPopup() ) {
-                        showNodeDataPopup( e, node );
+                    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 {
-                setCursor( ARROW_CURSOR );
+            else if ( e.getKeyCode() == KeyEvent.VK_X ) {
+                switchDisplaygetPhylogenyGraphicsType();
+                repaint();
             }
-        }
-    }
-
-    final void mouseReleasedInBrowserPanel( final MouseEvent e ) {
-        setCursor( ARROW_CURSOR );
-    }
-
-    @Override
-    final public void mouseWheelMoved( final MouseWheelEvent e ) {
-        final int notches = e.getWheelRotation();
-        if ( inOvVirtualRectangle( e ) ) {
-            if ( !isInOvRect() ) {
-                setInOvRect( true );
+            else if ( e.getKeyCode() == KeyEvent.VK_C ) {
+                cycleColors();
                 repaint();
             }
-        }
-        else {
-            if ( isInOvRect() ) {
-                setInOvRect( false );
+            else if ( getOptions().isShowOverview() && isOvOn() && ( e.getKeyCode() == KeyEvent.VK_O ) ) {
+                MainFrame.cycleOverview( getOptions(), this );
                 repaint();
             }
-        }
-        if ( e.isControlDown() ) {
-            if ( notches < 0 ) {
-                getTreeFontSet().increaseFontSize();
-                getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            else if ( getOptions().isShowOverview() && isOvOn() && ( e.getKeyCode() == KeyEvent.VK_I ) ) {
+                increaseOvSize();
             }
-            else {
-                getTreeFontSet().decreaseFontSize();
-                getControlPanel().displayedPhylogenyMightHaveChanged( true );
+            else if ( getOptions().isShowOverview() && isOvOn() && ( e.getKeyCode() == KeyEvent.VK_U ) ) {
+                decreaseOvSize();
             }
+            e.consume();
         }
-        else if ( e.isShiftDown() ) {
-            if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
-                    || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
-                if ( notches < 0 ) {
-                    for( int i = 0; i < ( -notches ); ++i ) {
-                        setStartingAngle( ( getStartingAngle() % TWO_PI ) + ANGLE_ROTATION_UNIT );
-                        getControlPanel().displayedPhylogenyMightHaveChanged( false );
-                    }
+    }
+
+    final private void makePopupMenus( final PhylogenyNode node ) {
+        _node_popup_menu = new JPopupMenu();
+        final List<String> clickto_names = _main_panel.getControlPanel().getSingleClickToNames();
+        _node_popup_menu_items = new JMenuItem[ clickto_names.size() ];
+        for( int i = 0; i < clickto_names.size(); i++ ) {
+            final String title = clickto_names.get( i );
+            _node_popup_menu_items[ i ] = new JMenuItem( title );
+            if ( title.equals( Configuration.clickto_options[ Configuration.open_seq_web ][ 0 ] ) ) {
+                _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 ) {
@@ -2372,82 +3231,23 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
         if ( !ForesterUtil.isEmpty( uri_str ) ) {
             try {
-                JApplet applet = null;
-                if ( isApplet() ) {
-                    applet = obtainApplet();
-                }
-                AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_tax" );
-            }
-            catch ( final IOException e ) {
-                AptxUtil.showErrorMessage( this, e.toString() );
-                e.printStackTrace();
-            }
-            catch ( final URISyntaxException e ) {
-                AptxUtil.showErrorMessage( this, e.toString() );
-                e.printStackTrace();
-            }
-        }
-        else {
-            cannotOpenBrowserWarningMessage( "taxonomic" );
-        }
-    }
-
-    final void paintBranchCircular( final PhylogenyNode p,
-                                    final PhylogenyNode c,
-                                    final Graphics2D g,
-                                    final boolean radial_labels,
-                                    final boolean to_pdf,
-                                    final boolean to_graphics_file ) {
-        final double angle = _urt_nodeid_angle_map.get( c.getId() );
-        final double root_x = _root.getXcoord();
-        final double root_y = _root.getYcoord();
-        final double dx = root_x - p.getXcoord();
-        final double dy = root_y - p.getYcoord();
-        final double parent_radius = Math.sqrt( ( dx * dx ) + ( dy * dy ) );
-        final double arc = ( _urt_nodeid_angle_map.get( p.getId() ) ) - angle;
-        assignGraphicsForBranchWithColorForParentBranch( c, false, g, to_pdf, to_graphics_file );
-        if ( ( c.isFirstChildNode() || c.isLastChildNode() )
-                && ( ( Math.abs( parent_radius * arc ) > 1.5 ) || to_pdf || to_graphics_file ) ) {
-            final double r2 = 2.0 * parent_radius;
-            drawArc( root_x - parent_radius, root_y - parent_radius, r2, r2, ( -angle - arc ), arc, g );
-        }
-        drawLine( c.getXcoord(),
-                  c.getYcoord(),
-                  root_x + ( Math.cos( angle ) * parent_radius ),
-                  root_y + ( Math.sin( angle ) * parent_radius ),
-                  g );
-        paintNodeBox( c.getXcoord(), c.getYcoord(), c, g, to_pdf, to_graphics_file, isInFoundNodes( c ) );
-        if ( c.isExternal() ) {
-            final boolean is_in_found_nodes = isInFoundNodes( c );
-            if ( ( _dynamic_hiding_factor > 1 ) && !is_in_found_nodes
-                    && ( ( _urt_nodeid_index_map.get( c.getId() ) % _dynamic_hiding_factor ) != 1 ) ) {
-                return;
+                JApplet applet = null;
+                if ( isApplet() ) {
+                    applet = obtainApplet();
+                }
+                AptxUtil.launchWebBrowser( new URI( uri_str ), isApplet(), applet, "_aptx_tax" );
+            }
+            catch ( final IOException e ) {
+                AptxUtil.showErrorMessage( this, e.toString() );
+                e.printStackTrace();
+            }
+            catch ( final URISyntaxException e ) {
+                AptxUtil.showErrorMessage( this, e.toString() );
+                e.printStackTrace();
             }
-            paintNodeDataUnrootedCirc( g, c, to_pdf, to_graphics_file, radial_labels, 0, is_in_found_nodes );
-        }
-    }
-
-    final void paintBranchCircularLite( final PhylogenyNode p, final PhylogenyNode c, final Graphics2D g ) {
-        final double angle = _urt_nodeid_angle_map.get( c.getId() );
-        final double root_x = _root.getXSecondary();
-        final double root_y = _root.getYSecondary();
-        final double dx = root_x - p.getXSecondary();
-        final double dy = root_y - p.getYSecondary();
-        final double arc = ( _urt_nodeid_angle_map.get( p.getId() ) ) - angle;
-        final double parent_radius = Math.sqrt( ( dx * dx ) + ( dy * dy ) );
-        g.setColor( getTreeColorSet().getOvColor() );
-        if ( ( c.isFirstChildNode() || c.isLastChildNode() ) && ( Math.abs( arc ) > 0.02 ) ) {
-            final double r2 = 2.0 * parent_radius;
-            drawArc( root_x - parent_radius, root_y - parent_radius, r2, r2, ( -angle - arc ), arc, g );
         }
-        drawLine( c.getXSecondary(),
-                  c.getYSecondary(),
-                  root_x + ( Math.cos( angle ) * parent_radius ),
-                  root_y + ( Math.sin( angle ) * parent_radius ),
-                  g );
-        if ( isInFoundNodes( c ) ) {
-            g.setColor( getTreeColorSet().getFoundColor() );
-            drawRectFilled( c.getXSecondary() - 1, c.getYSecondary() - 1, 3, 3, g );
+        else {
+            cannotOpenBrowserWarningMessage( "taxonomic" );
         }
     }
 
@@ -2644,80 +3444,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
-    final void paintCircular( final Phylogeny phy,
-                              final double starting_angle,
-                              final int center_x,
-                              final int center_y,
-                              final int radius,
-                              final Graphics2D g,
-                              final boolean to_pdf,
-                              final boolean to_graphics_file ) {
-        final int circ_num_ext_nodes = phy.getNumberOfExternalNodes() - _collapsed_external_nodeid_set.size();
-        System.out.println( "# collapsed external = " + _collapsed_external_nodeid_set.size() );
-        _root = phy.getRoot();
-        _root.setXcoord( center_x );
-        _root.setYcoord( center_y );
-        final boolean radial_labels = getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL;
-        double current_angle = starting_angle;
-        int i = 0;
-        for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
-            final PhylogenyNode n = it.next();
-            if ( !n.isCollapse() ) {
-                n.setXcoord( ( float ) ( center_x + ( radius * Math.cos( current_angle ) ) ) );
-                n.setYcoord( ( float ) ( center_y + ( radius * Math.sin( current_angle ) ) ) );
-                _urt_nodeid_angle_map.put( n.getId(), current_angle );
-                _urt_nodeid_index_map.put( n.getId(), i++ );
-                current_angle += ( TWO_PI / circ_num_ext_nodes );
-            }
-            else {
-                //TODO remove me
-                System.out.println( "is collapse" + n.getName() );
-            }
-        }
-        paintCirculars( phy.getRoot(), phy, center_x, center_y, radius, radial_labels, g, to_pdf, to_graphics_file );
-        paintNodeBox( _root.getXcoord(), _root.getYcoord(), _root, g, to_pdf, to_graphics_file, isInFoundNodes( _root ) );
-    }
-
-    void updateSetOfCollapsedExternalNodes() {
-        final Phylogeny phy = getPhylogeny();
-        _collapsed_external_nodeid_set.clear();
-        if ( phy != null ) {
-            E: for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
-                final PhylogenyNode ext_node = it.next();
-                PhylogenyNode n = ext_node;
-                while ( !n.isRoot() ) {
-                    if ( n.isCollapse() ) {
-                        _collapsed_external_nodeid_set.add( ext_node.getId() );
-                        ext_node.setCollapse( true );
-                        continue E;
-                    }
-                    n = n.getParent();
-                }
-            }
-        }
-    }
-
-    final void paintCircularLite( final Phylogeny phy,
-                                  final double starting_angle,
-                                  final int center_x,
-                                  final int center_y,
-                                  final int radius,
-                                  final Graphics2D g ) {
-        final int circ_num_ext_nodes = phy.getNumberOfExternalNodes();
-        _root = phy.getRoot();
-        _root.setXSecondary( center_x );
-        _root.setYSecondary( center_y );
-        double current_angle = starting_angle;
-        for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
-            final PhylogenyNode n = it.next();
-            n.setXSecondary( ( float ) ( center_x + ( radius * Math.cos( current_angle ) ) ) );
-            n.setYSecondary( ( float ) ( center_y + ( radius * Math.sin( current_angle ) ) ) );
-            _urt_nodeid_angle_map.put( n.getId(), current_angle );
-            current_angle += ( TWO_PI / circ_num_ext_nodes );
-        }
-        paintCircularsLite( phy.getRoot(), phy, center_x, center_y, radius, g );
-    }
-
     final private double paintCirculars( final PhylogenyNode n,
                                          final Phylogeny phy,
                                          final float center_x,
@@ -2849,29 +3575,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         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,
@@ -3273,131 +3976,52 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 x += getTreeFontSet()._fm_large.stringWidth( _sb.toString() ) + 5;
             }
             final Annotation ann = node.getNodeData().getSequence().getAnnotation( 0 );
-            if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
-                g.setColor( Color.BLACK );
-            }
-            else {
-                g.setColor( calculateColorForAnnotation( ann ) );
-            }
-            final String ann_str = ann.asSimpleText().toString();
-            TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + half_box_size, node.getYcoord()
-                    + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
-            _sb.setLength( 0 );
-            _sb.append( ann_str );
-        }
-        if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR )
-                || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE )
-                || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
-            if ( ( getControlPanel().isShowBinaryCharacters() || getControlPanel().isShowBinaryCharacterCounts() )
-                    && node.getNodeData().isHasBinaryCharacters() ) {
-                if ( _sb.length() > 0 ) {
-                    x += getTreeFontSet()._fm_large.stringWidth( _sb.toString() ) + 5;
-                }
-                if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
-                    g.setColor( Color.BLACK );
-                }
-                else {
-                    g.setColor( getTreeColorSet().getBinaryDomainCombinationsColor() );
-                }
-                if ( getControlPanel().isShowBinaryCharacters() ) {
-                    TreePanel.drawString( node.getNodeData().getBinaryCharacters().getPresentCharactersAsStringBuffer()
-                            .toString(), node.getXcoord() + x + 1 + half_box_size, node.getYcoord()
-                            + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
-                    paintGainedAndLostCharacters( g, node, node.getNodeData().getBinaryCharacters()
-                            .getGainedCharactersAsStringBuffer().toString(), node.getNodeData().getBinaryCharacters()
-                            .getLostCharactersAsStringBuffer().toString() );
-                }
-                else {
-                    TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount(),
-                                          node.getXcoord() + x + 4 + half_box_size,
-                                          node.getYcoord()
-                                                  + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ),
-                                          g );
-                    paintGainedAndLostCharacters( g, node, "+"
-                            + node.getNodeData().getBinaryCharacters().getGainedCount(), "-"
-                            + node.getNodeData().getBinaryCharacters().getLostCount() );
-                }
-            }
-        }
-    }
-
-    private StringBuffer propertiesToString( final PhylogenyNode node ) {
-        final PropertiesMap properties = node.getNodeData().getProperties();
-        final StringBuffer sb = new StringBuffer();
-        boolean first = true;
-        for( final String ref : properties.getPropertyRefs() ) {
-            if ( first ) {
-                first = false;
-            }
-            else {
-                sb.append( " " );
-            }
-            final Property p = properties.getProperty( ref );
-            sb.append( getPartAfterColon( p.getRef() ) );
-            sb.append( "=" );
-            sb.append( p.getValue() );
-            if ( !ForesterUtil.isEmpty( p.getUnit() ) ) {
-                sb.append( getPartAfterColon( p.getUnit() ) );
-            }
-        }
-        return sb;
-    }
-
-    final private static String getPartAfterColon( final String s ) {
-        final int i = s.indexOf( ':' );
-        if ( ( i < 1 ) || ( i == ( s.length() - 1 ) ) ) {
-            return s;
-        }
-        return s.substring( i + 1, s.length() );
-    }
-
-    private double drawTaxonomyImage( final double x, final double y, final PhylogenyNode node, final Graphics2D g ) {
-        final List<Uri> us = new ArrayList<Uri>();
-        for( final Taxonomy t : node.getNodeData().getTaxonomies() ) {
-            for( final Uri uri : t.getUris() ) {
-                us.add( uri );
-            }
-        }
-        double offset = 0;
-        for( final Uri uri : us ) {
-            if ( uri != null ) {
-                final String uri_str = uri.getValue().toString().toLowerCase();
-                if ( getImageMap().containsKey( uri_str ) ) {
-                    final BufferedImage bi = getImageMap().get( uri_str );
-                    if ( ( bi != null ) && ( bi.getHeight() > 5 ) && ( bi.getWidth() > 5 ) ) {
-                        double scaling_factor = 1;
-                        if ( getOptions().isAllowMagnificationOfTaxonomyImages()
-                                || ( bi.getHeight() > ( 1.8 * getYdistance() ) ) ) {
-                            scaling_factor = ( 1.8 * getYdistance() ) / bi.getHeight();
-                        }
-                        // y = y - ( 0.9 * getYdistance() );
-                        final double hs = bi.getHeight() * scaling_factor;
-                        double ws = ( bi.getWidth() * scaling_factor ) + offset;
-                        final double my_y = y - ( 0.5 * hs );
-                        final int x_w = ( int ) ( x + ws + 0.5 );
-                        final int y_h = ( int ) ( my_y + hs + 0.5 );
-                        if ( ( ( x_w - x ) > 7 ) && ( ( y_h - my_y ) > 7 ) ) {
-                            g.drawImage( bi,
-                                         ( int ) ( x + 0.5 + offset ),
-                                         ( int ) ( my_y + 0.5 ),
-                                         x_w,
-                                         y_h,
-                                         0,
-                                         0,
-                                         bi.getWidth(),
-                                         bi.getHeight(),
-                                         null );
-                            ws += 8;
-                        }
-                        else {
-                            ws = 0.0;
-                        }
-                        offset = ws;
-                    }
+            if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
+                g.setColor( Color.BLACK );
+            }
+            else {
+                g.setColor( calculateColorForAnnotation( ann ) );
+            }
+            final String ann_str = ann.asSimpleText().toString();
+            TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + half_box_size, node.getYcoord()
+                    + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
+            _sb.setLength( 0 );
+            _sb.append( ann_str );
+        }
+        if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.RECTANGULAR )
+                || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE )
+                || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
+            if ( ( getControlPanel().isShowBinaryCharacters() || getControlPanel().isShowBinaryCharacterCounts() )
+                    && node.getNodeData().isHasBinaryCharacters() ) {
+                if ( _sb.length() > 0 ) {
+                    x += getTreeFontSet()._fm_large.stringWidth( _sb.toString() ) + 5;
+                }
+                if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
+                    g.setColor( Color.BLACK );
+                }
+                else {
+                    g.setColor( getTreeColorSet().getBinaryDomainCombinationsColor() );
+                }
+                if ( getControlPanel().isShowBinaryCharacters() ) {
+                    TreePanel.drawString( node.getNodeData().getBinaryCharacters().getPresentCharactersAsStringBuffer()
+                            .toString(), node.getXcoord() + x + 1 + half_box_size, node.getYcoord()
+                            + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
+                    paintGainedAndLostCharacters( g, node, node.getNodeData().getBinaryCharacters()
+                            .getGainedCharactersAsStringBuffer().toString(), node.getNodeData().getBinaryCharacters()
+                            .getLostCharactersAsStringBuffer().toString() );
+                }
+                else {
+                    TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount(),
+                                          node.getXcoord() + x + 4 + half_box_size,
+                                          node.getYcoord()
+                                                  + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ),
+                                          g );
+                    paintGainedAndLostCharacters( g, node, "+"
+                            + node.getNodeData().getBinaryCharacters().getGainedCount(), "-"
+                            + node.getNodeData().getBinaryCharacters().getLostCount() );
                 }
             }
         }
-        return offset;
     }
 
     final private void paintNodeDataUnrootedCirc( final Graphics2D g,
@@ -3747,264 +4371,62 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                         x += getTreeFontSet()._fm_large.stringWidth( node.getName() + " " );
                     }
                     rds.render( node.getXcoord() + x, node.getYcoord() - 3, g, this, to_pdf );
-                }
-            }
-        }
-        //////////////
-        if ( getControlPanel().isShowVectorData() && ( node.getNodeData().getVector() != null )
-                && ( node.getNodeData().getVector().size() > 0 ) && ( getStatisticsForExpressionValues() != null ) ) {
-            final RenderableVector rv = RenderableVector.createInstance( node.getNodeData().getVector(),
-                                                                         getStatisticsForExpressionValues(),
-                                                                         getConfiguration() );
-            if ( rv != null ) {
-                int x = 0;
-                PhylogenyNode my_node = node;
-                if ( !getControlPanel().isDrawPhylogram() ) {
-                    my_node = getPhylogeny().getFirstExternalNode();
-                }
-                if ( getControlPanel().isShowTaxonomyCode() && ( PhylogenyMethods.getSpecies( my_node ).length() > 0 ) ) {
-                    x += getTreeFontSet()._fm_large_italic.stringWidth( PhylogenyMethods.getSpecies( my_node ) + " " );
-                }
-                if ( getControlPanel().isShowNodeNames() && ( my_node.getName().length() > 0 ) ) {
-                    x += getTreeFontSet()._fm_large.stringWidth( my_node.getName() + " " );
-                }
-                rv.render( my_node.getXcoord() + x, node.getYcoord() - 5, g, this, to_pdf );
-            }
-        }
-        //////////////
-    }
-
-    final private void paintOvRectangle( final Graphics2D g ) {
-        final float w_ratio = ( float ) getWidth() / getVisibleRect().width;
-        final float h_ratio = ( float ) getHeight() / getVisibleRect().height;
-        final float x_ratio = ( float ) getWidth() / getVisibleRect().x;
-        final float y_ratio = ( float ) getHeight() / getVisibleRect().y;
-        final float width = getOvMaxWidth() / w_ratio;
-        final float height = getOvMaxHeight() / h_ratio;
-        final float x = getVisibleRect().x + getOvXPosition() + ( getOvMaxWidth() / x_ratio );
-        final float y = getVisibleRect().y + getOvYPosition() + ( getOvMaxHeight() / y_ratio );
-        g.setColor( getTreeColorSet().getFoundColor() );
-        getOvRectangle().setRect( x, y, width, height );
-        if ( ( width < 6 ) && ( height < 6 ) ) {
-            drawRectFilled( x, y, 6, 6, g );
-            getOvVirtualRectangle().setRect( x, y, 6, 6 );
-        }
-        else if ( width < 6 ) {
-            drawRectFilled( x, y, 6, height, g );
-            getOvVirtualRectangle().setRect( x, y, 6, height );
-        }
-        else if ( height < 6 ) {
-            drawRectFilled( x, y, width, 6, g );
-            getOvVirtualRectangle().setRect( x, y, width, 6 );
-        }
-        else {
-            drawRect( x, y, width, height, g );
-            if ( isInOvRect() ) {
-                drawRect( x + 1, y + 1, width - 2, height - 2, g );
-            }
-            getOvVirtualRectangle().setRect( x, y, width, height );
-        }
-    }
-
-    final void paintPhylogeny( final Graphics2D g,
-                               final boolean to_pdf,
-                               final boolean to_graphics_file,
-                               final int graphics_file_width,
-                               final int graphics_file_height,
-                               final int graphics_file_x,
-                               final int graphics_file_y ) {
-        if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
-            return;
-        }
-        if ( _control_panel.isShowSequenceRelations() ) {
-            _query_sequence = _control_panel.getSelectedQuerySequence();
-        }
-        // Color the background
-        if ( !to_pdf ) {
-            final Rectangle r = getVisibleRect();
-            if ( !getOptions().isBackgroundColorGradient() || getOptions().isPrintBlackAndWhite() ) {
-                g.setColor( getTreeColorSet().getBackgroundColor() );
-                if ( !to_graphics_file ) {
-                    g.fill( r );
-                }
-                else {
-                    if ( getOptions().isPrintBlackAndWhite() ) {
-                        g.setColor( Color.WHITE );
-                    }
-                    g.fillRect( graphics_file_x, graphics_file_y, graphics_file_width, graphics_file_height );
-                }
-            }
-            else {
-                if ( !to_graphics_file ) {
-                    g.setPaint( new GradientPaint( r.x, r.y, getTreeColorSet().getBackgroundColor(), r.x, r.y
-                            + r.height, getTreeColorSet().getBackgroundColorGradientBottom() ) );
-                    g.fill( r );
-                }
-                else {
-                    g.setPaint( new GradientPaint( graphics_file_x,
-                                                   graphics_file_y,
-                                                   getTreeColorSet().getBackgroundColor(),
-                                                   graphics_file_x,
-                                                   graphics_file_y + graphics_file_height,
-                                                   getTreeColorSet().getBackgroundColorGradientBottom() ) );
-                    g.fillRect( graphics_file_x, graphics_file_y, graphics_file_width, graphics_file_height );
-                }
-            }
-            g.setStroke( new BasicStroke( 1 ) );
-        }
-        else {
-            g.setStroke( new BasicStroke( getOptions().getPrintLineWidth() ) );
-        }
-        if ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.UNROOTED )
-                && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) ) {
-            _external_node_index = 0;
-            // Position starting X of tree
-            if ( !_phylogeny.isRooted() /*|| ( _subtree_index > 0 )*/) {
-                _phylogeny.getRoot().setXcoord( TreePanel.MOVE );
-            }
-            else if ( ( _phylogeny.getRoot().getDistanceToParent() > 0.0 ) && getControlPanel().isDrawPhylogram() ) {
-                _phylogeny.getRoot().setXcoord( ( float ) ( TreePanel.MOVE + ( _phylogeny.getRoot()
-                        .getDistanceToParent() * getXcorrectionFactor() ) ) );
-            }
-            else {
-                _phylogeny.getRoot().setXcoord( TreePanel.MOVE + getXdistance() );
-            }
-            // Position starting Y of tree
-            _phylogeny.getRoot().setYcoord( ( getYdistance() * _phylogeny.getRoot().getNumberOfExternalNodes() )
-                    + ( TreePanel.MOVE / 2.0f ) );
-            final int dynamic_hiding_factor = ( int ) ( getTreeFontSet()._fm_large.getHeight() / ( 1.5 * getYdistance() ) );
-            if ( getControlPanel().isDynamicallyHideData() ) {
-                if ( dynamic_hiding_factor > 1 ) {
-                    getControlPanel().setDynamicHidingIsOn( true );
-                }
-                else {
-                    getControlPanel().setDynamicHidingIsOn( false );
-                }
-            }
-            if ( _nodes_in_preorder == null ) {
-                _nodes_in_preorder = new PhylogenyNode[ _phylogeny.getNodeCount() ];
-                int i = 0;
-                for( final PhylogenyNodeIterator it = _phylogeny.iteratorPreorder(); it.hasNext(); ) {
-                    _nodes_in_preorder[ i++ ] = it.next();
-                }
-            }
-            //final PhylogenyNodeIterator it;
-            //for( it = _phylogeny.iteratorPreorder(); it.hasNext(); ) {
-            //    paintNodeRectangular( g, it.next(), to_pdf, getControlPanel().isDynamicallyHideData()
-            //            && ( dynamic_hiding_factor > 1 ), dynamic_hiding_factor, to_graphics_file );
-            //}
-            for( 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 );
+        //////////////
+        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 );
         }
     }
 
@@ -4186,18 +4608,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,
@@ -4396,166 +4806,38 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         repaint();
     }
 
-    @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 {
-            final Graphics2D g2d = ( Graphics2D ) g;
-            g2d.translate( page_format.getImageableX(), page_format.getImageableY() );
-            // Turn off double buffering !?
-            paintPhylogeny( g2d, true, false, 0, 0, 0, 0 );
-            // Turn double buffering back on !?
-            return ( PAGE_EXISTS );
-        }
-    }
-
-    final void recalculateMaxDistanceToRoot() {
-        _max_distance_to_root = PhylogenyMethods.calculateMaxDistanceToRoot( getPhylogeny() );
-    }
-
-    /**
-     * Remove all edit-node frames
-     */
-    final void removeAllEditNodeJFrames() {
-        for( int i = 0; i <= ( TreePanel.MAX_NODE_FRAMES - 1 ); i++ ) {
-            if ( _node_frames[ i ] != null ) {
-                _node_frames[ i ].dispose();
-                _node_frames[ i ] = null;
-            }
-        }
-        _node_frame_index = 0;
-    }
-
-    /**
-     * Remove a node-edit frame.
-     */
-    final void removeEditNodeFrame( final int i ) {
-        _node_frame_index--;
-        _node_frames[ i ] = null;
-        if ( i < _node_frame_index ) {
-            for( int j = 0; j < ( _node_frame_index - 1 ); j++ ) {
-                _node_frames[ j ] = _node_frames[ j + 1 ];
-            }
-            _node_frames[ _node_frame_index ] = null;
-        }
-    }
-
-    final void reRoot( final PhylogenyNode node ) {
-        if ( !getPhylogeny().isRerootable() ) {
-            JOptionPane.showMessageDialog( this,
-                                           "This is not rerootable",
-                                           "Not rerootable",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
-        }
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot reroot in unrooted display type",
-                                           "Attempt to reroot tree in unrooted display",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
-        }
-        getPhylogeny().reRoot( node );
-        getPhylogeny().recalculateNumberOfExternalDescendants( true );
-        resetNodeIdToDistToLeafMap();
-        setNodeInPreorderToNull();
-        resetPreferredSize();
-        getMainPanel().adjustJScrollPane();
-        repaint();
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.CIRCULAR ) {
-            getControlPanel().showWhole();
-        }
-    }
-
-    final void resetNodeIdToDistToLeafMap() {
-        _nodeid_dist_to_leaf = new HashMap<Integer, Short>();
-    }
-
-    final void resetPreferredSize() {
-        if ( ( getPhylogeny() == null ) || getPhylogeny().isEmpty() ) {
-            return;
-        }
-        int x = 0;
-        int y = 0;
-        y = TreePanel.MOVE
-                + ForesterUtil.roundToInt( getYdistance() * getPhylogeny().getRoot().getNumberOfExternalNodes() * 2 );
-        if ( getControlPanel().isDrawPhylogram() ) {
-            x = TreePanel.MOVE
-                    + getLongestExtNodeInfo()
-                    + ForesterUtil
-                            .roundToInt( ( getXcorrectionFactor() * getPhylogeny().getHeight() ) + getXdistance() );
-        }
-        else {
-            if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) {
-                x = TreePanel.MOVE
-                        + getLongestExtNodeInfo()
-                        + ForesterUtil.roundToInt( getXdistance()
-                                * ( getPhylogeny().getRoot().getNumberOfExternalNodes() + 2 ) );
+    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 {
-                x = TreePanel.MOVE
-                        + getLongestExtNodeInfo()
-                        + ForesterUtil.roundToInt( getXdistance()
-                                * ( PhylogenyMethods.calculateMaxDepth( getPhylogeny() ) + 1 ) );
+                sb.append( " " );
             }
-        }
-        setPreferredSize( new Dimension( x, y ) );
-    }
-
-    public final void setArrowCursor() {
-        setCursor( ARROW_CURSOR );
-        repaint();
-    }
-
-    final void setControlPanel( final ControlPanel atv_control ) {
-        _control_panel = atv_control;
-    }
-
-    final private void setCopiedAndPastedNodes( final Set<Integer> nodeIds ) {
-        getMainPanel().setCopiedAndPastedNodes( nodeIds );
-    }
-
-    final private void setCutOrCopiedTree( final Phylogeny cut_or_copied_tree ) {
-        getMainPanel().setCutOrCopiedTree( cut_or_copied_tree );
-    }
-
-    public final void setEdited( final boolean edited ) {
-        _edited = edited;
-    }
-
-    final void setFoundNodes( final Set<Integer> found_nodes ) {
-        _found_nodes = found_nodes;
-    }
-
-    final private void setInOv( final boolean in_ov ) {
-        _in_ov = in_ov;
-    }
-
-    final 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 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 void setLastMouseDragPointY( final float y ) {
-        _last_drag_point_y = y;
+    final private void setCopiedAndPastedNodes( final Set<Integer> nodeIds ) {
+        getMainPanel().setCopiedAndPastedNodes( nodeIds );
     }
 
-    final void setLongestExtNodeInfo( final int i ) {
-        _longest_ext_node_info = i;
+    final private void setCutOrCopiedTree( final Phylogeny cut_or_copied_tree ) {
+        getMainPanel().setCutOrCopiedTree( cut_or_copied_tree );
     }
 
-    final void setMediumFonts() {
-        getTreeFontSet().mediumFonts();
+    final private void setInOv( final boolean in_ov ) {
+        _in_ov = in_ov;
     }
 
     final private void setOvMaxHeight( final float ov_max_height ) {
@@ -4566,10 +4848,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         _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;
     }
@@ -4594,72 +4872,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         _ov_y_start = ov_y_start;
     }
 
-    /**
-     * Set parameters for printing the displayed tree
-     * 
-     * @param x
-     * @param y
-     */
-    public final void setParametersForPainting( final int x, final int y, final boolean recalc_longest_ext_node_info ) {
-        // updateStyle(); not needed?
-        if ( ( _phylogeny != null ) && !_phylogeny.isEmpty() ) {
-            initNodeData();
-            if ( recalc_longest_ext_node_info ) {
-                calculateLongestExtNodeInfo();
-            }
-            int ext_nodes = _phylogeny.getRoot().getNumberOfExternalNodes();
-            final int max_depth = PhylogenyMethods.calculateMaxDepth( _phylogeny );
-            if ( ext_nodes == 1 ) {
-                ext_nodes = max_depth;
-                if ( ext_nodes < 1 ) {
-                    ext_nodes = 1;
-                }
-            }
-            updateOvSizes();
-            float xdist = 0;
-            float ov_xdist = 0;
-            if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) {
-                xdist = ( float ) ( ( x - getLongestExtNodeInfo() - TreePanel.MOVE ) / ( ext_nodes + 3.0 ) );
-                ov_xdist = ( float ) ( getOvMaxWidth() / ( ext_nodes + 3.0 ) );
-            }
-            else {
-                xdist = ( ( x - getLongestExtNodeInfo() - TreePanel.MOVE ) / ( max_depth + 1 ) );
-                ov_xdist = ( getOvMaxWidth() / ( max_depth + 1 ) );
-            }
-            float ydist = ( float ) ( ( y - TreePanel.MOVE ) / ( ext_nodes * 2.0 ) );
-            if ( xdist < 0.0 ) {
-                xdist = 0.0f;
-            }
-            if ( ov_xdist < 0.0 ) {
-                ov_xdist = 0.0f;
-            }
-            if ( ydist < 0.0 ) {
-                ydist = 0.0f;
-            }
-            setXdistance( xdist );
-            setYdistance( ydist );
-            setOvXDistance( ov_xdist );
-            final double height = _phylogeny.getHeight();
-            if ( height > 0 ) {
-                final float corr = ( float ) ( ( x - TreePanel.MOVE - getLongestExtNodeInfo() - getXdistance() ) / height );
-                setXcorrectionFactor( corr > 0 ? corr : 0 );
-                final float ov_corr = ( float ) ( ( getOvMaxWidth() - getOvXDistance() ) / height );
-                setOvXcorrectionFactor( ov_corr > 0 ? ov_corr : 0 );
-            }
-            else {
-                setXcorrectionFactor( 0 );
-                setOvXcorrectionFactor( 0 );
-            }
-            _circ_max_depth = max_depth;
-            setUpUrtFactor();
-        }
-    }
-
-    final void setPhylogenyGraphicsType( final PHYLOGENY_GRAPHICS_TYPE graphics_type ) {
-        _graphics_type = graphics_type;
-        setTextAntialias();
-    }
-
     final private void setScaleDistance( final double scale_distance ) {
         _scale_distance = scale_distance;
     }
@@ -4668,73 +4880,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         _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 )
-                    && !getMainPanel().getOptions().isShowDefaultNodeShapes()
-                    && ( ( getControlPanel() != null ) && !getControlPanel().isShowDomainArchitectures() ) ) {
-                _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
-            }
-            else {
-                _rendering_hints.put( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
-            }
-            try {
-                _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING,
-                                      RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB );
-            }
-            catch ( final Throwable e ) {
-                _rendering_hints.put( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
-            }
-        }
-        else {
-            _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();
-    }
-
-    /**
-     * Set a phylogeny tree.
-     * 
-     * @param t
-     *            an instance of a Phylogeny
-     */
-    public final void setTree( final Phylogeny t ) {
-        setNodeInPreorderToNull();
-        _phylogeny = t;
-    }
-
-    final void setNodeInPreorderToNull() {
-        _nodes_in_preorder = null;
-    }
-
-    final void setTreeFile( final File treefile ) {
-        _treefile = treefile;
-    }
-
     final private void setUpUrtFactor() {
         final int d = getVisibleRect().width < getVisibleRect().height ? getVisibleRect().width
                 : getVisibleRect().height;
@@ -4761,21 +4906,96 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         _urt_factor_ov = urt_factor_ov;
     }
 
-    public final void setWaitCursor() {
-        setCursor( WAIT_CURSOR );
-        repaint();
-    }
-
-    final void setXcorrectionFactor( final float f ) {
-        _x_correction_factor = f;
-    }
-
-    final void setXdistance( final float x ) {
-        _x_distance = x;
-    }
-
-    final void setYdistance( final float y ) {
-        _y_distance = y;
+    private void showExtDescNodeData( final PhylogenyNode node ) {
+        final List<String> data = new ArrayList<String>();
+        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 ) {
@@ -5015,123 +5235,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
-    final void subTree( final PhylogenyNode node ) {
-        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot get a sub/super tree in unrooted display",
-                                           "Attempt to get sub/super tree in unrooted display",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
-        }
-        if ( node.isExternal() ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot get a subtree of a external node",
-                                           "Attempt to get subtree of external node",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
-        }
-        if ( node.isRoot() && !isCurrentTreeIsSubtree() ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot get a subtree of the root node",
-                                           "Attempt to get subtree of root node",
-                                           JOptionPane.WARNING_MESSAGE );
-            return;
-        }
-        setNodeInPreorderToNull();
-        if ( !node.isExternal() && !node.isRoot() && ( _subtree_index <= ( TreePanel.MAX_SUBTREES - 1 ) ) ) {
-            _sub_phylogenies[ _subtree_index ] = _phylogeny;
-            _sub_phylogenies_temp_roots[ _subtree_index ] = node;
-            ++_subtree_index;
-            _phylogeny = subTree( node, _phylogeny );
-            updateSubSuperTreeButton();
-        }
-        else if ( node.isRoot() && isCurrentTreeIsSubtree() ) {
-            superTree();
-        }
-        _main_panel.getControlPanel().showWhole();
-        repaint();
-    }
-
-    final boolean isCurrentTreeIsSubtree() {
-        return ( _subtree_index > 0 );
-    }
-
-    final private static Phylogeny subTree( final PhylogenyNode new_root, final Phylogeny source_phy ) {
-        final Phylogeny new_phy = new Phylogeny();
-        new_phy.setRooted( true );
-        new_phy.setName( source_phy.getName() );
-        new_phy.setDescription( source_phy.getDescription() );
-        new_phy.setType( source_phy.getType() );
-        new_phy.setDistanceUnit( source_phy.getDistanceUnit() );
-        new_phy.setConfidence( source_phy.getConfidence() );
-        new_phy.setIdentifier( source_phy.getIdentifier() );
-        new_phy.setRoot( new_root.copyNodeDataShallow() );
-        int i = 0;
-        for( final PhylogenyNode n : new_root.getDescendants() ) {
-            new_phy.getRoot().setChildNode( i++, n );
-        }
-        return new_phy;
-    }
-
-    final void superTree() {
-        setNodeInPreorderToNull();
-        final PhylogenyNode temp_root = _sub_phylogenies_temp_roots[ _subtree_index - 1 ];
-        for( final PhylogenyNode n : temp_root.getDescendants() ) {
-            n.setParent( temp_root );
-        }
-        _sub_phylogenies[ _subtree_index ] = null;
-        _sub_phylogenies_temp_roots[ _subtree_index ] = null;
-        _phylogeny = _sub_phylogenies[ --_subtree_index ];
-        updateSubSuperTreeButton();
-    }
-
-    final void swap( final PhylogenyNode node ) {
-        if ( node.isExternal() || ( node.getNumberOfDescendants() < 2 ) ) {
-            return;
-        }
-        if ( node.getNumberOfDescendants() > 2 ) {
-            JOptionPane.showMessageDialog( this,
-                                           "Cannot swap descendants of nodes with more than 2 descendants",
-                                           "Cannot swap descendants",
-                                           JOptionPane.ERROR_MESSAGE );
-            return;
-        }
-        if ( !node.isExternal() ) {
-            node.swapChildren();
-            setNodeInPreorderToNull();
-            _phylogeny.externalNodesHaveChanged();
-            _phylogeny.clearHashIdToNodeMap();
-            _phylogeny.recalculateNumberOfExternalDescendants( true );
-            resetNodeIdToDistToLeafMap();
-            setEdited( true );
-        }
-        repaint();
-    }
-
-    final void sortDescendants( final PhylogenyNode node ) {
-        if ( !node.isExternal() ) {
-            DESCENDANT_SORT_PRIORITY pri = DESCENDANT_SORT_PRIORITY.TAXONOMY;
-            if ( ( !getControlPanel().isShowTaxonomyScientificNames() && !getControlPanel().isShowTaxonomyCode() && !getControlPanel()
-                    .isShowTaxonomyCommonNames() ) ) {
-                if ( ( getControlPanel().isShowSequenceAcc() || getControlPanel().isShowGeneNames() || getControlPanel()
-                        .isShowGeneSymbols() ) ) {
-                    pri = DESCENDANT_SORT_PRIORITY.SEQUENCE;
-                }
-                else if ( getControlPanel().isShowNodeNames() ) {
-                    pri = DESCENDANT_SORT_PRIORITY.NODE_NAME;
-                }
-            }
-            PhylogenyMethods.sortNodeDescendents( node, pri );
-            setNodeInPreorderToNull();
-            _phylogeny.externalNodesHaveChanged();
-            _phylogeny.clearHashIdToNodeMap();
-            _phylogeny.recalculateNumberOfExternalDescendants( true );
-            resetNodeIdToDistToLeafMap();
-            setEdited( true );
-        }
-        repaint();
-    }
-
     final private void switchDisplaygetPhylogenyGraphicsType() {
         switch ( getPhylogenyGraphicsType() ) {
             case RECTANGULAR:
@@ -5193,103 +5296,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
-    final void taxColor() {
-        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
-            return;
-        }
-        setWaitCursor();
-        AptxUtil.colorPhylogenyAccordingToExternalTaxonomy( _phylogeny, this );
-        _control_panel.setColorBranches( true );
-        if ( _control_panel.getColorBranchesCb() != null ) {
-            _control_panel.getColorBranchesCb().setSelected( true );
-        }
-        setArrowCursor();
-        repaint();
-    }
-
-    final void updateOvSettings() {
-        switch ( getOptions().getOvPlacement() ) {
-            case LOWER_LEFT:
-                setOvXPosition( OV_BORDER );
-                setOvYPosition( ForesterUtil.roundToInt( getVisibleRect().height - OV_BORDER - getOvMaxHeight() ) );
-                setOvYStart( ForesterUtil.roundToInt( getOvYPosition() + ( getOvMaxHeight() / 2 ) ) );
-                break;
-            case LOWER_RIGHT:
-                setOvXPosition( ForesterUtil.roundToInt( getVisibleRect().width - OV_BORDER - getOvMaxWidth() ) );
-                setOvYPosition( ForesterUtil.roundToInt( getVisibleRect().height - OV_BORDER - getOvMaxHeight() ) );
-                setOvYStart( ForesterUtil.roundToInt( getOvYPosition() + ( getOvMaxHeight() / 2 ) ) );
-                break;
-            case UPPER_RIGHT:
-                setOvXPosition( ForesterUtil.roundToInt( getVisibleRect().width - OV_BORDER - getOvMaxWidth() ) );
-                setOvYPosition( OV_BORDER );
-                setOvYStart( ForesterUtil.roundToInt( OV_BORDER + ( getOvMaxHeight() / 2 ) ) );
-                break;
-            default:
-                setOvXPosition( OV_BORDER );
-                setOvYPosition( OV_BORDER );
-                setOvYStart( ForesterUtil.roundToInt( OV_BORDER + ( getOvMaxHeight() / 2 ) ) );
-                break;
-        }
-    }
-
-    final void updateOvSizes() {
-        if ( ( getWidth() > ( 1.05 * getVisibleRect().width ) ) || ( getHeight() > ( 1.05 * getVisibleRect().height ) ) ) {
-            setOvOn( true );
-            float l = getLongestExtNodeInfo();
-            final float w_ratio = getOvMaxWidth() / getWidth();
-            l *= w_ratio;
-            final int ext_nodes = _phylogeny.getRoot().getNumberOfExternalNodes();
-            setOvYDistance( getOvMaxHeight() / ( 2 * ext_nodes ) );
-            float ov_xdist = 0;
-            if ( !isNonLinedUpCladogram() && !isUniformBranchLengthsForCladogram() ) {
-                ov_xdist = ( ( getOvMaxWidth() - l ) / ( ext_nodes ) );
-            }
-            else {
-                ov_xdist = ( ( getOvMaxWidth() - l ) / ( PhylogenyMethods.calculateMaxDepth( _phylogeny ) ) );
-            }
-            float ydist = ( float ) ( ( getOvMaxWidth() / ( ext_nodes * 2.0 ) ) );
-            if ( ov_xdist < 0.0 ) {
-                ov_xdist = 0.0f;
-            }
-            if ( ydist < 0.0 ) {
-                ydist = 0.0f;
-            }
-            setOvXDistance( ov_xdist );
-            final double height = _phylogeny.getHeight();
-            if ( height > 0 ) {
-                final float ov_corr = ( float ) ( ( ( getOvMaxWidth() - l ) - getOvXDistance() ) / height );
-                setOvXcorrectionFactor( ov_corr > 0 ? ov_corr : 0 );
-            }
-            else {
-                setOvXcorrectionFactor( 0 );
-            }
-        }
-        else {
-            setOvOn( false );
-        }
-    }
-
-    final void updateSubSuperTreeButton() {
-        if ( _subtree_index < 1 ) {
-            getControlPanel().deactivateButtonToReturnToSuperTree();
-        }
-        else {
-            getControlPanel().activateButtonToReturnToSuperTree( _subtree_index );
-        }
-    }
-
-    final void zoomInDomainStructure() {
-        if ( _domain_structure_width < 2000 ) {
-            _domain_structure_width *= 1.2;
-        }
-    }
-
-    final void zoomOutDomainStructure() {
-        if ( _domain_structure_width > 20 ) {
-            _domain_structure_width *= 0.8;
-        }
-    }
-
     final private static void drawString( final int i, final double x, final double y, final Graphics2D g ) {
         g.drawString( String.valueOf( i ), ( int ) ( x + 0.5 ), ( int ) ( y + 0.5 ) );
     }
@@ -5298,6 +5304,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         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() );
@@ -5314,12 +5328,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 ) );
     }
 
-    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 {
@@ -5340,12 +5363,4 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             }
         }
     }
-
-    public synchronized void setImageMap( final Hashtable<String, BufferedImage> image_map ) {
-        getMainPanel().setImageMap( image_map );
-    }
-
-    public synchronized Hashtable<String, BufferedImage> getImageMap() {
-        return getMainPanel().getImageMap();
-    }
 }