Allow to retrieve a snapshot of the edited phylogenetic tree using javascript code...
[jalview.git] / forester / java / src / org / forester / archaeopteryx / TreePanel.java
index e1bcfb7..9d29d9d 100644 (file)
@@ -95,6 +95,8 @@ import org.forester.archaeopteryx.Options.NODE_LABEL_DIRECTION;
 import org.forester.archaeopteryx.Options.PHYLOGENY_GRAPHICS_TYPE;
 import org.forester.archaeopteryx.phylogeny.data.RenderableDomainArchitecture;
 import org.forester.archaeopteryx.phylogeny.data.RenderableVector;
 import org.forester.archaeopteryx.Options.PHYLOGENY_GRAPHICS_TYPE;
 import org.forester.archaeopteryx.phylogeny.data.RenderableDomainArchitecture;
 import org.forester.archaeopteryx.phylogeny.data.RenderableVector;
+import org.forester.archaeopteryx.tools.Blast;
+import org.forester.archaeopteryx.tools.ImageLoader;
 import org.forester.io.parsers.phyloxml.PhyloXmlUtil;
 import org.forester.phylogeny.Phylogeny;
 import org.forester.phylogeny.PhylogenyMethods;
 import org.forester.io.parsers.phyloxml.PhyloXmlUtil;
 import org.forester.phylogeny.Phylogeny;
 import org.forester.phylogeny.PhylogenyMethods;
@@ -103,6 +105,9 @@ import org.forester.phylogeny.data.Annotation;
 import org.forester.phylogeny.data.BranchColor;
 import org.forester.phylogeny.data.Confidence;
 import org.forester.phylogeny.data.Event;
 import org.forester.phylogeny.data.BranchColor;
 import org.forester.phylogeny.data.Confidence;
 import org.forester.phylogeny.data.Event;
+import org.forester.phylogeny.data.NodeVisualization;
+import org.forester.phylogeny.data.NodeVisualization.NodeFill;
+import org.forester.phylogeny.data.NodeVisualization.NodeShape;
 import org.forester.phylogeny.data.PhylogenyData;
 import org.forester.phylogeny.data.PropertiesMap;
 import org.forester.phylogeny.data.Property;
 import org.forester.phylogeny.data.PhylogenyData;
 import org.forester.phylogeny.data.PropertiesMap;
 import org.forester.phylogeny.data.Property;
@@ -134,15 +139,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     private final static int                EURO_D                            = 10;
     private final static String             NODE_POPMENU_NODE_CLIENT_PROPERTY = "node";
     private final static int                MIN_ROOT_LENGTH                   = 3;
     private final static int                EURO_D                            = 10;
     private final static String             NODE_POPMENU_NODE_CLIENT_PROPERTY = "node";
     private final static int                MIN_ROOT_LENGTH                   = 3;
-    private final static int                BOX_SIZE                          = 4;
-    private final static int                HALF_BOX_SIZE                     = TreePanel.BOX_SIZE / 2;
     private final static int                MAX_SUBTREES                      = 100;
     private final static int                MAX_NODE_FRAMES                   = 10;
     private final static int                MOVE                              = 20;
     private final static NumberFormat       FORMATTER_CONFIDENCE;
     private final static NumberFormat       FORMATTER_BRANCH_LENGTH;
     private final static int                WIGGLE                            = 2;
     private final static int                MAX_SUBTREES                      = 100;
     private final static int                MAX_NODE_FRAMES                   = 10;
     private final static int                MOVE                              = 20;
     private final static NumberFormat       FORMATTER_CONFIDENCE;
     private final static NumberFormat       FORMATTER_BRANCH_LENGTH;
     private final static int                WIGGLE                            = 2;
-    private final static int                HALF_BOX_SIZE_PLUS_WIGGLE         = HALF_BOX_SIZE + WIGGLE;
     private final static int                LIMIT_FOR_HQ_RENDERING            = 1000;
     private final static int                CONFIDENCE_LEFT_MARGIN            = 4;
     // TODO "rendering_hints" was static before. Need to make sure everything is OK with it not
     private final static int                LIMIT_FOR_HQ_RENDERING            = 1000;
     private final static int                CONFIDENCE_LEFT_MARGIN            = 4;
     // TODO "rendering_hints" was static before. Need to make sure everything is OK with it not
@@ -204,11 +206,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     final private static double             _180_OVER_PI                      = 180.0 / Math.PI;
     private static final float              ROUNDED_D                         = 8;
     private int                             _circ_max_depth;
     final private static double             _180_OVER_PI                      = 180.0 / Math.PI;
     private static final float              ROUNDED_D                         = 8;
     private int                             _circ_max_depth;
-    private int                             _circ_num_ext_nodes;
     private PhylogenyNode                   _root;
     final private Arc2D                     _arc                              = new Arc2D.Double();
     final private HashMap<Integer, Double>  _urt_nodeid_angle_map             = new HashMap<Integer, Double>();
     final private HashMap<Integer, Integer> _urt_nodeid_index_map             = new HashMap<Integer, Integer>();
     private PhylogenyNode                   _root;
     final private Arc2D                     _arc                              = new Arc2D.Double();
     final private HashMap<Integer, Double>  _urt_nodeid_angle_map             = new HashMap<Integer, Double>();
     final private HashMap<Integer, Integer> _urt_nodeid_index_map             = new HashMap<Integer, Integer>();
+    final private Set<Integer>              _collapsed_external_nodeid_set    = new HashSet<Integer>();
     HashMap<Integer, Short>                 _nodeid_dist_to_leaf              = new HashMap<Integer, Short>();
     private AffineTransform                 _at;
     private double                          _max_distance_to_root             = -1;
     HashMap<Integer, Short>                 _nodeid_dist_to_leaf              = new HashMap<Integer, Short>();
     private AffineTransform                 _at;
     private double                          _max_distance_to_root             = -1;
@@ -216,6 +218,8 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     private boolean                         _edited                           = false;
     private Popup                           _node_desc_popup;
     private JTextArea                       _rollover_popup;
     private boolean                         _edited                           = false;
     private Popup                           _node_desc_popup;
     private JTextArea                       _rollover_popup;
+    // private final int                       _box_size;
+    // private final int                       _half_box_size;
     //private final short                     _skip_counter                     = 0;
     private final StringBuffer              _popup_buffer                     = new StringBuffer();
     final private static Font               POPUP_FONT                        = new Font( Configuration.getDefaultFontFamilyName(),
     //private final short                     _skip_counter                     = 0;
     private final StringBuffer              _popup_buffer                     = new StringBuffer();
     final private static Font               POPUP_FONT                        = new Font( Configuration.getDefaultFontFamilyName(),
@@ -441,12 +445,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    final void assignGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node, final Graphics g ) {
+    final Color getGraphicsForNodeBoxWithColorForParentBranch( final PhylogenyNode node ) {
         if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
         if ( getControlPanel().isColorBranches() && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
-            g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
+            return ( PhylogenyMethods.getBranchColorValue( node ) );
         }
         else {
         }
         else {
-            g.setColor( getTreeColorSet().getBranchColor() );
+            return ( getTreeColorSet().getBranchColor() );
         }
     }
 
         }
     }
 
@@ -571,6 +575,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                     sum += getTreeFontSet()._fm_large_italic.stringWidth( tax.getCommonName() + " ()" );
                 }
             }
                     sum += getTreeFontSet()._fm_large_italic.stringWidth( tax.getCommonName() + " ()" );
                 }
             }
+            if ( getControlPanel().isShowProperties() && node.getNodeData().isHasProperties() ) {
+                sum += getTreeFontSet()._fm_large.stringWidth( propertiesToString( node ).toString() );
+            }
             if ( getControlPanel().isShowBinaryCharacters() && node.getNodeData().isHasBinaryCharacters() ) {
                 sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getBinaryCharacters()
                         .getGainedCharactersAsStringBuffer().toString() );
             if ( getControlPanel().isShowBinaryCharacters() && node.getNodeData().isHasBinaryCharacters() ) {
                 sum += getTreeFontSet()._fm_large.stringWidth( node.getNodeData().getBinaryCharacters()
                         .getGainedCharactersAsStringBuffer().toString() );
@@ -687,6 +694,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         if ( !node.isExternal() && !node.isRoot() ) {
             final boolean collapse = !node.isCollapse();
             Util.collapseSubtree( node, collapse );
         if ( !node.isExternal() && !node.isRoot() ) {
             final boolean collapse = !node.isCollapse();
             Util.collapseSubtree( node, collapse );
+            updateSetOfCollapsedExternalNodes( _phylogeny );
             _phylogeny.recalculateNumberOfExternalDescendants( true );
             resetNodeIdToDistToLeafMap();
             calculateLongestExtNodeInfo();
             _phylogeny.recalculateNumberOfExternalDescendants( true );
             resetNodeIdToDistToLeafMap();
             calculateLongestExtNodeInfo();
@@ -704,6 +712,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
         setWaitCursor();
         Util.collapseSpeciesSpecificSubtrees( _phylogeny );
         }
         setWaitCursor();
         Util.collapseSpeciesSpecificSubtrees( _phylogeny );
+        updateSetOfCollapsedExternalNodes( _phylogeny );
         _phylogeny.recalculateNumberOfExternalDescendants( true );
         resetNodeIdToDistToLeafMap();
         calculateLongestExtNodeInfo();
         _phylogeny.recalculateNumberOfExternalDescendants( true );
         resetNodeIdToDistToLeafMap();
         calculateLongestExtNodeInfo();
@@ -758,6 +767,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             return;
         }
         setWaitCursor();
             return;
         }
         setWaitCursor();
+        Util.removeBranchColors( _phylogeny );
         Util.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this );
         _control_panel.setColorBranches( true );
         if ( _control_panel.getColorBranchesCb() != null ) {
         Util.colorPhylogenyAccordingToConfidenceValues( _phylogeny, this );
         _control_panel.setColorBranches( true );
         if ( _control_panel.getColorBranchesCb() != null ) {
@@ -767,6 +777,51 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         repaint();
     }
 
         repaint();
     }
 
+    final void colorRank( final String rank ) {
+        if ( ( _phylogeny == null ) || ( _phylogeny.getNumberOfExternalNodes() < 2 ) ) {
+            return;
+        }
+        setWaitCursor();
+        Util.removeBranchColors( _phylogeny );
+        final int colorizations = Util.colorPhylogenyAccordingToRanks( _phylogeny, rank, this );
+        if ( colorizations > 0 ) {
+            _control_panel.setColorBranches( true );
+            if ( _control_panel.getColorBranchesCb() != null ) {
+                _control_panel.getColorBranchesCb().setSelected( true );
+            }
+            if ( _control_panel.getColorAccSpeciesCb() != null ) {
+                _control_panel.getColorAccSpeciesCb().setSelected( false );
+            }
+            _options.setColorLabelsSameAsParentBranch( true );
+            _control_panel.repaint();
+        }
+        setArrowCursor();
+        repaint();
+        if ( colorizations > 0 ) {
+            String msg = "Taxonomy colorization via " + rank + " completed:\n";
+            if ( colorizations > 1 ) {
+                msg += "colorized " + colorizations + " subtrees";
+            }
+            else {
+                msg += "colorized one subtree";
+            }
+            JOptionPane.showMessageDialog( this,
+                                           msg,
+                                           "Taxonomy Colorization Completed (" + rank + ")",
+                                           JOptionPane.INFORMATION_MESSAGE );
+        }
+        else {
+            String msg = "Could not taxonomy colorize any subtree via " + rank + ".\n";
+            msg += "Possible solutions (given that suitable taxonomic information is present):\n";
+            msg += "select a different rank (e.g. phylum, genus, ...)\n";
+            msg += "  and/or\n";
+            msg += "execute:\n";
+            msg += "1. \"" + MainFrameApplication.OBTAIN_DETAILED_TAXONOMIC_INFORMATION + "\" (Tools)\n";
+            msg += "2. \"" + MainFrameApplication.INFER_ANCESTOR_TAXONOMIES + "\" (Analysis)";
+            JOptionPane.showMessageDialog( this, msg, "Taxonomy Colorization Failed", JOptionPane.WARNING_MESSAGE );
+        }
+    }
+
     final private void copySubtree( final PhylogenyNode node ) {
         if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
             errorMessageNoCutCopyPasteInUnrootedDisplay();
     final private void copySubtree( final PhylogenyNode node ) {
         if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.UNROOTED ) {
             errorMessageNoCutCopyPasteInUnrootedDisplay();
@@ -938,6 +993,52 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         g.fill( _rectangle );
     }
 
         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",
     final private void errorMessageNoCutCopyPasteInUnrootedDisplay() {
         JOptionPane.showMessageDialog( this,
                                        "Cannot cut, copy, paste, add, or delete subtrees/nodes in unrooted display",
@@ -956,13 +1057,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
             return null;
         }
         if ( ( _phylogeny == null ) || _phylogeny.isEmpty() ) {
             return null;
         }
+        final int half_box_size_plus_wiggle = getOptions().getDefaultNodeShapeSize() / 2 + WIGGLE;
         for( final PhylogenyNodeIterator iter = _phylogeny.iteratorPostorder(); iter.hasNext(); ) {
             final PhylogenyNode node = iter.next();
             if ( ( _phylogeny.isRooted() || !node.isRoot() || ( node.getNumberOfDescendants() > 2 ) )
         for( final PhylogenyNodeIterator iter = _phylogeny.iteratorPostorder(); iter.hasNext(); ) {
             final PhylogenyNode node = iter.next();
             if ( ( _phylogeny.isRooted() || !node.isRoot() || ( node.getNumberOfDescendants() > 2 ) )
-                    && ( ( node.getXcoord() - HALF_BOX_SIZE_PLUS_WIGGLE ) <= x )
-                    && ( ( node.getXcoord() + HALF_BOX_SIZE_PLUS_WIGGLE ) >= x )
-                    && ( ( node.getYcoord() - HALF_BOX_SIZE_PLUS_WIGGLE ) <= y )
-                    && ( ( node.getYcoord() + HALF_BOX_SIZE_PLUS_WIGGLE ) >= y ) ) {
+                    && ( ( node.getXcoord() - half_box_size_plus_wiggle ) <= x )
+                    && ( ( node.getXcoord() + half_box_size_plus_wiggle ) >= x )
+                    && ( ( node.getYcoord() - half_box_size_plus_wiggle ) <= y )
+                    && ( ( node.getYcoord() + half_box_size_plus_wiggle ) >= y ) ) {
                 return node;
             }
         }
                 return node;
             }
         }
@@ -1097,7 +1199,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
      * 
      * @return a pointer to the phylogeny
      */
      * 
      * @return a pointer to the phylogeny
      */
-    final Phylogeny getPhylogeny() {
+    public final Phylogeny getPhylogeny() {
         return _phylogeny;
     }
 
         return _phylogeny;
     }
 
@@ -2252,7 +2354,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     final private void paintBranchRectangular( final Graphics2D g,
                                                final float x1,
                                                final float x2,
     final private void paintBranchRectangular( final Graphics2D g,
                                                final float x1,
                                                final float x2,
-                                               float y1,
+                                               final float y1,
                                                final float y2,
                                                final PhylogenyNode node,
                                                final boolean to_pdf,
                                                final float y2,
                                                final PhylogenyNode node,
                                                final boolean to_pdf,
@@ -2273,87 +2375,45 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             g.draw( _cubic_curve );
         }
         else {
             g.draw( _cubic_curve );
         }
         else {
-            float x2a = x2;
-            float x1a = x1;
-            // draw the vertical line
-            boolean draw_horizontal = true;
+            final float x2a = x2;
+            final float x1a = x1;
             float y2_r = 0;
             if ( node.isFirstChildNode() || node.isLastChildNode()
                     || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE )
                     || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
             float y2_r = 0;
             if ( node.isFirstChildNode() || node.isLastChildNode()
                     || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE )
                     || ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
-                boolean draw_vertical = true;
-                final PhylogenyNode parent = node.getParent();
-                if ( ( ( getOptions().isShowNodeBoxes() && !to_pdf && !to_graphics_file ) || ( ( getControlPanel()
-                        .isEvents() ) && ( parent != null ) && parent.isHasAssignedEvent() ) )
-                        && ( _phylogeny.isRooted() || !( ( parent != null ) && parent.isRoot() ) )
-                        && !( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() && !parent
-                                .isDuplication() ) ) {
-                    if ( ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE )
-                            && ( getPhylogenyGraphicsType() != PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
-                        if ( Math.abs( y2 - y1 ) <= TreePanel.HALF_BOX_SIZE ) {
-                            draw_vertical = false;
-                        }
-                        else {
-                            if ( y1 < y2 ) {
-                                y1 += TreePanel.HALF_BOX_SIZE;
-                            }
-                            else {
-                                if ( !to_pdf ) {
-                                    y1 -= TreePanel.HALF_BOX_SIZE + 1;
-                                }
-                                else {
-                                    y1 -= TreePanel.HALF_BOX_SIZE;
-                                }
-                            }
-                        }
-                    }
-                    if ( ( x2 - x1 ) <= TreePanel.HALF_BOX_SIZE ) {
-                        draw_horizontal = false;
-                    }
-                    else if ( !draw_vertical ) {
-                        x1a += TreePanel.HALF_BOX_SIZE;
-                    }
-                    if ( ( ( x2 - x1a ) > TreePanel.HALF_BOX_SIZE )
-                            && !( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() && !node
-                                    .isDuplication() ) ) {
-                        x2a -= TreePanel.HALF_BOX_SIZE;
-                    }
+                if ( !to_graphics_file
+                        && !to_pdf
+                        && ( ( ( y2 < getVisibleRect().getMinY() - 20 ) && ( y1 < getVisibleRect().getMinY() - 20 ) ) || ( ( y2 > getVisibleRect()
+                                .getMaxY() + 20 ) && ( y1 > getVisibleRect().getMaxY() + 20 ) ) ) ) {
+                    // Do nothing.
                 }
                 }
-                if ( draw_vertical ) {
-                    if ( !to_graphics_file
-                            && !to_pdf
-                            && ( ( ( y2 < getVisibleRect().getMinY() - 20 ) && ( y1 < getVisibleRect().getMinY() - 20 ) ) || ( ( y2 > getVisibleRect()
-                                    .getMaxY() + 20 ) && ( y1 > getVisibleRect().getMaxY() + 20 ) ) ) ) {
-                        // Do nothing.
-                    }
-                    else {
-                        if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
-                            float x2c = x1 + EURO_D;
-                            if ( x2c > x2a ) {
-                                x2c = x2a;
-                            }
-                            drawLine( x1, y1, x2c, y2, g );
+                else {
+                    if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
+                        float x2c = x1 + EURO_D;
+                        if ( x2c > x2a ) {
+                            x2c = x2a;
                         }
                         }
-                        else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
-                            if ( y2 > y1 ) {
-                                y2_r = y2 - ROUNDED_D;
-                                if ( y2_r < y1 ) {
-                                    y2_r = y1;
-                                }
-                                drawLine( x1, y1, x1, y2_r, g );
-                            }
-                            else {
-                                y2_r = y2 + ROUNDED_D;
-                                if ( y2_r > y1 ) {
-                                    y2_r = y1;
-                                }
-                                drawLine( x1, y1, x1, y2_r, g );
+                        drawLine( x1, y1, x2c, y2, g );
+                    }
+                    else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
+                        if ( y2 > y1 ) {
+                            y2_r = y2 - ROUNDED_D;
+                            if ( y2_r < y1 ) {
+                                y2_r = y1;
                             }
                             }
+                            drawLine( x1, y1, x1, y2_r, g );
                         }
                         else {
                         }
                         else {
-                            drawLine( x1, y1, x1, y2, g );
+                            y2_r = y2 + ROUNDED_D;
+                            if ( y2_r > y1 ) {
+                                y2_r = y1;
+                            }
+                            drawLine( x1, y1, x1, y2_r, g );
                         }
                     }
                         }
                     }
+                    else {
+                        drawLine( x1, y1, x1, y2, g );
+                    }
                 }
             }
             // draw the horizontal line
                 }
             }
             // draw the horizontal line
@@ -2362,42 +2422,40 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 return;
             }
             float x1_r = 0;
                 return;
             }
             float x1_r = 0;
-            if ( draw_horizontal ) {
-                if ( !getControlPanel().isWidthBranches() || ( PhylogenyMethods.getBranchWidthValue( node ) == 1 ) ) {
-                    if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
-                        x1_r = x1a + ROUNDED_D;
-                        if ( x1_r < x2a ) {
-                            drawLine( x1_r, y2, x2a, y2, g );
-                        }
+            if ( !getControlPanel().isWidthBranches() || ( PhylogenyMethods.getBranchWidthValue( node ) == 1 ) ) {
+                if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
+                    x1_r = x1a + ROUNDED_D;
+                    if ( x1_r < x2a ) {
+                        drawLine( x1_r, y2, x2a, y2, g );
                     }
                     }
-                    else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
-                        final float x1c = x1a + EURO_D;
-                        if ( x1c < x2a ) {
-                            drawLine( x1c, y2, x2a, y2, g );
-                        }
-                    }
-                    else {
-                        drawLine( x1a, y2, x2a, y2, g );
+                }
+                else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
+                    final float x1c = x1a + EURO_D;
+                    if ( x1c < x2a ) {
+                        drawLine( x1c, y2, x2a, y2, g );
                     }
                 }
                 else {
                     }
                 }
                 else {
-                    final double w = PhylogenyMethods.getBranchWidthValue( node );
-                    if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
-                        x1_r = x1a + ROUNDED_D;
-                        if ( x1_r < x2a ) {
-                            drawRectFilled( x1_r, y2 - ( w / 2 ), x2a - x1_r, w, g );
-                        }
-                    }
-                    else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
-                        final float x1c = x1a + EURO_D;
-                        if ( x1c < x2a ) {
-                            drawRectFilled( x1c, y2 - ( w / 2 ), x2a - x1c, w, g );
-                        }
+                    drawLine( x1a, y2, x2a, y2, g );
+                }
+            }
+            else {
+                final double w = PhylogenyMethods.getBranchWidthValue( node );
+                if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) {
+                    x1_r = x1a + ROUNDED_D;
+                    if ( x1_r < x2a ) {
+                        drawRectFilled( x1_r, y2 - ( w / 2 ), x2a - x1_r, w, g );
                     }
                     }
-                    else {
-                        drawRectFilled( x1a, y2 - ( w / 2 ), x2a - x1a, w, g );
+                }
+                else if ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.EURO_STYLE ) {
+                    final float x1c = x1a + EURO_D;
+                    if ( x1c < x2a ) {
+                        drawRectFilled( x1c, y2 - ( w / 2 ), x2a - x1c, w, g );
                     }
                 }
                     }
                 }
+                else {
+                    drawRectFilled( x1a, y2 - ( w / 2 ), x2a - x1a, w, g );
+                }
             }
             if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
                 if ( x1_r > x2a ) {
             }
             if ( ( getPhylogenyGraphicsType() == PHYLOGENY_GRAPHICS_TYPE.ROUNDED ) ) {
                 if ( x1_r > x2a ) {
@@ -2413,7 +2471,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 g.draw( _arc );
             }
         }
                 g.draw( _arc );
             }
         }
-        paintNodeBox( x2, y2, node, g, to_pdf, to_graphics_file, isInFoundNodes( node ) );
+        if ( node.isExternal() ) {
+            paintNodeBox( x2, y2, node, g, to_pdf, to_graphics_file, isInFoundNodes( node ) );
+        }
     }
 
     final void paintCircular( final Phylogeny phy,
     }
 
     final void paintCircular( final Phylogeny phy,
@@ -2424,23 +2484,45 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                               final Graphics2D g,
                               final boolean to_pdf,
                               final boolean to_graphics_file ) {
                               final Graphics2D g,
                               final boolean to_pdf,
                               final boolean to_graphics_file ) {
-        _circ_num_ext_nodes = phy.getNumberOfExternalNodes();
+        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 );
         _root = phy.getRoot();
         _root.setXcoord( center_x );
         _root.setYcoord( center_y );
-        paintNodeBox( _root.getXcoord(), _root.getYcoord(), _root, g, to_pdf, to_graphics_file, isInFoundNodes( _root ) );
         final boolean radial_labels = getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL;
         double current_angle = starting_angle;
         int i = 0;
         for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
             final PhylogenyNode n = it.next();
         final boolean radial_labels = getOptions().getNodeLabelDirection() == NODE_LABEL_DIRECTION.RADIAL;
         double current_angle = starting_angle;
         int i = 0;
         for( final PhylogenyNodeIterator it = phy.iteratorExternalForward(); it.hasNext(); ) {
             final PhylogenyNode n = it.next();
-            n.setXcoord( ( float ) ( center_x + ( radius * Math.cos( current_angle ) ) ) );
-            n.setYcoord( ( float ) ( center_y + ( radius * Math.sin( current_angle ) ) ) );
-            _urt_nodeid_angle_map.put( n.getId(), current_angle );
-            _urt_nodeid_index_map.put( n.getId(), i++ );
-            current_angle += ( TWO_PI / _circ_num_ext_nodes );
+            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 );
         }
         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 ) );
+    }
+
+    private void updateSetOfCollapsedExternalNodes( final Phylogeny phy ) {
+        _collapsed_external_nodeid_set.clear();
+        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() );
+                    continue E;
+                }
+                n = n.getParent();
+            }
+        }
     }
 
     final void paintCircularLite( final Phylogeny phy,
     }
 
     final void paintCircularLite( final Phylogeny phy,
@@ -2449,7 +2531,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                   final int center_y,
                                   final int radius,
                                   final Graphics2D g ) {
                                   final int center_y,
                                   final int radius,
                                   final Graphics2D g ) {
-        _circ_num_ext_nodes = phy.getNumberOfExternalNodes();
+        final int circ_num_ext_nodes = phy.getNumberOfExternalNodes();
         _root = phy.getRoot();
         _root.setXSecondary( center_x );
         _root.setYSecondary( center_y );
         _root = phy.getRoot();
         _root.setXSecondary( center_x );
         _root.setYSecondary( center_y );
@@ -2459,7 +2541,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             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 );
             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 );
+            current_angle += ( TWO_PI / circ_num_ext_nodes );
         }
         paintCircularsLite( phy.getRoot(), phy, center_x, center_y, radius, g );
     }
         }
         paintCircularsLite( phy.getRoot(), phy, center_x, center_y, radius, g );
     }
@@ -2473,9 +2555,9 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                          final Graphics2D g,
                                          final boolean to_pdf,
                                          final boolean to_graphics_file ) {
                                          final Graphics2D g,
                                          final boolean to_pdf,
                                          final boolean to_graphics_file ) {
-        if ( n.isExternal() ) {
+        if ( n.isExternal() || n.isCollapse() ) { //~~circ collapse
             if ( !_urt_nodeid_angle_map.containsKey( n.getId() ) ) {
             if ( !_urt_nodeid_angle_map.containsKey( n.getId() ) ) {
-                System.out.println( "no " + n + ", fucker!" );//TODO
+                System.out.println( "no " + n + " =====>>>>>>> ERROR!" );//TODO
             }
             return _urt_nodeid_angle_map.get( n.getId() );
         }
             }
             return _urt_nodeid_angle_map.get( n.getId() );
         }
@@ -2540,21 +2622,22 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                            final boolean to_graphics_file,
                                            final boolean to_pdf,
                                            final boolean is_in_found_nodes ) {
                                            final boolean to_graphics_file,
                                            final boolean to_pdf,
                                            final boolean is_in_found_nodes ) {
+        Color c = null;
         if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
         if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
-            g.setColor( Color.BLACK );
+            c = Color.BLACK;
         }
         else if ( is_in_found_nodes ) {
         }
         else if ( is_in_found_nodes ) {
-            g.setColor( getTreeColorSet().getFoundColor() );
+            c = getTreeColorSet().getFoundColor();
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
         }
         else if ( getControlPanel().isColorAccordingToTaxonomy() ) {
-            g.setColor( getTaxonomyBasedColor( node ) );
+            c = getTaxonomyBasedColor( node );
         }
         else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches()
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
         }
         else if ( getOptions().isColorLabelsSameAsParentBranch() && getControlPanel().isColorBranches()
                 && ( PhylogenyMethods.getBranchColorValue( node ) != null ) ) {
-            g.setColor( PhylogenyMethods.getBranchColorValue( node ) );
+            c = PhylogenyMethods.getBranchColorValue( node );
         }
         else {
         }
         else {
-            g.setColor( getTreeColorSet().getCollapseFillColor() );
+            c = getTreeColorSet().getCollapseFillColor();
         }
         double d = node.getAllExternalDescendants().size();
         if ( d > 1000 ) {
         }
         double d = node.getAllExternalDescendants().size();
         if ( d > 1000 ) {
@@ -2563,17 +2646,34 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         else {
             d = ( Math.log10( d ) * _y_distance ) / 2.5;
         }
         else {
             d = ( Math.log10( d ) * _y_distance ) / 2.5;
         }
-        if ( d < BOX_SIZE ) {
-            d = BOX_SIZE;
+        final int box_size = getOptions().getDefaultNodeShapeSize();
+        if ( d < box_size ) {
+            d = box_size;
         }
         _polygon.reset();
         }
         _polygon.reset();
-        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() - TreePanel.BOX_SIZE ),
+        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() - box_size ),
                            ForesterUtil.roundToInt( node.getYcoord() ) );
                            ForesterUtil.roundToInt( node.getYcoord() ) );
-        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + TreePanel.BOX_SIZE ),
+        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ),
                            ForesterUtil.roundToInt( node.getYcoord() - d ) );
                            ForesterUtil.roundToInt( node.getYcoord() - d ) );
-        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + TreePanel.BOX_SIZE ),
+        _polygon.addPoint( ForesterUtil.roundToInt( node.getXcoord() + box_size ),
                            ForesterUtil.roundToInt( node.getYcoord() + d ) );
                            ForesterUtil.roundToInt( node.getYcoord() + d ) );
-        g.fillPolygon( _polygon );
+        if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) {
+            g.setColor( c );
+            g.fillPolygon( _polygon );
+        }
+        else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.NONE ) {
+            g.setColor( getBackground() );
+            g.fillPolygon( _polygon );
+            g.setColor( c );
+            g.drawPolygon( _polygon );
+        }
+        else if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) {
+            g.setPaint( new GradientPaint( node.getXcoord() - box_size, node.getYcoord(), getBackground(), ( node
+                    .getXcoord() + box_size ), ( float ) ( node.getYcoord() - d ), c, false ) );
+            g.fill( _polygon );
+            g.setPaint( c );
+            g.draw( _polygon );
+        }
         paintNodeData( g, node, to_graphics_file, to_pdf, is_in_found_nodes );
     }
 
         paintNodeData( g, node, to_graphics_file, to_pdf, is_in_found_nodes );
     }
 
@@ -2664,8 +2764,10 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     }
 
     final private void paintFoundNode( final int x, final int y, final Graphics2D g ) {
     }
 
     final private void paintFoundNode( final int x, final int y, final Graphics2D g ) {
+        final int box_size = getOptions().getDefaultNodeShapeSize();
+        final int half_box_size = getOptions().getDefaultNodeShapeSize() / 2;
         g.setColor( getTreeColorSet().getFoundColor() );
         g.setColor( getTreeColorSet().getFoundColor() );
-        g.fillRect( x - TreePanel.HALF_BOX_SIZE, y - TreePanel.HALF_BOX_SIZE, TreePanel.BOX_SIZE, TreePanel.BOX_SIZE );
+        g.fillRect( x - half_box_size, y - half_box_size, box_size, box_size );
     }
 
     final private void paintGainedAndLostCharacters( final Graphics2D g,
     }
 
     final private void paintGainedAndLostCharacters( final Graphics2D g,
@@ -2722,33 +2824,93 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             paintFoundNode( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ), g );
         }
         else {
             paintFoundNode( ForesterUtil.roundToInt( x ), ForesterUtil.roundToInt( y ), g );
         }
         else {
+            Color outline_color = null;
             if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
             if ( ( to_pdf || to_graphics_file ) && getOptions().isPrintBlackAndWhite() ) {
-                g.setColor( Color.BLACK );
+                outline_color = Color.BLACK;
             }
             else if ( getControlPanel().isEvents() && Util.isHasAssignedEvent( node ) ) {
                 final Event event = node.getNodeData().getEvent();
                 if ( event.isDuplication() ) {
             }
             else if ( getControlPanel().isEvents() && Util.isHasAssignedEvent( node ) ) {
                 final Event event = node.getNodeData().getEvent();
                 if ( event.isDuplication() ) {
-                    g.setColor( getTreeColorSet().getDuplicationBoxColor() );
+                    outline_color = getTreeColorSet().getDuplicationBoxColor();
                 }
                 else if ( event.isSpeciation() ) {
                 }
                 else if ( event.isSpeciation() ) {
-                    g.setColor( getTreeColorSet().getSpecBoxColor() );
+                    outline_color = getTreeColorSet().getSpecBoxColor();
                 }
                 else if ( event.isSpeciationOrDuplication() ) {
                 }
                 else if ( event.isSpeciationOrDuplication() ) {
-                    g.setColor( getTreeColorSet().getDuplicationOrSpeciationColor() );
+                    outline_color = getTreeColorSet().getDuplicationOrSpeciationColor();
                 }
             }
                 }
             }
-            else {
-                assignGraphicsForNodeBoxWithColorForParentBranch( node, g );
+            else if ( getOptions().isTaxonomyColorizeNodeShapes() ) {
+                outline_color = getTaxonomyBasedColor( node );
             }
             }
-            if ( ( getOptions().isShowNodeBoxes() && !to_pdf && !to_graphics_file )
-                    || ( getControlPanel().isEvents() && node.isHasAssignedEvent() ) ) {
-                if ( to_pdf || to_graphics_file ) {
-                    if ( node.isDuplication() || !getOptions().isPrintBlackAndWhite() ) {
-                        drawOvalFilled( x - HALF_BOX_SIZE, y - HALF_BOX_SIZE, BOX_SIZE, BOX_SIZE, g );
+            else {
+                outline_color = getGraphicsForNodeBoxWithColorForParentBranch( node );
+                if ( to_pdf && ( outline_color == getTreeColorSet().getBranchColor() ) ) {
+                    outline_color = getTreeColorSet().getBranchColorForPdf();
+                }
+            }
+            final int box_size = getOptions().getDefaultNodeShapeSize();
+            final int half_box_size = box_size / 2;
+            if ( getOptions().isShowDefaultNodeShapes() || ( getControlPanel().isEvents() && node.isHasAssignedEvent() ) ) {
+                if ( getOptions().getDefaultNodeShape() == NodeShape.CIRCLE ) {
+                    if ( getOptions().getDefaultNodeFill() == NodeFill.GRADIENT ) {
+                        drawOvalGradient( x - half_box_size,
+                                          y - half_box_size,
+                                          box_size,
+                                          box_size,
+                                          g,
+                                          to_pdf ? Color.WHITE : outline_color,
+                                          to_pdf ? outline_color : getBackground(),
+                                          outline_color );
+                    }
+                    else if ( getOptions().getDefaultNodeFill() == NodeFill.NONE ) {
+                        Color background = getBackground();
+                        if ( to_pdf ) {
+                            background = Color.WHITE;
+                        }
+                        drawOvalGradient( x - half_box_size,
+                                          y - half_box_size,
+                                          box_size,
+                                          box_size,
+                                          g,
+                                          background,
+                                          background,
+                                          outline_color );
+                    }
+                    else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) {
+                        g.setColor( outline_color );
+                        drawOvalFilled( x - half_box_size, y - half_box_size, box_size, box_size, g );
                     }
                 }
                     }
                 }
-                else {
-                    drawRectFilled( x - HALF_BOX_SIZE, y - HALF_BOX_SIZE, BOX_SIZE, BOX_SIZE, g );
+                else if ( getOptions().getDefaultNodeShape() == NodeVisualization.NodeShape.RECTANGLE ) {
+                    if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.GRADIENT ) {
+                        drawRectGradient( x - half_box_size,
+                                          y - half_box_size,
+                                          box_size,
+                                          box_size,
+                                          g,
+                                          to_pdf ? Color.WHITE : outline_color,
+                                          to_pdf ? outline_color : getBackground(),
+                                          outline_color );
+                    }
+                    else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.NONE ) {
+                        Color background = getBackground();
+                        if ( to_pdf ) {
+                            background = Color.WHITE;
+                        }
+                        drawRectGradient( x - half_box_size,
+                                          y - half_box_size,
+                                          box_size,
+                                          box_size,
+                                          g,
+                                          background,
+                                          background,
+                                          outline_color );
+                    }
+                    else if ( getOptions().getDefaultNodeFill() == NodeVisualization.NodeFill.SOLID ) {
+                        g.setColor( outline_color );
+                        drawRectFilled( x - half_box_size, y - half_box_size, box_size, box_size, g );
+                    }
                 }
             }
         }
                 }
             }
         }
@@ -2772,13 +2934,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             return;
         }
         int x = 0;
             return;
         }
         int x = 0;
+        final int half_box_size = getOptions().getDefaultNodeShapeSize() / 2;
         if ( getControlPanel().isShowTaxonomyImages()
                 && ( getImageMap() != null )
                 && !getImageMap().isEmpty()
                 && node.getNodeData().isHasTaxonomy()
                 && ( ( node.getNodeData().getTaxonomy().getUris() != null ) && !node.getNodeData().getTaxonomy()
                         .getUris().isEmpty() ) ) {
         if ( getControlPanel().isShowTaxonomyImages()
                 && ( getImageMap() != null )
                 && !getImageMap().isEmpty()
                 && node.getNodeData().isHasTaxonomy()
                 && ( ( node.getNodeData().getTaxonomy().getUris() != null ) && !node.getNodeData().getTaxonomy()
                         .getUris().isEmpty() ) ) {
-            x += drawTaxonomyImage( node.getXcoord() + 2 + TreePanel.HALF_BOX_SIZE, node.getYcoord(), node, g );
+            x += drawTaxonomyImage( node.getXcoord() + 2 + half_box_size, node.getYcoord(), node, g );
         }
         if ( ( getControlPanel().isShowTaxonomyCode() || getControlPanel().isShowTaxonomyScientificNames() || getControlPanel()
                 .isShowTaxonomyCommonNames() ) && node.getNodeData().isHasTaxonomy() ) {
         }
         if ( ( getControlPanel().isShowTaxonomyCode() || getControlPanel().isShowTaxonomyScientificNames() || getControlPanel()
                 .isShowTaxonomyCommonNames() ) && node.getNodeData().isHasTaxonomy() ) {
@@ -2839,6 +3002,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 _sb.append( node.getNodeData().getSequence().getAccession().getValue() );
             }
         }
                 _sb.append( node.getNodeData().getSequence().getAccession().getValue() );
             }
         }
+        if ( getControlPanel().isShowProperties() && node.getNodeData().isHasProperties() ) {
+            if ( _sb.length() > 0 ) {
+                _sb.append( " " );
+            }
+            _sb.append( propertiesToString( node ) );
+        }
         g.setFont( getTreeFontSet().getLargeFont() );
         if ( is_in_found_nodes ) {
             g.setFont( getTreeFontSet().getLargeFont().deriveFont( Font.BOLD ) );
         g.setFont( getTreeFontSet().getLargeFont() );
         if ( is_in_found_nodes ) {
             g.setFont( getTreeFontSet().getLargeFont().deriveFont( Font.BOLD ) );
@@ -2847,7 +3016,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         if ( !node.isExternal() && ( node.getNumberOfDescendants() == 1 ) ) {
             down_shift_factor = 1;
         }
         if ( !node.isExternal() && ( node.getNumberOfDescendants() == 1 ) ) {
             down_shift_factor = 1;
         }
-        final double pos_x = node.getXcoord() + x + 2 + TreePanel.HALF_BOX_SIZE;
+        final double pos_x = node.getXcoord() + x + 2 + half_box_size;
         final double pos_y = ( node.getYcoord() + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ) );
         final String sb_str = _sb.toString();
         // GUILHEM_BEG ______________
         final double pos_y = ( node.getYcoord() + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ) );
         final String sb_str = _sb.toString();
         // GUILHEM_BEG ______________
@@ -2872,7 +3041,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                             && seqRelation.getType().equals( getControlPanel().getSequenceRelationTypeBox()
                                     .getSelectedItem() );
                     if ( fGotRelationWithQuery ) { // we will underline the text to show that this sequence is ortholog to the query
                             && seqRelation.getType().equals( getControlPanel().getSequenceRelationTypeBox()
                                     .getSelectedItem() );
                     if ( fGotRelationWithQuery ) { // we will underline the text to show that this sequence is ortholog to the query
-                        final double linePosX = node.getXcoord() + 2 + TreePanel.HALF_BOX_SIZE;
+                        final double linePosX = node.getXcoord() + 2 + half_box_size;
                         final String sConfidence = ( !getControlPanel().isShowSequenceRelationConfidence() || ( seqRelation
                                 .getConfidence() == null ) ) ? null : " (" + seqRelation.getConfidence().getValue()
                                 + ")";
                         final String sConfidence = ( !getControlPanel().isShowSequenceRelationConfidence() || ( seqRelation
                                 .getConfidence() == null ) ) ? null : " (" + seqRelation.getConfidence().getValue()
                                 + ")";
@@ -2930,7 +3099,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 g.setColor( calculateColorForAnnotation( ann ) );
             }
             final String ann_str = ann.asSimpleText().toString();
                 g.setColor( calculateColorForAnnotation( ann ) );
             }
             final String ann_str = ann.asSimpleText().toString();
-            TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + TreePanel.HALF_BOX_SIZE, node.getYcoord()
+            TreePanel.drawString( ann_str, node.getXcoord() + x + 3 + half_box_size, node.getYcoord()
                     + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
             _sb.setLength( 0 );
             _sb.append( ann_str );
                     + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
             _sb.setLength( 0 );
             _sb.append( ann_str );
@@ -2951,7 +3120,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 }
                 if ( getControlPanel().isShowBinaryCharacters() ) {
                     TreePanel.drawString( node.getNodeData().getBinaryCharacters().getPresentCharactersAsStringBuffer()
                 }
                 if ( getControlPanel().isShowBinaryCharacters() ) {
                     TreePanel.drawString( node.getNodeData().getBinaryCharacters().getPresentCharactersAsStringBuffer()
-                            .toString(), node.getXcoord() + x + 1 + TreePanel.HALF_BOX_SIZE, node.getYcoord()
+                            .toString(), node.getXcoord() + x + 1 + half_box_size, node.getYcoord()
                             + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
                     paintGainedAndLostCharacters( g, node, node.getNodeData().getBinaryCharacters()
                             .getGainedCharactersAsStringBuffer().toString(), node.getNodeData().getBinaryCharacters()
                             + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
                     paintGainedAndLostCharacters( g, node, node.getNodeData().getBinaryCharacters()
                             .getGainedCharactersAsStringBuffer().toString(), node.getNodeData().getBinaryCharacters()
@@ -2970,12 +3139,12 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                         }
                         final double mean = ForesterUtil.round( sum / count, 1 );
                         TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount() + " ["
                         }
                         final double mean = ForesterUtil.round( sum / count, 1 );
                         TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount() + " ["
-                                + mean + "]", node.getXcoord() + x + 4 + TreePanel.HALF_BOX_SIZE, node.getYcoord()
+                                + mean + "]", node.getXcoord() + x + 4 + half_box_size, node.getYcoord()
                                 + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
                     }
                     else {
                         TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount(),
                                 + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ), g );
                     }
                     else {
                         TreePanel.drawString( " " + node.getNodeData().getBinaryCharacters().getPresentCount(),
-                                              node.getXcoord() + x + 4 + TreePanel.HALF_BOX_SIZE,
+                                              node.getXcoord() + x + 4 + half_box_size,
                                               node.getYcoord()
                                                       + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ),
                                               g );
                                               node.getYcoord()
                                                       + ( getTreeFontSet()._fm_large.getAscent() / down_shift_factor ),
                                               g );
@@ -2988,6 +3157,22 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
+    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( " " );
+            }
+            sb.append( properties.getProperty( ref ).asText() );
+        }
+        return sb;
+    }
+
     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() ) {
     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() ) {
@@ -3306,6 +3491,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                 child_node.setYcoord( y2 );
                 y2 += _y_distance * child_node.getNumberOfExternalNodes();
             }
                 child_node.setYcoord( y2 );
                 y2 += _y_distance * child_node.getNumberOfExternalNodes();
             }
+            paintNodeBox( node.getXcoord(), node.getYcoord(), node, g, to_pdf, to_graphics_file, isInFoundNodes( node ) );
         }
         if ( dynamically_hide
                 && !is_in_found_nodes
         }
         if ( dynamically_hide
                 && !is_in_found_nodes
@@ -3715,7 +3901,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         else {
             g.setColor( getTreeColorSet().getTaxonomyColor() );
         }
         else {
             g.setColor( getTreeColorSet().getTaxonomyColor() );
         }
-        final double start_x = node.getXcoord() + 3 + TreePanel.HALF_BOX_SIZE + x_shift;
+        final double start_x = node.getXcoord() + 3 + ( getOptions().getDefaultNodeShapeSize() / 2 ) + x_shift;
         final double start_y = node.getYcoord()
                 + ( getTreeFontSet()._fm_large.getAscent() / ( node.getNumberOfDescendants() == 1 ? 1 : 3.0 ) );
         _sb.setLength( 0 );
         final double start_y = node.getYcoord()
                 + ( getTreeFontSet()._fm_large.getAscent() / ( node.getNumberOfDescendants() == 1 ? 1 : 3.0 ) );
         _sb.setLength( 0 );
@@ -3814,7 +4000,6 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         if ( n.isRoot() ) {
             n.setXcoord( getWidth() / 2 );
             n.setYcoord( getHeight() / 2 );
         if ( n.isRoot() ) {
             n.setXcoord( getWidth() / 2 );
             n.setYcoord( getHeight() / 2 );
-            paintNodeBox( n.getXcoord(), n.getYcoord(), n, g, to_pdf, to_graphics_file, isInFoundNodes( n ) );
         }
         if ( n.isExternal() ) {
             paintNodeDataUnrootedCirc( g,
         }
         if ( n.isExternal() ) {
             paintNodeDataUnrootedCirc( g,
@@ -3867,11 +4052,14 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
             final float new_y = ( float ) ( y + Math.sin( mid_angle ) * length );
             desc.setXcoord( new_x );
             desc.setYcoord( new_y );
             final float new_y = ( float ) ( y + Math.sin( mid_angle ) * length );
             desc.setXcoord( new_x );
             desc.setYcoord( new_y );
-            paintNodeBox( new_x, new_y, desc, g, to_pdf, to_graphics_file, isInFoundNodes( desc ) );
             paintUnrooted( desc, current_angle, current_angle + arc_size, radial_labels, g, to_pdf, to_graphics_file );
             current_angle += arc_size;
             assignGraphicsForBranchWithColorForParentBranch( desc, false, g, to_pdf, to_graphics_file );
             drawLine( x, y, new_x, new_y, g );
             paintUnrooted( desc, current_angle, current_angle + arc_size, radial_labels, g, to_pdf, to_graphics_file );
             current_angle += arc_size;
             assignGraphicsForBranchWithColorForParentBranch( desc, false, g, to_pdf, to_graphics_file );
             drawLine( x, y, new_x, new_y, g );
+            paintNodeBox( new_x, new_y, desc, g, to_pdf, to_graphics_file, isInFoundNodes( desc ) );
+        }
+        if ( n.isRoot() ) {
+            paintNodeBox( n.getXcoord(), n.getYcoord(), n, g, to_pdf, to_graphics_file, isInFoundNodes( n ) );
         }
     }
 
         }
     }
 
@@ -4108,7 +4296,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         setPreferredSize( new Dimension( x, y ) );
     }
 
         setPreferredSize( new Dimension( x, y ) );
     }
 
-    final void setArrowCursor() {
+    public final void setArrowCursor() {
         setCursor( ARROW_CURSOR );
         repaint();
     }
         setCursor( ARROW_CURSOR );
         repaint();
     }
@@ -4125,7 +4313,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         getMainPanel().setCutOrCopiedTree( cut_or_copied_tree );
     }
 
         getMainPanel().setCutOrCopiedTree( cut_or_copied_tree );
     }
 
-    final void setEdited( final boolean edited ) {
+    public final void setEdited( final boolean edited ) {
         _edited = edited;
     }
 
         _edited = edited;
     }
 
@@ -4323,7 +4511,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
      * @param t
      *            an instance of a Phylogeny
      */
      * @param t
      *            an instance of a Phylogeny
      */
-    final void setTree( final Phylogeny t ) {
+    public final void setTree( final Phylogeny t ) {
         _nodes_in_preorder = null;
         _phylogeny = t;
     }
         _nodes_in_preorder = null;
         _phylogeny = t;
     }
@@ -4358,7 +4546,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         _urt_factor_ov = urt_factor_ov;
     }
 
         _urt_factor_ov = urt_factor_ov;
     }
 
-    final void setWaitCursor() {
+    public final void setWaitCursor() {
         setCursor( WAIT_CURSOR );
         repaint();
     }
         setCursor( WAIT_CURSOR );
         repaint();
     }
@@ -4614,6 +4802,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
                                            JOptionPane.WARNING_MESSAGE );
             return;
         }
                                            JOptionPane.WARNING_MESSAGE );
             return;
         }
+        _nodes_in_preorder = null;
         if ( !node.isExternal() && !node.isRoot() && ( _subtree_index <= ( TreePanel.MAX_SUBTREES - 1 ) ) ) {
             _sub_phylogenies[ _subtree_index ] = _phylogeny;
             _sub_phylogenies_temp_roots[ _subtree_index ] = node;
         if ( !node.isExternal() && !node.isRoot() && ( _subtree_index <= ( TreePanel.MAX_SUBTREES - 1 ) ) ) {
             _sub_phylogenies[ _subtree_index ] = _phylogeny;
             _sub_phylogenies_temp_roots[ _subtree_index ] = node;
@@ -4650,6 +4839,7 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
     }
 
     final void superTree() {
     }
 
     final void superTree() {
+        _nodes_in_preorder = null;
         final PhylogenyNode temp_root = _sub_phylogenies_temp_roots[ _subtree_index - 1 ];
         for( final PhylogenyNode n : temp_root.getDescendants() ) {
             n.setParent( temp_root );
         final PhylogenyNode temp_root = _sub_phylogenies_temp_roots[ _subtree_index - 1 ];
         for( final PhylogenyNode n : temp_root.getDescendants() ) {
             n.setParent( temp_root );
@@ -4877,11 +5067,11 @@ public final class TreePanel extends JPanel implements ActionListener, MouseWhee
         }
     }
 
         }
     }
 
-    synchronized void setImageMap( final Hashtable<String, BufferedImage> image_map ) {
+    public synchronized void setImageMap( final Hashtable<String, BufferedImage> image_map ) {
         getMainPanel().setImageMap( image_map );
     }
 
         getMainPanel().setImageMap( image_map );
     }
 
-    synchronized Hashtable<String, BufferedImage> getImageMap() {
+    public synchronized Hashtable<String, BufferedImage> getImageMap() {
         return getMainPanel().getImageMap();
     }
 }
         return getMainPanel().getImageMap();
     }
 }