changeset 1989:10e0b0fe84ef

Improve treemap building code PR3059 Reviewed-by: jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/019844.html Original-thread: http://icedtea.classpath.org/pipermail/thermostat/2015-November/016974.html
author James Aziz <jaziz@redhat.com>
date Wed, 29 Jun 2016 12:23:11 -0400
parents 44ded819f2bf
children 1ee23f6c4b50
files client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/AbstractTreeAssembler.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/NodeDataExtractor.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeAssembler.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeConverter.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMap.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/AbstractTreeAssemblerTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeConverterTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapTest.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectHistogramNodeDataExtractor.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectHistogramTreeAssembler.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapTreeMapView.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectHistogramTreeAssemblerTest.java
diffstat 12 files changed, 492 insertions(+), 760 deletions(-) [+]
line wrap: on
line diff
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/AbstractTreeAssembler.java	Wed Jun 29 12:23:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Copyright 2012-2015 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.util.List;
-import java.util.regex.Pattern;
-
-public abstract class AbstractTreeAssembler<T> implements TreeAssembler<T> {
-
-    @Override
-    public abstract void buildTree(T data, TreeMapNode root);
-
-    public static TreeMapNode processRecord(String name, String token, TreeMapNode lastProcessed) {
-        while (!name.equals("")) {
-
-            String nodeId = name.split(Pattern.quote(token))[0];
-
-            TreeMapNode child = searchNode(lastProcessed.getChildren(), nodeId);
-            if (child == null) {
-                child = new TreeMapNode(nodeId, 0);
-                lastProcessed.addChild(child);
-            }
-
-            lastProcessed = child;
-
-            name = name.substring(nodeId.length());
-            if (name.startsWith(".")) {
-                name = name.substring(1);
-            }
-        }
-        return lastProcessed;
-    }
-
-    public static TreeMapNode searchNode(List<TreeMapNode> nodes, String nodeId) {
-        for (TreeMapNode node : nodes) {
-            if (node.getLabel().equals(nodeId)) {
-                return node;
-            }
-        }
-        return null;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/NodeDataExtractor.java	Wed Jun 29 12:23:11 2016 -0400
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2012-2015 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.util.Collection;
+
+/**
+ * This interface facilitates the extraction of a collection of elements from a dataset and
+ * provides methods for reading information from these elements.
+ *
+ * @param <S> a dataset that aggregates elements of type {@link T}
+ * @param <T> an element, holding some weight and labelled by some key (e.g. a pathname) that
+ *           expresses a delimited set of (hierarchical) nodes
+ */
+public interface NodeDataExtractor<S, T> {
+
+    String getNodeSeparator();
+
+    String getKey(T element);
+    double getWeight(T element);
+
+    Collection<T> getAsCollection(S data);
+}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeAssembler.java	Wed Jun 29 12:23:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Copyright 2012-2015 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 interface TreeAssembler<T> {
-
-    void buildTree(T data, TreeMapNode root);
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeConverter.java	Wed Jun 29 12:23:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * Copyright 2012-2015 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.util.List;
-
-public class TreeConverter {
-
-    /**
-     * This method builds a tree map model of the {@link T} data provided, using the
-     * specified {@link TreeAssembler} assembler.
-     *
-     * @return the root of the resulting tree
-     */
-    public static <T> TreeMapNode convertToTreeMap(T data, TreeAssembler<T> assembler) {
-        TreeMapNode root = new TreeMapNode("", 0);
-
-        assembler.buildTree(data, root);
-        // calculates weights for inner nodes
-        fillWeights(root);
-        // collapse nodes with only one child
-        packTree(root);
-        return root;
-    }
-
-    /**
-     * This method calculates the real weights using a bottom-up traversal.  The weight of a
-     * parent node is the sum of its children's weights.
-     *
-     * Package-private for testing purposes.
-     *
-     * @param node the root of the subtree
-     * @return the real weight of the root
-     */
-    static double fillWeights(TreeMapNode node) {
-        if (node.getChildren().size() == 0) {
-            return node.getRealWeight();
-        }
-
-        double sum = 0;
-        for (TreeMapNode child : node.getChildren()) {
-            sum += fillWeights(child);
-        }
-        node.setRealWeight(sum);
-        return node.getRealWeight();
-    }
-
-    /**
-     * This method allows the collapse of a series of nodes, each with at most one child, into a
-     * single node placed at the root of the series.
-     *
-     * Package-private for testing purposes.
-     *
-     * @param node the root of the subtree
-     */
-    static void packTree(TreeMapNode node) {
-        List<TreeMapNode> children = node.getChildren();
-        if (children.size() == 1) {
-            TreeMapNode child = children.get(0);
-            node.setLabel(node.getLabel() + "." + child.getLabel());
-            node.setChildren(child.getChildren());
-            packTree(node);
-        } else {
-            for (TreeMapNode child : children) {
-                packTree(child);
-            }
-        }
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/experimental/TreeMap.java	Wed Jun 29 12:23:11 2016 -0400
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2012-2015 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.util.List;
+import java.util.regex.Pattern;
+
+/**
+ * This class represents a treemap and facilitates its construction from information available in
+ * the {@link S} dataset.
+ *
+ * @param <S> a dataset that aggregates elements of type {@link T}
+ * @param <T> an element, holding some weight and labelled by some key (e.g. a pathname) that
+ *           expresses a delimited set of (hierarchical) nodes
+ */
+public class TreeMap<S, T> {
+    
+    private final TreeMapNode root;
+    
+    public TreeMap(S data, NodeDataExtractor<S, T> extractor) {
+        root = new TreeMapNode("", 0);
+        buildTree(data, root, extractor);
+        // calculates weights for inner nodes
+        fillWeights(root);
+        // collapse nodes with only one child
+        packTree(root);
+    }
+    
+    public TreeMapNode getRoot() {
+        return root;
+    }
+
+    private static <S, T> void buildTree(S data, TreeMapNode root, NodeDataExtractor<S, T> extractor) {
+
+        for(T element: extractor.getAsCollection(data)) {
+            String key = extractor.getKey(element);
+            String splitToken = extractor.getNodeSeparator();
+            double weight = extractor.getWeight(element);
+
+            TreeMapNode lastProcessed = root;
+            while (!key.equals("")) {
+
+                String nodeId = key.split(Pattern.quote(splitToken))[0];
+
+                TreeMapNode child = searchNode(lastProcessed, nodeId);
+                if (child == null) {
+                    child = new TreeMapNode(nodeId, 0);
+                    lastProcessed.addChild(child);
+                }
+
+                lastProcessed = child;
+
+                key = key.substring(nodeId.length());
+                if (key.startsWith(splitToken)) {
+                    key = key.substring(1);
+                }
+            }
+            lastProcessed.setRealWeight(weight);
+        }
+    }
+    
+    /**
+     * This method calculates the real weights using a bottom-up traversal.  The weight of a
+     * parent node is the sum of its children's weights.
+     *
+     * Package-private for testing purposes.
+     *
+     * @param node the root of the subtree
+     * @return the real weight of the root
+     */
+    static double fillWeights(TreeMapNode node) {
+        if (node.getChildren().size() == 0) {
+            return node.getRealWeight();
+        }
+
+        double sum = 0;
+        for (TreeMapNode child : node.getChildren()) {
+            sum += fillWeights(child);
+        }
+        node.setRealWeight(sum);
+        return node.getRealWeight();
+    }
+    
+    /**
+     * This method allows the collapse of a series of nodes, each with at most one child, into a
+     * single node placed at the root of the series.
+     *
+     * Package-private for testing purposes.
+     *
+     * @param node the root of the subtree
+     */
+    static void packTree(TreeMapNode node) {
+        List<TreeMapNode> children = node.getChildren();
+        if (children.size() == 1) {
+            TreeMapNode child = children.get(0);
+            node.setLabel(node.getLabel() + "." + child.getLabel());
+            node.setChildren(child.getChildren());
+            packTree(node);
+        } else {
+            for (TreeMapNode child : children) {
+                packTree(child);
+            }
+        }
+    }
+    
+    public static TreeMapNode searchNode(TreeMapNode startingPoint, String nodeId) {
+        List<TreeMapNode> children = startingPoint.getChildren();
+        for (TreeMapNode node : children) {
+            if (node.getLabel().equals(nodeId)) {
+                return node;
+            }
+        }
+        return null;
+    }
+}
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/AbstractTreeAssemblerTest.java	Wed Jun 29 12:23:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * Copyright 2012-2015 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 java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-
-public class AbstractTreeAssemblerTest {
-
-    final private String SOME_ROOT_LABEL = "root";
-    final private double SOME_ROOT_WEIGHT = 25.0;
-    final private String SPLIT_TOKEN = ".";
-
-    private TreeMapNode root;
-
-    @Before
-    public void setup() {
-        root = new TreeMapNode(SOME_ROOT_LABEL, SOME_ROOT_WEIGHT);
-    }
-
-    @Test
-    public void testProcessRecord() {
-        String class1 = "com.Class1";
-        AbstractTreeAssembler.processRecord(class1, SPLIT_TOKEN, root);
-
-        List<TreeMapNode> children = root.getChildren();
-        assertEquals(1, children.size());
-        assertEquals("com", children.get(0).getLabel());
-
-        children = children.get(0).getChildren();
-        assertEquals(1, children.size());
-        assertEquals("Class1", children.get(0).getLabel());
-        assertEquals(0, children.get(0).getChildren().size());
-
-        String class2 = "com.Class2";
-        AbstractTreeAssembler.processRecord(class2, SPLIT_TOKEN, root);
-
-        children = root.getChildren();
-        assertEquals(1, children.size());
-        assertEquals("com", children.get(0).getLabel());
-
-        children = children.get(0).getChildren();
-        assertEquals(2, children.size());
-        assertNotNull(AbstractTreeAssembler.searchNode(children, "Class1"));
-        assertNotNull(AbstractTreeAssembler.searchNode(children, "Class2"));
-        assertEquals(0, children.get(0).getChildren().size());
-        assertEquals(0, children.get(1).getChildren().size());
-    }
-}
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeConverterTest.java	Wed Jun 29 12:23:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,228 +0,0 @@
-/*
- * Copyright 2012-2015 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.util.ArrayList;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import com.redhat.thermostat.common.Pair;
-
-public class TreeConverterTest {
-
-    final private String SPLIT_TOKEN = ".";
-    final private String SOME_ROOT_LABEL = "root";
-    final private double SOME_ROOT_WEIGHT = 25.0;
-    final private double DELTA = 0.01;
-    final private double SOME_WEIGHT = 3.14;
-
-    private ArrayList<Pair<String, Double>> data;
-    private TreeMapNode root;
-
-    @Before
-    public void setUp() {
-        /*
-         * This is the classes structure used for the test and built using
-         * the data. Nodes are compacted at the point of branching
-         * so for example the node relative to "example2.package1.Class1" is
-         * still just one node "example2.package1.Class1" but the node relative
-         * to "com.example1.package1.Class1" branches at "com" so becomes the
-         * common parent node "com" with children "example1" and "example2",
-         * and so forth:
-         *
-         *                ________com_______                    java
-         *               /                  \                     |
-         *        __example1__            example2              lang
-         *       /            \             |                     |
-         *    package1      package2      package1              Object
-         *    /     \           |            |
-         * Class1  Class2     Class3       Class4
-         *
-         *
-         *
-         *
-         * Expected tree after conversion:
-         *
-         *                           ________________________root_______________
-         *                          /                                           \
-         *                ________com_______                                java.lang.Object
-         *               /                  \
-         *         __example1__           example2.package1.Class4
-         *        /            \
-         *    package1      package2.Class3
-         *    /     \
-         *  Class1  Class2
-         *
-         */
-        final String[] classes = {
-                "com.example1.package1.Class1",
-                "com.example1.package1.Class2",
-                "com.example1.package2.Class3",
-                "com.example2.package1.Class4",
-                "example2.package1.Class1",
-                "java.lang.Object",
-                "repeat1.repeat1.RepeatClass",
-                "repeat2.repeat2A.RepeatClass",
-                "repeat2.repeat2B.RepeatClass",
-        };
-
-        data = new ArrayList<Pair<String, Double>>();
-
-        for (int i = 0; i < classes.length; i++) {
-            data.add(new Pair<String, Double>(classes[i], new Double(i)));
-        }
-
-        root = new TreeMapNode(SOME_ROOT_LABEL, SOME_ROOT_WEIGHT);
-    }
-
-    @Test
-    public void testConvertToTreeMap() {
-        AbstractTreeAssembler<ArrayList<Pair<String, Double>>> assembler =
-                new AbstractTreeAssembler<ArrayList<Pair<String, Double>>>() {
-
-            @Override
-            public void buildTree(ArrayList<Pair<String, Double>> data, TreeMapNode root) {
-                for (Pair<String, Double> element: data) {
-                    TreeMapNode lastProcessed = processRecord(element.getFirst(), SPLIT_TOKEN, root);
-                    lastProcessed.setRealWeight(element.getSecond());
-                }
-            }
-        };
-        TreeMapNode tree = TreeConverter.convertToTreeMap(data, assembler);
-
-        List<TreeMapNode> nodes = tree.getChildren();
-        assertEquals(5, nodes.size());
-
-        TreeMapNode node = AbstractTreeAssembler.searchNode(nodes, "com");
-        assertNotNull(node);
-
-        List<TreeMapNode> nodesFromCom = node.getChildren();
-
-        // example1 and example2
-        assertEquals(2, nodesFromCom.size());
-        node = AbstractTreeAssembler.searchNode(nodesFromCom, "example1");
-        assertNotNull(node);
-
-        // package2.Class3 and package1
-        assertEquals(2, node.getChildren().size());
-
-        node = AbstractTreeAssembler.searchNode(node.getChildren(), "package2.Class3");
-        assertNotNull(node);
-        assertTrue(node.getChildren().isEmpty());
-
-        node = AbstractTreeAssembler.searchNode(nodes, "java.lang.Object");
-        assertNotNull(node);
-        assertTrue(node.getChildren().isEmpty());
-
-        node = AbstractTreeAssembler.searchNode(nodes, "example2.package1.Class1");
-        assertNotNull(node);
-        assertTrue(node.getChildren().isEmpty());
-
-        // now on to the  "repeat1.repeat1.RepeatClass" bunch
-        node = AbstractTreeAssembler.searchNode(nodes, "repeat1.repeat1.RepeatClass");
-        assertNotNull(node);
-        assertTrue(node.getChildren().isEmpty());
-
-        node = AbstractTreeAssembler.searchNode(nodes, "repeat2");
-        assertNotNull(node);
-        assertEquals(2, node.getChildren().size());
-
-        List<TreeMapNode> nodesFromRepeat2 = node.getChildren();
-        node = AbstractTreeAssembler.searchNode(nodesFromRepeat2, "repeat2A.RepeatClass");
-        assertNotNull(node);
-        assertTrue(node.getChildren().isEmpty());
-
-        node = AbstractTreeAssembler.searchNode(nodesFromRepeat2, "repeat2B.RepeatClass");
-        assertNotNull(node);
-        assertTrue(node.getChildren().isEmpty());
-    }
-
-    @Test
-    public void testFillWeights() {
-        assertEquals(SOME_ROOT_WEIGHT, TreeConverter.fillWeights(root), DELTA);
-        TreeMapNode parent = new TreeMapNode("childA", SOME_WEIGHT);
-        root.addChild(parent);
-
-        final double weightAA = 5.0;
-        final double weightAB = 10.0;
-        parent.addChild(new TreeMapNode("childAA", weightAA));
-        parent.addChild(new TreeMapNode("childAB", weightAB));
-
-        assertEquals(SOME_ROOT_WEIGHT, root.getRealWeight(), DELTA);
-        TreeConverter.fillWeights(root);
-        assertEquals(weightAA + weightAB, root.getRealWeight(), DELTA);
-
-        List<TreeMapNode> children = parent.getChildren();
-
-        TreeMapNode child = AbstractTreeAssembler.searchNode(children, "childAA");
-        assertNotNull(child);
-        assertEquals(weightAA, child.getRealWeight(), DELTA);
-
-        child = AbstractTreeAssembler.searchNode(children, "childAB");
-        assertNotNull(child);
-        assertEquals(weightAB, child.getRealWeight(), DELTA);
-    }
-
-    @Test
-    public void testPackTree() {
-        TreeMapNode child = new TreeMapNode("childA", SOME_WEIGHT);
-        root.addChild(child);
-        child.addChild(new TreeMapNode("childAA", SOME_WEIGHT));
-        child.addChild(new TreeMapNode("childAB", SOME_WEIGHT));
-        child = new TreeMapNode("childB", SOME_WEIGHT);
-        root.addChild(child);
-        TreeMapNode grandchild = new TreeMapNode("childBA", SOME_WEIGHT);
-        child.addChild(grandchild);
-        grandchild.addChild(new TreeMapNode("childBAA", SOME_WEIGHT));
-
-        TreeConverter.packTree(root);
-
-        assertEquals(0, child.getChildren().size());
-        assertEquals("childB.childBA.childBAA", child.getLabel());
-
-        child = AbstractTreeAssembler.searchNode(root.getChildren(), "childA");
-        assertNotNull(child);
-        assertNotNull(AbstractTreeAssembler.searchNode(child.getChildren(), "childAA"));
-        assertNotNull(AbstractTreeAssembler.searchNode(child.getChildren(), "childAB"));
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/experimental/TreeMapTest.java	Wed Jun 29 12:23:11 2016 -0400
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2012-2015 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.util.ArrayList;
+import java.util.Collection;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.redhat.thermostat.common.Pair;
+
+public class TreeMapTest {
+
+    final private String SOME_ROOT_LABEL = "root";
+    final private double SOME_ROOT_WEIGHT = 25.0;
+    final private double DELTA = 0.01;
+    final private double SOME_WEIGHT = 3.14;
+
+    private ArrayList<Pair<String, Double>> data;
+    private TreeMapNode root;
+
+    @Before
+    public void setUp() {
+        /*
+         * This is a tree visualization of the data  (weights in parentheses).
+         *
+         *                          ___________root(25)__________
+         *                         /                             \
+         *                ________com_______                    java
+         *               /                  \                     |
+         *        __example1__            example2              lang
+         *       /            \              |                    |
+         *   Class1(0)     Class2(1)      Class1(2)           Object(3)
+         *
+         */
+
+        final String[] classes = {
+                "com.example1.Class1",
+                "com.example1.Class2",
+                "com.example2.Class1",
+                "java.lang.Object",
+        };
+
+        data = new ArrayList<Pair<String, Double>>();
+
+        for (int i = 0; i < classes.length; i++) {
+            data.add(new Pair<String, Double>(classes[i], new Double(i)));
+        }
+
+        root = new TreeMapNode(SOME_ROOT_LABEL, SOME_ROOT_WEIGHT);
+    }
+
+    @Test
+    public void testCreateTreeMap() {
+        /*
+         * This is the expected resulting tree (weights in parentheses).
+         *
+         *                          ___________root(6)___________
+         *                         /                             \
+         *                ______com(3)______             java.lang.Object(3)
+         *               /                  \
+         *        _example1(1)_       example2.Class1(2)
+         *       /             \
+         *   Class1(0)      Class2(1)
+         *
+         */
+
+        NodeDataExtractor<ArrayList<Pair<String, Double>>, Pair<String, Double>> extractor =
+                new NodeDataExtractor<ArrayList<Pair<String, Double>>, Pair<String, Double>>() {
+
+                    @Override
+                    public String getNodeSeparator() {
+                        return ".";
+                    }
+
+                    @Override
+                    public String getKey(Pair<String, Double> element) {
+                        return element.getFirst();
+                    }
+
+                    @Override
+                    public double getWeight(Pair<String, Double> element) {
+                        return element.getSecond();
+                    }
+
+                    @Override
+                    public Collection<Pair<String, Double>> getAsCollection(
+                            ArrayList<Pair<String, Double>> data) {
+                        return data;
+                    }
+                };
+        TreeMap<ArrayList<Pair<String, Double>>, Pair<String, Double>> treeMap = new TreeMap<>(data, extractor);
+
+        assertEquals(6.0, treeMap.getRoot().getRealWeight(), DELTA);
+        assertEquals(2, treeMap.getRoot().getChildren().size());
+
+        TreeMapNode javaLangObjectNode = TreeMap.searchNode(treeMap.getRoot(), "java.lang.Object");
+        assertNotNull(javaLangObjectNode);
+        assertEquals(3.0, javaLangObjectNode.getRealWeight(), DELTA);
+        assertTrue(javaLangObjectNode.getChildren().isEmpty());
+
+        TreeMapNode comNode = TreeMap.searchNode(treeMap.getRoot(), "com");
+        assertNotNull(comNode);
+        assertEquals(3.0, comNode.getRealWeight(), DELTA);
+        assertEquals(2, comNode.getChildren().size());
+
+        TreeMapNode example2Class1Node = TreeMap.searchNode(comNode, "example2.Class1");
+        assertNotNull(example2Class1Node);
+        assertEquals(2.0, example2Class1Node.getRealWeight(), DELTA);
+        assertTrue(example2Class1Node.getChildren().isEmpty());
+
+        TreeMapNode example1Node = TreeMap.searchNode(comNode, "example1");
+        assertNotNull(example1Node);
+        assertEquals(1.0, example1Node.getRealWeight(), DELTA);
+        assertEquals(2, example1Node.getChildren().size());
+
+        TreeMapNode class1Node = TreeMap.searchNode(example1Node, "Class1");
+        assertNotNull(class1Node);
+        assertEquals(0.0, class1Node.getRealWeight(), DELTA);
+        assertTrue(class1Node.getChildren().isEmpty());
+
+        TreeMapNode class2Node = TreeMap.searchNode(example1Node, "Class2");
+        assertNotNull(class2Node);
+        assertEquals(1.0, class2Node.getRealWeight(), DELTA);
+        assertTrue(class2Node.getChildren().isEmpty());
+    }
+
+    @Test
+    public void testFillWeights() {
+        assertEquals(SOME_ROOT_WEIGHT, TreeMap.fillWeights(root), DELTA);
+        TreeMapNode parent = new TreeMapNode("childA", SOME_WEIGHT);
+        root.addChild(parent);
+
+        final double weightAA = 5.0;
+        final double weightAB = 10.0;
+        parent.addChild(new TreeMapNode("childAA", weightAA));
+        parent.addChild(new TreeMapNode("childAB", weightAB));
+
+        assertEquals(SOME_ROOT_WEIGHT, root.getRealWeight(), DELTA);
+        TreeMap.fillWeights(root);
+        assertEquals(weightAA + weightAB, root.getRealWeight(), DELTA);
+
+        TreeMapNode childAANode = TreeMap.searchNode(parent, "childAA");
+        assertNotNull(childAANode);
+        assertEquals(weightAA, childAANode.getRealWeight(), DELTA);
+
+        TreeMapNode childABNode = TreeMap.searchNode(parent, "childAB");
+        assertNotNull(childABNode);
+        assertEquals(weightAB, childABNode.getRealWeight(), DELTA);
+    }
+
+    @Test
+    public void testPackTree() {
+        TreeMapNode child = new TreeMapNode("childA", SOME_WEIGHT);
+        root.addChild(child);
+        child.addChild(new TreeMapNode("childAA", SOME_WEIGHT));
+        child.addChild(new TreeMapNode("childAB", SOME_WEIGHT));
+        child = new TreeMapNode("childB", SOME_WEIGHT);
+        root.addChild(child);
+        TreeMapNode grandchild = new TreeMapNode("childBA", SOME_WEIGHT);
+        child.addChild(grandchild);
+        grandchild.addChild(new TreeMapNode("childBAA", SOME_WEIGHT));
+
+        TreeMap.packTree(root);
+
+        assertEquals(0, child.getChildren().size());
+        assertEquals("childB.childBA.childBAA", child.getLabel());
+
+        child = TreeMap.searchNode(root, "childA");
+        assertNotNull(child);
+        assertNotNull(TreeMap.searchNode(child, "childAA"));
+        assertNotNull(TreeMap.searchNode(child, "childAB"));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectHistogramNodeDataExtractor.java	Wed Jun 29 12:23:11 2016 -0400
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2012-2015 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.util.Collection;
+
+import com.redhat.thermostat.client.swing.components.experimental.NodeDataExtractor;
+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;
+
+public class ObjectHistogramNodeDataExtractor implements NodeDataExtractor<ObjectHistogram, HistogramRecord> {
+
+    @Override
+    public String getNodeSeparator() {
+        return ".";
+    }
+
+    @Override
+    public String getKey(HistogramRecord record) {
+        String className = record.getClassname();
+        // if className is a primitive type it is converted with its full name
+        return DescriptorConverter.toJavaType(className);
+    }
+
+    @Override
+    public double getWeight(HistogramRecord record) {
+        return record.getTotalSize();
+    }
+
+    @Override
+    public Collection<HistogramRecord> getAsCollection(ObjectHistogram histogram) {
+        return histogram.getHistogram();
+    }
+}
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectHistogramTreeAssembler.java	Wed Jun 29 12:23:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright 2012-2015 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 com.redhat.thermostat.client.swing.components.experimental.AbstractTreeAssembler;
-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;
-
-public class ObjectHistogramTreeAssembler extends AbstractTreeAssembler<ObjectHistogram> {
-
-    /**
-     * Key used to put into nodes the <i>number of instances</i> information
-     * stored in histogram records.
-     */
-    private static final String NUMBER_OF = "Number Of Instances";
-
-    @Override
-    public void buildTree(ObjectHistogram histogram, TreeMapNode root) {
-        for (HistogramRecord record : histogram.getHistogram()) {
-            String className = record.getClassname();
-
-            // if className is a primitive type it is converted with its full name
-            className = DescriptorConverter.toJavaType(className);
-            TreeMapNode lastProcessed = processRecord(className, ".", root);
-
-            // at this point lastProcessed references to a leaf
-            lastProcessed.setRealWeight(record.getTotalSize());
-            lastProcessed.addInfo(NUMBER_OF, Long.toString(record.getNumberOf()));
-        }
-    }
-}
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapTreeMapView.java	Wed Jun 29 12:23:11 2016 -0400
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapTreeMapView.java	Wed Jun 29 12:23:11 2016 -0400
@@ -43,12 +43,13 @@
 import javax.swing.SwingUtilities;
 
 import com.redhat.thermostat.client.swing.SwingComponent;
-import com.redhat.thermostat.client.swing.components.experimental.TreeConverter;
+import com.redhat.thermostat.client.swing.components.experimental.TreeMap;
 import com.redhat.thermostat.client.swing.components.experimental.TreeMapComponent;
 import com.redhat.thermostat.client.swing.components.experimental.TreeMapNode;
 import com.redhat.thermostat.client.swing.components.experimental.TreeMapToolbar;
 import com.redhat.thermostat.common.Size;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapTreeMapView;
+import com.redhat.thermostat.vm.heap.analysis.common.HistogramRecord;
 import com.redhat.thermostat.vm.heap.analysis.common.ObjectHistogram;
 
 public class SwingHeapTreeMapView extends HeapTreeMapView implements SwingComponent {
@@ -69,8 +70,8 @@
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
-                TreeMapNode model = TreeConverter.convertToTreeMap(
-                        histogram, new ObjectHistogramTreeAssembler());
+                TreeMap<ObjectHistogram, HistogramRecord> map = new TreeMap<>(histogram, new ObjectHistogramNodeDataExtractor());
+                TreeMapNode model = map.getRoot();
                 treeMap.setModel(model);
                 panel.removeAll();
                 panel.add(treeMap, BorderLayout.CENTER);
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectHistogramTreeAssemblerTest.java	Wed Jun 29 12:23:11 2016 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,153 +0,0 @@
-/*
- * Copyright 2012-2015 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.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import com.redhat.thermostat.client.swing.components.experimental.AbstractTreeAssembler;
-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;
-
-public class ObjectHistogramTreeAssemblerTest {
-
-    private final String ROOT_LABEL = "root";
-    private final double ROOT_WEIGHT = 10.0;
-
-    private ObjectHistogram histogram;
-    private TreeMapNode root;
-
-    @Before
-    public void setup() {
-
-        final String[] classes = {
-                "com.example1.Class1",
-                "com.example1.Class2",
-                "com.example2",
-                "java.lang.Object",
-        };
-
-        histogram = new ObjectHistogram();
-        for (int i = 0; i < classes.length; i++) {
-            final String className = classes[i];
-
-            histogram.addThing(new JavaHeapObject() {
-                public int getSize() {
-                    return 0;
-                }
-
-                public long getId() {
-                    return 0;
-                }
-
-                public JavaClass getClazz() {
-                    return new JavaClass(className, 0, 0, 0, 0, null, null, 0);
-                }
-            });
-        }
-
-        root = new TreeMapNode(ROOT_LABEL, ROOT_WEIGHT);
-    }
-
-    @Test
-    public void testBuildTree() {
-        /*
-         * This is a visualization of the expected resulting tree.
-         *
-         *                          _____________root____________
-         *                         /                             \
-         *                ________com_______                    java
-         *               /                  \                     |
-         *        __example1__            example2              lang
-         *       /            \                                   |
-         *    Class1         Class2                            Object
-         *
-         */
-
-        ObjectHistogramTreeAssembler assembler = new ObjectHistogramTreeAssembler();
-        assembler.buildTree(histogram, root);
-
-        List<TreeMapNode> children = root.getChildren();
-        assertEquals(2, children.size());
-
-        TreeMapNode node = AbstractTreeAssembler.searchNode(children, "java");
-        assertNotNull(node);
-        children = node.getChildren();
-        assertEquals(1, children.size());
-        node = AbstractTreeAssembler.searchNode(children, "lang");
-        assertNotNull(node);
-        children = node.getChildren();
-        assertEquals(1, children.size());
-        node = AbstractTreeAssembler.searchNode(children, "Object");
-        assertNotNull(node);
-        assertTrue(node.getChildren().isEmpty());
-
-        children = root.getChildren();
-        node = AbstractTreeAssembler.searchNode(children, "com");
-        assertNotNull(node);
-        children = node.getChildren();
-        assertEquals(2, children.size());
-
-        node = AbstractTreeAssembler.searchNode(children, "example2");
-        assertNotNull(node);
-        assertTrue(node.getChildren().isEmpty());
-
-        node = AbstractTreeAssembler.searchNode(root.getChildren(), "com");
-        assertNotNull(node);
-        node = AbstractTreeAssembler.searchNode(node.getChildren(), "example1");
-        assertNotNull(node);
-        children = node.getChildren();
-        assertEquals(2, children.size());
-
-        node = AbstractTreeAssembler.searchNode(children, "Class1");
-        assertNotNull(node);
-        assertTrue(node.getChildren().isEmpty());
-
-        node = AbstractTreeAssembler.searchNode(children, "Class2");
-        assertNotNull(node);
-        assertTrue(node.getChildren().isEmpty());
-    }
-
-}