changeset 1904:78e7dfeec5dc

Move treemap to c.r.t.client.swing.components.experimental This patch moves treemap code not specific to the heap treemap to c.r.t.client.swing.components.experimental. Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/019181.html Original-thread: http://icedtea.classpath.org/pipermail/thermostat/2015-August/015544.html
author James Aziz <jaziz@redhat.com>
date Mon, 06 Jun 2016 15:17:50 -0400
parents f656ad7098bf
children 5a3e91f53ee3
files client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/BreadcrumbIconResources.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/SquarifiedTreeMap.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapBreadcrumb.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapComponent.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapNode.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapObserver.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapToolbar.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapZoomBar.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeProcessor.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/ValueFormatter.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/LocaleResources.java client/swing/src/main/resources/com/redhat/thermostat/client/swing/components/experimental/breadcrumb_body.png client/swing/src/main/resources/com/redhat/thermostat/client/swing/components/experimental/breadcrumb_head.png client/swing/src/main/resources/com/redhat/thermostat/client/swing/components/experimental/breadcrumb_tail.png client/swing/src/main/resources/com/redhat/thermostat/client/swing/internal/strings.properties client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/SquarifiedTreeMapTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapComponentTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapNodeTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapToolbarTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapZoomBarTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeProcessorTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/ValueFormatterTest.java vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapIconResources.java vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/locale/LocaleResources.java vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/locale/strings.properties vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/swing/breadcrumb_body.png vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/swing/breadcrumb_head.png vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/swing/breadcrumb_tail.png vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramConverter.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SquarifiedTreeMap.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapBreadcrumb.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapComponent.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapNode.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapObserver.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapPanel.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapToolbar.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapZoomBar.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeProcessor.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ValueFormatter.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramConverterTest.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SquarifiedTreeMapTest.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapComponentTest.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapNodeTest.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapToolbarTest.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapZoomBarTest.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeProcessorTest.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ValueFormatterTest.java
diffstat 47 files changed, 3815 insertions(+), 3753 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/BreadcrumbIconResources.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.client.ui.IconDescriptor;
+
+class BreadcrumbIconResources {
+
+    private static final String PACKAGE_PATH =
+        BreadcrumbIconResources.class.getPackage().getName().replace(".", "/");
+    public static final String BREADCRUMB_HEAD = PACKAGE_PATH + "/breadcrumb_head.png";
+    public static final String BREADCRUMB_BODY = PACKAGE_PATH + "/breadcrumb_body.png";
+    public static final String BREADCRUMB_TAIL = PACKAGE_PATH + "/breadcrumb_tail.png";
+
+    private static Map<String, IconDescriptor> icons = new HashMap<>();
+
+    public synchronized static IconDescriptor getIcon(String path) {
+        if (!icons.containsKey(path)) {
+            try {
+                IconDescriptor icon = IconDescriptor.loadIcon(BreadcrumbIconResources.class.getClassLoader(),
+                        path);
+                icons.put(path, icon);
+
+            } catch (IOException ex) {
+                Logger.getLogger(BreadcrumbIconResources.class.getName()).log(Level.SEVERE, ex.getMessage(), ex);
+            }
+        }
+        return icons.get(path);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/SquarifiedTreeMap.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,463 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+
+
+/**
+ *  This class implements the Squarified algorithm for TreeMaps. Using it, it is 
+ *  possible to associate a rectangle to a {@link TreeMapNode} element and its
+ *  children.
+ *  <p>
+ *  @see TreeMapNode
+ *  @see TreMapBuilder
+ */
+public class SquarifiedTreeMap {
+    
+    /**
+     * List of node to represent as TreeMap.
+     */
+    private LinkedList<TreeMapNode> elements;
+    
+    /**
+     * Represent the area in which draw nodes.
+     */
+    private Rectangle2D.Double container;
+    
+    private enum DIRECTION {
+        LEFT_RIGHT,
+        TOP_BOTTOM
+    }
+
+    /**
+     * Indicates the drawing direction.
+     */
+    private DIRECTION drawingDir;
+
+    /**
+     * The rectangles area available for drawing.
+     */
+    private Rectangle2D.Double availableArea;
+
+    /**
+     * List of the calculated rectangles.
+     */
+    private List<TreeMapNode> squarifiedNodes;
+
+    /**
+     * List of the current rectangles under processing.
+     */
+    private List<TreeMapNode> currentRow;
+
+    /**
+     * Coordinates on which to draw.
+     */
+    private double lastX = 0;
+    private double lastY = 0;
+
+
+    /**
+     * Constructor.
+     * 
+     * @param d the dimension of the total area in which draw elements.
+     * @param list the list of elements to draw as TreeMap.
+     * 
+     * @throws a NullPointerException if one of the arguments is null.
+     */
+    public SquarifiedTreeMap(Rectangle2D.Double bounds, List<TreeMapNode> list) {
+        this.elements = new LinkedList<>();
+        elements.addAll(Objects.requireNonNull(list));
+        this.container = Objects.requireNonNull(bounds);
+    }
+
+    /**
+     * Invoke this method to calculate the rectangles for the TreeMap.
+     * 
+     * @return a list of node having a rectangle built in percentage to the 
+     * available area.
+     */
+    public List<TreeMapNode> squarify() {
+        initializeArea();
+        prepareData(elements);
+        List<TreeMapNode> row = new ArrayList<>();
+        double w = getPrincipalSide();	
+        squarify(elements, row, w);
+        return getSquarifiedNodes();
+    }
+
+    /**
+     * Calculate recursively the rectangles to draw and their size.
+     * 
+     * @param nodes the list of elements to draw.
+     * @param row the list of current rectangles to process.
+     * @param w the side against which to calculate the rectangles.
+     */
+    private void squarify(LinkedList<TreeMapNode> nodes, List<TreeMapNode> row, double w) {
+        if (nodes.isEmpty() && row.isEmpty()) {
+            // work done
+            return;
+        }
+        if (nodes.isEmpty()) {
+            // no more element to process, just draw current row
+            finalizeRow(row);
+            return;
+        }
+        if (row.isEmpty()) {
+            // add the first element to the row and iterate the process over it
+            row.add(nodes.getFirst());
+            nodes.removeFirst();
+            squarify(nodes, row, w);
+            return;
+        }
+        
+        /*  Greedy step: calculate the best aspect ratio of actual row and the
+         *  best aspect ratio given by adding another rectangle to the row.
+         *  If the current row can not be improved then finalize it
+         *  else add the next element, to improve the global aspect ratio
+         */
+        List<TreeMapNode> expandedRow = new ArrayList<TreeMapNode>(row);
+        expandedRow.add(nodes.getFirst());
+        double actualAspectRatio = bestAspectRatio(row, w);
+        double expandedAspectRatio = bestAspectRatio(expandedRow, w);
+
+        if (!willImprove(actualAspectRatio, expandedAspectRatio)) {
+            finalizeRow(row);
+            squarify(nodes, new ArrayList<TreeMapNode>(), getPrincipalSide());
+        } else {
+            nodes.removeFirst();
+            squarify(nodes, expandedRow, w);
+        }
+    }
+
+    /**
+     * Return the rectangles list.
+     * @return a list of rectangles.
+     */
+    public List<TreeMapNode> getSquarifiedNodes() {
+        return squarifiedNodes;
+    }
+    
+    /**
+     * Initialize the available area used to create the tree map
+     */
+    private void initializeArea() {
+        availableArea = new Rectangle2D.Double(container.getX(), container.getY(), 
+                container.getWidth(), container.getHeight());
+        lastX = 0;
+        lastY = 0;
+        squarifiedNodes = new ArrayList<>();
+        currentRow = new ArrayList<>();
+        updateDirection();
+    }
+    
+    /**
+     * Recalculate the drawing direction.
+     */
+    private void updateDirection() {
+        drawingDir = availableArea.getWidth() > availableArea.getHeight() ? 
+                DIRECTION.TOP_BOTTOM : DIRECTION.LEFT_RIGHT;
+    }
+
+
+    /**
+     * Invert the drawing direction.
+     */
+    private void invertDirection() {
+        drawingDir = drawingDir == DIRECTION.LEFT_RIGHT ? 
+                DIRECTION.TOP_BOTTOM : DIRECTION.LEFT_RIGHT;
+    }
+    
+    /**
+     * Keep the current list of nodes which produced the best aspect ratio
+     * in the available area, draw their respective rectangles and reinitialize 
+     * the current row to draw.
+     * <p>
+     * @param nodes the list of numbers which represent the rectangles' area.
+     * @return the number of Rectangles created.
+     */
+    private void finalizeRow(List<TreeMapNode> nodes) {
+        if (nodes == null || nodes.isEmpty()) {
+            return;
+        }
+        // get the total weight of nodes in order to calculate their percentages
+        double sum = getSum(nodes);
+        // greedy optimization step: get the best aspect ratio for nodes drawn 
+        // on the longer and on the smaller side, to evaluate the best.
+        double actualAR = bestAspectRatio(nodes, getPrincipalSide());
+        double alternativeAR = bestAspectRatio(nodes, getSecondarySide());
+      
+        if (willImprove(actualAR, alternativeAR)) {
+            invertDirection();
+        }
+
+        for (TreeMapNode node: nodes) {
+            // assign a rectangle calculated as percentage of the total weight
+            Rectangle2D.Double r = createRectangle(sum, node.getWeight());
+            node.setRectangle(r);
+            
+            // recalculate coordinates to draw next rectangle
+            updateXY(r);
+
+            // add the node to the current list of rectangles in processing
+            currentRow.add(node);
+        }
+        // recalculate the area in which new rectangles will be drawn and 
+        // reinitialize the current list of node to represent.
+        reduceAvailableArea();
+        newRow();
+    }
+    
+
+    /**
+     * Create a rectangle having area = @param area in percentage of @param sum. 
+     * <p>
+     * For example: assume @param area = 4 and @param sum = 12 and the 
+     * drawing direction is top to bottom. <br>
+     * <p>
+     *   __ __ __ __
+     *  |     |     | 
+     *  |__ __|     |  
+     *  |__ __ __ __|
+     * 
+     * <br>the internal rectangle will be calculated as follow:<br>
+     *  {@code height = (4 / 9) * 3} <--note that the principal side for actual  
+     *  drawing direction is 3.
+     *  <br>Now it is possible to calculate the width:<br>
+     *  {@code width = 4 / 1.3} <-- note this is the height value
+     *  
+     * <p>
+     * @param sum the total size of all rectangles in the actual row.
+     * @param area this Rectangle's area.
+     * @return the Rectangle which correctly fill the available area.
+     */
+    private Rectangle2D.Double createRectangle(Double sum, Double area) {
+        double side = getPrincipalSide();
+        double w = 0;
+        double h = 0;
+        
+        //don't want division by 0
+        if (validate(area) == 0 || validate(sum) == 0 || validate(side) == 0) {
+            return new Rectangle2D.Double(lastX, lastY, 0, 0);
+        }
+        
+        // calculate the rectangle's principal side relatively to the container 
+        // rectangle's principal side.
+        if (drawingDir == DIRECTION.TOP_BOTTOM) {
+            h = (area / sum) * side;
+            w = area / h;
+        } else {
+            w = (area / sum) * side;
+            h = area / w;
+        }        
+        return new Rectangle2D.Double(lastX, lastY, w, h);
+    }
+    
+    /**
+     * Check if a double value is defined as Not a Number and sets it to 0.
+     * @param d the value to check.
+     * @return the checked value: 0 if the given number is NaN, else the number
+     * itself.
+     */
+    private double validate(double d) {
+        if (d == Double.NaN) {
+            d = 0;
+        }
+        return d;
+    }
+
+    /**
+     * Check in which direction the rectangles have to be drawn.
+     * @return the side on which rectangles will be created.
+     */
+    private double getPrincipalSide() {
+        return drawingDir == DIRECTION.LEFT_RIGHT ? 
+                availableArea.getWidth() : availableArea.getHeight();
+    }
+
+    /**
+     * 
+     * @return the secondary available area's side.
+     */
+    private double getSecondarySide() {
+        return drawingDir == DIRECTION.LEFT_RIGHT ? 
+                availableArea.getHeight() : availableArea.getWidth();
+    }
+
+    /**
+     * Sum the elements in the list.
+     * @param nodes the list which contains elements to sum.
+     * @return the sum of the elements.
+     */
+    private double getSum(List<TreeMapNode> nodes) {
+        double sum = 0;
+        for (TreeMapNode n : nodes) {
+            sum += n.getWeight();
+        }
+        return sum;
+    }
+
+    /**
+     * Recalculate the origin to draw next rectangles.
+     * @param r the rectangle from which recalculate the origin.
+     */
+    private void updateXY(Rectangle2D.Double r) {
+        if (drawingDir == DIRECTION.LEFT_RIGHT) {
+            //lastY doesn't change
+            lastX += r.width; 
+        } else {
+            //lastX doesn't change
+            lastY += r.height;
+        }
+    }
+
+    /**
+     * Initialize the origin at the rectangle's origin.
+     * @param r the rectangle used as origin source.
+     */
+    private void initializeXY(Rectangle2D.Double r) {
+        lastX = r.x;
+        lastY = r.y;
+    }
+
+    /**
+     * Reduce the size of the available rectangle. Use it after the current 
+     * row's closure.
+     */
+    private void reduceAvailableArea() {
+        if (drawingDir == DIRECTION.LEFT_RIGHT) {
+            // all rectangles inside the row have the same height
+            availableArea.height -= currentRow.get(0).getRectangle().height;
+            availableArea.y = lastY + currentRow.get(0).getRectangle().height;
+            availableArea.x = currentRow.get(0).getRectangle().x;
+        } else {
+            // all rectangles inside the row have the same width
+            availableArea.width -= currentRow.get(0).getRectangle().width;
+            availableArea.x = lastX + currentRow.get(0).getRectangle().width;
+            availableArea.y = currentRow.get(0).getRectangle().y;
+        }
+        updateDirection();
+        initializeXY(availableArea);
+    }
+    
+    /**
+     * Close the current row and initialize a new one.
+     */
+    private void newRow() {
+        squarifiedNodes.addAll(currentRow);
+        currentRow = new ArrayList<>();
+    }
+
+    /**
+     * Calculate the aspect ratio for all the rectangles in the list and
+     * return the max of them.
+     * @param row the list of rectangles.
+     * @param side the side against which to calculate the the aspect ratio.
+     * @return the max aspect ratio calculated for the row.
+     */
+    private double bestAspectRatio(List<TreeMapNode> row, double side) {
+        if (row == null || row.isEmpty()) {
+            return Double.MAX_VALUE;
+        }
+        double sum = getSum(row);
+        double max = 0;
+        // calculate the aspect ratio against the main side, and also its inverse.
+        // this is because aspect ratio of rectangle 6x4 can be calculated as 
+        // 6/4 but also 4/6. Here the aspect ratio has been calculated as 
+        // indicated in the Squarified algorithm.
+        for (TreeMapNode node : row) {
+            double m1 = (Math.pow(side, 2) * node.getWeight()) / Math.pow(sum, 2);
+            double m2 = Math.pow(sum, 2) / (Math.pow(side, 2) * node.getWeight());
+            double m = Math.max(m1, m2);
+
+            if (m > max) {
+                max = m;
+            }
+        }
+        return max;
+    }
+
+    
+    /**
+     * Prepare the elements in the list, sorting them and transforming them
+     * proportionally the given dimension.
+     * @param dim the dimension in which rectangles will be drawn.
+     * @param elements the list of elements to draw.
+     * @return the list sorted and proportioned to the dimension.
+     */
+    private void  prepareData(List<TreeMapNode> elements) {
+        if (elements == null || elements.isEmpty()) {
+            return;
+        }
+        TreeMapNode.sort(elements);
+        double totArea = availableArea.width * availableArea.height;
+        double sum = getSum(elements);
+        
+        // recalculate weights in percentage of their sum
+        for (TreeMapNode node : elements) {
+            double w = (node.getWeight()/sum) * totArea;
+            node.setWeight(w);
+        }
+    }
+
+    /**
+     * This method check which from the values in input, that represent 
+     * rectangles' aspect ratio, produces more approximatively a square.
+     * It checks if one of the aspect ratio values gives a value nearest to 1 
+     * against the other, which means that width and height are similar.
+     * @param actualAR the actual aspect ratio
+     * @param expandedAR the aspect ratio to evaluate
+     * @return false if the actual aspect ratio is better than the new one, 
+     * else true.
+     */
+    private boolean willImprove(double actualAR, double expandedAR) {
+        if (actualAR == 0) {
+            return true;
+        }
+        if (expandedAR == 0) {
+            return false;
+        }
+        // check which value is closer to 1, the square's aspect ratio
+        double v1 = Math.abs(actualAR - 1);
+        double v2 = Math.abs(expandedAR - 1);       
+        return v1 > v2;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapBreadcrumb.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import java.awt.Font;
+import java.awt.Image;
+import java.awt.Rectangle;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.font.FontRenderContext;
+import java.util.LinkedList;
+import java.util.Objects;
+import java.util.Stack;
+
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.UIManager;
+
+import com.redhat.thermostat.client.swing.components.Icon;
+
+/**
+ * This object creates a breadcrumb navigation bar used to trace 
+ * {@link TreeMapComponent} objects' state.
+ */
+public class TreeMapBreadcrumb extends JComponent implements TreeMapObserver {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Font used by bradcrumb items.
+     */
+    private Font FONT = (Font) UIManager.get("thermostat-default-font");
+
+    /**
+     * Stack containing all items part of the breadcrumb.
+     */
+    private Stack<BreadcrumbItem> items;
+
+    /**
+     * The TreeMap object to interact with.
+     */
+    private TreeMapComponent treemap;
+
+    /**
+     * Constructor. Creates a breadcumbs navigation bar with the starting 
+     * element and register itself as observer to the given treemap.
+     * 
+     * @param start the treemap's root.
+     */
+    public TreeMapBreadcrumb(TreeMapComponent treemap, TreeMapNode start) {
+        super();  
+        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+        this.items = new Stack<>();
+        this.treemap = Objects.requireNonNull(treemap);
+        this.treemap.register(this);
+        buildBreadcrumb(start);
+    }
+
+
+    /**
+     * Builds the breadcrumb using the nodes'ancestors.
+     * @param node the tree's branch to represent ad breadcrumb bar.
+     */
+    public void buildBreadcrumb(TreeMapNode node) {
+        LinkedList<TreeMapNode> nodes = node.getAncestors();
+
+        while (!nodes.isEmpty()) {
+            BreadcrumbItem item = new BreadcrumbItem(nodes.removeLast());
+            items.push(item);
+            add(item);
+        }
+        // the first element has no tail
+        items.get(0).setAsFirst();
+
+        //the last element has no head
+        items.peek().setAsLast();
+    }
+
+
+    @Override
+    public void notifySelection(TreeMapNode node) {
+        // do nothing
+    }
+
+    @Override
+    public void notifyZoomIn(TreeMapNode node) {
+        items.clear();
+        removeAll();
+        buildBreadcrumb(node);
+    }
+
+    @Override
+    public void notifyZoomOut() {
+        this.remove(items.pop());
+        items.peek().setAsLast();
+        items.peek().repaint();
+    }
+
+    @Override
+    public void notifyZoomFull() {
+        items.clear();
+        this.removeAll();
+        BreadcrumbItem item = new BreadcrumbItem(treemap.getTreeMapRoot());
+        item.setAsFirst();
+        item.setAsLast();
+        items.push(item);
+        this.add(item);
+    }
+
+
+
+    /**
+     *  This class allows to create a single item in a breadcrumb object.
+     *  This component has 3 {@link JLabel}s which contain the images needed
+     *  to draw an arrow.
+     *        _____
+     *    >  |_____|  >
+     *    |     |     |
+     *  tail   body  head
+     *  
+     */
+    class BreadcrumbItem extends JComponent {
+
+        private static final long serialVersionUID = 1L;
+
+        private final String ROOT_TEXT = "root";
+
+        private JLabel tail;
+        private JLabel body;
+        private JLabel head;
+
+        /**
+         * The node this items represents.
+         */
+        private TreeMapNode node;
+
+        /**
+         * The constructor creates a complete item, including both tail and head
+         * @param node
+         */
+        public BreadcrumbItem(final TreeMapNode node) {
+            super();
+            this.node = node;
+            this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
+            initComponent();
+
+            /**
+             * Simulate the click effect increasing and reducing the font size
+             */
+            this.addMouseListener(new MouseAdapter() {
+
+                @Override
+                public void mouseReleased(MouseEvent arg0) {
+                    increaseFont(body, 2);
+                }
+
+                @Override
+                public void mousePressed(MouseEvent arg0) {
+                    increaseFont(body, -2);
+                }
+
+                @Override
+                public void mouseClicked(MouseEvent arg0) {
+                    treemap.zoomIn(node);
+                }
+            });
+        }
+
+
+        /**
+         * Increases the given component's font size.
+         * @param comp the component which edit the font size to.
+         * @param increment value of the increment. Negative values reduce the 
+         * font size.
+         */
+        private void increaseFont(JComponent comp, int increment) {
+            Font f = comp.getFont();
+            int newSize = f.getSize() + increment;
+            f = new Font(f.getName(), f.getStyle(), newSize);
+            comp.setFont(f);
+            comp.repaint();
+        }
+
+        private void initComponent() {
+            initTail();
+            initBody();
+            initHead();
+        }
+
+
+        private void initTail() {
+            tail = new JLabel();
+            tail.setIcon(new Icon(BreadcrumbIconResources.getIcon(BreadcrumbIconResources.BREADCRUMB_TAIL)));
+            this.add(tail);
+        }
+
+        private void initHead() {
+            head = new JLabel();
+            head.setIcon(new Icon(BreadcrumbIconResources.getIcon(BreadcrumbIconResources.BREADCRUMB_HEAD)));
+            this.add(head);
+        }
+
+        private void initBody() {
+            body = new JLabel();
+            body.setFont(FONT);
+            body.setHorizontalTextPosition(JLabel.CENTER);
+            body.setText(node.getLabel());
+            adaptIcon(body, new Icon(BreadcrumbIconResources.getIcon(BreadcrumbIconResources.BREADCRUMB_BODY)));
+            this.add(body);
+        }
+
+
+        public TreeMapNode getNode() {
+            return this.node;
+        }
+
+        /**
+         * Remove the tail of his breadcrumb item.
+         */
+        public void setAsFirst() {
+            this.remove(tail);
+            this.tail = null;
+            this.body.setText(ROOT_TEXT);
+            adaptIcon(body, new Icon(BreadcrumbIconResources.getIcon(BreadcrumbIconResources.BREADCRUMB_BODY)));
+        }
+
+        /**
+         * Remove the head of his breadcrumb item.
+         */
+        public void setAsLast() {
+            this.remove(head);
+            this.head = null;
+        }
+
+        /**
+         * Sets the text of this item, which is placed in the body.
+         * @param text
+         */
+        public void setText(String text) {
+            body.setText(text);
+        }
+
+        public int getHeight() {
+            return body.getPreferredSize().height;
+        }
+    }
+
+    /**
+     * Calculates the labels' text size in order to scale the given image
+     * and to apply to it.
+     */
+    private void adaptIcon(JLabel label, ImageIcon icon) {
+        Rectangle fontArea;
+        try {
+            fontArea = label.getFont().getStringBounds(label.getText(), 
+                    new FontRenderContext(label.getFont().getTransform(),
+                            false, false)).getBounds();
+
+        } catch (NullPointerException npe) {
+            fontArea = label.getBounds();
+        }
+        
+        Image img = icon.getImage();
+        Image newimg = img.getScaledInstance(fontArea.getBounds().width + 10, 
+                img.getHeight(null),  java.awt.Image.SCALE_SMOOTH);
+        icon = new ImageIcon(newimg);
+        label.setIcon(icon);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapComponent.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,785 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Graphics;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.font.FontRenderContext;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.Stack;
+
+import javax.swing.BorderFactory;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.border.Border;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.EtchedBorder;
+import javax.swing.border.LineBorder;
+
+import com.redhat.thermostat.client.swing.ThermostatSwingCursors;
+
+/**
+ * This class allows to represent a hierarchical data structure as a TreeMap.
+ * It extends {@link JComponent} so it can be used like usual Swing objects.
+ *
+ */
+public class TreeMapComponent extends JComponent {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * TreeMap's graphic root.
+     */
+    Comp mainComp;
+
+    /**
+     * Label Object to clone for faster initialization.
+     */
+    private Label cachedLabel;
+
+    /**
+     * The tree to render as TreeMap.
+     */
+    TreeMapNode tree;
+
+    /**
+     * Horizontal and vertical padding for nested component.
+     */
+    private final int X_PADDING = TreeProcessor.X_PADDING;
+    private final int Y_PADDING = TreeProcessor.Y_PADDING;
+
+    /**
+     * Min size for rectangles' sides. rectangles having one or both sides less
+     * than MIN_SIDE pixels will be not drawn.
+     */
+    private final int MIN_SIDE = 1;
+
+    /**
+     * Default value for a TreeMap component.
+     */
+    private static final String TITLE = "";
+
+    /**
+     * TreeMap UI Constraint.
+     */
+    public static final int SIMPLE = 0;
+    public static final int FLAT = 1;
+    public static final int ETCHED_LOWERED = 2;
+    public static final int ETCHED_RAISED = 3;
+
+    /**
+     * Stores the chosen UI mode.
+     */
+    private int borderStyle = ETCHED_LOWERED;
+
+    /**
+     * The components' border
+     */
+    private Border defaultBorder;
+
+    /**
+     * Font and size for this component's label.
+     */
+    private int FONT_SIZE = 8;
+    private Font FONT = (Font) UIManager.get("thermostat-default-font");
+
+
+    /**
+     * Variable in which store last resize dimension.
+     */
+    private Dimension lastDim;
+
+    /**
+     * Variable in which store last resize event call time.
+     */
+    private static long lastCall = 0;
+
+    /**
+     * Wait time in millisec to resize the TreeMap.
+     */
+    private final int MIN_DRAGGING_TIME = 60;
+
+
+    /**
+     * Stack containing the zoom calls on the TreeMap.
+     */
+    private Stack<TreeMapNode> zoomStack;
+
+    /**
+     * This object stores the last clicked rectangle in the TreeMap, in order to 
+     * repaint it when another rectangle will be selected.
+     */
+    private static Comp lastClicked;
+    
+    /**
+     * List of objects observing this.
+     */
+    private List<TreeMapObserver> observers;
+
+    /**
+     * Constructor. It draw a TreeMap of the given tree in according to the 
+     * {@Dimension} object in input.
+     * 
+     * @param tree the tree to represent as TreeMap.
+     * @param d the dimension the TreeMap will fulfill.
+     * 
+     * @throws NullPointerException if one of the parameters is null
+     */
+    public TreeMapComponent(TreeMapNode tree, Dimension d) {
+        super();
+        Objects.requireNonNull(tree);
+        Objects.requireNonNull(d);
+        this.tree = tree;
+        lastDim = getSize();
+        this.zoomStack = new Stack<>();
+        this.zoomStack.push(this.tree);
+        this.observers = new ArrayList<>();
+
+        // assign a rectangle to the tree's root in order to process the tree.
+        Rectangle2D.Double area = new Rectangle2D.Double(0, 0, d.width, d.height);
+
+        // calculate rectangles of tree's subtrees
+        TreeProcessor.processTreeMap(tree, area);
+
+        drawTreeMap(tree); 
+
+        addResizeListener(this);        
+        repaint();
+    }
+
+    /**
+     * This method returns the root of the tree showed ad TreeMap.
+     * @return the TreeMap's root node.
+     */
+    public TreeMapNode getTreeMapRoot() {
+        return this.tree;
+    }
+
+    /**
+     * This method is responsible for the TreeMap drawing process.
+     * @param tree the tree to represent as TreeMap.
+     */
+    private void drawTreeMap(TreeMapNode tree) {
+        // draw root
+        drawMainComp(tree);
+        setBorderStyle(borderStyle);
+        
+        // draw subtrees nested in children 
+        for (TreeMapNode child : tree.getChildren()) {
+            drawSubTree(child, mainComp);
+        }
+        // setup this component
+        prepareGUI();
+    }
+
+    /**
+     * This method prepares the layout for this component. 
+     */
+    private void prepareGUI() {
+        setLayout(new BorderLayout());
+        setBounds(mainComp.getBounds());
+        setBorder(null);
+        add(mainComp, BorderLayout.CENTER);
+        revalidate();
+        repaint();
+    }
+
+    /**
+     * This method prepares the main component which is the parent object where 
+     * sub components will be placed. 
+     * @param tree the tree's root used to prepare the main component.
+     */
+    private void drawMainComp(TreeMapNode tree) {
+        mainComp = new Comp();
+        mainComp.setLayout(null);
+        mainComp.setBounds(tree.getRectangle().getBounds());        
+        mainComp.setNode(tree);
+        cachedLabel = new Label(TITLE + tree.getLabel());        
+        addLabelIfPossible(TITLE + tree.getLabel(), mainComp);
+    }
+
+    /**
+     * Create a TreeMapComp from the given node. The component is not 
+     * instantiated as a new component but is cloned from an existing one, in 
+     * order to improve performance.
+     * 
+     * @param node the node to represent as a component.
+     * @return the component representing the given node.
+     */
+    private Comp renderizeNode(TreeMapNode node) {
+        // if the rectangle's node is too small to be viewed, don't draw it.
+        if (node.getRectangle().getWidth() <= MIN_SIDE || 
+                node.getRectangle().getHeight() <= MIN_SIDE) {
+            return null;
+        }
+
+        Comp comp = (Comp) mainComp.clone();
+        comp.setBounds(node.getRectangle().getBounds());
+
+        return comp;
+    }
+
+    /**
+     * This method checks if the given container has enough space to instantiate
+     * a Label in it. If yes, a Label is cloned from an existing one, in order 
+     * to improve performance. If not, it exits.
+     * 
+     * @param s the label text.
+     * @param cont the parent container which will contain the new label.
+     * @return the cloned label.
+     */
+    private Label addLabelIfPossible(String s, Container cont) {
+        if (s == null || s.equals("")) {
+            return null;
+        }
+        int componentW = cont.getSize().width;
+        int componentH = cont.getSize().height;
+        // get the rectangle associated to the area needed for the label's text
+        Rectangle fontArea = FONT.getStringBounds(s, 
+                new FontRenderContext(FONT.getTransform(),
+                        false, false)).getBounds();
+
+        // if the container is greater than the label, add it to the container
+        if (componentW > fontArea.width && componentH > fontArea.height) {
+            Label label = (Label) cachedLabel.clone();
+            label.setBounds(5, 1, cont.getWidth(), fontArea.height);
+            label.setText(s);
+            cont.add(label);
+            return label;
+        }
+        return null;
+    }
+
+    /**
+     * Draw the whole {@param tree}'s subtree inside the given component.
+     * @param tree the tree to draw
+     * @param parent the component in which build the tree.
+     */
+    private void drawSubTree(TreeMapNode tree, JComponent parent) {
+        Comp comp = addCompIfPossible(tree, parent);
+
+        // if space was enough to draw a component, try to draw its children
+        if (comp != null) {
+            comp.setNode(tree);
+            for (TreeMapNode child : tree.getChildren()) {
+                drawSubTree(child, comp);
+            }
+        }
+    }
+
+    /**
+     * Create and add to the {@link Container} given in input a 
+     * {@link java.awt.event.ComponentListener} listener.
+     * @param container the container in to assign the listener.
+     */
+    private void addResizeListener(final Container container) {
+        ComponentAdapter adapter = new ComponentAdapter() {
+            public void componentResized(ComponentEvent e) {
+                // if enough time is passed from the last call, redraw the TreeMap
+                if (canResize(MIN_DRAGGING_TIME)) {
+                    Dimension newDim = container.getSize();
+
+                    if (isChangedSize(newDim)) {
+                        redrawTreeMap(tree); 
+                    }
+                } 
+            }            
+        };
+        container.addComponentListener(adapter);
+    }
+
+    /**
+     * This method checks if the given container has enough space to instantiate
+     * a TreeMapComp object in it. If yes, a Label is cloned from an existing 
+     * one, in order to improve performance. If not, it exits.
+     * 
+     * @param node the node to draw and add to the given container.
+     * @param cont the parent container which will contain the new component.
+     * @return true if the component was created and added, else false.
+     */
+    private Comp addCompIfPossible(TreeMapNode node, Container cont) {
+        Rectangle2D rect = node.getRectangle();
+        // if the ndoe's rectangle is smaller than the container, it is added
+        if (cont.getWidth() > rect.getWidth() + X_PADDING && 
+                cont.getHeight() > rect.getHeight() + Y_PADDING) {
+
+            Comp toReturn = renderizeNode(node);
+            if (toReturn == null) {
+                return null;
+            }
+            addLabelIfPossible(TITLE + node.getLabel(), toReturn);
+
+            // leaves some space from the parent's origin location
+            Point loc = toReturn.getLocation();
+            loc.x += X_PADDING;
+            loc.y += Y_PADDING;
+            toReturn.setLocation(loc);
+
+            cont.add(toReturn);
+            return toReturn;
+        }
+        return null;
+    }
+
+
+    /**
+     * This method recalculates and redraws the TreeMap in according to the size
+     * of this component and the actual {@link TreeMapNode} object.
+     */
+    private void redrawTreeMap(TreeMapNode newRoot) {
+        tree = newRoot;
+        Rectangle2D.Double newArea = tree.getRectangle();
+        // give to the root node the size of this object so it can be recalculated
+        newArea.width = getSize().width;
+        newArea.height = getSize().height;
+
+        // recalculate the tree
+        TreeProcessor.processTreeMap(tree, newArea);
+
+        removeAll();
+        drawTreeMap(tree);        
+    }
+
+    boolean isZoomInEnabled(TreeMapNode node) {
+        return !(node == null
+                || node.equals(this.tree)
+                || node.isLeaf());
+    }
+
+    public void zoomIn(TreeMapNode node) {
+        if (isZoomInEnabled(node)) {
+            fillZoomStack(node.getAncestors());
+            redrawTreeMap(node);
+            notifyZoomInToObservers(zoomStack.peek());
+        } 
+    }
+
+    private void fillZoomStack(LinkedList<TreeMapNode> ancestors) {
+        zoomStack.clear();
+        while (!ancestors.isEmpty()) {
+            zoomStack.push(ancestors.removeLast());
+        }
+    }
+
+    public void zoomOut() {
+        // if the actual root element is not the tree's original root
+        if (zoomStack.size() > 1) {
+            zoomStack.pop();
+            redrawTreeMap(zoomStack.peek());
+            notifyZoomOutToObservers();
+        }
+    }
+
+    /**
+     * Zoom out the view directly to the original root.
+     */
+    public void zoomFull() {
+        if (zoomStack.size() > 1) {
+            clearZoomCallsStack();
+            redrawTreeMap(zoomStack.peek());
+            notifyZoomFullToObservers();
+        }
+    }
+    
+    /**
+     * Add the object in input to the list of registered objects to this TreeMap.
+     * @param observer the Notifiable object to register to this object.
+     */
+    public void register(TreeMapObserver observer) {
+        this.observers.add(observer);
+    }
+    
+    /**
+     * Remove the object in input from the list of registered objects to this TreeMap.
+     * @param observer the Notifiable object to unregister from this object.
+     */
+    public void unregister(TreeMapObserver observer) {
+        this.observers.remove(observer);
+    }
+    /**
+     * Notify observers that an object in the TreeMap has been selected.
+     * @param comp the selected component.
+     */
+    private void notifySelectionToObservers(TreeMapNode node) {
+        for (TreeMapObserver observer : observers) {
+            observer.notifySelection(node);
+        }
+    }
+
+    /**
+     * Notify observers that  TreeMap has been zoomed.
+     * @param zoomedComponent 
+     */
+    private void notifyZoomInToObservers(TreeMapNode node) {
+        for (TreeMapObserver observer : observers) {
+            observer.notifyZoomIn(node);
+        }
+    }
+    
+    /**
+     * Notify observers that  TreeMap has been zoomed.
+     * @param zoomedComponent 
+     */
+    private void notifyZoomOutToObservers() {
+        for (TreeMapObserver observer : observers) {
+            observer.notifyZoomOut();
+        }
+    }
+    
+    /**
+     * Notify observers that  TreeMap has been zoomed.
+     * @param zoomedComponent 
+     */
+    private void notifyZoomFullToObservers() {
+        for (TreeMapObserver observer : observers) {
+            observer.notifyZoomFull();
+        }
+    }
+    
+    
+
+    /**
+     * Returns the list of zoom operation calls.
+     * @return the stack that holds the zoom calls.
+     */
+    public Stack<TreeMapNode> getZoomCallsStack() {
+        return zoomStack;
+    }
+
+    /**
+     * Clear the zoom calls of this object leaving the stack with just the root.
+     */
+    public void clearZoomCallsStack() {
+        while (zoomStack.size() > 1) {
+            zoomStack.pop();
+        }
+    }
+
+    /**
+     * check if last resize operation was called too closer to this
+     * one. If so, ignore it: the container is being dragged. 
+     * 
+     * @return true if this method is invoked at distance of 
+     * MIN_DRAGGING_TIME millisec, else false. 
+     */
+    private boolean canResize(int millisec) {
+        long time = System.currentTimeMillis();
+        if (time - lastCall >= millisec) {
+            lastCall = time;
+            return true;
+        }
+        return false;
+    }
+
+
+    /**
+     * Check if the dimension given in input differs from the last one stored
+     * by 2. 
+     * @param newDim the new dimension to check.
+     * @return true if the dimensions are different, else false.
+     */
+    private boolean isChangedSize(Dimension newDim) {
+        int minResizeDim = 2;
+        int deltaX = Math.abs(newDim.width - lastDim.width);
+        int deltaY = Math.abs(newDim.height - lastDim.height);
+
+        if (deltaX > minResizeDim || deltaY > minResizeDim) {
+            lastDim = newDim;
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Switch the component's visualization mode to the one given in input. 
+     * Use static constraints to set correctly a visualization mode.
+     * @param constraint the UI visualization mode to set.
+     */
+    public void setBorderStyle(int UIMode) {
+        this.borderStyle = UIMode;
+        switch (borderStyle) {
+            case 1 : {
+                defaultBorder = new EmptyBorder(0, 0, 0, 0);
+                break;
+            }    
+            case 2 : {                
+                defaultBorder = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.white, Color.darkGray);
+                break;
+            }
+            case 3 : {
+                defaultBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.white, Color.darkGray);
+                break;
+            }
+            default : {
+                defaultBorder = new LineBorder(Color.black, 1);
+                break;
+            }
+        }
+        applyBorderToSubtree(mainComp);
+    }
+    
+    /**
+     * Traverse recursively the tree from the given component applying to it 
+     * the default border.
+     * @param comp the subtree's root from which apply the border style.
+     */
+    private void applyBorderToSubtree(Comp comp) {
+        comp.setBorder(defaultBorder);
+        Component[] children = comp.getComponents();
+        for (int i = 0; i < children.length; i++) {
+            if (children[i] instanceof Comp) {
+                applyBorderToSubtree((Comp) children[i]);
+            }
+        }
+    }
+
+    /**
+     * Return the last clicked component inside the TreeMap.
+     * @return the last clicked {@Comp} object.
+     */
+    public Comp getClickedComponent() {
+        return lastClicked;
+    }
+
+    /**
+     * This class provides an extension of {@link JLabel} which main 
+     * characteristic is to implement the {@link Cloneable} interface in order
+     * to make his creation faster then JLabel class.
+     */
+    class Label extends JLabel implements Cloneable {
+        private static final long serialVersionUID = 1L;
+
+        public Label(String s) {
+            super(s);
+            setFont(FONT);
+            setBounds(0, 0, getPreferredSize().width, FONT_SIZE);
+        }
+
+        @Override
+        protected JLabel clone() {
+            Label clone = new Label("");
+            clone.setFont(getFont());
+            clone.setText(getText());
+            clone.setBackground(getBackground());
+            clone.setBounds(getBounds());
+            clone.setBorder(getBorder());
+            return clone;
+        }
+    }    
+
+    /**
+     * This class provides an extension of {@link JComponent} which main 
+     * characteristic is to implement {@link Cloneable} interface in order to
+     * make his creation faster. <br>
+     * It also provides some action listeners that allow to select it, performing
+     * zoom operations for the treemap.
+     */
+    class Comp extends JComponent implements Cloneable {
+
+        private static final long serialVersionUID = 1L;
+
+        /**
+         * The node represented by this component.
+         */
+        private TreeMapNode node;
+
+        /**
+         * The background color. It depends by the node's depth.
+         */
+        private Color color;
+
+        /**
+         * Reference to this.
+         */
+        private Comp thisComponent;
+
+        public Comp() {
+            super();
+            thisComponent = this;
+            addClickListener(this);
+            addMouseListener(this);
+        }
+
+        @Override
+        public Comp clone() {
+            Comp clone = new Comp();
+            clone.setBounds(getBounds());
+            clone.setBorder(getBorder());
+            clone.setLayout(getLayout());
+            clone.setOpaque(true);
+            return clone;
+        }
+
+        public void setNode(TreeMapNode node) {
+            this.node = node;
+            this.color = node.getColor();
+            ValueFormatter f = new ValueFormatter(this.node.getRealWeight());
+            this.setToolTipText(this.node.getLabel() + " - " + f.format());
+        }
+        
+        public TreeMapNode getNode() {
+            return this.node;
+        }
+
+        public Color getColor() {
+            return this.color;
+        }
+
+        public void setColor(Color c) {
+            this.color = c;
+        }
+
+        @Override
+        public void paintComponent(Graphics g) {
+            super.paintComponent(g); 
+            if (this.color != null) {
+                g.setColor(color);
+                g.fillRect(0, 0, getWidth(), getHeight());
+            }
+        }   
+
+        /**
+         * Add a mouse listener to this component. It allows to select it and
+         * zoom it. 
+         * @param component the component which will have the mouse listener.
+         */
+        private void addClickListener(final JComponent component) {
+            MouseListener click = new MouseAdapter() {
+                @Override
+                public void mousePressed(MouseEvent e) {
+                    // one left click select the rectangle
+                    if (SwingUtilities.isLeftMouseButton(e)) {
+                        selectComp();
+                    }
+                    // double left click to zoom in (on non-leaf nodes only)
+                    if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e)) {
+                        zoomIn(getNode());
+                    }
+                    // one right click to zoom out
+                    if (SwingUtilities.isRightMouseButton(e)) {
+                        zoomOut();
+                    }
+                    // one middle click to reset zoom
+                    if (SwingUtilities.isMiddleMouseButton(e)) {
+                        zoomFull();
+                    }
+                }
+            };
+            component.addMouseListener(click);
+        }
+
+        /**
+         * Add a mouse motion listener to this component. This allows for the mouse cursor to be changed into a
+         * magnifying glass icon when the cursor enters a zoomable component, and back to a default cursor when it
+         * exits a zoomable component.
+         * @param component the component which will have the mouse motion listener.
+         */
+        private void addMouseListener(final JComponent component) {
+            MouseListener listener = new MouseAdapter() {
+                @Override
+                public void mouseEntered(MouseEvent e) {
+                    if (getNode().isLeaf()) {
+                        setDefaultCursor();
+                    } else {
+                        setZoomableCursor();
+                    }
+                }
+
+                @Override
+                public void mouseExited(MouseEvent e) {
+                    if (!getNode().isLeaf()) {
+                        setDefaultCursor();
+                    } else {
+                        setZoomableCursor();
+                    }
+                }
+
+                private void setZoomableCursor() {
+                    component.setCursor(ThermostatSwingCursors.getZoomIconCursor());
+                }
+
+                private void setDefaultCursor() {
+                    component.setCursor(Cursor.getDefaultCursor());
+                }
+            };
+            component.addMouseListener(listener);
+        }
+
+        /**
+         * This method gives a darker color to this component and restore the
+         * original color to the last selected component.
+         */
+        private void selectComp() {
+            if (lastClicked != null) {
+                if (!lastClicked.getNode().isLeaf()) {
+                    lastClicked.setColor(lastClicked.getColor().brighter());
+                }
+                lastClicked.repaint();
+            } 
+            lastClicked = thisComponent;
+            if (!getNode().isLeaf()) {
+                setColor(getColor().darker());
+            }
+            repaint();
+            notifySelectionToObservers(node);
+        }
+    }
+}
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapNode.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,447 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import java.awt.Color;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This class provide a tree recursive implementation used in
+ * {@link SquarifiedTreeMap}. It contains a reference to the parent node and to
+ * a node list, which represent the node's children. It is also 
+ * possible to store generic information inside the node using a {@link Map} 
+ * object. Furthermore, the main property of this class is the chance to have a
+ * weight for the node and associate to it a {@link Rectangle2D.Double} object.
+ * 
+ * <p>When an instance of this class is created, it will automatically be 
+ * assigned a unique id.
+ * 
+ * <p>By default, this class' comparator is based on the nodes' weight.
+ * 
+ * <p>A static Quick Sort algorithm implementation is also provided by this 
+ * class.
+ * 
+ * @see Rectangle2D.Double
+ */
+public class TreeMapNode {
+        
+    /**
+     * Counter for assign unique id to nodes.
+     */
+    private static int idCounter = 0;
+
+    /**
+     * The rectangle which will graphically represent this node.
+     */
+    private Rectangle2D.Double rectangle;
+
+    /**
+     * This node's id.
+     */
+    private int id;
+    
+    /**
+     * A Map in which store information for this node.
+     */
+    private Map<String, String> info;
+    
+    /**
+     * Reference to the parent.
+     */
+    private TreeMapNode parent;
+    
+    /**
+     * Reference to children.
+     */
+    private List<TreeMapNode> children;
+    
+    /**
+     * The node's weight.
+     */
+    private double weight;
+    
+    /**
+     * The node's label. It can be the same of another node.
+     */
+    private String label;
+    
+    /**
+     * The node's weight which has been set inside the constructor. All
+     * operations which refers to node's weight work on the weight field, that 
+     * is used to make calcs.
+     */
+    private double realWeight;
+    
+    /**
+     * This flag indicates if weight value can be a non positive number.
+     */
+    static boolean allowNonPositiveWeight = false;
+    
+    /**
+     * The color of this node.
+     */
+    private Color color;
+    
+    /**
+     * Colors available on which iterate
+     */
+    static final Color[] colors = {
+            Color.decode("#FACED2"), // red
+            Color.decode("#B9D6FF"), // blue
+            Color.decode("#E5E5E5"), // grey
+            Color.decode("#FFE7C7"), // orange
+            Color.decode("#ABEBEE"), // aqua
+            Color.decode("#E4D1FC"), // purple
+            Color.decode("#FFFFFF"), // white
+            Color.decode("#CDF9D4")  // green
+    };
+    
+    public final Color START_COLOR = colors[0];
+    
+    /**
+     * 
+     * Constructor that allow to set the nodes' real weight. Others fields are 
+     * initialized to their default value.
+     * It automatically set the node's id.
+     *
+     * <p>
+     * @param realWeight the nodes real weight, which will be not affected 
+     * during node processing.
+     * 
+     */
+    public TreeMapNode(double realWeight) {
+        this("", realWeight);
+    }
+
+    /**
+     * 
+     * Constructor that allow to set the nodes' real weight and the label. 
+     * Others fields are initialized to their default value.
+     * It automatically set the node's id.
+     *
+     * <p>
+     * @param label the node's label.
+     * @param realWeight the nodes real weight, which will be not affected 
+     * during node processing.
+     * 
+     */
+    public TreeMapNode(String label, double realWeight) {
+        this.id = idCounter++;
+        this.label = label;
+        this.parent = null;
+        this.children = new ArrayList<TreeMapNode>();
+        this.rectangle = new Rectangle2D.Double();
+        this.info = new HashMap<String, String>();
+        this.weight = realWeight;
+        this.realWeight = realWeight;
+    }
+
+    /**
+     * Return the id of this object.
+     * @return the id automatically assigned at this object initialization.
+     */
+    public int getId() {
+        return this.id;
+    }
+    
+    /**
+     * Set this node's label.
+     * @param newLabel the new label to set.
+     */
+    public void setLabel(String newLabel) {
+        this.label = newLabel;
+    }
+    
+    /**
+     * Return the label of this object.
+     * @return the label assigned at instantiation time to this object.
+     */
+    public String getLabel() {
+        return this.label;
+    }
+
+    /**
+     * Return the reference to the node parent of this object.
+     * @return the parent of this node. It can be null.
+     */
+    public TreeMapNode getParent() {
+        return this.parent;
+    }
+
+    /**
+     * Set as parent of this object the node given in input.
+     * @param parent the new parent of this object. No checks are made for null
+     * value.
+     */
+    public void setParent(TreeMapNode parent) {
+        this.parent = parent;
+    }
+
+    /**
+     * Return the list of nodes representing this node's children.
+     * @return a list of {@link TreeMapNode} objects.
+     */
+    public List<TreeMapNode> getChildren() {
+        return this.children;
+    }
+
+    public boolean isLeaf() {
+        return getChildren().isEmpty();
+    }
+    
+    /**
+     * Set as children list of this object the list given in input.
+     * @param children the new list of children for this node.
+     */
+    public void setChildren(List<TreeMapNode> children) {
+        this.children = children;
+        for (TreeMapNode child : this.children) {
+            child.setParent(this);
+        }
+    }
+
+    /**
+     * Return the {@link Map} object containing all information of this node.
+     * @return a {@link Map} object.
+     */
+    public Map<String, String> getInfo() {
+        return this.info;
+    }
+    
+    /**
+     * Store the given information into this object.
+     * @param key the key searching value for the information to store.
+     * @param value the information to store into this object.
+     * @return the old value for the given key.
+     */
+    public String addInfo(String key, String value) {
+        return this.info.put(key, value);
+    }
+
+    /**
+     * Return the information stored in this object, corresponding to the key 
+     * given in input.
+     * @param key the key value for the search information.
+     * @return the corresponding value for the given key.
+     */
+    public String getInfo(String key) {
+        return this.info.get(key);
+    }
+
+    /**
+     * Add the object given in input to the children list of this object. It 
+     * also add this object as its parent.
+     * @param child the new child to add at this object.
+     */
+    public void addChild(TreeMapNode child) {
+        if (child != null) {
+            this.children.add(child);
+            child.setParent(this);
+        }
+    }
+
+    @Override
+    /**
+     * Return a {@link String}  representing this object.
+     */
+    public String toString() {
+        return  getClass().getSimpleName() + " [" + "label = " + getLabel() + 
+                "; weight =" + getRealWeight() + 
+                "; rectangle=" + rectangle.getBounds() + "]";
+    }
+
+    /**
+     * Return the weight of this object. In case of allowNonPositiveWeight is 
+     * set to false and the weight is 0, less than 0 or not a number 
+     * ({@link Double.Nan}), this method returns a value that can be transformed
+     * by external objects, so if you need the real weight you have to
+     * invoke getrealWeight().
+     * 
+     * @return the node's weight.
+     */
+    public double getWeight() {
+        if ((weight <= 0 || weight == Double.NaN) && !allowNonPositiveWeight) {
+            return realWeight;
+        }
+        return this.weight;
+    }
+    
+    /**
+     * Use this method to retrieve the real weight assigned to this node.
+     * @return the weight corresponding to this node.
+     */
+    public double getRealWeight() {
+        return this.realWeight;
+    }
+    
+    
+    /**
+     * Use this method to set the real weight of this node.
+     */
+    public void setRealWeight(double w) {
+        this.realWeight = w;
+    }
+
+    /**
+     * Set the weight of this object. If a negative value is given, it is set 
+     * automatically to 0.
+     * @param weight the new weight for this object.
+     */
+    public void setWeight(double w) {
+        this.weight = w < 0 && !allowNonPositiveWeight ? 0 : w;
+    }
+
+
+    /**
+     * Return the rectangle representing this object.
+     * @return a {@link Rectangle2D.Double} object.
+     */
+    public Rectangle2D.Double getRectangle() {
+        if (this.rectangle == null) {
+            throw new RuntimeException();
+        }
+        return this.rectangle;
+    }
+
+    /**
+     * Set a new rectangle for this object.
+     * @param rectangle the new rectangle that represent this node.
+     */
+    public void setRectangle(Rectangle2D.Double rectangle) {
+        this.rectangle = rectangle;
+    }    
+
+    /**
+     * 
+     * @return true if non positive value can be used as weight, else false.
+     */
+    public static boolean isAllowNonPositiveWeight() {
+        return allowNonPositiveWeight;
+    }
+
+    /**
+     * Set this value to false and nodes will be not able to manage non positive
+     * values for weight field, otherwise set to true.
+     * @param allowed the flag value for managing non positive values as weight
+     */
+    public static void setAllowNonPositiveWeight(boolean allowed) {
+        allowNonPositiveWeight = allowed;
+    }
+
+    /**
+     * This method assess if the rectangle associated to this node is drawable,
+     * which means that its sides are greater than 1.
+     * @return true if the rectangle associated to this node  is drawable, 
+     * else false.
+     */
+    public boolean isDrawable() {
+        if (rectangle.width >= 1 && rectangle.height >= 1) {
+            return true;
+        }
+        return false;
+    }
+    
+    public Color getColor() {
+        return color;
+    }
+
+    public void setColor(Color color) {
+        this.color = color;
+    }
+    
+    /**
+     * Returns this node's next color.
+     * @return the color which came after this node's color in the color list.
+     * If this node has no color assigned then the START_COLOR is returned.
+     */
+    public Color getNextColor() {
+        if (this.color != null) {
+            for (int i = 0; i < colors.length; i++) {
+                if (this.color.equals(colors[i])) {
+                    return colors[(i + 1) % colors.length];
+                }
+            }
+        }
+        return START_COLOR;
+    }
+
+
+    public int getDepth() {
+        if (this.parent == null) {
+            return 0;
+        } else {
+            return 1 + parent.getDepth();
+        }
+    }
+
+    /**
+     * This method sorts the given list in <b>descending<b> way.
+     * 
+     * @param nodes the list of {@link TreeMapNode} to sort.
+     */
+    public static void sort(List<TreeMapNode> nodes) {
+        Comparator<TreeMapNode> c = new Comparator<TreeMapNode>() {
+          @Override
+          public int compare(TreeMapNode o1, TreeMapNode o2) {
+              // inverting the result to descending sort the list
+              return -(Double.compare(o1.getWeight(), o2.getWeight()));
+          }
+      };
+      Collections.sort(nodes, c);
+    }
+    
+    /**
+     * Return the list of ancestors node of this object. The first one is this 
+     * node itself, the last one the root.
+     * @return a list of ancestors nodes.
+     */
+    public LinkedList<TreeMapNode> getAncestors() {
+        LinkedList<TreeMapNode> toReturn = new LinkedList<TreeMapNode>();
+        TreeMapNode tmp = this;
+        do {
+            toReturn.add(tmp);
+        } while ((tmp = tmp.getParent()) != null);
+        return toReturn;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapObserver.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+/**
+ * This interface is used as part of the Observer Design Pattern developed
+ * for objects who want to be notified about TreeMap's events.
+ */
+public interface TreeMapObserver {
+    
+    /**
+     * This method inform the Observer object that the object passed as 
+     * argument has been selected.
+     * 
+     * @param selectedComp the selected component to communicate to 
+     * this Observer object.
+     */
+    public void notifySelection(TreeMapNode node);
+    
+    /**
+     * This method informs objects that a zoom in event has been performed on
+     * the given node.
+     * @param node the zoomed node.
+     */
+    public void notifyZoomIn(TreeMapNode node);
+    
+    /**
+     * This method informs objects that a zoom out event has been performed.
+     */
+    public void notifyZoomOut();
+    
+    /**
+     * This method informs objects that the zoom level has been resetted.
+     */
+    public void notifyZoomFull();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapToolbar.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.util.Objects;
+
+import javax.swing.Box;
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.ScrollPaneConstants;
+
+/**
+ * This class provides a tool bar containing a {@lnk TreeMapBreadcrumb} object 
+ * and a {@link TreeMapZoomBar} instance to control the state of 
+ * {@link TreeMapComponent} objects.
+ */
+@SuppressWarnings("serial")
+public class TreeMapToolbar extends JComponent {
+    
+    /**
+     * The panel in which objects are placed.
+     */
+    private JPanel contentPane;
+    
+    /**
+     * The scroll pane used to hide breadcrumb's first items.
+     */
+    private JScrollPane scrollPane;
+    
+    
+    public TreeMapToolbar(TreeMapComponent treemap) {
+        super();
+        initComponent(Objects.requireNonNull(treemap));
+    }
+
+
+    private void initComponent(TreeMapComponent treemap) {
+        this.setLayout(new BorderLayout());
+        
+        final JPanel breadcrumbPanel = new JPanel();
+        breadcrumbPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
+        add(breadcrumbPanel, BorderLayout.CENTER);
+        
+        JPanel zoomPanel = new JPanel(new FlowLayout());
+        // add some empty space between the breadcrumb bar and buttons
+        zoomPanel.add(Box.createHorizontalStrut(20));
+        add(zoomPanel, BorderLayout.EAST);
+
+        TreeMapZoomBar zoomBar = new TreeMapZoomBar(treemap);
+        zoomPanel.add(zoomBar);
+        
+        TreeMapBreadcrumb bc = new TreeMapBreadcrumb(treemap, treemap.getTreeMapRoot());
+        
+        contentPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
+        contentPane.add(bc);
+
+        scrollPane = new JScrollPane(contentPane);
+        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
+        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
+        scrollPane.setBorder(null);
+        
+        // allows to see always the last elements of the breadcrumb.
+        scrollPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
+            public void adjustmentValueChanged(AdjustmentEvent e) {
+                e.getAdjustable().setValue(e.getAdjustable().getMaximum());
+            }
+        });
+        breadcrumbPanel.add(scrollPane);
+        
+        // when the component is resized the new dimension is used to arrange 
+        // the scrollpane, in order to use all available space.
+        breadcrumbPanel.addComponentListener(new ComponentAdapter() {
+            @Override
+            public void componentResized(ComponentEvent arg0) {
+                Dimension d = breadcrumbPanel.getSize();
+                d.height = 20;
+                scrollPane.setPreferredSize(d);
+            }
+        });
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapZoomBar.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,242 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.Objects;
+
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+
+import com.redhat.thermostat.client.swing.components.FontAwesomeIcon;
+import com.redhat.thermostat.client.swing.components.Icon;
+import com.redhat.thermostat.client.swing.internal.LocaleResources;
+import com.redhat.thermostat.client.ui.Palette;
+import com.redhat.thermostat.shared.locale.Translate;
+
+/**
+ * This class provides a component containing zoom in/out/full buttons which can
+ * control a {@link TreeMapComponent} object.
+ */
+public class TreeMapZoomBar extends JComponent implements TreeMapObserver {
+
+    private static final long serialVersionUID = 1L;
+
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
+
+    private JLabel zoomOut;
+    private JLabel zoomFull;
+    private JLabel zoomIn;
+    
+    private Color defaultColor = Palette.BLACK.getColor();
+    private Color enterColor = Palette.THERMOSTAT_BLU.getColor();
+
+    /**
+     * The treemap object to interact with.
+     */
+    private TreeMapComponent treemap;
+
+    /**
+     * If an item is selected in the treemap, it is stored in order to zoom on 
+     * it if the ZoomIn button is pressed.
+     */
+    private TreeMapNode selectedItem;
+    
+    /**
+     * Constructor. It creates the zoom buttons and registers this object as 
+     * treemap observer.
+     */
+    public TreeMapZoomBar(TreeMapComponent treemap) {
+        super();
+        this.treemap = Objects.requireNonNull(treemap);
+        initComponent();
+        treemap.register(this);
+    }
+
+    private void initComponent() {
+        this.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0));
+        createZoomInButton();
+        createZoomFullButton();
+        createZoomOutButton();
+
+        /*
+         * At the beginning no actions can be performed:
+         * Cannot zoom in because no item is selected;
+         * cannot zoom out because zoom in hasn't been performed;
+         * the same for zoom full.
+         */
+        zoomIn.setEnabled(false);
+        zoomFull.setEnabled(false);
+        zoomOut.setEnabled(false);
+    }
+
+
+
+    private void createZoomInButton() {
+        zoomIn = new JLabel();
+        final Icon baseIcon = new FontAwesomeIcon('\uf065', 15, defaultColor);
+        final Icon hoverIcon = new FontAwesomeIcon('\uf065', 15, enterColor);
+        
+        zoomIn.setIcon(baseIcon);
+        zoomIn.setToolTipText(t.localize(LocaleResources.TREEMAP_ZOOM_IN).getContents());
+        
+        zoomIn.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseExited(MouseEvent e) {
+                zoomIn.setIcon(baseIcon);
+            }
+
+            @Override
+            public void mouseEntered(MouseEvent e) {
+                zoomIn.setIcon(hoverIcon);
+            }
+
+            @Override
+            public void mouseClicked(MouseEvent arg0) {
+                if (selectedItem != null) {
+                    treemap.zoomIn(selectedItem);
+                }
+            }
+        });
+
+        this.add(zoomIn);
+    }
+
+    private void createZoomOutButton() {
+        zoomOut = new JLabel();
+        
+        final Icon baseIcon = new FontAwesomeIcon('\uf066', 15, defaultColor);
+        final Icon hoverIcon = new FontAwesomeIcon('\uf066', 15, enterColor);
+        
+        zoomOut.setIcon(baseIcon);
+        zoomOut.setToolTipText(t.localize(LocaleResources.TREEMAP_ZOOM_OUT).getContents());
+        zoomOut.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseExited(MouseEvent e) {
+                zoomOut.setIcon(baseIcon);
+            }
+
+            @Override
+            public void mouseEntered(MouseEvent e) {
+                zoomOut.setIcon(hoverIcon);
+            }
+
+            @Override
+            public void mouseClicked(MouseEvent arg0) {
+                treemap.zoomOut();
+            }
+        });
+
+        this.add(zoomOut);
+    }
+
+    private void createZoomFullButton() {
+        zoomFull = new JLabel();
+
+        final Icon baseIcon = new FontAwesomeIcon('\uf03b', 15, defaultColor);
+        final Icon hoverIcon = new FontAwesomeIcon('\uf03b', 15, enterColor);
+        
+        zoomFull.setIcon(baseIcon);
+        zoomFull.setToolTipText(t.localize(LocaleResources.TREEMAP_ZOOM_FULL).getContents());
+        zoomFull.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mouseExited(MouseEvent e) {
+                zoomFull.setIcon(baseIcon);
+            }
+
+            @Override
+            public void mouseEntered(MouseEvent e) {
+                zoomFull.setIcon(hoverIcon);
+            }
+
+            @Override
+            public void mouseClicked(MouseEvent arg0) {
+                treemap.zoomFull();
+            }
+        });
+
+        this.add(zoomFull);
+    }
+
+    /**
+     * Changes the buttons state in according to the treemap view.
+     */
+    private void changeState() {
+        selectedItem = null;
+        zoomIn.setEnabled(false);
+
+        if (!isRootShown()) {
+            zoomFull.setEnabled(true);
+            zoomOut.setEnabled(true);
+        } else {
+            zoomFull.setEnabled(false);
+            zoomOut.setEnabled(false);
+        }
+    }
+
+    @Override
+    public void notifySelection(TreeMapNode node) {
+        selectedItem = node;
+        zoomIn.setEnabled(treemap.isZoomInEnabled(node));
+    }
+
+    @Override
+    public void notifyZoomIn(TreeMapNode node) {
+        changeState();
+    }    
+
+    @Override
+    public void notifyZoomOut() {
+        changeState();
+    }
+
+    @Override
+    public void notifyZoomFull() {
+        // no actions can be performed
+        zoomFull.setEnabled(false);
+        zoomOut.setEnabled(false);
+        zoomIn.setEnabled(false);
+    }
+
+    private boolean isRootShown() {
+        return treemap.getTreeMapRoot() == treemap.getZoomCallsStack().firstElement();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeProcessor.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import java.awt.Color;
+import java.awt.geom.Rectangle2D;
+import java.util.Objects;
+
+
+public class TreeProcessor {
+
+    /**
+     * Padding between the main component and its sub component.
+     */
+    public static final int X_PADDING = 15;
+    public static final int Y_PADDING = 20;
+
+    /**
+     * This method process recursively the tree nested in the node element
+     * passed as argument in the constructor calculating the children TreeMap 
+     * for each node also applying coloring.
+     * @return the updated tree, where nodes have additional information like
+     * {@link Rectangle2D>Float} instance and a color.
+     */
+    public static TreeMapNode processTreeMap(TreeMapNode tree, Rectangle2D.Double area) {
+        Objects.requireNonNull(tree);
+        Objects.requireNonNull(area);
+        tree.setRectangle(area);
+        if (tree.getColor() == null) {
+            tree.setColor(tree.START_COLOR);
+        }
+        
+        process(tree);
+        return tree;
+    }
+
+    /**
+     * This method is used to effectively process the whole tree structure. It
+     * uses a {@link SquarifiedTreeMap} object to calculate a TreeMap for each
+     * node who has children.
+     * @param node the subtree's root to process
+     */
+    private static void process(TreeMapNode node) {                                                                                                                            
+        
+        SquarifiedTreeMap algorithm = new SquarifiedTreeMap(getSubArea(node.getRectangle()), node.getChildren());
+        node.setChildren(algorithm.squarify());
+
+        Color c = node.getNextColor();
+        
+        for (TreeMapNode child : node.getChildren()) {
+            //children will have all the same color, which is the parent's next one
+            if (child.getColor() == null) {
+                child.setColor(c);
+            }
+            // if squarified rectangles have drawable sides then continue to 
+            // process, else don't process the subtree having as root a 
+            // non drawable rectangle.
+            if (child.isDrawable()) {
+                process(child);
+            } 
+        }
+    }
+
+    /**
+     * Calculate space and coordinates in which children's rectangle will be 
+     * drawn, from the main component.
+     * @return the rectangle representing the new available area.
+     */
+    private static Rectangle2D.Double getSubArea(Rectangle2D.Double area) {
+        Rectangle2D.Double subArea = new Rectangle2D.Double();
+        subArea.setRect(area);
+
+        subArea.width = Math.max(0, (subArea.width - 2 * X_PADDING));
+        subArea.height = Math.max(0, (subArea.height - 1.5 * Y_PADDING));
+        return subArea;
+    }  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/ValueFormatter.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+public class ValueFormatter {
+    
+    private double value;
+    
+    public ValueFormatter(double val) {
+        this.value = val;
+    }
+    
+    /**
+     * This method returns the node value calculating it in bytes, KB or MB. 
+     * 
+     * i.e. if node's weight = 200 it returns: "200 bytes" <br>
+     * if weight = 20152: "20.15 KB"  <br>
+     * if weight = 2015248: "2.01 MB"  <br>
+     * 
+     * Note that float values are approximated to the second decimal digit.
+     */
+    public String format() {
+        int KB = 1000;
+        int MB = 1000000;
+        String unit = "Bytes";
+        
+        if (value >= KB && value < MB) {
+            value /= KB;
+            unit = "KBytes";
+        } else if (value >= MB) {
+            value /= MB;
+            unit = "MBytes";
+        }
+        // show 2 decimal digits 
+        String formattedValue = String.format("%.2f", value);
+        return formattedValue + " " + unit;
+    }
+}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/LocaleResources.java	Wed Jun 01 15:58:04 2016 -0400
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/LocaleResources.java	Mon Jun 06 15:17:50 2016 -0400
@@ -47,6 +47,10 @@
     ZOOM_OUT,
     RESET_ZOOM,
 
+    TREEMAP_ZOOM_IN,
+    TREEMAP_ZOOM_OUT,
+    TREEMAP_ZOOM_FULL,
+
     CUT,
     COPY,
     PASTE,
Binary file client/swing/src/main/resources/com/redhat/thermostat/client/swing/components/experimental/breadcrumb_body.png has changed
Binary file client/swing/src/main/resources/com/redhat/thermostat/client/swing/components/experimental/breadcrumb_head.png has changed
Binary file client/swing/src/main/resources/com/redhat/thermostat/client/swing/components/experimental/breadcrumb_tail.png has changed
--- a/client/swing/src/main/resources/com/redhat/thermostat/client/swing/internal/strings.properties	Wed Jun 01 15:58:04 2016 -0400
+++ b/client/swing/src/main/resources/com/redhat/thermostat/client/swing/internal/strings.properties	Mon Jun 06 15:17:50 2016 -0400
@@ -5,6 +5,10 @@
 ZOOM_OUT = Zoom Out
 RESET_ZOOM = Reset Zoom
 
+TREEMAP_ZOOM_IN = Zoom in the selected item. Try also with a double click
+TREEMAP_ZOOM_OUT = Zoom out the view. Try also with a left click
+TREEMAP_ZOOM_FULL = Restore the original zoom level. Try also with a mouse wheel click
+
 CUT = Cut
 COPY = Copy
 PASTE = Paste
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/SquarifiedTreeMapTest.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Using eclEmma tool has been proved that this test covers 100% 
+ * of {@link SquarifiedTreeMap} code and also 90% of {@link TreeMapBuilder} code.
+ */
+public class SquarifiedTreeMapTest {
+    
+    private SquarifiedTreeMap algorithm;
+    Rectangle2D.Double bounds;
+    List<TreeMapNode> list;
+
+    @Before
+    public void setUp() throws Exception {
+        bounds = new Rectangle2D.Double(0, 0, 10, 5);
+        list = new ArrayList<>();
+    }
+
+    @Test
+    public final void testSquarifiedTreeMap() {
+        //check every parameters combinations
+        boolean catched = false;
+        try {
+            algorithm = new SquarifiedTreeMap(null, null);
+        } catch(NullPointerException e) {
+            catched = true;
+        }
+        assertTrue(catched);
+        catched = false;
+        
+        try {
+            algorithm = new SquarifiedTreeMap(bounds, null);
+        } catch(NullPointerException e) {
+            catched = true;
+        }
+        assertTrue(catched);
+        catched = false;
+        
+        try {
+            algorithm = new SquarifiedTreeMap(null, list);
+        } catch(NullPointerException e) {
+            catched = true;
+        }
+        assertTrue(catched);
+    }
+    
+    @Test
+    public final void testSquarify() {
+        // test using an empty node list
+        algorithm = new SquarifiedTreeMap(bounds, new ArrayList<TreeMapNode>());
+        assertEquals(0, algorithm.squarify().size());
+        
+        // test using a correct list
+        int n = 10;
+        for (int i = 0; i < n; i++) {
+            list.add(new TreeMapNode(i+1));
+        }
+        // process the list
+        algorithm = new SquarifiedTreeMap(bounds, list);
+        list = algorithm.squarify();
+        
+        assertEquals(n, list.size());
+        
+        for (int i = 0; i < n; i++) {
+            // node has been processed
+            assertNotNull(list.get(i).getRectangle());
+        }
+        
+        assertEquals(list, algorithm.getSquarifiedNodes());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapComponentTest.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import junit.framework.Assert;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.awt.Dimension;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.SwingUtilities;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+
+public class TreeMapComponentTest {
+
+    private TreeMapComponent treeMap;
+    private static TreeMapNode tree;
+    private static TreeMapNode node1;
+    private static TreeMapNode node2;
+    private static Dimension dim;
+
+    @BeforeClass
+    public static void setUpOnce() {
+        tree = new TreeMapNode(1);
+        node1 = new TreeMapNode(1);
+        node2 = new TreeMapNode(1);
+        tree.addChild(node1);
+        node1.addChild(node2);
+        dim = new Dimension(500, 500);
+    }
+
+
+    @Test
+    public final void testTreeMapComponent() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+
+                boolean catched = false;
+
+                try {
+                    treeMap = new TreeMapComponent(tree, dim);
+                    // pass
+                 } catch(NullPointerException e) {
+                    Assert.fail("Didn't expect exception.");
+                 }
+                try {
+                    treeMap = new TreeMapComponent(null, null);
+                } catch(NullPointerException e) {
+                    catched = true;
+                }
+                assertTrue(catched);
+                catched = false;
+
+                try {
+                    treeMap = new TreeMapComponent(tree, null);
+                } catch(NullPointerException e) {
+                    catched = true;
+                }
+                assertTrue(catched);
+                catched = false;
+
+                try {
+                    treeMap = new TreeMapComponent(null, dim);
+                } catch(NullPointerException e) {
+                    catched = true;
+                }
+                assertTrue(catched);
+            }
+        });
+    }
+
+    @Test
+    public final void testGetRoot() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                treeMap = new TreeMapComponent(tree, dim);
+                assertEquals(tree, treeMap.getTreeMapRoot());
+            }
+        });
+    }
+
+    @Test
+    public final void testIsZoomInEnabled() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                TreeMapComponent treeMap = new TreeMapComponent(tree, dim);
+
+                assertFalse("Should not be able to zoom in on null", treeMap.isZoomInEnabled(null));
+                assertFalse("Should not be able to zoom in on root", treeMap.isZoomInEnabled(tree));
+                assertTrue("Should be able to zoom in on node 1", treeMap.isZoomInEnabled(node1));
+                assertFalse("Should not be able to zoom in on node 2", treeMap.isZoomInEnabled(node2));
+            }
+        });
+    }
+
+    @Test
+    public final void testZoomIn() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                TreeMapComponent treeMap = new TreeMapComponent(tree, dim);
+
+                treeMap.zoomIn(node1);
+                assertEquals(node1, treeMap.getTreeMapRoot());
+
+                treeMap.zoomIn(node2);
+                assertEquals(node1, treeMap.getTreeMapRoot());
+            }
+        });
+    }
+
+    @Test
+    public final void testZoomOut() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                treeMap = new TreeMapComponent(tree, dim);
+
+                treeMap.zoomOut();
+                assertEquals(tree, treeMap.getTreeMapRoot());
+
+                treeMap.zoomIn(node1); //if zoom out root is tree
+                treeMap.zoomIn(node2); //no-op, cannot zoom on leaf
+
+                assertEquals(node1, treeMap.getTreeMapRoot());
+
+                treeMap.zoomOut();
+                assertEquals(tree, treeMap.getTreeMapRoot());
+            }
+        });
+    }
+
+    @Test
+    public final void testZoomFull() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                treeMap = new TreeMapComponent(tree, dim);
+
+                treeMap.zoomIn(node2);
+                treeMap.zoomFull();
+                assertEquals(tree, treeMap.getTreeMapRoot());
+
+            }
+        });
+    }
+
+    @Test
+    public final void testGetZoomCallsStack() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                treeMap = new TreeMapComponent(tree, dim);
+
+                // the root is always in the stack
+                assertEquals(1, treeMap.getZoomCallsStack().size());
+
+                treeMap.zoomIn(tree);
+                // zooming on the same element nothing happen
+                assertEquals(1, treeMap.getZoomCallsStack().size());
+
+                treeMap.zoomIn(node1);
+                treeMap.zoomIn(node2);
+                treeMap.zoomFull();
+                assertEquals(tree, treeMap.getTreeMapRoot());
+            }
+        });
+    }
+
+
+    @Test
+    public final void testClearZoomCallsStack() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                treeMap = new TreeMapComponent(tree, dim);
+
+                treeMap.clearZoomCallsStack();
+                assertEquals(1, treeMap.getZoomCallsStack().size());
+
+                treeMap.zoomIn(node1);
+                treeMap.zoomIn(node2);
+                treeMap.clearZoomCallsStack();
+                assertEquals(1, treeMap.getZoomCallsStack().size());
+            }
+        });
+    }
+    
+    @Test
+    public final void testObserver() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            boolean zoomedIn = false;
+            boolean zoomedOut = false;
+            boolean zoomedFull = false;
+            
+            TreeMapObserver observer = new TreeMapObserver() {
+                @Override
+                public void notifyZoomOut() {
+                    zoomedOut = true;
+                }
+                
+                @Override
+                public void notifyZoomIn(TreeMapNode node) {
+                    zoomedIn = true;
+                }
+                
+                @Override
+                public void notifyZoomFull() {
+                    zoomedFull = true;
+                }
+                
+                @Override
+                public void notifySelection(TreeMapNode node) {
+                }
+            };
+
+            @Override
+            public void run() {
+                TreeMapNode child = new TreeMapNode(1);
+                tree.addChild(child);
+                TreeMapNode grandchild = new TreeMapNode(1);
+                child.addChild(grandchild);
+
+                treeMap = new TreeMapComponent(tree, dim);
+                treeMap.register(observer);
+                
+                treeMap.zoomIn(child);
+                assertTrue("Should have zoomed in on child", zoomedIn);
+                zoomedIn = false;
+
+                treeMap.zoomIn(grandchild);
+                assertFalse("Should not have zoomed in on grandchild", zoomedIn);
+                
+                treeMap.zoomOut();
+                assertTrue("Should have zoomed out", zoomedOut);
+                
+                treeMap.zoomIn(child);
+                treeMap.zoomFull();
+                assertTrue("Should have zoomed full", zoomedFull);
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapNodeTest.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.awt.Color;
+import java.awt.geom.Rectangle2D;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class TreeMapNodeTest {
+
+    private TreeMapNode node;
+    private static final double DELTA = 0.001;
+
+    @Before
+    public void setUp() {
+        node = new TreeMapNode(null, 1);
+    }
+
+    @Test
+    public final void testGetId() {
+        TreeMapNode node1 = new TreeMapNode(null, 1);
+        TreeMapNode node2 = new TreeMapNode(null, 1);
+        assertTrue(node1.getId() != node2.getId());
+        assertTrue(node1.getId() + 1 == node2.getId());
+    }
+
+    @Test
+    public final void testGetSetParent() {
+        TreeMapNode parent = new TreeMapNode(null, 1);
+        assertTrue(node.getParent() == null);
+        node.setParent(parent);
+        assertTrue(node.getParent() == parent);
+    }
+
+    @Test
+    public final void testGetSetLabel() {
+        TreeMapNode node = new TreeMapNode("MyLabel", 1);
+        assertTrue(node.getLabel().equals("MyLabel"));
+        node.setLabel("MyNewLabel");
+        assertTrue(node.getLabel().equals("MyNewLabel"));
+    }
+
+    @Test
+    public final void testGetSetChildren() {
+        assertTrue(node.getChildren().isEmpty());
+
+        TreeMapNode node = new TreeMapNode(null, 1);
+        List<TreeMapNode> children = new ArrayList<>();
+        children.add(node);
+
+        node.setChildren(children);
+        assertTrue(1 == node.getChildren().size());
+    }
+
+    @Test
+    public final void testIsLeaf() {
+        assertTrue(node.isLeaf());
+        node.addChild(new TreeMapNode(null, 1));
+        assertFalse(node.isLeaf());
+        node.setChildren(Collections.<TreeMapNode>emptyList());
+        assertTrue(node.isLeaf());
+    }
+
+    @Test
+    public final void testGetAddInfo() {
+        node.addInfo("exampleKey", "exampleValue");
+        assertEquals("exampleValue", node.getInfo("exampleKey"));
+    }
+
+    @Test
+    public final void testAddChild() {
+        assertTrue(node.getChildren().size() == 0);
+        node.addChild(new TreeMapNode(null, 1));
+        assertTrue(node.getChildren().size() == 1);
+
+        node.addChild(null);
+        assertTrue(node.getChildren().size() == 1); // null has not been added
+    }
+
+    @Test
+    public final void testGetSetWeight() {
+        assertEquals(1.0, node.getWeight(), DELTA);
+        node.setWeight(5);
+        assertEquals(5.0, node.getWeight(), DELTA);
+    }
+
+    @Test
+    public final void testGetSetRectangle() {        
+        Rectangle2D.Double r = new Rectangle2D.Double(5, 5, 5, 5);
+        node.setRectangle(r);
+        assertEquals(r, node.getRectangle());
+
+        node.setRectangle(null);
+        boolean catched = false;
+        try {
+            node.getRectangle();
+        } catch(RuntimeException e) {
+            catched = true;
+        }
+        assertTrue(catched);
+    }
+
+
+    @Test
+    public final void testGetSetRealWeight() {
+        node = new TreeMapNode(null, 5);
+        assertEquals(5.0, node.getRealWeight(), DELTA);
+        node.setRealWeight(8);
+        assertEquals(8.0, node.getRealWeight(), DELTA);
+    }
+
+    @Test
+    public final void testAllowNonPositiveWeight() {
+        assertFalse(TreeMapNode.isAllowNonPositiveWeight());
+        node.setWeight(-5);
+        assertEquals(1.0, node.getWeight(), DELTA);
+        assertEquals(1.0, node.getRealWeight(), DELTA);
+
+        TreeMapNode.setAllowNonPositiveWeight(true);
+        node.setWeight(-5);
+        assertEquals(-5.0, node.getWeight(), DELTA);
+    }
+
+    @Test
+    public final void testIsDrawable() {
+        Rectangle2D.Double r = new Rectangle2D.Double(5, 5, 5, 5);
+        node.setRectangle(r);
+        assertTrue(node.isDrawable());
+
+        r.setRect(0,  0,  0.5f, 0.5f);
+        assertFalse(node.isDrawable());
+
+        r.setRect(0,  0,  5f, 0.5f);
+        assertFalse(node.isDrawable());
+
+        r.setRect(0,  0,  0.5f, 5f);
+        assertFalse(node.isDrawable());
+    }
+
+    @Test
+    public final void testGetSetColor() {
+        assertNull(node.getColor());
+        node.setColor(Color.black);
+        assertEquals(Color.black, node.getColor());
+    }
+
+    @Test
+    public final void testGetDepth() {
+        TreeMapNode depth1 = new TreeMapNode(null, 1);
+        TreeMapNode depth2 = new TreeMapNode(null, 1);
+
+        node.addChild(depth1);
+        depth1.addChild(depth2);
+
+        assertTrue(node.getDepth() == 0);
+        assertTrue(depth1.getDepth() == 1);
+        assertTrue(depth2.getDepth() == 2);
+    }
+
+    @Test
+    public final void testSort() {
+
+        TreeMapNode n1 = new TreeMapNode(null, 5);
+        TreeMapNode n2 = new TreeMapNode(null, 4);
+        TreeMapNode n4 = new TreeMapNode(null, 2);
+        TreeMapNode n3 = new TreeMapNode(null, 3);
+        TreeMapNode n5 = new TreeMapNode(null, 0);
+        TreeMapNode n6 = new TreeMapNode(null, 7);
+        TreeMapNode n7 = new TreeMapNode(null, 1);
+        TreeMapNode n8 = new TreeMapNode(null, 9);
+
+        List<TreeMapNode> toSort = new ArrayList<>();
+        toSort.add(n3);
+        toSort.add(n2);
+        toSort.add(n4);
+        toSort.add(n1);
+        toSort.add(n5);
+        toSort.add(n6);
+        toSort.add(n7);
+        toSort.add(n8);
+
+        TreeMapNode.sort(toSort);
+
+        assertEquals(toSort.get(0), n8);
+        assertEquals(toSort.get(1), n6);
+        assertEquals(toSort.get(2), n1);
+        assertEquals(toSort.get(3), n2);
+        assertEquals(toSort.get(4), n3);
+        assertEquals(toSort.get(5), n4);
+        assertEquals(toSort.get(6), n7);
+        assertEquals(toSort.get(7), n5);
+    }
+
+    @Test
+    public final void testGetInfo() {
+        Map<String, String> map = node.getInfo();
+        assertNotNull(map);
+        assertEquals(0, map.keySet().size());
+    }
+
+    @Test
+    public final void testToString() {
+        assertNotNull(node.toString());
+    }
+    
+    
+    @Test
+    public final void testGetNextColor() {
+        assertNull(node.getColor());
+        assertTrue(node.getNextColor().equals(node.START_COLOR));
+        
+        Color start = node.START_COLOR;
+        node.setColor(start);
+
+        for (int i = 0; i < TreeMapNode.colors.length; i++) {
+            assertEquals(TreeMapNode.colors[i], node.getColor());
+            node.setColor(node.getNextColor());
+        }
+    }
+    
+    
+    @Test
+    public final void testGetAncestors() {
+        TreeMapNode node1 = new TreeMapNode(0);
+        TreeMapNode node2 = new TreeMapNode(0);
+        TreeMapNode node3 = new TreeMapNode(0);
+        TreeMapNode node4 = new TreeMapNode(0);
+        
+        node1.addChild(node2);
+        node2.addChild(node3);
+        node3.addChild(node4);
+        
+        LinkedList<TreeMapNode> ancestors = node4.getAncestors();
+        
+        assertEquals(node1, ancestors.get(3));
+        assertEquals(node2, ancestors.get(2));
+        assertEquals(node3, ancestors.get(1));
+        assertEquals(node4, ancestors.get(0));        
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapToolbarTest.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import junit.framework.Assert;
+
+import static org.junit.Assert.assertTrue;
+
+import java.awt.Dimension;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.SwingUtilities;
+
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.redhat.thermostat.annotations.internal.CacioTest;
+
+@Category(CacioTest.class)
+public class TreeMapToolbarTest {
+
+    private TreeMapComponent treeMap;
+    @SuppressWarnings("unused")
+    private TreeMapToolbar toolbar;
+
+    private static TreeMapNode tree;
+    private static Dimension dim;
+
+    @Test
+    public final void testTreeMapToolbar() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                
+                tree = new TreeMapNode(1);
+                dim = new Dimension(500, 500);
+                treeMap = new TreeMapComponent(tree, dim);
+                
+                boolean catched = false;
+                try {
+                    toolbar = new TreeMapToolbar(null);
+                } catch(NullPointerException e) {
+                    catched = true;
+                }
+                assertTrue(catched);
+                try {
+                    toolbar = new TreeMapToolbar(treeMap);
+                } catch (NullPointerException e) {
+                    Assert.fail("Should not throw any exception.");
+                }
+            }
+        });
+    }
+
+   
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapZoomBarTest.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import junit.framework.Assert;
+
+import static org.junit.Assert.assertTrue;
+
+import java.awt.Dimension;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.SwingUtilities;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+
+import com.redhat.thermostat.annotations.internal.CacioTest;
+
+@Category(CacioTest.class)
+public class TreeMapZoomBarTest {
+
+    private TreeMapComponent treeMap;
+    @SuppressWarnings("unused")
+    private TreeMapZoomBar zoomBar;
+
+    private static TreeMapNode tree;
+    private static Dimension dim;
+
+    @Before
+    public void setUp() {
+        tree = new TreeMapNode(1);
+        dim = new Dimension(500, 500);
+    }
+
+    @Test
+    public final void testTreeMapZoomBar() throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                boolean catched = false;
+                try {
+                    zoomBar = new TreeMapZoomBar(null);
+                } catch(NullPointerException e) {
+                    catched = true;
+                }
+                assertTrue(catched);
+                try {
+                    treeMap = new TreeMapComponent(tree, dim);
+                    zoomBar = new TreeMapZoomBar(treeMap);
+                } catch (NullPointerException e) {
+                    Assert.fail("Should not throw any exception.");
+                }
+            }
+        });
+    }
+
+   
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeProcessorTest.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.awt.geom.Rectangle2D;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+
+public class TreeProcessorTest {
+
+    private static final double DELTA = 0.1;
+    private static final double BASE = 2.0;
+
+    TreeMapNode node;
+    Rectangle2D.Double area;
+
+    @Before
+    public void setUp() throws Exception {
+        node = new TreeMapNode(1);
+        area = new Rectangle2D.Double(0, 0, 500, 500);
+    }
+
+    @Test
+    public final void testTreeProcessor() {
+        boolean caught = false;
+        // this test check all wrong combinations for constructor parameters
+        try {
+            TreeProcessor.processTreeMap(null, area);
+        } catch(NullPointerException e) {
+            caught = true;
+        }
+        assertTrue(caught);
+        caught = false;
+
+        try {
+            TreeProcessor.processTreeMap(node, null);
+        } catch(NullPointerException e) {
+            caught = true;
+        }
+        assertTrue(caught);
+        caught = false;
+
+        try {
+            TreeProcessor.processTreeMap(null, null);
+        } catch(NullPointerException e) {
+            caught = true;
+        }
+        assertTrue(caught);
+    }
+
+
+    @Test
+    public final void testProcessTreeMapProcessesWholeTree() {
+        generateTree(node, 5, 5);
+        TreeProcessor.processTreeMap(node, area);
+
+        // the test will check if any drawable node in the tree has a rectangle and a 
+        // color, which means the processor function has processed the whole tree
+        traverse(node);        
+    }
+
+    private void traverse(TreeMapNode tree) {
+        if (tree.isDrawable() && (tree.getRectangle() == null || tree.getColor() == null)) {
+            fail("node " + tree.getId() + " not processed");
+        }
+        for (TreeMapNode child : tree.getChildren()) {
+            traverse(child);
+        }
+    }
+
+    private void generateTree(TreeMapNode root, int levels, int childrenNumber) {        
+        if (levels == 0) {
+            return;
+        } else {
+            for (int i = 0; i < childrenNumber; i++) {
+                root.addChild(new TreeMapNode(100));
+            }
+            for (TreeMapNode child : root.getChildren()) {
+                generateTree(child, levels-1, childrenNumber);
+            }
+        }
+    }
+
+    @Test
+    public final void testProcessTreeMapNodeSizing() {
+        final int numSiblings = 5;
+        final double originalDimension = 64.0;
+        final double smallerDimension = 32.0;
+
+        generateSiblingTree(node, numSiblings);
+
+        TreeProcessor.processTreeMap(node, new Rectangle2D.Double(0, 0, originalDimension, originalDimension));
+        checkNodeWeightRatios(numSiblings);
+
+        //now resize smaller
+        TreeProcessor.processTreeMap(node, new Rectangle2D.Double(0, 0, smallerDimension, smallerDimension));
+
+        //now resize back to original size
+        TreeProcessor.processTreeMap(node, new Rectangle2D.Double(0, 0, originalDimension, originalDimension));
+        //if the first call to checkNodeWeightRatios(numSiblings) worked, this should too
+        checkNodeWeightRatios(numSiblings);
+    }
+
+    private void generateSiblingTree(TreeMapNode root, int numSiblings) {
+        assertTrue(numSiblings > 1);
+        root.addChild(new TreeMapNode(1.0)); //this is not a random weight
+        for(int i = 0; i < (numSiblings - 1); i++) {
+            root.addChild(new TreeMapNode(Math.pow(BASE, i)));
+        }
+    }
+
+    private void checkNodeWeightRatios(int numSiblings) {
+        List<TreeMapNode> children = node.getChildren();
+        assertEquals(numSiblings, children.size());
+        TreeMapNode.sort(children);
+
+        double weight = children.get(0).getWeight();
+        for(int i = 1; i < numSiblings - 1; i++) {
+            double currentWeight = children.get(i).getWeight();
+            //check that the ratio between node weights is approximately 2 (which is the BASE)
+            assertEquals(BASE, weight/currentWeight, DELTA);
+            weight = currentWeight;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/ValueFormatterTest.java	Mon Jun 06 15:17:50 2016 -0400
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components.experimental;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class ValueFormatterTest {
+
+    private ValueFormatter formatter;
+
+    @Test
+    public final void getFormattedWeight() {
+        formatter = new ValueFormatter(2);
+        assertEquals("2.00 Bytes", formatter.format());
+
+        formatter = new ValueFormatter(2222);
+        assertEquals("2.22 KBytes", formatter.format());
+
+        formatter = new ValueFormatter(2222222);
+        assertEquals("2.22 MBytes", formatter.format());
+    }
+}
\ No newline at end of file
--- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapIconResources.java	Wed Jun 01 15:58:04 2016 -0400
+++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/core/HeapIconResources.java	Mon Jun 06 15:17:50 2016 -0400
@@ -36,22 +36,20 @@
 
 package com.redhat.thermostat.vm.heap.analysis.client.core;
 
-import com.redhat.thermostat.client.ui.IconDescriptor;
-
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import com.redhat.thermostat.client.ui.IconDescriptor;
+
 public class HeapIconResources {
 
-    public static final String PIN_MASK = "com/redhat/thermostat/vm/heap/analysis/client/core/pin_mask.png";
-    public static final String TRIGGER_HEAP_DUMP = "com/redhat/thermostat/vm/heap/analysis/client/core/take_dump.png";
-
-    public static final String BREADCRUMB_HEAD = "com/redhat/thermostat/vm/heap/analysis/client/swing/breadcrumb_head.png";
-    public static final String BREADCRUMB_BODY = "com/redhat/thermostat/vm/heap/analysis/client/swing/breadcrumb_body.png";
-    public static final String BREADCRUMB_TAIL = "com/redhat/thermostat/vm/heap/analysis/client/swing/breadcrumb_tail.png";
+    private static final String PACKAGE_PATH =
+            HeapIconResources.class.getPackage().getName().replace(".", "/");
+    public static final String PIN_MASK = PACKAGE_PATH + "/pin_mask.png";
+    public static final String TRIGGER_HEAP_DUMP = PACKAGE_PATH + "/take_dump.png";
 
     private static Map<String, IconDescriptor> icons = new HashMap<>();
     
--- a/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/locale/LocaleResources.java	Wed Jun 01 15:58:04 2016 -0400
+++ b/vm-heap-analysis/client-core/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/locale/LocaleResources.java	Mon Jun 06 15:17:50 2016 -0400
@@ -79,10 +79,6 @@
     DUMPS_LIST,
     LIST_DUMPS_ACTION, 
     HEAP_DUMP_SECTION_TREEMAP,
-
-    ZOOM_IN,
-    ZOOM_OUT,
-    ZOOM_FULL,
     ;
 
     static final String RESOURCE_BUNDLE = "com.redhat.thermostat.vm.heap.analysis.client.locale.strings";
--- a/vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/locale/strings.properties	Wed Jun 01 15:58:04 2016 -0400
+++ b/vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/locale/strings.properties	Mon Jun 06 15:17:50 2016 -0400
@@ -37,7 +37,3 @@
 HEAP_DUMP_IN_PROGRESS = Dumping heap\u2026
 HEAP_DUMP_LOADING_IN_PROGRESS = Loading heap dump\u2026
 PROCESS_EXITED = Process exited.
-
-ZOOM_IN = Zoom in the selected item. Try also with a double click
-ZOOM_OUT = Zoom out the view. Try also with a left click
-ZOOM_FULL = Restore the original zoom level. Try also with a mouse wheel click
Binary file vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/swing/breadcrumb_body.png has changed
Binary file vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/swing/breadcrumb_head.png has changed
Binary file vm-heap-analysis/client-core/src/main/resources/com/redhat/thermostat/vm/heap/analysis/client/swing/breadcrumb_tail.png has changed
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramConverter.java	Wed Jun 01 15:58:04 2016 -0400
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramConverter.java	Mon Jun 06 15:17:50 2016 -0400
@@ -39,6 +39,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
+import com.redhat.thermostat.client.swing.components.experimental.TreeMapNode;
 import com.redhat.thermostat.common.utils.DescriptorConverter;
 import com.redhat.thermostat.vm.heap.analysis.common.HistogramRecord;
 import com.redhat.thermostat.vm.heap.analysis.common.ObjectHistogram;
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SquarifiedTreeMap.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,463 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-
-
-/**
- *  This class implements the Squarified algorithm for TreeMaps. Using it, it is 
- *  possible to associate a rectangle to a {@link TreeMapNode} element and its 
- *  children.
- *  <p>
- *  @see TreeMapNode
- *  @see TreMapBuilder
- */
-public class SquarifiedTreeMap {
-    
-    /**
-     * List of node to represent as TreeMap.
-     */
-    private LinkedList<TreeMapNode> elements;
-    
-    /**
-     * Represent the area in which draw nodes.
-     */
-    private Rectangle2D.Double container;
-    
-    private enum DIRECTION {
-        LEFT_RIGHT,
-        TOP_BOTTOM
-    }
-
-    /**
-     * Indicates the drawing direction.
-     */
-    private DIRECTION drawingDir;
-
-    /**
-     * The rectangles area available for drawing.
-     */
-    private Rectangle2D.Double availableArea;
-
-    /**
-     * List of the calculated rectangles.
-     */
-    private List<TreeMapNode> squarifiedNodes;
-
-    /**
-     * List of the current rectangles under processing.
-     */
-    private List<TreeMapNode> currentRow;
-
-    /**
-     * Coordinates on which to draw.
-     */
-    private double lastX = 0;
-    private double lastY = 0;
-
-
-    /**
-     * Constructor.
-     * 
-     * @param d the dimension of the total area in which draw elements.
-     * @param list the list of elements to draw as TreeMap.
-     * 
-     * @throws a NullPointerException if one of the arguments is null.
-     */
-    public SquarifiedTreeMap(Rectangle2D.Double bounds, List<TreeMapNode> list) {
-        this.elements = new LinkedList<>();
-        elements.addAll(Objects.requireNonNull(list));
-        this.container = Objects.requireNonNull(bounds);
-    }
-
-    /**
-     * Invoke this method to calculate the rectangles for the TreeMap.
-     * 
-     * @return a list of node having a rectangle built in percentage to the 
-     * available area.
-     */
-    public List<TreeMapNode> squarify() {
-        initializeArea();
-        prepareData(elements);
-        List<TreeMapNode> row = new ArrayList<>();
-        double w = getPrincipalSide();	
-        squarify(elements, row, w);
-        return getSquarifiedNodes();
-    }
-
-    /**
-     * Calculate recursively the rectangles to draw and their size.
-     * 
-     * @param nodes the list of elements to draw.
-     * @param row the list of current rectangles to process.
-     * @param w the side against which to calculate the rectangles.
-     */
-    private void squarify(LinkedList<TreeMapNode> nodes, List<TreeMapNode> row, double w) {
-        if (nodes.isEmpty() && row.isEmpty()) {
-            // work done
-            return;
-        }
-        if (nodes.isEmpty()) {
-            // no more element to process, just draw current row
-            finalizeRow(row);
-            return;
-        }
-        if (row.isEmpty()) {
-            // add the first element to the row and iterate the process over it
-            row.add(nodes.getFirst());
-            nodes.removeFirst();
-            squarify(nodes, row, w);
-            return;
-        }
-        
-        /*  Greedy step: calculate the best aspect ratio of actual row and the
-         *  best aspect ratio given by adding another rectangle to the row.
-         *  If the current row can not be improved then finalize it
-         *  else add the next element, to improve the global aspect ratio
-         */
-        List<TreeMapNode> expandedRow = new ArrayList<TreeMapNode>(row);
-        expandedRow.add(nodes.getFirst());
-        double actualAspectRatio = bestAspectRatio(row, w);
-        double expandedAspectRatio = bestAspectRatio(expandedRow, w);
-
-        if (!willImprove(actualAspectRatio, expandedAspectRatio)) {
-            finalizeRow(row);
-            squarify(nodes, new ArrayList<TreeMapNode>(), getPrincipalSide());
-        } else {
-            nodes.removeFirst();
-            squarify(nodes, expandedRow, w);
-        }
-    }
-
-    /**
-     * Return the rectangles list.
-     * @return a list of rectangles.
-     */
-    public List<TreeMapNode> getSquarifiedNodes() {
-        return squarifiedNodes;
-    }
-    
-    /**
-     * Initialize the available area used to create the tree map
-     */
-    private void initializeArea() {
-        availableArea = new Rectangle2D.Double(container.getX(), container.getY(), 
-                container.getWidth(), container.getHeight());
-        lastX = 0;
-        lastY = 0;
-        squarifiedNodes = new ArrayList<>();
-        currentRow = new ArrayList<>();
-        updateDirection();
-    }
-    
-    /**
-     * Recalculate the drawing direction.
-     */
-    private void updateDirection() {
-        drawingDir = availableArea.getWidth() > availableArea.getHeight() ? 
-                DIRECTION.TOP_BOTTOM : DIRECTION.LEFT_RIGHT;
-    }
-
-
-    /**
-     * Invert the drawing direction.
-     */
-    private void invertDirection() {
-        drawingDir = drawingDir == DIRECTION.LEFT_RIGHT ? 
-                DIRECTION.TOP_BOTTOM : DIRECTION.LEFT_RIGHT;
-    }
-    
-    /**
-     * Keep the current list of nodes which produced the best aspect ratio
-     * in the available area, draw their respective rectangles and reinitialize 
-     * the current row to draw.
-     * <p>
-     * @param nodes the list of numbers which represent the rectangles' area.
-     * @return the number of Rectangles created.
-     */
-    private void finalizeRow(List<TreeMapNode> nodes) {
-        if (nodes == null || nodes.isEmpty()) {
-            return;
-        }
-        // get the total weight of nodes in order to calculate their percentages
-        double sum = getSum(nodes);
-        // greedy optimization step: get the best aspect ratio for nodes drawn 
-        // on the longer and on the smaller side, to evaluate the best.
-        double actualAR = bestAspectRatio(nodes, getPrincipalSide());
-        double alternativeAR = bestAspectRatio(nodes, getSecondarySide());
-      
-        if (willImprove(actualAR, alternativeAR)) {
-            invertDirection();
-        }
-
-        for (TreeMapNode node: nodes) {
-            // assign a rectangle calculated as percentage of the total weight
-            Rectangle2D.Double r = createRectangle(sum, node.getWeight());
-            node.setRectangle(r);
-            
-            // recalculate coordinates to draw next rectangle
-            updateXY(r);
-
-            // add the node to the current list of rectangles in processing
-            currentRow.add(node);
-        }
-        // recalculate the area in which new rectangles will be drawn and 
-        // reinitialize the current list of node to represent.
-        reduceAvailableArea();
-        newRow();
-    }
-    
-
-    /**
-     * Create a rectangle having area = @param area in percentage of @param sum. 
-     * <p>
-     * For example: assume @param area = 4 and @param sum = 12 and the 
-     * drawing direction is top to bottom. <br>
-     * <p>
-     *   __ __ __ __
-     *  |     |     | 
-     *  |__ __|     |  
-     *  |__ __ __ __|
-     * 
-     * <br>the internal rectangle will be calculated as follow:<br>
-     *  {@code height = (4 / 9) * 3} <--note that the principal side for actual  
-     *  drawing direction is 3.
-     *  <br>Now it is possible to calculate the width:<br>
-     *  {@code width = 4 / 1.3} <-- note this is the height value
-     *  
-     * <p>
-     * @param sum the total size of all rectangles in the actual row.
-     * @param area this Rectangle's area.
-     * @return the Rectangle which correctly fill the available area.
-     */
-    private Rectangle2D.Double createRectangle(Double sum, Double area) {
-        double side = getPrincipalSide();
-        double w = 0;
-        double h = 0;
-        
-        //don't want division by 0
-        if (validate(area) == 0 || validate(sum) == 0 || validate(side) == 0) {
-            return new Rectangle2D.Double(lastX, lastY, 0, 0);
-        }
-        
-        // calculate the rectangle's principal side relatively to the container 
-        // rectangle's principal side.
-        if (drawingDir == DIRECTION.TOP_BOTTOM) {
-            h = (area / sum) * side;
-            w = area / h;
-        } else {
-            w = (area / sum) * side;
-            h = area / w;
-        }        
-        return new Rectangle2D.Double(lastX, lastY, w, h);
-    }
-    
-    /**
-     * Check if a double value is defined as Not a Number and sets it to 0.
-     * @param d the value to check.
-     * @return the checked value: 0 if the given number is NaN, else the number
-     * itself.
-     */
-    private double validate(double d) {
-        if (d == Double.NaN) {
-            d = 0;
-        }
-        return d;
-    }
-
-    /**
-     * Check in which direction the rectangles have to be drawn.
-     * @return the side on which rectangles will be created.
-     */
-    private double getPrincipalSide() {
-        return drawingDir == DIRECTION.LEFT_RIGHT ? 
-                availableArea.getWidth() : availableArea.getHeight();
-    }
-
-    /**
-     * 
-     * @return the secondary available area's side.
-     */
-    private double getSecondarySide() {
-        return drawingDir == DIRECTION.LEFT_RIGHT ? 
-                availableArea.getHeight() : availableArea.getWidth();
-    }
-
-    /**
-     * Sum the elements in the list.
-     * @param nodes the list which contains elements to sum.
-     * @return the sum of the elements.
-     */
-    private double getSum(List<TreeMapNode> nodes) {
-        double sum = 0;
-        for (TreeMapNode n : nodes) {
-            sum += n.getWeight();
-        }
-        return sum;
-    }
-
-    /**
-     * Recalculate the origin to draw next rectangles.
-     * @param r the rectangle from which recalculate the origin.
-     */
-    private void updateXY(Rectangle2D.Double r) {
-        if (drawingDir == DIRECTION.LEFT_RIGHT) {
-            //lastY doesn't change
-            lastX += r.width; 
-        } else {
-            //lastX doesn't change
-            lastY += r.height;
-        }
-    }
-
-    /**
-     * Initialize the origin at the rectangle's origin.
-     * @param r the rectangle used as origin source.
-     */
-    private void initializeXY(Rectangle2D.Double r) {
-        lastX = r.x;
-        lastY = r.y;
-    }
-
-    /**
-     * Reduce the size of the available rectangle. Use it after the current 
-     * row's closure.
-     */
-    private void reduceAvailableArea() {
-        if (drawingDir == DIRECTION.LEFT_RIGHT) {
-            // all rectangles inside the row have the same height
-            availableArea.height -= currentRow.get(0).getRectangle().height;
-            availableArea.y = lastY + currentRow.get(0).getRectangle().height;
-            availableArea.x = currentRow.get(0).getRectangle().x;
-        } else {
-            // all rectangles inside the row have the same width
-            availableArea.width -= currentRow.get(0).getRectangle().width;
-            availableArea.x = lastX + currentRow.get(0).getRectangle().width;
-            availableArea.y = currentRow.get(0).getRectangle().y;
-        }
-        updateDirection();
-        initializeXY(availableArea);
-    }
-    
-    /**
-     * Close the current row and initialize a new one.
-     */
-    private void newRow() {
-        squarifiedNodes.addAll(currentRow);
-        currentRow = new ArrayList<>();
-    }
-
-    /**
-     * Calculate the aspect ratio for all the rectangles in the list and
-     * return the max of them.
-     * @param row the list of rectangles.
-     * @param side the side against which to calculate the the aspect ratio.
-     * @return the max aspect ratio calculated for the row.
-     */
-    private double bestAspectRatio(List<TreeMapNode> row, double side) {
-        if (row == null || row.isEmpty()) {
-            return Double.MAX_VALUE;
-        }
-        double sum = getSum(row);
-        double max = 0;
-        // calculate the aspect ratio against the main side, and also its inverse.
-        // this is because aspect ratio of rectangle 6x4 can be calculated as 
-        // 6/4 but also 4/6. Here the aspect ratio has been calculated as 
-        // indicated in the Squarified algorithm.
-        for (TreeMapNode node : row) {
-            double m1 = (Math.pow(side, 2) * node.getWeight()) / Math.pow(sum, 2);
-            double m2 = Math.pow(sum, 2) / (Math.pow(side, 2) * node.getWeight());
-            double m = Math.max(m1, m2);
-
-            if (m > max) {
-                max = m;
-            }
-        }
-        return max;
-    }
-
-    
-    /**
-     * Prepare the elements in the list, sorting them and transforming them
-     * proportionally the given dimension.
-     * @param dim the dimension in which rectangles will be drawn.
-     * @param elements the list of elements to draw.
-     * @return the list sorted and proportioned to the dimension.
-     */
-    private void  prepareData(List<TreeMapNode> elements) {
-        if (elements == null || elements.isEmpty()) {
-            return;
-        }
-        TreeMapNode.sort(elements);
-        double totArea = availableArea.width * availableArea.height;
-        double sum = getSum(elements);
-        
-        // recalculate weights in percentage of their sum
-        for (TreeMapNode node : elements) {
-            double w = (node.getWeight()/sum) * totArea;
-            node.setWeight(w);
-        }
-    }
-
-    /**
-     * This method check which from the values in input, that represent 
-     * rectangles' aspect ratio, produces more approximatively a square.
-     * It checks if one of the aspect ratio values gives a value nearest to 1 
-     * against the other, which means that width and height are similar.
-     * @param actualAR the actual aspect ratio
-     * @param expandedAR the aspect ratio to evaluate
-     * @return false if the actual aspect ratio is better than the new one, 
-     * else true.
-     */
-    private boolean willImprove(double actualAR, double expandedAR) {
-        if (actualAR == 0) {
-            return true;
-        }
-        if (expandedAR == 0) {
-            return false;
-        }
-        // check which value is closer to 1, the square's aspect ratio
-        double v1 = Math.abs(actualAR - 1);
-        double v2 = Math.abs(expandedAR - 1);       
-        return v1 > v2;
-    }
-}
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapBreadcrumb.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import java.awt.Font;
-import java.awt.Image;
-import java.awt.Rectangle;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.font.FontRenderContext;
-import java.util.LinkedList;
-import java.util.Objects;
-import java.util.Stack;
-
-import javax.swing.BoxLayout;
-import javax.swing.ImageIcon;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.UIManager;
-
-import com.redhat.thermostat.client.swing.components.Icon;
-import com.redhat.thermostat.vm.heap.analysis.client.core.HeapIconResources;
-
-/**
- * This object creates a breadcrumb navigation bar used to trace 
- * {@link TreeMapComponent} objects' state.
- */
-public class TreeMapBreadcrumb extends JComponent implements TreeMapObserver {
-
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * Font used by bradcrumb items.
-     */
-    private Font FONT = (Font) UIManager.get("thermostat-default-font");
-
-    /**
-     * Stack containing all items part of the breadcrumb.
-     */
-    private Stack<BreadcrumbItem> items;
-
-    /**
-     * The TreeMap object to interact with.
-     */
-    private TreeMapComponent treemap;
-
-    /**
-     * Constructor. Creates a breadcumbs navigation bar with the starting 
-     * element and register itself as observer to the given treemap.
-     * 
-     * @param start the treemap's root.
-     */
-    public TreeMapBreadcrumb(TreeMapComponent treemap, TreeMapNode start) {
-        super();  
-        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
-        this.items = new Stack<>();
-        this.treemap = Objects.requireNonNull(treemap);
-        this.treemap.register(this);
-        buildBreadcrumb(start);
-    }
-
-
-    /**
-     * Builds the breadcrumb using the nodes'ancestors.
-     * @param node the tree's branch to represent ad breadcrumb bar.
-     */
-    public void buildBreadcrumb(TreeMapNode node) {
-        LinkedList<TreeMapNode> nodes = node.getAncestors();
-
-        while (!nodes.isEmpty()) {
-            BreadcrumbItem item = new BreadcrumbItem(nodes.removeLast());
-            items.push(item);
-            add(item);
-        }
-        // the first element has no tail
-        items.get(0).setAsFirst();
-
-        //the last element has no head
-        items.peek().setAsLast();
-    }
-
-
-    @Override
-    public void notifySelection(TreeMapNode node) {
-        // do nothing
-    }
-
-    @Override
-    public void notifyZoomIn(TreeMapNode node) {
-        items.clear();
-        removeAll();
-        buildBreadcrumb(node);
-    }
-
-    @Override
-    public void notifyZoomOut() {
-        this.remove(items.pop());
-        items.peek().setAsLast();
-        items.peek().repaint();
-    }
-
-    @Override
-    public void notifyZoomFull() {
-        items.clear();
-        this.removeAll();
-        BreadcrumbItem item = new BreadcrumbItem(treemap.getTreeMapRoot());
-        item.setAsFirst();
-        item.setAsLast();
-        items.push(item);
-        this.add(item);
-    }
-
-
-
-    /**
-     *  This class allows to create a single item in a breadcrumb object.
-     *  This component has 3 {@link JLabel}s which contain the images needed
-     *  to draw an arrow.
-     *        _____
-     *    >  |_____|  >
-     *    |     |     |
-     *  tail   body  head
-     *  
-     */
-    class BreadcrumbItem extends JComponent {
-
-        private static final long serialVersionUID = 1L;
-
-        private final String ROOT_TEXT = "root";
-
-        private JLabel tail;
-        private JLabel body;
-        private JLabel head;
-
-        /**
-         * The node this items represents.
-         */
-        private TreeMapNode node;
-
-        /**
-         * The constructor creates a complete item, including both tail and head
-         * @param node
-         */
-        public BreadcrumbItem(final TreeMapNode node) {
-            super();
-            this.node = node;
-            this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
-            initComponent();
-
-            /**
-             * Simulate the click effect increasing and reducing the font size
-             */
-            this.addMouseListener(new MouseAdapter() {
-
-                @Override
-                public void mouseReleased(MouseEvent arg0) {
-                    increaseFont(body, 2);
-                }
-
-                @Override
-                public void mousePressed(MouseEvent arg0) {
-                    increaseFont(body, -2);
-                }
-
-                @Override
-                public void mouseClicked(MouseEvent arg0) {
-                    treemap.zoomIn(node);
-                }
-            });
-        }
-
-
-        /**
-         * Increases the given component's font size.
-         * @param comp the component which edit the font size to.
-         * @param increment value of the increment. Negative values reduce the 
-         * font size.
-         */
-        private void increaseFont(JComponent comp, int increment) {
-            Font f = comp.getFont();
-            int newSize = f.getSize() + increment;
-            f = new Font(f.getName(), f.getStyle(), newSize);
-            comp.setFont(f);
-            comp.repaint();
-        }
-
-        private void initComponent() {
-            initTail();
-            initBody();
-            initHead();
-        }
-
-
-        private void initTail() {
-            tail = new JLabel();
-            tail.setIcon(new Icon(HeapIconResources.getIcon(HeapIconResources.BREADCRUMB_TAIL)));
-            this.add(tail);
-        }
-
-        private void initHead() {
-            head = new JLabel();
-            head.setIcon(new Icon(HeapIconResources.getIcon(HeapIconResources.BREADCRUMB_HEAD)));
-            this.add(head);
-        }
-
-        private void initBody() {
-            body = new JLabel();
-            body.setFont(FONT);
-            body.setHorizontalTextPosition(JLabel.CENTER);
-            body.setText(node.getLabel());
-            adaptIcon(body, new Icon(HeapIconResources.getIcon(HeapIconResources.BREADCRUMB_BODY)));
-            this.add(body);
-        }
-
-
-        public TreeMapNode getNode() {
-            return this.node;
-        }
-
-        /**
-         * Remove the tail of his breadcrumb item.
-         */
-        public void setAsFirst() {
-            this.remove(tail);
-            this.tail = null;
-            this.body.setText(ROOT_TEXT);
-            adaptIcon(body, new Icon(HeapIconResources.getIcon(HeapIconResources.BREADCRUMB_BODY)));
-        }
-
-        /**
-         * Remove the head of his breadcrumb item.
-         */
-        public void setAsLast() {
-            this.remove(head);
-            this.head = null;
-        }
-
-        /**
-         * Sets the text of this item, which is placed in the body.
-         * @param text
-         */
-        public void setText(String text) {
-            body.setText(text);
-        }
-
-        public int getHeight() {
-            return body.getPreferredSize().height;
-        }
-    }
-
-    /**
-     * Calculates the labels' text size in order to scale the given image
-     * and to apply to it.
-     */
-    private void adaptIcon(JLabel label, ImageIcon icon) {
-        Rectangle fontArea;
-        try {
-            fontArea = label.getFont().getStringBounds(label.getText(), 
-                    new FontRenderContext(label.getFont().getTransform(),
-                            false, false)).getBounds();
-
-        } catch (NullPointerException npe) {
-            fontArea = label.getBounds();
-        }
-        
-        Image img = icon.getImage();
-        Image newimg = img.getScaledInstance(fontArea.getBounds().width + 10, 
-                img.getHeight(null),  java.awt.Image.SCALE_SMOOTH);
-        icon = new ImageIcon(newimg);
-        label.setIcon(icon);
-    }
-}
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapComponent.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,794 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.font.FontRenderContext;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import java.util.Stack;
-
-import javax.swing.BorderFactory;
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-import javax.swing.SwingUtilities;
-import javax.swing.UIManager;
-import javax.swing.border.Border;
-import javax.swing.border.EmptyBorder;
-import javax.swing.border.EtchedBorder;
-import javax.swing.border.LineBorder;
-
-import com.redhat.thermostat.client.swing.ThermostatSwingCursors;
-import com.redhat.thermostat.vm.heap.analysis.common.ObjectHistogram;
-
-/**
- * This class allows to represent a hierarchical data structure as a TreeMap.
- * It extends {@link JComponent} so it can be used like usual Swing objects.
- *
- */
-public class TreeMapComponent extends JComponent {
-
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * TreeMap's graphic root.
-     */
-    Comp mainComp;
-
-    /**
-     * Label Object to clone for faster initialization.
-     */
-    private Label cachedLabel;
-
-    /**
-     * The tree to render as TreeMap.
-     */
-    TreeMapNode tree;
-
-    /**
-     * Horizontal and vertical padding for nested component.
-     */
-    private final int X_PADDING = TreeProcessor.X_PADDING;
-    private final int Y_PADDING = TreeProcessor.Y_PADDING;
-
-    /**
-     * Min size for rectangles' sides. rectangles having one or both sides less
-     * than MIN_SIDE pixels will be not drawn.
-     */
-    private final int MIN_SIDE = 1;
-
-    /**
-     * Default value for a TreeMap component.
-     */
-    private static final String TITLE = "";
-
-    /**
-     * TreeMap UI Constraint.
-     */
-    public static final int SIMPLE = 0;
-    public static final int FLAT = 1;
-    public static final int ETCHED_LOWERED = 2;
-    public static final int ETCHED_RAISED = 3;
-
-    /**
-     * Stores the chosen UI mode.
-     */
-    private int borderStyle = ETCHED_LOWERED;
-
-    /**
-     * The components' border
-     */
-    private Border defaultBorder;
-
-    /**
-     * Font and size for this component's label.
-     */
-    private int FONT_SIZE = 8;
-    private Font FONT = (Font) UIManager.get("thermostat-default-font");
-
-
-    /**
-     * Variable in which store last resize dimension.
-     */
-    private Dimension lastDim;
-
-    /**
-     * Variable in which store last resize event call time.
-     */
-    private static long lastCall = 0;
-
-    /**
-     * Wait time in millisec to resize the TreeMap.
-     */
-    private final int MIN_DRAGGING_TIME = 60;
-
-
-    /**
-     * Stack containing the zoom calls on the TreeMap.
-     */
-    private Stack<TreeMapNode> zoomStack;
-
-    /**
-     * This object stores the last clicked rectangle in the TreeMap, in order to 
-     * repaint it when another rectangle will be selected.
-     */
-    private static Comp lastClicked;
-    
-    /**
-     * List of objects observing this.
-     */
-    private List<TreeMapObserver> observers;
-
-    /**
-     * Constructor which creates a TreeMapComponent by an histogram object.
-     * @param histogram the histogram to represent as tree map.
-     */
-    public TreeMapComponent(ObjectHistogram histogram) {
-        this(HistogramConverter.convertToTreeMap(histogram), new Dimension());
-    }
-
-    /**
-     * Constructor. It draw a TreeMap of the given tree in according to the 
-     * {@Dimension} object in input.
-     * 
-     * @param tree the tree to represent as TreeMap.
-     * @param d the dimension the TreeMap will fulfill.
-     * 
-     * @throws NullPointerException if one of the parameters is null
-     */
-    public TreeMapComponent(TreeMapNode tree, Dimension d) {
-        super();
-        Objects.requireNonNull(tree);
-        Objects.requireNonNull(d);
-        this.tree = tree;
-        lastDim = getSize();
-        this.zoomStack = new Stack<>();
-        this.zoomStack.push(this.tree);
-        this.observers = new ArrayList<>();
-
-        // assign a rectangle to the tree's root in order to process the tree.
-        Rectangle2D.Double area = new Rectangle2D.Double(0, 0, d.width, d.height);
-
-        // calculate rectangles of tree's subtrees
-        TreeProcessor.processTreeMap(tree, area);
-
-        drawTreeMap(tree); 
-
-        addResizeListener(this);        
-        repaint();
-    }
-
-    /**
-     * This method returns the root of the tree showed ad TreeMap.
-     * @return the TreeMap's root node.
-     */
-    public TreeMapNode getTreeMapRoot() {
-        return this.tree;
-    }
-
-    /**
-     * This method is responsible for the TreeMap drawing process.
-     * @param tree the tree to represent as TreeMap.
-     */
-    private void drawTreeMap(TreeMapNode tree) {
-        // draw root
-        drawMainComp(tree);
-        setBorderStyle(borderStyle);
-        
-        // draw subtrees nested in children 
-        for (TreeMapNode child : tree.getChildren()) {
-            drawSubTree(child, mainComp);
-        }
-        // setup this component
-        prepareGUI();
-    }
-
-    /**
-     * This method prepares the layout for this component. 
-     */
-    private void prepareGUI() {
-        setLayout(new BorderLayout());
-        setBounds(mainComp.getBounds());
-        setBorder(null);
-        add(mainComp, BorderLayout.CENTER);
-        revalidate();
-        repaint();
-    }
-
-    /**
-     * This method prepares the main component which is the parent object where 
-     * sub components will be placed. 
-     * @param tree the tree's root used to prepare the main component.
-     */
-    private void drawMainComp(TreeMapNode tree) {
-        mainComp = new Comp();
-        mainComp.setLayout(null);
-        mainComp.setBounds(tree.getRectangle().getBounds());        
-        mainComp.setNode(tree);
-        cachedLabel = new Label(TITLE + tree.getLabel());        
-        addLabelIfPossible(TITLE + tree.getLabel(), mainComp);
-    }
-
-    /**
-     * Create a TreeMapComp from the given node. The component is not 
-     * instantiated as a new component but is cloned from an existing one, in 
-     * order to improve performance.
-     * 
-     * @param node the node to represent as a component.
-     * @return the component representing the given node.
-     */
-    private Comp renderizeNode(TreeMapNode node) {
-        // if the rectangle's node is too small to be viewed, don't draw it.
-        if (node.getRectangle().getWidth() <= MIN_SIDE || 
-                node.getRectangle().getHeight() <= MIN_SIDE) {
-            return null;
-        }
-
-        Comp comp = (Comp) mainComp.clone();
-        comp.setBounds(node.getRectangle().getBounds());
-
-        return comp;
-    }
-
-    /**
-     * This method checks if the given container has enough space to instantiate
-     * a Label in it. If yes, a Label is cloned from an existing one, in order 
-     * to improve performance. If not, it exits.
-     * 
-     * @param s the label text.
-     * @param cont the parent container which will contain the new label.
-     * @return the cloned label.
-     */
-    private Label addLabelIfPossible(String s, Container cont) {
-        if (s == null || s.equals("")) {
-            return null;
-        }
-        int componentW = cont.getSize().width;
-        int componentH = cont.getSize().height;
-        // get the rectangle associated to the area needed for the label's text
-        Rectangle fontArea = FONT.getStringBounds(s, 
-                new FontRenderContext(FONT.getTransform(),
-                        false, false)).getBounds();
-
-        // if the container is greater than the label, add it to the container
-        if (componentW > fontArea.width && componentH > fontArea.height) {
-            Label label = (Label) cachedLabel.clone();
-            label.setBounds(5, 1, cont.getWidth(), fontArea.height);
-            label.setText(s);
-            cont.add(label);
-            return label;
-        }
-        return null;
-    }
-
-    /**
-     * Draw the whole {@param tree}'s subtree inside the given component.
-     * @param tree the tree to draw
-     * @param parent the component in which build the tree.
-     */
-    private void drawSubTree(TreeMapNode tree, JComponent parent) {
-        Comp comp = addCompIfPossible(tree, parent);
-
-        // if space was enough to draw a component, try to draw its children
-        if (comp != null) {
-            comp.setNode(tree);
-            for (TreeMapNode child : tree.getChildren()) {
-                drawSubTree(child, comp);
-            }
-        }
-    }
-
-    /**
-     * Create and add to the {@link Container} given in input a 
-     * {@link ComponentResized} listener.
-     * @param c the container in to assign the listener.
-     */
-    private void addResizeListener(final Container container) {
-        ComponentAdapter adapter = new ComponentAdapter() {
-            public void componentResized(ComponentEvent e) {
-                // if enough time is passed from the last call, redraw the TreeMap
-                if (canResize(MIN_DRAGGING_TIME)) {
-                    Dimension newDim = container.getSize();
-
-                    if (isChangedSize(newDim)) {
-                        redrawTreeMap(tree); 
-                    }
-                } 
-            }            
-        };
-        container.addComponentListener(adapter);
-    }
-
-    /**
-     * This method checks if the given container has enough space to instantiate
-     * a TreeMapComp object in it. If yes, a Label is cloned from an existing 
-     * one, in order to improve performance. If not, it exits.
-     * 
-     * @param node the node to draw and add to the given container.
-     * @param cont the parent container which will contain the new component.
-     * @return true if the component was created and added, else false.
-     */
-    private Comp addCompIfPossible(TreeMapNode node, Container cont) {
-        Rectangle2D rect = node.getRectangle();
-        // if the ndoe's rectangle is smaller than the container, it is added
-        if (cont.getWidth() > rect.getWidth() + X_PADDING && 
-                cont.getHeight() > rect.getHeight() + Y_PADDING) {
-
-            Comp toReturn = renderizeNode(node);
-            if (toReturn == null) {
-                return null;
-            }
-            addLabelIfPossible(TITLE + node.getLabel(), toReturn);
-
-            // leaves some space from the parent's origin location
-            Point loc = toReturn.getLocation();
-            loc.x += X_PADDING;
-            loc.y += Y_PADDING;
-            toReturn.setLocation(loc);
-
-            cont.add(toReturn);
-            return toReturn;
-        }
-        return null;
-    }
-
-
-    /**
-     * This method recalculates and redraws the TreeMap in according to the size
-     * of this component and the actual {@link TreeMapNode} object.
-     */
-    private void redrawTreeMap(TreeMapNode newRoot) {
-        tree = newRoot;
-        Rectangle2D.Double newArea = tree.getRectangle();
-        // give to the root node the size of this object so it can be recalculated
-        newArea.width = getSize().width;
-        newArea.height = getSize().height;
-
-        // recalculate the tree
-        TreeProcessor.processTreeMap(tree, newArea);
-
-        removeAll();
-        drawTreeMap(tree);        
-    }
-
-    boolean isZoomInEnabled(TreeMapNode node) {
-        return !(node == null
-                || node.equals(this.tree)
-                || node.isLeaf());
-    }
-
-    public void zoomIn(TreeMapNode node) {
-        if (isZoomInEnabled(node)) {
-            fillZoomStack(node.getAncestors());
-            redrawTreeMap(node);
-            notifyZoomInToObservers(zoomStack.peek());
-        } 
-    }
-
-    private void fillZoomStack(LinkedList<TreeMapNode> ancestors) {
-        zoomStack.clear();
-        while (!ancestors.isEmpty()) {
-            zoomStack.push(ancestors.removeLast());
-        }
-    }
-
-    public void zoomOut() {
-        // if the actual root element is not the tree's original root
-        if (zoomStack.size() > 1) {
-            zoomStack.pop();
-            redrawTreeMap(zoomStack.peek());
-            notifyZoomOutToObservers();
-        }
-    }
-
-    /**
-     * Zoom out the view directly to the original root.
-     */
-    public void zoomFull() {
-        if (zoomStack.size() > 1) {
-            clearZoomCallsStack();
-            redrawTreeMap(zoomStack.peek());
-            notifyZoomFullToObservers();
-        }
-    }
-    
-    /**
-     * Add the object in input to the list of registered objects to this TreeMap.
-     * @param observer the Notifiable object to register to this object.
-     */
-    public void register(TreeMapObserver observer) {
-        this.observers.add(observer);
-    }
-    
-    /**
-     * Remove the object in input from the list of registered objects to this TreeMap.
-     * @param observer the Notifiable object to unregister from this object.
-     */
-    public void unregister(TreeMapObserver observer) {
-        this.observers.remove(observer);
-    }
-    /**
-     * Notify observers that an object in the TreeMap has been selected.
-     * @param comp the selected component.
-     */
-    private void notifySelectionToObservers(TreeMapNode node) {
-        for (TreeMapObserver observer : observers) {
-            observer.notifySelection(node);
-        }
-    }
-
-    /**
-     * Notify observers that  TreeMap has been zoomed.
-     * @param zoomedComponent 
-     */
-    private void notifyZoomInToObservers(TreeMapNode node) {
-        for (TreeMapObserver observer : observers) {
-            observer.notifyZoomIn(node);
-        }
-    }
-    
-    /**
-     * Notify observers that  TreeMap has been zoomed.
-     * @param zoomedComponent 
-     */
-    private void notifyZoomOutToObservers() {
-        for (TreeMapObserver observer : observers) {
-            observer.notifyZoomOut();
-        }
-    }
-    
-    /**
-     * Notify observers that  TreeMap has been zoomed.
-     * @param zoomedComponent 
-     */
-    private void notifyZoomFullToObservers() {
-        for (TreeMapObserver observer : observers) {
-            observer.notifyZoomFull();
-        }
-    }
-    
-    
-
-    /**
-     * Returns the list of zoom operation calls.
-     * @return the stack that holds the zoom calls.
-     */
-    public Stack<TreeMapNode> getZoomCallsStack() {
-        return zoomStack;
-    }
-
-    /**
-     * Clear the zoom calls of this object leaving the stack with just the root.
-     */
-    public void clearZoomCallsStack() {
-        while (zoomStack.size() > 1) {
-            zoomStack.pop();
-        }
-    }
-
-    /**
-     * check if last resize operation was called too closer to this
-     * one. If so, ignore it: the container is being dragged. 
-     * 
-     * @return true if this method is invoked at distance of 
-     * MIN_DRAGGING_TIME millisec, else false. 
-     */
-    private boolean canResize(int millisec) {
-        long time = System.currentTimeMillis();
-        if (time - lastCall >= millisec) {
-            lastCall = time;
-            return true;
-        }
-        return false;
-    }
-
-
-    /**
-     * Check if the dimension given in input differs from the last one stored
-     * by 2. 
-     * @param newDim the new dimension to check.
-     * @return true if the dimensions are different, else false.
-     */
-    private boolean isChangedSize(Dimension newDim) {
-        int minResizeDim = 2;
-        int deltaX = Math.abs(newDim.width - lastDim.width);
-        int deltaY = Math.abs(newDim.height - lastDim.height);
-
-        if (deltaX > minResizeDim || deltaY > minResizeDim) {
-            lastDim = newDim;
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * Switch the component's visualization mode to the one given in input. 
-     * Use static constraints to set correctly a visualization mode.
-     * @param constraint the UI visualization mode to set.
-     */
-    public void setBorderStyle(int UIMode) {
-        this.borderStyle = UIMode;
-        switch (borderStyle) {
-            case 1 : {
-                defaultBorder = new EmptyBorder(0, 0, 0, 0);
-                break;
-            }    
-            case 2 : {                
-                defaultBorder = BorderFactory.createEtchedBorder(EtchedBorder.LOWERED, Color.white, Color.darkGray);
-                break;
-            }
-            case 3 : {
-                defaultBorder = BorderFactory.createEtchedBorder(EtchedBorder.RAISED, Color.white, Color.darkGray);
-                break;
-            }
-            default : {
-                defaultBorder = new LineBorder(Color.black, 1);
-                break;
-            }
-        }
-        applyBorderToSubtree(mainComp);
-    }
-    
-    /**
-     * Traverse recursively the tree from the given component applying to it 
-     * the default border.
-     * @param comp the subtree's root from which apply the border style.
-     */
-    private void applyBorderToSubtree(Comp comp) {
-        comp.setBorder(defaultBorder);
-        Component[] children = comp.getComponents();
-        for (int i = 0; i < children.length; i++) {
-            if (children[i] instanceof Comp) {
-                applyBorderToSubtree((Comp) children[i]);
-            }
-        }
-    }
-
-    /**
-     * Return the last clicked component inside the TreeMap.
-     * @return the last clicked {@Comp} object.
-     */
-    public Comp getClickedComponent() {
-        return lastClicked;
-    }
-
-    /**
-     * This class provides an extension of {@link JLabel} which main 
-     * characteristic is to implement the {@link Cloneable} interface in order
-     * to make his creation faster then JLabel class.
-     */
-    class Label extends JLabel implements Cloneable {
-        private static final long serialVersionUID = 1L;
-
-        public Label(String s) {
-            super(s);
-            setFont(FONT);
-            setBounds(0, 0, getPreferredSize().width, FONT_SIZE);
-        }
-
-        @Override
-        protected JLabel clone() {
-            Label clone = new Label("");
-            clone.setFont(getFont());
-            clone.setText(getText());
-            clone.setBackground(getBackground());
-            clone.setBounds(getBounds());
-            clone.setBorder(getBorder());
-            return clone;
-        }
-    }    
-
-    /**
-     * This class provides an extension of {@link JComponent} which main 
-     * characteristic is to implement {@link Cloneable} interface in order to
-     * make his creation faster. <br>
-     * It also provides some action listeners that allow to select it, performing
-     * zoom operations for the treemap.
-     */
-    class Comp extends JComponent implements Cloneable {
-
-        private static final long serialVersionUID = 1L;
-
-        /**
-         * The node represented by this component.
-         */
-        private TreeMapNode node;
-
-        /**
-         * The background color. It depends by the node's depth.
-         */
-        private Color color;
-
-        /**
-         * Reference to this.
-         */
-        private Comp thisComponent;
-
-        public Comp() {
-            super();
-            thisComponent = this;
-            addClickListener(this);
-            addMouseListener(this);
-        }
-
-        @Override
-        public Comp clone() {
-            Comp clone = new Comp();
-            clone.setBounds(getBounds());
-            clone.setBorder(getBorder());
-            clone.setLayout(getLayout());
-            clone.setOpaque(true);
-            return clone;
-        }
-
-        public void setNode(TreeMapNode node) {
-            this.node = node;
-            this.color = node.getColor();
-            ValueFormatter f = new ValueFormatter(this.node.getRealWeight());
-            this.setToolTipText(this.node.getLabel() + " - " + f.format());
-        }
-        
-        public TreeMapNode getNode() {
-            return this.node;
-        }
-
-        public Color getColor() {
-            return this.color;
-        }
-
-        public void setColor(Color c) {
-            this.color = c;
-        }
-
-        @Override
-        public void paintComponent(Graphics g) {
-            super.paintComponent(g); 
-            if (this.color != null) {
-                g.setColor(color);
-                g.fillRect(0, 0, getWidth(), getHeight());
-            }
-        }   
-
-        /**
-         * Add a mouse listener to this component. It allows to select it and
-         * zoom it. 
-         * @param component the component which will have the mouse listener.
-         */
-        private void addClickListener(final JComponent component) {
-            MouseListener click = new MouseAdapter() {
-                @Override
-                public void mousePressed(MouseEvent e) {
-                    // one left click select the rectangle
-                    if (SwingUtilities.isLeftMouseButton(e)) {
-                        selectComp();
-                    }
-                    // double left click to zoom in (on non-leaf nodes only)
-                    if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e)) {
-                        zoomIn(getNode());
-                    }
-                    // one right click to zoom out
-                    if (SwingUtilities.isRightMouseButton(e)) {
-                        zoomOut();
-                    }
-                    // one middle click to reset zoom
-                    if (SwingUtilities.isMiddleMouseButton(e)) {
-                        zoomFull();
-                    }
-                }
-            };
-            component.addMouseListener(click);
-        }
-
-        /**
-         * Add a mouse motion listener to this component. This allows for the mouse cursor to be changed into a
-         * magnifying glass icon when the cursor enters a zoomable component, and back to a default cursor when it
-         * exits a zoomable component.
-         * @param component the component which will have the mouse motion listener.
-         */
-        private void addMouseListener(final JComponent component) {
-            MouseListener listener = new MouseAdapter() {
-                @Override
-                public void mouseEntered(MouseEvent e) {
-                    if (getNode().isLeaf()) {
-                        setDefaultCursor();
-                    } else {
-                        setZoomableCursor();
-                    }
-                }
-
-                @Override
-                public void mouseExited(MouseEvent e) {
-                    if (!getNode().isLeaf()) {
-                        setDefaultCursor();
-                    } else {
-                        setZoomableCursor();
-                    }
-                }
-
-                private void setZoomableCursor() {
-                    component.setCursor(ThermostatSwingCursors.getZoomIconCursor());
-                }
-
-                private void setDefaultCursor() {
-                    component.setCursor(Cursor.getDefaultCursor());
-                }
-            };
-            component.addMouseListener(listener);
-        }
-
-        /**
-         * This method gives a darker color to this component and restore the
-         * original color to the last selected component.
-         */
-        private void selectComp() {
-            if (lastClicked != null) {
-                if (!lastClicked.getNode().isLeaf()) {
-                    lastClicked.setColor(lastClicked.getColor().brighter());
-                }
-                lastClicked.repaint();
-            } 
-            lastClicked = thisComponent;
-            if (!getNode().isLeaf()) {
-                setColor(getColor().darker());
-            }
-            repaint();
-            notifySelectionToObservers(node);
-        }
-    }
-}
-
-
-
-
-
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapNode.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,447 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import java.awt.Color;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-/**
- * This class provide a tree recursive implementation used in
- * {@link SquarifiedTreeMap}. It contains a reference to the parent node and to
- * a node list, which represent the node's children. It is also 
- * possible to store generic information inside the node using a {@link Map} 
- * object. Furthermore, the main property of this class is the chance to have a
- * weight for the node and associate to it a {@link Rectangle2D.Double} object.
- * 
- * <p>When an instance of this class is created, it will automatically be 
- * assigned a unique id.
- * 
- * <p>By default, this class' comparator is based on the nodes' weight.
- * 
- * <p>A static Quick Sort algorithm implementation is also provided by this 
- * class.
- * 
- * @see Rectangle2D.Double
- */
-public class TreeMapNode {
-        
-    /**
-     * Counter for assign unique id to nodes.
-     */
-    private static int idCounter = 0;
-
-    /**
-     * The rectangle which will graphically represent this node.
-     */
-    private Rectangle2D.Double rectangle;
-
-    /**
-     * This node's id.
-     */
-    private int id;
-    
-    /**
-     * A Map in which store information for this node.
-     */
-    private Map<String, String> info;
-    
-    /**
-     * Reference to the parent.
-     */
-    private TreeMapNode parent;
-    
-    /**
-     * Reference to children.
-     */
-    private List<TreeMapNode> children;
-    
-    /**
-     * The node's weight.
-     */
-    private double weight;
-    
-    /**
-     * The node's label. It can be the same of another node.
-     */
-    private String label;
-    
-    /**
-     * The node's weight which has been set inside the constructor. All
-     * operations which refers to node's weight work on the weight field, that 
-     * is used to make calcs.
-     */
-    private double realWeight;
-    
-    /**
-     * This flag indicates if weight value can be a non positive number.
-     */
-    static boolean allowNonPositiveWeight = false;
-    
-    /**
-     * The color of this node.
-     */
-    private Color color;
-    
-    /**
-     * Colors available on which iterate
-     */
-    static final Color[] colors = {
-            Color.decode("#FACED2"), // red
-            Color.decode("#B9D6FF"), // blue
-            Color.decode("#E5E5E5"), // grey
-            Color.decode("#FFE7C7"), // orange
-            Color.decode("#ABEBEE"), // aqua
-            Color.decode("#E4D1FC"), // purple
-            Color.decode("#FFFFFF"), // white
-            Color.decode("#CDF9D4")  // green
-    };
-    
-    public final Color START_COLOR = colors[0];
-    
-    /**
-     * 
-     * Constructor that allow to set the nodes' real weight. Others fields are 
-     * initialized to their default value.
-     * It automatically set the node's id.
-     *
-     * <p>
-     * @param realWeight the nodes real weight, which will be not affected 
-     * during node processing.
-     * 
-     */
-    public TreeMapNode(double realWeight) {
-        this("", realWeight);
-    }
-
-    /**
-     * 
-     * Constructor that allow to set the nodes' real weight and the label. 
-     * Others fields are initialized to their default value.
-     * It automatically set the node's id.
-     *
-     * <p>
-     * @param label the node's label.
-     * @param realWeight the nodes real weight, which will be not affected 
-     * during node processing.
-     * 
-     */
-    public TreeMapNode(String label, double realWeight) {
-        this.id = idCounter++;
-        this.label = label;
-        this.parent = null;
-        this.children = new ArrayList<TreeMapNode>();
-        this.rectangle = new Rectangle2D.Double();
-        this.info = new HashMap<String, String>();
-        this.weight = realWeight;
-        this.realWeight = realWeight;
-    }
-
-    /**
-     * Return the id of this object.
-     * @return the id automatically assigned at this object initialization.
-     */
-    public int getId() {
-        return this.id;
-    }
-    
-    /**
-     * Set this node's label.
-     * @param newLabel the new label to set.
-     */
-    public void setLabel(String newLabel) {
-        this.label = newLabel;
-    }
-    
-    /**
-     * Return the label of this object.
-     * @return the label assigned at instantiation time to this object.
-     */
-    public String getLabel() {
-        return this.label;
-    }
-
-    /**
-     * Return the reference to the node parent of this object.
-     * @return the parent of this node. It can be null.
-     */
-    public TreeMapNode getParent() {
-        return this.parent;
-    }
-
-    /**
-     * Set as parent of this object the node given in input.
-     * @param parent the new parent of this object. No checks are made for null
-     * value.
-     */
-    public void setParent(TreeMapNode parent) {
-        this.parent = parent;
-    }
-
-    /**
-     * Return the list of nodes representing this node's children.
-     * @return a list of {@link TreeMapNode} objects.
-     */
-    public List<TreeMapNode> getChildren() {
-        return this.children;
-    }
-
-    public boolean isLeaf() {
-        return getChildren().isEmpty();
-    }
-    
-    /**
-     * Set as children list of this object the list given in input.
-     * @param children the new list of children for this node.
-     */
-    public void setChildren(List<TreeMapNode> children) {
-        this.children = children;
-        for (TreeMapNode child : this.children) {
-            child.setParent(this);
-        }
-    }
-
-    /**
-     * Return the {@link Map} object containing all information of this node.
-     * @return a {@link Map} object.
-     */
-    public Map<String, String> getInfo() {
-        return this.info;
-    }
-    
-    /**
-     * Store the given information into this object.
-     * @param key the key searching value for the information to store.
-     * @param value the information to store into this object.
-     * @return the old value for the given key.
-     */
-    public String addInfo(String key, String value) {
-        return this.info.put(key, value);
-    }
-
-    /**
-     * Return the information stored in this object, corresponding to the key 
-     * given in input.
-     * @param key the key value for the search information.
-     * @return the corresponding value for the given key.
-     */
-    public String getInfo(String key) {
-        return this.info.get(key);
-    }
-
-    /**
-     * Add the object given in input to the children list of this object. It 
-     * also add this object as its parent.
-     * @param child the new child to add at this object.
-     */
-    public void addChild(TreeMapNode child) {
-        if (child != null) {
-            this.children.add(child);
-            child.setParent(this);
-        }
-    }
-
-    @Override
-    /**
-     * Return a {@link String}  representing this object.
-     */
-    public String toString() {
-        return  getClass().getSimpleName() + " [" + "label = " + getLabel() + 
-                "; weight =" + getRealWeight() + 
-                "; rectangle=" + rectangle.getBounds() + "]";
-    }
-
-    /**
-     * Return the weight of this object. In case of allowNonPositiveWeight is 
-     * set to false and the weight is 0, less than 0 or not a number 
-     * ({@link Double.Nan}), this method returns a value that can be transformed
-     * by external objects, so if you need the real weight you have to
-     * invoke getrealWeight().
-     * 
-     * @return the node's weight.
-     */
-    public double getWeight() {
-        if ((weight <= 0 || weight == Double.NaN) && !allowNonPositiveWeight) {
-            return realWeight;
-        }
-        return this.weight;
-    }
-    
-    /**
-     * Use this method to retrieve the real weight assigned to this node.
-     * @return the weight corresponding to this node.
-     */
-    public double getRealWeight() {
-        return this.realWeight;
-    }
-    
-    
-    /**
-     * Use this method to set the real weight of this node.
-     */
-    public void setRealWeight(double w) {
-        this.realWeight = w;
-    }
-
-    /**
-     * Set the weight of this object. If a negative value is given, it is set 
-     * automatically to 0.
-     * @param weight the new weight for this object.
-     */
-    public void setWeight(double w) {
-        this.weight = w < 0 && !allowNonPositiveWeight ? 0 : w;
-    }
-
-
-    /**
-     * Return the rectangle representing this object.
-     * @return a {@link Rectangle2D.Double} object.
-     */
-    public Rectangle2D.Double getRectangle() {
-        if (this.rectangle == null) {
-            throw new RuntimeException();
-        }
-        return this.rectangle;
-    }
-
-    /**
-     * Set a new rectangle for this object.
-     * @param rectangle the new rectangle that represent this node.
-     */
-    public void setRectangle(Rectangle2D.Double rectangle) {
-        this.rectangle = rectangle;
-    }    
-
-    /**
-     * 
-     * @return true if non positive value can be used as weight, else false.
-     */
-    public static boolean isAllowNonPositiveWeight() {
-        return allowNonPositiveWeight;
-    }
-
-    /**
-     * Set this value to false and nodes will be not able to manage non positive
-     * values for weight field, otherwise set to true.
-     * @param allowed the flag value for managing non positive values as weight
-     */
-    public static void setAllowNonPositiveWeight(boolean allowed) {
-        allowNonPositiveWeight = allowed;
-    }
-
-    /**
-     * This method assess if the rectangle associated to this node is drawable,
-     * which means that its sides are greater than 1.
-     * @return true if the rectangle associated to this node  is drawable, 
-     * else false.
-     */
-    public boolean isDrawable() {
-        if (rectangle.width >= 1 && rectangle.height >= 1) {
-            return true;
-        }
-        return false;
-    }
-    
-    public Color getColor() {
-        return color;
-    }
-
-    public void setColor(Color color) {
-        this.color = color;
-    }
-    
-    /**
-     * Returns this node's next color.
-     * @return the color which came after this node's color in the color list.
-     * If this node has no color assigned then the START_COLOR is returned.
-     */
-    public Color getNextColor() {
-        if (this.color != null) {
-            for (int i = 0; i < colors.length; i++) {
-                if (this.color.equals(colors[i])) {
-                    return colors[(i + 1) % colors.length];
-                }
-            }
-        }
-        return START_COLOR;
-    }
-
-
-    public int getDepth() {
-        if (this.parent == null) {
-            return 0;
-        } else {
-            return 1 + parent.getDepth();
-        }
-    }
-
-    /**
-     * This method sorts the given list in <b>descending<b> way.
-     * 
-     * @param nodes the list of {@link TreeMapNode} to sort.
-     */
-    public static void sort(List<TreeMapNode> nodes) {
-        Comparator<TreeMapNode> c = new Comparator<TreeMapNode>() {
-          @Override
-          public int compare(TreeMapNode o1, TreeMapNode o2) {
-              // inverting the result to descending sort the list
-              return -(Double.compare(o1.getWeight(), o2.getWeight()));
-          }
-      };
-      Collections.sort(nodes, c);
-    }
-    
-    /**
-     * Return the list of ancestors node of this object. The first one is this 
-     * node itself, the last one the root.
-     * @return a list of ancestors nodes.
-     */
-    public LinkedList<TreeMapNode> getAncestors() {
-        LinkedList<TreeMapNode> toReturn = new LinkedList<TreeMapNode>();
-        TreeMapNode tmp = this;
-        do {
-            toReturn.add(tmp);
-        } while ((tmp = tmp.getParent()) != null);
-        return toReturn;
-    }
-}
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapObserver.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-/**
- * This interface is used as part of the Observer Design Pattern developed
- * for objects who want to be notified about TreeMap's events.
- */
-public interface TreeMapObserver {
-    
-    /**
-     * This method inform the Observer object that the object passed as 
-     * argument has been selected.
-     * 
-     * @param selectedComp the selected component to communicate to 
-     * this Observer object.
-     */
-    public void notifySelection(TreeMapNode node);
-    
-    /**
-     * This method informs objects that a zoom in event has been performed on
-     * the given node.
-     * @param node the zoomed node.
-     */
-    public void notifyZoomIn(TreeMapNode node);
-    
-    /**
-     * This method informs objects that a zoom out event has been performed.
-     */
-    public void notifyZoomOut();
-    
-    /**
-     * This method informs objects that the zoom level has been resetted.
-     */
-    public void notifyZoomFull();
-}
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapPanel.java	Wed Jun 01 15:58:04 2016 -0400
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapPanel.java	Mon Jun 06 15:17:50 2016 -0400
@@ -38,10 +38,13 @@
 
 import java.awt.BorderLayout;
 import java.awt.Component;
+import java.awt.Dimension;
 
 import javax.swing.JPanel;
 
 import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.experimental.TreeMapComponent;
+import com.redhat.thermostat.client.swing.components.experimental.TreeMapToolbar;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapTreeMapView;
 import com.redhat.thermostat.vm.heap.analysis.common.ObjectHistogram;
 
@@ -58,7 +61,7 @@
 
     @Override
     public void display(ObjectHistogram histogram) {
-        treeMap = new TreeMapComponent(histogram);
+        treeMap = new TreeMapComponent(HistogramConverter.convertToTreeMap(histogram), new Dimension());
         panel.add(treeMap, BorderLayout.CENTER);
         panel.add(new TreeMapToolbar(treeMap), BorderLayout.NORTH);
     }
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapToolbar.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.awt.event.AdjustmentEvent;
-import java.awt.event.AdjustmentListener;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
-import java.util.Objects;
-
-import javax.swing.Box;
-import javax.swing.JComponent;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.ScrollPaneConstants;
-
-/**
- * This class provides a tool bar containing a {@lnk TreeMapBreadcrumb} object 
- * and a {@link TreeMapZoomBar} instance to control the state of 
- * {@link TreeMapComponent} objects.
- */
-@SuppressWarnings("serial")
-public class TreeMapToolbar extends JComponent {
-    
-    /**
-     * The panel in which objects are placed.
-     */
-    private JPanel contentPane;
-    
-    /**
-     * The scroll pane used to hide breadcrumb's first items.
-     */
-    private JScrollPane scrollPane;
-    
-    
-    public TreeMapToolbar(TreeMapComponent treemap) {
-        super();
-        initComponent(Objects.requireNonNull(treemap));
-    }
-
-
-    private void initComponent(TreeMapComponent treemap) {
-        this.setLayout(new BorderLayout());
-        
-        final JPanel breadcrumbPanel = new JPanel();
-        breadcrumbPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
-        add(breadcrumbPanel, BorderLayout.CENTER);
-        
-        JPanel zoomPanel = new JPanel(new FlowLayout());
-        // add some empty space between the breadcrumb bar and buttons
-        zoomPanel.add(Box.createHorizontalStrut(20));
-        add(zoomPanel, BorderLayout.EAST);
-
-        TreeMapZoomBar zoomBar = new TreeMapZoomBar(treemap);
-        zoomPanel.add(zoomBar);
-        
-        TreeMapBreadcrumb bc = new TreeMapBreadcrumb(treemap, treemap.getTreeMapRoot());
-        
-        contentPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
-        contentPane.add(bc);
-
-        scrollPane = new JScrollPane(contentPane);
-        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
-        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
-        scrollPane.setBorder(null);
-        
-        // allows to see always the last elements of the breadcrumb.
-        scrollPane.getHorizontalScrollBar().addAdjustmentListener(new AdjustmentListener() {
-            public void adjustmentValueChanged(AdjustmentEvent e) {
-                e.getAdjustable().setValue(e.getAdjustable().getMaximum());
-            }
-        });
-        breadcrumbPanel.add(scrollPane);
-        
-        // when the component is resized the new dimension is used to arrange 
-        // the scrollpane, in order to use all available space.
-        breadcrumbPanel.addComponentListener(new ComponentAdapter() {
-            @Override
-            public void componentResized(ComponentEvent arg0) {
-                Dimension d = breadcrumbPanel.getSize();
-                d.height = 20;
-                scrollPane.setPreferredSize(d);
-            }
-        });
-    }
-
-}
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapZoomBar.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,242 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import java.awt.Color;
-import java.awt.FlowLayout;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.util.Objects;
-
-import javax.swing.JComponent;
-import javax.swing.JLabel;
-
-import com.redhat.thermostat.client.swing.components.FontAwesomeIcon;
-import com.redhat.thermostat.client.swing.components.Icon;
-import com.redhat.thermostat.client.ui.Palette;
-import com.redhat.thermostat.shared.locale.Translate;
-import com.redhat.thermostat.vm.heap.analysis.client.locale.LocaleResources;
-
-/**
- * This class provides a component containing zoom in/out/full buttons which can
- * control a {@link TreeMapComponent} object.
- */
-public class TreeMapZoomBar extends JComponent implements TreeMapObserver {
-
-    private static final long serialVersionUID = 1L;
-
-    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
-
-    private JLabel zoomOut;
-    private JLabel zoomFull;
-    private JLabel zoomIn;
-    
-    private Color defaultColor = Palette.BLACK.getColor();
-    private Color enterColor = Palette.THERMOSTAT_BLU.getColor();
-
-    /**
-     * The treemap object to interact with.
-     */
-    private TreeMapComponent treemap;
-
-    /**
-     * If an item is selected in the treemap, it is stored in order to zoom on 
-     * it if the ZoomIn button is pressed.
-     */
-    private TreeMapNode selectedItem;
-    
-    /**
-     * Constructor. It creates the zoom buttons and registers this object as 
-     * treemap observer.
-     */
-    public TreeMapZoomBar(TreeMapComponent treemap) {
-        super();
-        this.treemap = Objects.requireNonNull(treemap);
-        initComponent();
-        treemap.register(this);
-    }
-
-    private void initComponent() {
-        this.setLayout(new FlowLayout(FlowLayout.LEFT, 5, 0));
-        createZoomInButton();
-        createZoomFullButton();
-        createZoomOutButton();
-
-        /*
-         * At the beginning no actions can be performed:
-         * Cannot zoom in because no item is selected;
-         * cannot zoom out because zoom in hasn't been performed;
-         * the same for zoom full.
-         */
-        zoomIn.setEnabled(false);
-        zoomFull.setEnabled(false);
-        zoomOut.setEnabled(false);
-    }
-
-
-
-    private void createZoomInButton() {
-        zoomIn = new JLabel();
-        final Icon baseIcon = new FontAwesomeIcon('\uf065', 15, defaultColor);
-        final Icon hoverIcon = new FontAwesomeIcon('\uf065', 15, enterColor);
-        
-        zoomIn.setIcon(baseIcon);
-        zoomIn.setToolTipText(t.localize(LocaleResources.ZOOM_IN).getContents());
-        
-        zoomIn.addMouseListener(new MouseAdapter() {
-            @Override
-            public void mouseExited(MouseEvent e) {
-                zoomIn.setIcon(baseIcon);
-            }
-
-            @Override
-            public void mouseEntered(MouseEvent e) {
-                zoomIn.setIcon(hoverIcon);
-            }
-
-            @Override
-            public void mouseClicked(MouseEvent arg0) {
-                if (selectedItem != null) {
-                    treemap.zoomIn(selectedItem);
-                }
-            }
-        });
-
-        this.add(zoomIn);
-    }
-
-    private void createZoomOutButton() {
-        zoomOut = new JLabel();
-        
-        final Icon baseIcon = new FontAwesomeIcon('\uf066', 15, defaultColor);
-        final Icon hoverIcon = new FontAwesomeIcon('\uf066', 15, enterColor);
-        
-        zoomOut.setIcon(baseIcon);
-        zoomOut.setToolTipText(t.localize(LocaleResources.ZOOM_OUT).getContents());
-        zoomOut.addMouseListener(new MouseAdapter() {
-            @Override
-            public void mouseExited(MouseEvent e) {
-                zoomOut.setIcon(baseIcon);
-            }
-
-            @Override
-            public void mouseEntered(MouseEvent e) {
-                zoomOut.setIcon(hoverIcon);
-            }
-
-            @Override
-            public void mouseClicked(MouseEvent arg0) {
-                treemap.zoomOut();
-            }
-        });
-
-        this.add(zoomOut);
-    }
-
-    private void createZoomFullButton() {
-        zoomFull = new JLabel();
-
-        final Icon baseIcon = new FontAwesomeIcon('\uf03b', 15, defaultColor);
-        final Icon hoverIcon = new FontAwesomeIcon('\uf03b', 15, enterColor);
-        
-        zoomFull.setIcon(baseIcon);
-        zoomFull.setToolTipText(t.localize(LocaleResources.ZOOM_FULL).getContents());
-        zoomFull.addMouseListener(new MouseAdapter() {
-            @Override
-            public void mouseExited(MouseEvent e) {
-                zoomFull.setIcon(baseIcon);
-            }
-
-            @Override
-            public void mouseEntered(MouseEvent e) {
-                zoomFull.setIcon(hoverIcon);
-            }
-
-            @Override
-            public void mouseClicked(MouseEvent arg0) {
-                treemap.zoomFull();
-            }
-        });
-
-        this.add(zoomFull);
-    }
-
-    /**
-     * Changes the buttons state in according to the treemap view.
-     */
-    private void changeState() {
-        selectedItem = null;
-        zoomIn.setEnabled(false);
-
-        if (!isRootShown()) {
-            zoomFull.setEnabled(true);
-            zoomOut.setEnabled(true);
-        } else {
-            zoomFull.setEnabled(false);
-            zoomOut.setEnabled(false);
-        }
-    }
-
-    @Override
-    public void notifySelection(TreeMapNode node) {
-        selectedItem = node;
-        zoomIn.setEnabled(treemap.isZoomInEnabled(node));
-    }
-
-    @Override
-    public void notifyZoomIn(TreeMapNode node) {
-        changeState();
-    }    
-
-    @Override
-    public void notifyZoomOut() {
-        changeState();
-    }
-
-    @Override
-    public void notifyZoomFull() {
-        // no actions can be performed
-        zoomFull.setEnabled(false);
-        zoomOut.setEnabled(false);
-        zoomIn.setEnabled(false);
-    }
-
-    private boolean isRootShown() {
-        return treemap.getTreeMapRoot() == treemap.getZoomCallsStack().firstElement();
-    }
-
-}
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeProcessor.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import java.awt.Color;
-import java.awt.geom.Rectangle2D;
-import java.util.Objects;
-
-
-public class TreeProcessor {
-
-    /**
-     * Padding between the main component and its sub component.
-     */
-    public static final int X_PADDING = 15;
-    public static final int Y_PADDING = 20;
-
-    /**
-     * This method process recursively the tree nested in the node element
-     * passed as argument in the constructor calculating the children TreeMap 
-     * for each node also applying coloring.
-     * @return the updated tree, where nodes have additional information like
-     * {@link Rectangle2D>Float} instance and a color.
-     */
-    public static TreeMapNode processTreeMap(TreeMapNode tree, Rectangle2D.Double area) {
-        Objects.requireNonNull(tree);
-        Objects.requireNonNull(area);
-        tree.setRectangle(area);
-        if (tree.getColor() == null) {
-            tree.setColor(tree.START_COLOR);
-        }
-        
-        process(tree);
-        return tree;
-    }
-
-    /**
-     * This method is used to effectively process the whole tree structure. It
-     * uses a {@link SquarifiedTreeMap} object to calculate a TreeMap for each
-     * node who has children.
-     * @param node the subtree's root to process
-     */
-    private static void process(TreeMapNode node) {                                                                                                                            
-        
-        SquarifiedTreeMap algorithm = new SquarifiedTreeMap(getSubArea(node.getRectangle()), node.getChildren());
-        node.setChildren(algorithm.squarify());
-
-        Color c = node.getNextColor();
-        
-        for (TreeMapNode child : node.getChildren()) {
-            //children will have all the same color, which is the parent's next one
-            if (child.getColor() == null) {
-                child.setColor(c);
-            }
-            // if squarified rectangles have drawable sides then continue to 
-            // process, else don't process the subtree having as root a 
-            // non drawable rectangle.
-            if (child.isDrawable()) {
-                process(child);
-            } 
-        }
-    }
-
-    /**
-     * Calculate space and coordinates in which children's rectangle will be 
-     * drawn, from the main component.
-     * @return the rectangle representing the new available area.
-     */
-    private static Rectangle2D.Double getSubArea(Rectangle2D.Double area) {
-        Rectangle2D.Double subArea = new Rectangle2D.Double();
-        subArea.setRect(area);
-
-        subArea.width = Math.max(0, (subArea.width - 2 * X_PADDING));
-        subArea.height = Math.max(0, (subArea.height - 1.5 * Y_PADDING));
-        return subArea;
-    }  
-}
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ValueFormatter.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-public class ValueFormatter {
-    
-    private double value;
-    
-    public ValueFormatter(double val) {
-        this.value = val;
-    }
-    
-    /**
-     * This method returns the node value calculating it in bytes, KB or MB. 
-     * 
-     * i.e. if node's weight = 200 it returns: "200 bytes" <br>
-     * if weight = 20152: "20.15 KB"  <br>
-     * if weight = 2015248: "2.01 MB"  <br>
-     * 
-     * Note that float values are approximated to the second decimal digit.
-     */
-    public String format() {
-        int KB = 1000;
-        int MB = 1000000;
-        String unit = "Bytes";
-        
-        if (value >= KB && value < MB) {
-            value /= KB;
-            unit = "KBytes";
-        } else if (value >= MB) {
-            value /= MB;
-            unit = "MBytes";
-        }
-        // show 2 decimal digits 
-        String formattedValue = String.format("%.2f", value);
-        return formattedValue + " " + unit;
-    }
-}
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramConverterTest.java	Wed Jun 01 15:58:04 2016 -0400
+++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramConverterTest.java	Mon Jun 06 15:17:50 2016 -0400
@@ -45,6 +45,7 @@
 import org.junit.Before;
 import org.junit.Test;
 
+import com.redhat.thermostat.client.swing.components.experimental.TreeMapNode;
 import com.redhat.thermostat.vm.heap.analysis.common.ObjectHistogram;
 import com.sun.tools.hat.internal.model.JavaClass;
 import com.sun.tools.hat.internal.model.JavaHeapObject;
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SquarifiedTreeMapTest.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-
-/**
- * Using eclEmma tool has been proved that this test covers 100% 
- * of {@link SquarifiedTreeMap} code and also 90% of {@link TreeMapBuilder} code.
- */
-public class SquarifiedTreeMapTest {
-    
-    private SquarifiedTreeMap algorithm;
-    Rectangle2D.Double bounds;
-    List<TreeMapNode> list;
-
-    @Before
-    public void setUp() throws Exception {
-        bounds = new Rectangle2D.Double(0, 0, 10, 5);
-        list = new ArrayList<>();
-    }
-
-    @Test
-    public final void testSquarifiedTreeMap() {
-        //check every parameters combinations
-        boolean catched = false;
-        try {
-            algorithm = new SquarifiedTreeMap(null, null);
-        } catch(NullPointerException e) {
-            catched = true;
-        }
-        assertTrue(catched);
-        catched = false;
-        
-        try {
-            algorithm = new SquarifiedTreeMap(bounds, null);
-        } catch(NullPointerException e) {
-            catched = true;
-        }
-        assertTrue(catched);
-        catched = false;
-        
-        try {
-            algorithm = new SquarifiedTreeMap(null, list);
-        } catch(NullPointerException e) {
-            catched = true;
-        }
-        assertTrue(catched);
-    }
-    
-    @Test
-    public final void testSquarify() {
-        // test using an empty node list
-        algorithm = new SquarifiedTreeMap(bounds, new ArrayList<TreeMapNode>());
-        assertEquals(0, algorithm.squarify().size());
-        
-        // test using a correct list
-        int n = 10;
-        for (int i = 0; i < n; i++) {
-            list.add(new TreeMapNode(i+1));
-        }
-        // process the list
-        algorithm = new SquarifiedTreeMap(bounds, list);
-        list = algorithm.squarify();
-        
-        assertEquals(n, list.size());
-        
-        for (int i = 0; i < n; i++) {
-            // node has been processed
-            assertNotNull(list.get(i).getRectangle());
-        }
-        
-        assertEquals(list, algorithm.getSquarifiedNodes());
-    }
-}
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapComponentTest.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,293 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-
-import java.awt.Dimension;
-import java.lang.reflect.InvocationTargetException;
-
-import javax.swing.SwingUtilities;
-
-import junit.framework.Assert;
-
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-
-public class TreeMapComponentTest {
-
-    private TreeMapComponent treeMap;
-    private static TreeMapNode tree;
-    private static TreeMapNode node1;
-    private static TreeMapNode node2;
-    private static Dimension dim;
-
-    @BeforeClass
-    public static void setUpOnce() {
-        tree = new TreeMapNode(1);
-        node1 = new TreeMapNode(1);
-        node2 = new TreeMapNode(1);
-        tree.addChild(node1);
-        node1.addChild(node2);
-        dim = new Dimension(500, 500);
-    }
-
-
-    @Test
-    public final void testTreeMapComponent() throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-
-            @Override
-            public void run() {
-
-                boolean catched = false;
-
-                try {
-                    treeMap = new TreeMapComponent(tree, dim);
-                    // pass
-                 } catch(NullPointerException e) {
-                    Assert.fail("Didn't expect exception.");
-                 }
-                try {
-                    treeMap = new TreeMapComponent(null, null);
-                } catch(NullPointerException e) {
-                    catched = true;
-                }
-                assertTrue(catched);
-                catched = false;
-
-                try {
-                    treeMap = new TreeMapComponent(tree, null);
-                } catch(NullPointerException e) {
-                    catched = true;
-                }
-                assertTrue(catched);
-                catched = false;
-
-                try {
-                    treeMap = new TreeMapComponent(null, dim);
-                } catch(NullPointerException e) {
-                    catched = true;
-                }
-                assertTrue(catched);
-            }
-        });
-    }
-
-    @Test
-    public final void testGetRoot() throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-
-            @Override
-            public void run() {
-                treeMap = new TreeMapComponent(tree, dim);
-                assertEquals(tree, treeMap.getTreeMapRoot());
-            }
-        });
-    }
-
-    @Test
-    public final void testIsZoomInEnabled() throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-            @Override
-            public void run() {
-                TreeMapComponent treeMap = new TreeMapComponent(tree, dim);
-
-                assertFalse("Should not be able to zoom in on null", treeMap.isZoomInEnabled(null));
-                assertFalse("Should not be able to zoom in on root", treeMap.isZoomInEnabled(tree));
-                assertTrue("Should be able to zoom in on node 1", treeMap.isZoomInEnabled(node1));
-                assertFalse("Should not be able to zoom in on node 2", treeMap.isZoomInEnabled(node2));
-            }
-        });
-    }
-
-    @Test
-    public final void testZoomIn() throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-
-            @Override
-            public void run() {
-                TreeMapComponent treeMap = new TreeMapComponent(tree, dim);
-
-                treeMap.zoomIn(node1);
-                assertEquals(node1, treeMap.getTreeMapRoot());
-
-                treeMap.zoomIn(node2);
-                assertEquals(node1, treeMap.getTreeMapRoot());
-            }
-        });
-    }
-
-    @Test
-    public final void testZoomOut() throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-
-            @Override
-            public void run() {
-                treeMap = new TreeMapComponent(tree, dim);
-
-                treeMap.zoomOut();
-                assertEquals(tree, treeMap.getTreeMapRoot());
-
-                treeMap.zoomIn(node1); //if zoom out root is tree
-                treeMap.zoomIn(node2); //no-op, cannot zoom on leaf
-
-                assertEquals(node1, treeMap.getTreeMapRoot());
-
-                treeMap.zoomOut();
-                assertEquals(tree, treeMap.getTreeMapRoot());
-            }
-        });
-    }
-
-    @Test
-    public final void testZoomFull() throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-
-            @Override
-            public void run() {
-                treeMap = new TreeMapComponent(tree, dim);
-
-                treeMap.zoomIn(node2);
-                treeMap.zoomFull();
-                assertEquals(tree, treeMap.getTreeMapRoot());
-
-            }
-        });
-    }
-
-    @Test
-    public final void testGetZoomCallsStack() throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-
-            @Override
-            public void run() {
-                treeMap = new TreeMapComponent(tree, dim);
-
-                // the root is always in the stack
-                assertEquals(1, treeMap.getZoomCallsStack().size());
-
-                treeMap.zoomIn(tree);
-                // zooming on the same element nothing happen
-                assertEquals(1, treeMap.getZoomCallsStack().size());
-
-                treeMap.zoomIn(node1);
-                treeMap.zoomIn(node2);
-                treeMap.zoomFull();
-                assertEquals(tree, treeMap.getTreeMapRoot());
-            }
-        });
-    }
-
-
-    @Test
-    public final void testClearZoomCallsStack() throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-
-            @Override
-            public void run() {
-                treeMap = new TreeMapComponent(tree, dim);
-
-                treeMap.clearZoomCallsStack();
-                assertEquals(1, treeMap.getZoomCallsStack().size());
-
-                treeMap.zoomIn(node1);
-                treeMap.zoomIn(node2);
-                treeMap.clearZoomCallsStack();
-                assertEquals(1, treeMap.getZoomCallsStack().size());
-            }
-        });
-    }
-    
-    @Test
-    public final void testObserver() throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-            boolean zoomedIn = false;
-            boolean zoomedOut = false;
-            boolean zoomedFull = false;
-            
-            TreeMapObserver observer = new TreeMapObserver() {
-                @Override
-                public void notifyZoomOut() {
-                    zoomedOut = true;
-                }
-                
-                @Override
-                public void notifyZoomIn(TreeMapNode node) {
-                    zoomedIn = true;
-                }
-                
-                @Override
-                public void notifyZoomFull() {
-                    zoomedFull = true;
-                }
-                
-                @Override
-                public void notifySelection(TreeMapNode node) {
-                }
-            };
-
-            @Override
-            public void run() {
-                TreeMapNode child = new TreeMapNode(1);
-                tree.addChild(child);
-                TreeMapNode grandchild = new TreeMapNode(1);
-                child.addChild(grandchild);
-
-                treeMap = new TreeMapComponent(tree, dim);
-                treeMap.register(observer);
-                
-                treeMap.zoomIn(child);
-                assertTrue("Should have zoomed in on child", zoomedIn);
-                zoomedIn = false;
-
-                treeMap.zoomIn(grandchild);
-                assertFalse("Should not have zoomed in on grandchild", zoomedIn);
-                
-                treeMap.zoomOut();
-                assertTrue("Should have zoomed out", zoomedOut);
-                
-                treeMap.zoomIn(child);
-                treeMap.zoomFull();
-                assertTrue("Should have zoomed full", zoomedFull);
-            }
-        });
-    }
-}
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapNodeTest.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,289 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
-
-import java.awt.Color;
-import java.awt.geom.Rectangle2D;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import org.junit.Before;
-import org.junit.Test;
-
-
-public class TreeMapNodeTest {
-
-    private TreeMapNode node;
-    private static final double DELTA = 0.001;
-
-    @Before
-    public void setUp() {
-        node = new TreeMapNode(null, 1);
-    }
-
-    @Test
-    public final void testGetId() {
-        TreeMapNode node1 = new TreeMapNode(null, 1);
-        TreeMapNode node2 = new TreeMapNode(null, 1);
-        assertTrue(node1.getId() != node2.getId());
-        assertTrue(node1.getId() + 1 == node2.getId());
-    }
-
-    @Test
-    public final void testGetSetParent() {
-        TreeMapNode parent = new TreeMapNode(null, 1);
-        assertTrue(node.getParent() == null);
-        node.setParent(parent);
-        assertTrue(node.getParent() == parent);
-    }
-
-    @Test
-    public final void testGetSetLabel() {
-        TreeMapNode node = new TreeMapNode("MyLabel", 1);
-        assertTrue(node.getLabel().equals("MyLabel"));
-        node.setLabel("MyNewLabel");
-        assertTrue(node.getLabel().equals("MyNewLabel"));
-    }
-
-    @Test
-    public final void testGetSetChildren() {
-        assertTrue(node.getChildren().isEmpty());
-
-        TreeMapNode node = new TreeMapNode(null, 1);
-        List<TreeMapNode> children = new ArrayList<>();
-        children.add(node);
-
-        node.setChildren(children);
-        assertTrue(1 == node.getChildren().size());
-    }
-
-    @Test
-    public final void testIsLeaf() {
-        assertTrue(node.isLeaf());
-        node.addChild(new TreeMapNode(null, 1));
-        assertFalse(node.isLeaf());
-        node.setChildren(Collections.<TreeMapNode>emptyList());
-        assertTrue(node.isLeaf());
-    }
-
-    @Test
-    public final void testGetAddInfo() {
-        node.addInfo("exampleKey", "exampleValue");
-        assertEquals("exampleValue", node.getInfo("exampleKey"));
-    }
-
-    @Test
-    public final void testAddChild() {
-        assertTrue(node.getChildren().size() == 0);
-        node.addChild(new TreeMapNode(null, 1));
-        assertTrue(node.getChildren().size() == 1);
-
-        node.addChild(null);
-        assertTrue(node.getChildren().size() == 1); // null has not been added
-    }
-
-    @Test
-    public final void testGetSetWeight() {
-        assertEquals(1.0, node.getWeight(), DELTA);
-        node.setWeight(5);
-        assertEquals(5.0, node.getWeight(), DELTA);
-    }
-
-    @Test
-    public final void testGetSetRectangle() {        
-        Rectangle2D.Double r = new Rectangle2D.Double(5, 5, 5, 5);
-        node.setRectangle(r);
-        assertEquals(r, node.getRectangle());
-
-        node.setRectangle(null);
-        boolean catched = false;
-        try {
-            node.getRectangle();
-        } catch(RuntimeException e) {
-            catched = true;
-        }
-        assertTrue(catched);
-    }
-
-
-    @Test
-    public final void testGetSetRealWeight() {
-        node = new TreeMapNode(null, 5);
-        assertEquals(5.0, node.getRealWeight(), DELTA);
-        node.setRealWeight(8);
-        assertEquals(8.0, node.getRealWeight(), DELTA);
-    }
-
-    @Test
-    public final void testAllowNonPositiveWeight() {
-        assertFalse(TreeMapNode.isAllowNonPositiveWeight());
-        node.setWeight(-5);
-        assertEquals(1.0, node.getWeight(), DELTA);
-        assertEquals(1.0, node.getRealWeight(), DELTA);
-
-        TreeMapNode.setAllowNonPositiveWeight(true);
-        node.setWeight(-5);
-        assertEquals(-5.0, node.getWeight(), DELTA);
-    }
-
-    @Test
-    public final void testIsDrawable() {
-        Rectangle2D.Double r = new Rectangle2D.Double(5, 5, 5, 5);
-        node.setRectangle(r);
-        assertTrue(node.isDrawable());
-
-        r.setRect(0,  0,  0.5f, 0.5f);
-        assertFalse(node.isDrawable());
-
-        r.setRect(0,  0,  5f, 0.5f);
-        assertFalse(node.isDrawable());
-
-        r.setRect(0,  0,  0.5f, 5f);
-        assertFalse(node.isDrawable());
-    }
-
-    @Test
-    public final void testGetSetColor() {
-        assertNull(node.getColor());
-        node.setColor(Color.black);
-        assertEquals(Color.black, node.getColor());
-    }
-
-    @Test
-    public final void testGetDepth() {
-        TreeMapNode depth1 = new TreeMapNode(null, 1);
-        TreeMapNode depth2 = new TreeMapNode(null, 1);
-
-        node.addChild(depth1);
-        depth1.addChild(depth2);
-
-        assertTrue(node.getDepth() == 0);
-        assertTrue(depth1.getDepth() == 1);
-        assertTrue(depth2.getDepth() == 2);
-    }
-
-    @Test
-    public final void testSort() {
-
-        TreeMapNode n1 = new TreeMapNode(null, 5);
-        TreeMapNode n2 = new TreeMapNode(null, 4);
-        TreeMapNode n4 = new TreeMapNode(null, 2);
-        TreeMapNode n3 = new TreeMapNode(null, 3);
-        TreeMapNode n5 = new TreeMapNode(null, 0);
-        TreeMapNode n6 = new TreeMapNode(null, 7);
-        TreeMapNode n7 = new TreeMapNode(null, 1);
-        TreeMapNode n8 = new TreeMapNode(null, 9);
-
-        List<TreeMapNode> toSort = new ArrayList<>();
-        toSort.add(n3);
-        toSort.add(n2);
-        toSort.add(n4);
-        toSort.add(n1);
-        toSort.add(n5);
-        toSort.add(n6);
-        toSort.add(n7);
-        toSort.add(n8);
-
-        TreeMapNode.sort(toSort);
-
-        assertEquals(toSort.get(0), n8);
-        assertEquals(toSort.get(1), n6);
-        assertEquals(toSort.get(2), n1);
-        assertEquals(toSort.get(3), n2);
-        assertEquals(toSort.get(4), n3);
-        assertEquals(toSort.get(5), n4);
-        assertEquals(toSort.get(6), n7);
-        assertEquals(toSort.get(7), n5);
-    }
-
-    @Test
-    public final void testGetInfo() {
-        Map<String, String> map = node.getInfo();
-        assertNotNull(map);
-        assertEquals(0, map.keySet().size());
-    }
-
-    @Test
-    public final void testToString() {
-        assertNotNull(node.toString());
-    }
-    
-    
-    @Test
-    public final void testGetNextColor() {
-        assertNull(node.getColor());
-        assertTrue(node.getNextColor().equals(node.START_COLOR));
-        
-        Color start = node.START_COLOR;
-        node.setColor(start);
-
-        for (int i = 0; i < TreeMapNode.colors.length; i++) {
-            assertEquals(TreeMapNode.colors[i], node.getColor());
-            node.setColor(node.getNextColor());
-        }
-    }
-    
-    
-    @Test
-    public final void testGetAncestors() {
-        TreeMapNode node1 = new TreeMapNode(0);
-        TreeMapNode node2 = new TreeMapNode(0);
-        TreeMapNode node3 = new TreeMapNode(0);
-        TreeMapNode node4 = new TreeMapNode(0);
-        
-        node1.addChild(node2);
-        node2.addChild(node3);
-        node3.addChild(node4);
-        
-        LinkedList<TreeMapNode> ancestors = node4.getAncestors();
-        
-        assertEquals(node1, ancestors.get(3));
-        assertEquals(node2, ancestors.get(2));
-        assertEquals(node3, ancestors.get(1));
-        assertEquals(node4, ancestors.get(0));        
-    }
-    
-}
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapToolbarTest.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import static org.junit.Assert.assertTrue;
-
-import java.awt.Dimension;
-import java.lang.reflect.InvocationTargetException;
-
-import javax.swing.SwingUtilities;
-
-import junit.framework.Assert;
-
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import com.redhat.thermostat.annotations.internal.CacioTest;
-
-@Category(CacioTest.class)
-public class TreeMapToolbarTest {
-
-    private TreeMapComponent treeMap;
-    @SuppressWarnings("unused")
-    private TreeMapToolbar toolbar;
-
-    private static TreeMapNode tree;
-    private static Dimension dim;
-
-    @Test
-    public final void testTreeMapToolbar() throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-            @Override
-            public void run() {
-                
-                tree = new TreeMapNode(1);
-                dim = new Dimension(500, 500);
-                treeMap = new TreeMapComponent(tree, dim);
-                
-                boolean catched = false;
-                try {
-                    toolbar = new TreeMapToolbar(null);
-                } catch(NullPointerException e) {
-                    catched = true;
-                }
-                assertTrue(catched);
-                try {
-                    toolbar = new TreeMapToolbar(treeMap);
-                } catch (NullPointerException e) {
-                    Assert.fail("Should not throw any exception.");
-                }
-            }
-        });
-    }
-
-   
-}
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeMapZoomBarTest.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import static org.junit.Assert.assertTrue;
-
-import java.awt.Dimension;
-import java.lang.reflect.InvocationTargetException;
-
-import javax.swing.SwingUtilities;
-
-import junit.framework.Assert;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import com.redhat.thermostat.annotations.internal.CacioTest;
-
-@Category(CacioTest.class)
-public class TreeMapZoomBarTest {
-
-    private TreeMapComponent treeMap;
-    @SuppressWarnings("unused")
-    private TreeMapZoomBar zoomBar;
-
-    private static TreeMapNode tree;
-    private static Dimension dim;
-
-    @Before
-    public void setUp() {
-        tree = new TreeMapNode(1);
-        dim = new Dimension(500, 500);
-    }
-
-    @Test
-    public final void testTreeMapZoomBar() throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-
-            @Override
-            public void run() {
-                boolean catched = false;
-                try {
-                    zoomBar = new TreeMapZoomBar(null);
-                } catch(NullPointerException e) {
-                    catched = true;
-                }
-                assertTrue(catched);
-                try {
-                    treeMap = new TreeMapComponent(tree, dim);
-                    zoomBar = new TreeMapZoomBar(treeMap);
-                } catch (NullPointerException e) {
-                    Assert.fail("Should not throw any exception.");
-                }
-            }
-        });
-    }
-
-   
-}
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/TreeProcessorTest.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.awt.geom.Rectangle2D;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class TreeProcessorTest {
-
-    private static final double DELTA = 0.1;
-    private static final double BASE = 2.0;
-
-    TreeMapNode node;
-    Rectangle2D.Double area;
-
-    @Before
-    public void setUp() throws Exception {
-        node = new TreeMapNode(1);
-        area = new Rectangle2D.Double(0, 0, 500, 500);
-    }
-
-    @Test
-    public final void testTreeProcessor() {
-        boolean caught = false;
-        // this test check all wrong combinations for constructor parameters
-        try {
-            TreeProcessor.processTreeMap(null, area);
-        } catch(NullPointerException e) {
-            caught = true;
-        }
-        assertTrue(caught);
-        caught = false;
-
-        try {
-            TreeProcessor.processTreeMap(node, null);
-        } catch(NullPointerException e) {
-            caught = true;
-        }
-        assertTrue(caught);
-        caught = false;
-
-        try {
-            TreeProcessor.processTreeMap(null, null);
-        } catch(NullPointerException e) {
-            caught = true;
-        }
-        assertTrue(caught);
-    }
-
-
-    @Test
-    public final void testProcessTreeMapProcessesWholeTree() {
-        generateTree(node, 5, 5);
-        TreeProcessor.processTreeMap(node, area);
-
-        // the test will check if any drawable node in the tree has a rectangle and a 
-        // color, which means the processor function has processed the whole tree
-        traverse(node);        
-    }
-
-    private void traverse(TreeMapNode tree) {
-        if (tree.isDrawable() && (tree.getRectangle() == null || tree.getColor() == null)) {
-            fail("node " + tree.getId() + " not processed");
-        }
-        for (TreeMapNode child : tree.getChildren()) {
-            traverse(child);
-        }
-    }
-
-    private void generateTree(TreeMapNode root, int levels, int childrenNumber) {        
-        if (levels == 0) {
-            return;
-        } else {
-            for (int i = 0; i < childrenNumber; i++) {
-                root.addChild(new TreeMapNode(100));
-            }
-            for (TreeMapNode child : root.getChildren()) {
-                generateTree(child, levels-1, childrenNumber);
-            }
-        }
-    }
-
-    @Test
-    public final void testProcessTreeMapNodeSizing() {
-        final int numSiblings = 5;
-        final double originalDimension = 64.0;
-        final double smallerDimension = 32.0;
-
-        generateSiblingTree(node, numSiblings);
-
-        TreeProcessor.processTreeMap(node, new Rectangle2D.Double(0, 0, originalDimension, originalDimension));
-        checkNodeWeightRatios(numSiblings);
-
-        //now resize smaller
-        TreeProcessor.processTreeMap(node, new Rectangle2D.Double(0, 0, smallerDimension, smallerDimension));
-
-        //now resize back to original size
-        TreeProcessor.processTreeMap(node, new Rectangle2D.Double(0, 0, originalDimension, originalDimension));
-        //if the first call to checkNodeWeightRatios(numSiblings) worked, this should too
-        checkNodeWeightRatios(numSiblings);
-    }
-
-    private void generateSiblingTree(TreeMapNode root, int numSiblings) {
-        assertTrue(numSiblings > 1);
-        root.addChild(new TreeMapNode(1.0)); //this is not a random weight
-        for(int i = 0; i < (numSiblings - 1); i++) {
-            root.addChild(new TreeMapNode(Math.pow(BASE, i)));
-        }
-    }
-
-    private void checkNodeWeightRatios(int numSiblings) {
-        List<TreeMapNode> children = node.getChildren();
-        assertEquals(numSiblings, children.size());
-        TreeMapNode.sort(children);
-
-        double weight = children.get(0).getWeight();
-        for(int i = 1; i < numSiblings - 1; i++) {
-            double currentWeight = children.get(i).getWeight();
-            //check that the ratio between node weights is approximately 2 (which is the BASE)
-            assertEquals(BASE, weight/currentWeight, DELTA);
-            weight = currentWeight;
-        }
-    }
-}
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ValueFormatterTest.java	Wed Jun 01 15:58:04 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/*
- * Copyright 2012-2016 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.vm.heap.analysis.client.swing.internal;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.Test;
-
-public class ValueFormatterTest {
-
-    private ValueFormatter formatter;
-
-    @Test
-    public final void getFormattedWeight() {
-        formatter = new ValueFormatter(2);
-        assertEquals("2.00 Bytes", formatter.format());
-
-        formatter = new ValueFormatter(2222);
-        assertEquals("2.22 KBytes", formatter.format());
-
-        formatter = new ValueFormatter(2222222);
-        assertEquals("2.22 MBytes", formatter.format());
-    }
-}
\ No newline at end of file