changeset 2904:1916da1d3e11

Merge.
author Thomas Wuerthinger <thomas@wuerthinger.net>
date Wed, 08 Jun 2011 17:26:49 +0200
parents eb3a82946429 (current diff) 43224fe0f240 (diff)
children 8681191723f3
files graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlockEdge.java src/share/tools/IdealGraphVisualizer/Filter/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/JavaSE6ScriptEngine.java src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Source.java src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/combine.filter src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/extendedColor.filter src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/linestyle.filter src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeMemory.filter src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeRootInputs.filter src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSafepointInputs.filter src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSelfLoops.filter src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/split.filter src/share/tools/IdealGraphVisualizer/View/src/META-INF/services/com.sun.hotspot.igv.data.services.InputGraphProvider src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ConnectionAnchor.java src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedPanAction.java src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/PreferenceConstants.java src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/SlotLayout.java src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NodeFindAction.java src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/DiagramConnectionWidget.java src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/MultiConnectionWidget.java
diffstat 255 files changed, 9251 insertions(+), 3044 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java	Wed Jun 08 17:26:49 2011 +0200
@@ -84,6 +84,7 @@
 
         if (GraalOptions.OptCanonicalizer) {
             new CanonicalizerPhase().apply(graph);
+            verifyAndPrint("After Canonicalization");
         }
 
         new SplitCriticalEdgesPhase().apply(graph);
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Compare.java	Wed Jun 08 17:26:49 2011 +0200
@@ -27,6 +27,13 @@
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.ci.*;
 
+/* (tw/gd) For high-level optimization purpose the compare node should be a boolean *value* (it is currently only a helper node)
+ * But in the back-end the comparison should not always be materialized (for example in x86 the comparison result will not be in a register but in a flag)
+ *
+ * Compare should probably be made a value (so that it can be canonicalized for example) and in later stages some Compare usage should be transformed
+ * into variants that do not materialize the value (CompareIf, CompareGuard...)
+ *
+ */
 public final class Compare extends FloatingNode {
 
     private static final int INPUT_COUNT = 2;
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/FloatDiv.java	Wed Jun 08 17:26:49 2011 +0200
@@ -51,7 +51,8 @@
 
     @Override
     public Node copy(Graph into) {
-        return new FloatDiv(kind, null, null, isStrictFP(), into);
+        FloatDiv x = new FloatDiv(kind, null, null, isStrictFP(), into);
+        return x;
     }
 
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAdd.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerAdd.java	Wed Jun 08 17:26:49 2011 +0200
@@ -22,12 +22,14 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 
 public final class IntegerAdd extends IntegerArithmetic {
+    private static final IntegerAddCanonicalizerOp CANONICALIZER = new IntegerAddCanonicalizerOp();
 
     public IntegerAdd(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IADD : Bytecodes.LADD, x, y, graph);
@@ -43,4 +45,51 @@
         return "+";
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class IntegerAddCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            IntegerAdd add = (IntegerAdd) node;
+            Value x = add.x();
+            Value y = add.y();
+            CiKind kind = add.kind;
+            Graph graph = add.graph();
+            if (x.isConstant() && !y.isConstant()) {
+                add.swapOperands();
+                Value t = y;
+                y = x;
+                x = t;
+            }
+            if (x.isConstant()) {
+                if (kind == CiKind.Int) {
+                    return Constant.forInt(x.asConstant().asInt() + y.asConstant().asInt(), graph);
+                } else {
+                    assert kind == CiKind.Long;
+                    return Constant.forLong(x.asConstant().asLong() + y.asConstant().asLong(), graph);
+                }
+            } else if (y.isConstant()) {
+                if (kind == CiKind.Int) {
+                    int c = y.asConstant().asInt();
+                    if (c == 0) {
+                        return x;
+                    }
+                } else {
+                    assert kind == CiKind.Long;
+                    long c = y.asConstant().asLong();
+                    if (c == 0) {
+                        return x;
+                    }
+                }
+            }
+            return add;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerDiv.java	Wed Jun 08 17:26:49 2011 +0200
@@ -22,12 +22,14 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 
 public final class IntegerDiv extends IntegerArithmetic {
+    private static final IntegerDivCanonicalizerOp CANONICALIZER = new IntegerDivCanonicalizerOp();
 
     public IntegerDiv(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IDIV : Bytecodes.LDIV, x, y, graph);
@@ -43,4 +45,41 @@
         return new IntegerDiv(kind, null, null, into);
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class IntegerDivCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            IntegerDiv div = (IntegerDiv) node;
+            Value x = div.x();
+            Value y = div.y();
+            CiKind kind = div.kind;
+            Graph graph = div.graph();
+            if (x.isConstant() && y.isConstant()) {
+                long yConst = y.asConstant().asLong();
+                if (yConst == 0) {
+                    return div; // this will trap, can not canonicalize
+                }
+                if (kind == CiKind.Int) {
+                    return Constant.forInt(x.asConstant().asInt() / (int) yConst, graph);
+                } else {
+                    assert kind == CiKind.Long;
+                    return Constant.forLong(x.asConstant().asLong() / yConst, graph);
+                }
+            } else if (y.isConstant()) {
+                long c = y.asConstant().asLong();
+                if (c == 1) {
+                    return x;
+                }
+            }
+            return div;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerMul.java	Wed Jun 08 17:26:49 2011 +0200
@@ -22,12 +22,14 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 
 public final class IntegerMul extends IntegerArithmetic {
+    private static final IntegerMulCanonicalizerOp CANONICALIZER = new IntegerMulCanonicalizerOp();
 
     public IntegerMul(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IMUL : Bytecodes.LMUL, x, y, graph);
@@ -43,4 +45,49 @@
         return new IntegerMul(kind, null, null, into);
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class IntegerMulCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            IntegerMul mul = (IntegerMul) node;
+            Value x = mul.x();
+            Value y = mul.y();
+            CiKind kind = mul.kind;
+            Graph graph = mul.graph();
+            if (x.isConstant() && !y.isConstant()) {
+                mul.swapOperands();
+                Value t = y;
+                y = x;
+                x = t;
+            }
+            if (x.isConstant()) {
+                if (kind == CiKind.Int) {
+                    return Constant.forInt(x.asConstant().asInt() * y.asConstant().asInt(), graph);
+                } else {
+                    assert kind == CiKind.Long;
+                    return Constant.forLong(x.asConstant().asLong() * y.asConstant().asLong(), graph);
+                }
+            } else if (y.isConstant()) {
+                long c = y.asConstant().asLong();
+                if (c == 1) {
+                    return x;
+                }
+                if (c == 0) {
+                    return Constant.forInt(0, graph);
+                }
+                if (c > 0 && CiUtil.isPowerOf2(c)) {
+                    return new LeftShift(kind, x, Constant.forInt(CiUtil.log2(c), graph), graph);
+                }
+            }
+            return mul;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/IntegerSub.java	Wed Jun 08 17:26:49 2011 +0200
@@ -22,12 +22,14 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 
 public final class IntegerSub extends IntegerArithmetic {
+    private static final IntegerSubCanonicalizerOp CANONICALIZER = new IntegerSubCanonicalizerOp();
 
     public IntegerSub(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.ISUB : Bytecodes.LSUB, x, y, graph);
@@ -42,4 +44,59 @@
     public String shortName() {
         return "-";
     }
+
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class IntegerSubCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            IntegerSub sub = (IntegerSub) node;
+            Value x = sub.x();
+            Value y = sub.y();
+            CiKind kind = sub.kind;
+            Graph graph = sub.graph();
+            if (x == y) {
+                if (kind == CiKind.Int) {
+                    return Constant.forInt(0, graph);
+                } else {
+                    assert kind == CiKind.Long;
+                    return Constant.forLong(0, graph);
+                }
+            }
+            if (x.isConstant() && y.isConstant()) {
+                if (kind == CiKind.Int) {
+                    return Constant.forInt(x.asConstant().asInt() - y.asConstant().asInt(), graph);
+                } else {
+                    assert kind == CiKind.Long;
+                    return Constant.forLong(x.asConstant().asLong() - y.asConstant().asLong(), graph);
+                }
+            } else if (y.isConstant()) {
+                if (kind == CiKind.Int) {
+                    int c = y.asConstant().asInt();
+                    if (c == 0) {
+                        return x;
+                    }
+                } else {
+                    assert kind == CiKind.Long;
+                    long c = y.asConstant().asLong();
+                    if (c == 0) {
+                        return x;
+                    }
+                }
+            } else if (x.isConstant()) {
+                long c = x.asConstant().asLong();
+                if (c == 0) {
+                    return new Negate(y, graph);
+                }
+            }
+            return sub;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LeftShift.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LeftShift.java	Wed Jun 08 17:26:49 2011 +0200
@@ -22,20 +22,15 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.CanonicalizerOp;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 
 public final class LeftShift extends Shift {
+    private static final LeftShiftCanonicalizerOp CANONICALIZER = new LeftShiftCanonicalizerOp();
 
-    /**
-     * @param opcode
-     * @param kind
-     * @param x
-     * @param y
-     * @param graph
-     */
     public LeftShift(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.ISHL : Bytecodes.LSHL, x, y, graph);
     }
@@ -51,4 +46,70 @@
         return ls;
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class LeftShiftCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            LeftShift leftShift = (LeftShift) node;
+            CiKind kind = leftShift.kind;
+            Graph graph = leftShift.graph();
+            Value value = leftShift.x();
+            Value y = leftShift.y();
+            if (y.isConstant()) {
+                int amount = y.asConstant().asInt();
+                int originalAmout = amount;
+                int mask;
+                if (kind == CiKind.Int) {
+                    mask = 0x1f;
+                } else {
+                    assert kind == CiKind.Long;
+                    mask = 0x3f;
+                }
+                amount &= mask;
+                if (value.isConstant()) {
+                    if (kind == CiKind.Int) {
+                        return Constant.forInt(value.asConstant().asInt() << amount, graph);
+                    } else {
+                        assert kind == CiKind.Long;
+                        return Constant.forLong(value.asConstant().asLong() << amount, graph);
+                    }
+                }
+                if (amount == 0) {
+                    return value;
+                }
+                if (value instanceof Shift) {
+                    Shift other = (Shift) value;
+                    if (other.y().isConstant()) {
+                        int otherAmount = other.y().asConstant().asInt() & mask;
+                        if (other instanceof LeftShift) {
+                            int total = amount + otherAmount;
+                            if (total != (total & mask)) {
+                                return Constant.forInt(0, graph);
+                            }
+                            return new LeftShift(kind, other.x(), Constant.forInt(total, graph), graph);
+                        } else if ((other instanceof RightShift || other instanceof UnsignedRightShift) && otherAmount == amount) {
+                            if (kind == CiKind.Long) {
+                                return new And(kind, other.x(), Constant.forLong(-1L << amount, graph), graph);
+                            } else {
+                                assert kind == CiKind.Int;
+                                return new And(kind, other.x(), Constant.forInt(-1 << amount, graph), graph);
+                            }
+                        }
+                    }
+                }
+                if (originalAmout != amount) {
+                    return new LeftShift(kind, value, Constant.forInt(amount, graph), graph);
+                }
+            }
+            return leftShift;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RightShift.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/RightShift.java	Wed Jun 08 17:26:49 2011 +0200
@@ -22,20 +22,15 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 
 public final class RightShift extends Shift {
+    private static final RighShiftCanonicalizerOp CANONICALIZER = new RighShiftCanonicalizerOp();
 
-    /**
-     * @param opcode
-     * @param kind
-     * @param x
-     * @param y
-     * @param graph
-     */
     public RightShift(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.ISHR : Bytecodes.LSHR, x, y, graph);
     }
@@ -51,4 +46,63 @@
         return rs;
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class RighShiftCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            RightShift rightShift = (RightShift) node;
+            CiKind kind = rightShift.kind;
+            Graph graph = rightShift.graph();
+            Value value = rightShift.x();
+            Value y = rightShift.y();
+            if (y.isConstant()) {
+                int amount = y.asConstant().asInt();
+                int originalAmout = amount;
+                int mask;
+                if (kind == CiKind.Int) {
+                    mask = 0x1f;
+                } else {
+                    assert kind == CiKind.Long;
+                    mask = 0x3f;
+                }
+                amount &= mask;
+                if (value.isConstant()) {
+                    if (kind == CiKind.Int) {
+                        return Constant.forInt(value.asConstant().asInt() >> amount, graph);
+                    } else {
+                        assert kind == CiKind.Long;
+                        return Constant.forLong(value.asConstant().asLong() >> amount, graph);
+                    }
+                }
+                if (amount == 0) {
+                    return value;
+                }
+                if (value instanceof Shift) {
+                    Shift other = (Shift) value;
+                    if (other.y().isConstant()) {
+                        int otherAmount = other.y().asConstant().asInt() & mask;
+                        if (other instanceof RightShift) {
+                            int total = amount + otherAmount;
+                            if (total != (total & mask)) {
+                                return Constant.forInt(0, graph);
+                            }
+                            return new RightShift(kind, other.x(), Constant.forInt(total, graph), graph);
+                        }
+                    }
+                }
+                if (originalAmout != amount) {
+                    return new RightShift(kind, value, Constant.forInt(amount, graph), graph);
+                }
+            }
+            return rightShift;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Shift.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/Shift.java	Wed Jun 08 17:26:49 2011 +0200
@@ -38,10 +38,11 @@
      * Creates a new shift operation.
      * @param opcode the opcode of the shift
      * @param x the first input value
-     * @param y the second input value
+     * @param s the second input value
      */
-    public Shift(CiKind kind, int opcode, Value x, Value y, Graph graph) {
-        super(kind, opcode, x, y, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+    public Shift(CiKind kind, int opcode, Value x, Value s, Graph graph) {
+        super(kind, opcode, x, s, INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        assert x == null || x.kind == kind;
     }
 
     @Override
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/UnsignedRightShift.java	Wed Jun 08 17:26:49 2011 +0200
@@ -22,20 +22,15 @@
  */
 package com.oracle.max.graal.compiler.ir;
 
+import com.oracle.max.graal.compiler.phases.CanonicalizerPhase.*;
 import com.oracle.max.graal.graph.*;
 import com.sun.cri.bytecode.*;
 import com.sun.cri.ci.*;
 
 
 public final class UnsignedRightShift extends Shift {
+    private static final UnsignedRightShiftCanonicalizerOp CANONICALIZER = new UnsignedRightShiftCanonicalizerOp();
 
-    /**
-     * @param opcode
-     * @param kind
-     * @param x
-     * @param y
-     * @param graph
-     */
     public UnsignedRightShift(CiKind kind, Value x, Value y, Graph graph) {
         super(kind, kind == CiKind.Int ? Bytecodes.IUSHR : Bytecodes.LUSHR, x, y, graph);
     }
@@ -51,4 +46,70 @@
         return x;
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
+    public <T extends Op> T lookup(Class<T> clazz) {
+        if (clazz == CanonicalizerOp.class) {
+            return (T) CANONICALIZER;
+        }
+        return super.lookup(clazz);
+    }
+
+    private static class UnsignedRightShiftCanonicalizerOp implements CanonicalizerOp {
+        @Override
+        public Node canonical(Node node) {
+            UnsignedRightShift ushr = (UnsignedRightShift) node;
+            CiKind kind = ushr.kind;
+            Graph graph = ushr.graph();
+            Value value = ushr.x();
+            Value y = ushr.y();
+            if (y.isConstant()) {
+                int amount = y.asConstant().asInt();
+                int originalAmout = amount;
+                int mask;
+                if (kind == CiKind.Int) {
+                    mask = 0x1f;
+                } else {
+                    assert kind == CiKind.Long;
+                    mask = 0x3f;
+                }
+                amount &= mask;
+                if (value.isConstant()) {
+                    if (kind == CiKind.Int) {
+                        return Constant.forInt(value.asConstant().asInt() >>> amount, graph);
+                    } else {
+                        assert kind == CiKind.Long;
+                        return Constant.forLong(value.asConstant().asLong() >>> amount, graph);
+                    }
+                }
+                if (amount == 0) {
+                    return value;
+                }
+                if (value instanceof Shift) {
+                    Shift other = (Shift) value;
+                    if (other.y().isConstant()) {
+                        int otherAmount = other.y().asConstant().asInt() & mask;
+                        if (other instanceof UnsignedRightShift) {
+                            int total = amount + otherAmount;
+                            if (total != (total & mask)) {
+                                return Constant.forInt(0, graph);
+                            }
+                            return new UnsignedRightShift(kind, other.x(), Constant.forInt(total, graph), graph);
+                        } else if (other instanceof LeftShift && otherAmount == amount) {
+                            if (kind == CiKind.Long) {
+                                return new And(kind, other.x(), Constant.forLong(-1L >>> amount, graph), graph);
+                            } else {
+                                assert kind == CiKind.Int;
+                                return new And(kind, other.x(), Constant.forInt(-1 >>> amount, graph), graph);
+                            }
+                        }
+                    }
+                }
+                if (originalAmout != amount) {
+                    return new UnsignedRightShift(kind, value, Constant.forInt(amount, graph), graph);
+                }
+            }
+            return ushr;
+        }
+    }
 }
--- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/CanonicalizerPhase.java	Wed Jun 08 17:26:49 2011 +0200
@@ -38,7 +38,7 @@
             if (n == null) {
                 continue;
             }
-            if (!visited.isMarked(n)) {
+            if (!n.isDeleted() && !visited.isMarked(n)) {
                 this.canonicalize(n, visited);
             }
         }
--- a/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/genfiles.properties	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/genfiles.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -1,6 +1,3 @@
-build.xml.data.CRC32=ebcf0422
-build.xml.script.CRC32=d7a2678d
-build.xml.stylesheet.CRC32=a56c6a5b@1.45.1
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
 nbproject/build-impl.xml.data.CRC32=ebcf0422
--- a/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/BatikSVG.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/BatikSVG.java	Wed Jun 08 17:26:49 2011 +0200
@@ -31,34 +31,42 @@
 import org.w3c.dom.DOMImplementation;
 
 /**
- *
+ * Utility class
  * @author Thomas Wuerthinger
  */
 public class BatikSVG {
 
+    private BatikSVG() {
+    }
+
     private static Constructor SVGGraphics2DConstructor;
-    private static Method Method_stream;
-    private static Method Method_createDefault;
-    private static Method Method_getDOMImplementation;
-    private static Method Method_setEmbeddedFontsOn;
+    private static Method streamMethod;
+    private static Method createDefaultMethod;
+    private static Method getDOMImplementationMethod;
+    private static Method setEmbeddedFontsOnMethod;
+    private static Class classSVGGraphics2D;
 
+    /**
+     * Creates a graphics object that allows to be exported to SVG data using the {@link #printToStream(Graphics2D, Writer, boolean) printToStream} method.
+     * @return the newly created Graphics2D object or null if the library does not exist
+     */
     public static Graphics2D createGraphicsObject() {
         try {
             if (SVGGraphics2DConstructor == null) {
                 ClassLoader cl = BatikSVG.class.getClassLoader();
-                Class Class_GenericDOMImplementation = cl.loadClass("org.apache.batik.dom.GenericDOMImplementation");
-                Class Class_SVGGeneratorContext = cl.loadClass("org.apache.batik.svggen.SVGGeneratorContext");
-                Class Class_SVGGraphics2D = cl.loadClass("org.apache.batik.svggen.SVGGraphics2D");
-                Method_getDOMImplementation = Class_GenericDOMImplementation.getDeclaredMethod("getDOMImplementation", new Class[0]);
-                Method_createDefault = Class_SVGGeneratorContext.getDeclaredMethod("createDefault", new Class[]{org.w3c.dom.Document.class});
-                Method_setEmbeddedFontsOn = Class_SVGGeneratorContext.getDeclaredMethod("setEmbeddedFontsOn", new Class[]{boolean.class});
-                Method_stream = Class_SVGGraphics2D.getDeclaredMethod("stream", Writer.class, boolean.class);
-                SVGGraphics2DConstructor = Class_SVGGraphics2D.getConstructor(Class_SVGGeneratorContext, boolean.class);
+                Class classGenericDOMImplementation = cl.loadClass("org.apache.batik.dom.GenericDOMImplementation");
+                Class classSVGGeneratorContext = cl.loadClass("org.apache.batik.svggen.SVGGeneratorContext");
+                classSVGGraphics2D = cl.loadClass("org.apache.batik.svggen.SVGGraphics2D");
+                getDOMImplementationMethod = classGenericDOMImplementation.getDeclaredMethod("getDOMImplementation", new Class[0]);
+                createDefaultMethod = classSVGGeneratorContext.getDeclaredMethod("createDefault", new Class[]{org.w3c.dom.Document.class});
+                setEmbeddedFontsOnMethod = classSVGGeneratorContext.getDeclaredMethod("setEmbeddedFontsOn", new Class[]{boolean.class});
+                streamMethod = classSVGGraphics2D.getDeclaredMethod("stream", Writer.class, boolean.class);
+                SVGGraphics2DConstructor = classSVGGraphics2D.getConstructor(classSVGGeneratorContext, boolean.class);
             }
-            DOMImplementation dom = (DOMImplementation) Method_getDOMImplementation.invoke(null);
+            DOMImplementation dom = (DOMImplementation) getDOMImplementationMethod.invoke(null);
             org.w3c.dom.Document document = dom.createDocument("http://www.w3.org/2000/svg", "svg", null);
-            Object ctx = Method_createDefault.invoke(null, document);
-            Method_setEmbeddedFontsOn.invoke(ctx, true);
+            Object ctx = createDefaultMethod.invoke(null, document);
+            setEmbeddedFontsOnMethod.invoke(ctx, true);
             Graphics2D svgGenerator = (Graphics2D) SVGGraphics2DConstructor.newInstance(ctx, true);
             return svgGenerator;
         } catch (ClassNotFoundException e) {
@@ -74,9 +82,17 @@
         }
     }
 
+    /**
+     * Serializes a graphics object to a stream in SVG format.
+     * @param svgGenerator the graphics object. Only graphics objects created by the {@link #createGraphicsObject() createGraphicsObject} method are valid.
+     * @param stream the stream to which the data is written
+     * @param useCSS whether to use CSS styles in the SVG output
+     */
     public static void printToStream(Graphics2D svgGenerator, Writer stream, boolean useCSS) {
+        assert classSVGGraphics2D != null;
+        assert classSVGGraphics2D.isInstance(svgGenerator);
         try {
-            Method_stream.invoke(svgGenerator, stream, useCSS);
+            streamMethod.invoke(svgGenerator, stream, useCSS);
         } catch (IllegalAccessException e) {
             assert false;
         } catch (InvocationTargetException e) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/package-info.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+/**
+ * This package is used to proxy the SVG export functionality of the BatikSVG library. Reflection is used such that the
+ * library is optional and need not be present at build time.
+ */
+package com.sun.hotspot.igv.svg;
+
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -15,6 +15,22 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>org.jdesktop.layout</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Wed Jun 08 17:26:49 2011 +0200
@@ -30,6 +30,7 @@
 import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
 import java.awt.Image;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 import javax.swing.Action;
@@ -58,7 +59,7 @@
         StringPropertyMatcher matcher = new StringPropertyMatcher("bci", bciValue);
         List<InputNode> nodeList = selector.selectMultiple(matcher);
         if (nodeList.size() > 0) {
-            nodes = new HashSet<InputNode>();
+            nodes = new LinkedHashSet<InputNode>();
             for (InputNode n : nodeList) {
                 nodes.add(n);
             }
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.form	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.form	Wed Jun 08 17:26:49 2011 +0200
@@ -3,6 +3,8 @@
 <Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Wed Jun 08 17:26:49 2011 +0200
@@ -26,6 +26,7 @@
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.util.LookupHistory;
 import java.awt.BorderLayout;
 import java.io.Serializable;
 import javax.swing.SwingUtilities;
@@ -91,6 +92,7 @@
     }// </editor-fold>//GEN-END:initComponents
     // Variables declaration - do not modify//GEN-BEGIN:variables
     // End of variables declaration//GEN-END:variables
+
     /**
      * Gets default instance. Do not use directly: reserved for *.settings files only,
      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
@@ -126,7 +128,7 @@
 
     @Override
     public void componentOpened() {
-        Lookup.Template tpl = new Lookup.Template(Object.class);
+        Lookup.Template tpl = new Lookup.Template(InputGraphProvider.class);
         result = Utilities.actionsGlobalContext().lookup(tpl);
         result.addLookupListener(this);
     }
@@ -151,17 +153,35 @@
         return manager;
     }
 
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        this.treeView.requestFocus();
+    }
+
+    @Override
+    public boolean requestFocus(boolean temporary) {
+        this.treeView.requestFocus();
+        return super.requestFocus(temporary);
+    }
+
+    @Override
+    protected boolean requestFocusInWindow(boolean temporary) {
+        this.treeView.requestFocus();
+        return super.requestFocusInWindow(temporary);
+    }
+
     public void resultChanged(LookupEvent lookupEvent) {
-        final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
         if (p != null) {
             SwingUtilities.invokeLater(new Runnable() {
                 public void run() {
-            InputGraph graph = p.getGraph();
-            if (graph != null) {
-                Group g = graph.getGroup();
-                rootNode.update(graph, g.getMethod());
-            }
-        }
+                    InputGraph graph = p.getGraph();
+                    if (graph != null) {
+                        Group g = graph.getGroup();
+                        rootNode.update(graph, g.getMethod());
+                    }
+                }
             });
         }
     }
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java	Wed Jun 08 17:26:49 2011 +0200
@@ -24,10 +24,11 @@
 package com.sun.hotspot.igv.bytecodes;
 
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.util.LookupHistory;
 import org.openide.nodes.Node;
 import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
 import org.openide.util.NbBundle;
+import org.openide.util.Utilities;
 import org.openide.util.actions.CookieAction;
 
 /**
@@ -38,7 +39,7 @@
 
     protected void performAction(Node[] activatedNodes) {
         SelectBytecodesCookie c = activatedNodes[0].getCookie(SelectBytecodesCookie.class);
-        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
         if (p != null) {
             p.setSelectedNodes(c.getNodes());
         }
@@ -73,3 +74,4 @@
         return false;
     }
 }
+
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -31,6 +31,14 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>org.jdesktop.layout</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockConnectionWidget.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockConnectionWidget.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,7 +23,7 @@
  */
 package com.sun.hotspot.igv.controlflow;
 
-import com.sun.hotspot.igv.data.InputBlockEdge;
+import com.sun.hotspot.igv.controlflow.InputBlockEdge;
 import com.sun.hotspot.igv.layout.Link;
 import com.sun.hotspot.igv.layout.Port;
 import java.awt.Point;
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockWidget.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockWidget.java	Wed Jun 08 17:26:49 2011 +0200
@@ -47,7 +47,7 @@
     private Port outputSlot;
     private Cluster cluster;
     private boolean root;
-    private static final Font font = new Font(Font.SERIF, Font.PLAIN, 12);
+    private static final Font font = new Font("Serif", Font.PLAIN, 12);
     private static final Font boldFont = font.deriveFont(Font.BOLD);
     public static final Color NORMAL_FOREGROUND_COLOR = Color.BLACK;
     public static final Color HOVER_FOREGROUND_COLOR = Color.BLUE;
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Wed Jun 08 17:26:49 2011 +0200
@@ -24,16 +24,16 @@
 package com.sun.hotspot.igv.controlflow;
 
 import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.InputBlockEdge;
+import com.sun.hotspot.igv.controlflow.InputBlockEdge;
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.util.LookupHistory;
 import java.awt.Color;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.HashMap;
 import java.util.Set;
 import javax.swing.BorderFactory;
 import org.netbeans.api.visual.action.ActionFactory;
@@ -52,7 +52,7 @@
 import org.netbeans.api.visual.graph.layout.GraphLayout;
 import org.netbeans.api.visual.layout.SceneLayout;
 import org.netbeans.api.visual.widget.ConnectionWidget;
-import org.openide.util.Lookup;
+import org.openide.util.Utilities;
 
 /**
  *
@@ -61,7 +61,6 @@
 public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
 
     private HashSet<BlockWidget> selection;
-    private HashMap<InputBlock, BlockWidget> blockMap;
     private InputGraph oldGraph;
     private LayerWidget edgeLayer;
     private LayerWidget mainLayer;
@@ -81,7 +80,7 @@
 
         edgeLayer = new LayerWidget(this);
         this.addChild(edgeLayer);
-
+        
         selectLayer = new LayerWidget(this);
         this.addChild(selectLayer);
 
@@ -112,7 +111,8 @@
         }
 
         for (InputBlock b : g.getBlocks()) {
-            for (InputBlockEdge e : b.getOutputs()) {
+            for (InputBlock succ : b.getSuccessors()) {
+                final InputBlockEdge e = new InputBlockEdge(b, succ);
                 addEdge(e);
                 assert g.getBlocks().contains(e.getFrom());
                 assert g.getBlocks().contains(e.getTo());
@@ -128,10 +128,6 @@
         this.validate();
     }
 
-    public BlockWidget getBlockWidget(InputBlock b) {
-        return blockMap.get(b);
-    }
-
     public void clearSelection() {
         for (BlockWidget w : selection) {
             w.setState(w.getState().deriveSelected(false));
@@ -141,7 +137,7 @@
     }
 
     public void selectionChanged() {
-        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
         if (p != null) {
             Set<InputNode> inputNodes = new HashSet<InputNode>();
             for (BlockWidget w : selection) {
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.form	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.form	Wed Jun 08 17:26:49 2011 +0200
@@ -3,6 +3,8 @@
 <Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java	Wed Jun 08 17:26:49 2011 +0200
@@ -25,6 +25,7 @@
 
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.util.LookupHistory;
 import java.awt.BorderLayout;
 import java.io.Serializable;
 import javax.swing.JScrollPane;
@@ -39,7 +40,7 @@
 import org.openide.windows.WindowManager;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
 final class ControlFlowTopComponent extends TopComponent implements LookupListener {
@@ -63,17 +64,7 @@
         this.add(panel, BorderLayout.CENTER);
     }
 
-    @Override
-    public void requestFocus() {
-        super.requestFocus();
-        scene.getView().requestFocus();
-    }
 
-    @Override
-    public boolean requestFocusInWindow() {
-        super.requestFocusInWindow();
-        return scene.getView().requestFocusInWindow();
-    }
 
     /** This method is called from within the constructor to
      * initialize the form.
@@ -96,6 +87,7 @@
     }// </editor-fold>//GEN-END:initComponents
     // Variables declaration - do not modify//GEN-BEGIN:variables
     // End of variables declaration//GEN-END:variables
+
     /**
      * Gets default instance. Do not use directly: reserved for *.settings files only,
      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
@@ -131,7 +123,7 @@
 
     @Override
     public void componentOpened() {
-        Lookup.Template tpl = new Lookup.Template(Object.class);
+        Lookup.Template tpl = new Lookup.Template(InputGraphProvider.class);
         result = Utilities.actionsGlobalContext().lookup(tpl);
         result.addLookupListener(this);
     }
@@ -143,16 +135,16 @@
     }
 
     public void resultChanged(LookupEvent lookupEvent) {
-
-        final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
         if (p != null) {
             SwingUtilities.invokeLater(new Runnable() {
+
                 public void run() {
-            InputGraph g = p.getGraph();
-            if (g != null) {
-                scene.setGraph(g);
-            }
-        }
+                    InputGraph g = p.getGraph();
+                    if (g != null) {
+                        scene.setGraph(g);
+                    }
+                }
             });
         }
     }
@@ -169,8 +161,8 @@
 
     @Override
     public void requestActive() {
-        scene.getView().requestFocusInWindow();
         super.requestActive();
+        scene.getView().requestFocus();
     }
 
     final static class ResolvableHelper implements Serializable {
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/HierarchicalGraphLayout.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/HierarchicalGraphLayout.java	Wed Jun 08 17:26:49 2011 +0200
@@ -35,6 +35,7 @@
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -137,9 +138,9 @@
     }
 
     protected void performGraphLayout(UniversalGraph<N, E> graph) {
-
-        Set<LinkWrapper> links = new HashSet<LinkWrapper>();
-        Set<VertexWrapper> vertices = new HashSet<VertexWrapper>();
+        
+        Set<LinkWrapper> links = new LinkedHashSet<LinkWrapper>();
+        Set<VertexWrapper> vertices = new LinkedHashSet<VertexWrapper>();
         Map<N, VertexWrapper> vertexMap = new HashMap<N, VertexWrapper>();
 
         for (N node : graph.getNodes()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/InputBlockEdge.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+import com.sun.hotspot.igv.data.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputBlockEdge {
+
+    private InputBlock from;
+    private InputBlock to;
+
+    public InputBlockEdge(InputBlock from, InputBlock to) {
+        assert from != null;
+        assert to != null;
+        this.from = from;
+        this.to = to;
+    }
+
+    public InputBlock getFrom() {
+        return from;
+    }
+
+    public InputBlock getTo() {
+        return to;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof InputBlockEdge && obj != null) {
+            InputBlockEdge e = (InputBlockEdge) obj;
+            return e.from.equals(from) && e.to.equals(to);
+        }
+        return super.equals(obj);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = from.hashCode();
+        hash = 59 * hash + to.hashCode();
+        return hash;
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -48,6 +48,14 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>org.netbeans.spi.quicksearch</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>org.openide.actions</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/Bundle.properties	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -5,3 +5,5 @@
 CTL_SomeAction=test
 HINT_OutlineTopComponent=This is a Outline window
 OpenIDE-Module-Name=Coordinator
+Toolbars/QuickSearch=Quick Search
+QuickSearch/Nodes/com-sun-hotspot-igv-coordinator-QuickSearch.instance=Nodes
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Wed Jun 08 17:26:49 2011 +0200
@@ -25,6 +25,7 @@
 
 import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
 import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.data.GraphDocument;
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.services.GroupOrganizer;
 import com.sun.hotspot.igv.data.InputGraph;
@@ -55,6 +56,11 @@
 
         private FolderNode parent;
         private List<Group> registeredGroups;
+        private GraphDocument document;
+
+        public FolderChildren(GraphDocument document) {
+            this.document = document;
+        }
 
         public void setParent(FolderNode parent) {
             this.parent = parent;
@@ -68,7 +74,7 @@
                 g.getChangedEvent().removeListener(this);
             }
             registeredGroups.clear();
-
+            
             Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0;
             if (p.getLeft().length() == 0) {
 
@@ -88,7 +94,7 @@
                 return result;
 
             } else {
-                return new Node[]{new FolderNode(p.getLeft(), parent.organizer, parent.subFolders, p.getRight())};
+                return new Node[]{new FolderNode(document, p.getLeft(), parent.organizer, parent.subFolders, p.getRight())};
             }
         }
 
@@ -96,13 +102,12 @@
         public void addNotify() {
             this.setKeys(parent.structure);
         }
-
+        
         public void changed(Group source) {
-            List<Pair<String, List<Group>>> newStructure = new ArrayList<Pair<String, List<Group>>>();
             for(Pair<String, List<Group>> p : parent.structure) {
                 refreshKey(p);
             }
-        }
+         }
     }
 
     protected InstanceContent getContent() {
@@ -114,11 +119,11 @@
         return Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.gif");
     }
 
-    protected FolderNode(String name, GroupOrganizer organizer, List<String> subFolders, List<Group> groups) {
-        this(name, organizer, subFolders, groups, new FolderChildren(), new InstanceContent());
+    protected FolderNode(GraphDocument document, String name, GroupOrganizer organizer, List<String> subFolders, List<Group> groups) {
+        this(document, name, organizer, subFolders, groups, new FolderChildren(document), new InstanceContent());
     }
 
-    private FolderNode(String name, GroupOrganizer organizer, List<String> oldSubFolders, final List<Group> groups, FolderChildren children, InstanceContent content) {
+    private FolderNode(final GraphDocument document, String name, GroupOrganizer organizer, List<String> oldSubFolders, final List<Group> groups, FolderChildren children, InstanceContent content) {
         super(children, new AbstractLookup(content));
         children.setParent(this);
         this.content = content;
@@ -127,9 +132,8 @@
 
             public void remove() {
                 for (Group g : groups) {
-                    if (g.getDocument() != null) {
-                        g.getDocument().removeGroup(g);
-                    }
+                    document.removeGroup(g);
+                    
                 }
             }
         });
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphCountGroupOrganizer.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphCountGroupOrganizer.java	Wed Jun 08 17:26:49 2011 +0200
@@ -49,7 +49,7 @@
         List<Pair<String, List<Group>>> result = new ArrayList<Pair<String, List<Group>>>();
 
         if (subFolders.size() == 0) {
-            Map<Integer, List<Group>> map = new HashMap<Integer, List<Group>>();
+            Map<Integer, List<Group>> map = new HashMap<Integer, List<Group>>(groups.size());
             for (Group g : groups) {
                 Integer cur = g.getGraphs().size();
                 if (!map.containsKey(cur)) {
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphNode.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphNode.java	Wed Jun 08 17:26:49 2011 +0200
@@ -27,8 +27,8 @@
 import com.sun.hotspot.igv.coordinator.actions.DiffGraphCookie;
 import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
 import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.data.services.GraphViewer;
-import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import com.sun.hotspot.igv.util.PropertiesSheet;
 import java.awt.Image;
 import javax.swing.Action;
@@ -36,7 +36,6 @@
 import org.openide.cookies.OpenCookie;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
-import org.openide.nodes.Node;
 import org.openide.nodes.Sheet;
 import org.openide.util.Lookup;
 import org.openide.util.Utilities;
@@ -81,12 +80,19 @@
                 graph.getGroup().removeGraph(graph);
             }
         });
+
+        // Action for diffing to the current graph
+        content.add(new DiffGraphCookie(graph));
     }
 
     @Override
     protected Sheet createSheet() {
         Sheet s = super.createSheet();
-        PropertiesSheet.initializeSheet(graph.getProperties(), s);
+        Properties p = new Properties();
+        p.add(graph.getProperties());
+        p.setProperty("nodeCount", Integer.toString(graph.getNodes().size()));
+        p.setProperty("edgeCount", Integer.toString(graph.getEdges().size()));
+        PropertiesSheet.initializeSheet(p, s);
         return s;
     }
 
@@ -101,24 +107,6 @@
     }
 
     @Override
-    public <T extends Node.Cookie> T getCookie(Class<T> aClass) {
-        if (aClass == DiffGraphCookie.class) {
-            InputGraphProvider graphProvider = Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
-
-            InputGraph graphA = null;
-            if (graphProvider != null) {
-                graphA = graphProvider.getGraph();
-            }
-
-            if (graphA != null && !graphA.isDifferenceGraph()) {
-                return (T) new DiffGraphCookie(graphA, graph);
-            }
-        }
-
-        return super.getCookie(aClass);
-    }
-
-    @Override
     public Action[] getActions(boolean b) {
         return new Action[]{(Action) DiffGraphAction.findObject(DiffGraphAction.class, true), (Action) OpenAction.findObject(OpenAction.class, true)};
     }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.form	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.form	Wed Jun 08 17:26:49 2011 +0200
@@ -3,6 +3,8 @@
 <Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
@@ -23,7 +25,7 @@
 
       <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
       <SubComponents>
-        <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+        <Container class="javax.swing.JScrollPane" name="treeView">
           <AuxValues>
             <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BeanTreeView();"/>
           </AuxValues>
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java	Wed Jun 08 17:26:49 2011 +0200
@@ -62,7 +62,7 @@
 import org.openide.windows.WindowManager;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
 public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener {
@@ -89,9 +89,9 @@
     private void initListView() {
         manager = new ExplorerManager();
         organizer = new StandardGroupOrganizer();
-        root = new FolderNode("", organizer, new ArrayList<String>(), document.getGroups());
+        root = new FolderNode(document, "", organizer, new ArrayList<String>(), document.getGroups());
         manager.setRootContext(root);
-        ((BeanTreeView) this.jScrollPane1).setRootVisible(false);
+        ((BeanTreeView) this.treeView).setRootVisible(false);
 
         document.getChangedEvent().addListener(new ChangedListener<GraphDocument>() {
 
@@ -122,8 +122,6 @@
         for (Toolbar tb : ToolbarPool.getDefault().getToolbars()) {
             tb.setVisible(false);
         }
-
-        initOrganizers();
     }
 
     public void setOrganizer(GroupOrganizer organizer) {
@@ -131,10 +129,6 @@
         updateStructure();
     }
 
-    private void initOrganizers() {
-
-    }
-
     private void initReceivers() {
 
         final GroupCallback callback = new GroupCallback() {
@@ -221,6 +215,24 @@
         return PREFERRED_ID;
     }
 
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        treeView.requestFocus();
+    }
+
+    @Override
+    public boolean requestFocus(boolean temporary) {
+        treeView.requestFocus();
+        return super.requestFocus(temporary);
+    }
+
+    @Override
+    protected boolean requestFocusInWindow(boolean temporary) {
+        treeView.requestFocus();
+        return super.requestFocusInWindow(temporary);
+    }
+
     public void resultChanged(LookupEvent lookupEvent) {
     }
 
@@ -228,7 +240,7 @@
     public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException {
         // Not called when user starts application for the first time
         super.readExternal(objectInput);
-        ((BeanTreeView) this.jScrollPane1).setRootVisible(false);
+        ((BeanTreeView) this.treeView).setRootVisible(false);
     }
 
     @Override
@@ -254,18 +266,18 @@
     private void initComponents() {
 
         jPanel2 = new javax.swing.JPanel();
-        jScrollPane1 = new BeanTreeView();
+        treeView = new BeanTreeView();
 
         setLayout(new java.awt.BorderLayout());
 
         jPanel2.setLayout(new java.awt.BorderLayout());
-        jPanel2.add(jScrollPane1, java.awt.BorderLayout.CENTER);
+        jPanel2.add(treeView, java.awt.BorderLayout.CENTER);
 
         add(jPanel2, java.awt.BorderLayout.CENTER);
     }// </editor-fold>//GEN-END:initComponents
 
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JPanel jPanel2;
-    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JScrollPane treeView;
     // End of variables declaration//GEN-END:variables
 }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -5,6 +5,7 @@
         <Toolbar name="Edit" position="1" visible="false"/>
         <Toolbar name="File" position="1" visible="false" />
         <Toolbar name="Memory" position="1" visible="false" />
+        <Toolbar name="QuickSearch" position="1" visible="true" />
     </Row>
     <Row>
         <Toolbar name="WorkspaceSwitcher" />
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardGroupOrganizer.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardGroupOrganizer.java	Wed Jun 08 17:26:49 2011 +0200
@@ -50,10 +50,15 @@
             for (Group g : groups) {
                 List<Group> children = new ArrayList<Group>();
                 children.add(g);
-                Pair<String, List<Group>> p = new Pair<String, List<Group>>();
-                p.setLeft(g.getName());
-                p.setRight(children);
-                result.add(p);
+                if(g.getGraphs().size() == 1) {
+                    //g.getGraphs().get(0).setName(g.getName() + " / " + g.getGraphs().get(0).getName());
+                    result.add(new Pair<String, List<Group>>("", children));
+                } else {
+                    Pair<String, List<Group>> p = new Pair<String, List<Group>>();
+                    p.setLeft(g.getName());
+                    p.setRight(children);
+                    result.add(p);
+                }
             }
         }
 
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/Bundle.properties	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -1,18 +1,9 @@
-CTL_EditFilterAction=Edit...
 CTL_ImportAction=Open...
 CTL_OpenGraphAction=View graph
 CTL_DiffGraphAction=Difference to current graph
 CTL_RemoveAction=Remove methods
-CTL_ApplyFilterAction=Apply
-CTL_FilterAction=Open Filter Window
-CTL_AppliedFilterAction=Open AppliedFilter Window
-CTL_OutlineAction=Open Outline Window
-CTL_MoveFilterUpAction=Move upwards
-CTL_MoveFilterDownAction=Move downwards
-CTL_RemoveFilterAction=Remove
-CTL_RemoveFilterSettingsAction=Remove filter setting
+CTL_OutlineAction=Open Outline Window 
 CTL_SaveAsAction=Save selected methods...
 CTL_SaveAllAction=Save all...
-CTL_SaveFilterSettingsAction=Save filter settings...
-CTL_PropertiesAction=Open Properties Window
+CTL_PropertiesAction=Open Properties Window 
 CTL_NewFilterAction=New filter...
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphAction.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphAction.java	Wed Jun 08 17:26:49 2011 +0200
@@ -37,6 +37,7 @@
 
     protected void performAction(Node[] activatedNodes) {
         DiffGraphCookie c = activatedNodes[0].getCookie(DiffGraphCookie.class);
+        assert c != null;
         c.openDiff();
     }
 
@@ -44,6 +45,19 @@
         return CookieAction.MODE_EXACTLY_ONE;
     }
 
+    @Override
+    protected boolean enable(Node[] activatedNodes) {
+        boolean b = super.enable(activatedNodes);
+        if (b) {
+            assert activatedNodes.length == 1;
+            DiffGraphCookie c = activatedNodes[0].getCookie(DiffGraphCookie.class);
+            assert c != null;
+            return c.isPossible();
+        }
+
+        return false;
+    }
+
     public String getName() {
         return NbBundle.getMessage(DiffGraphAction.class, "CTL_DiffGraphAction");
     }
@@ -68,3 +82,4 @@
         return false;
     }
 }
+
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphCookie.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphCookie.java	Wed Jun 08 17:26:49 2011 +0200
@@ -26,9 +26,12 @@
 
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.services.GraphViewer;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import com.sun.hotspot.igv.difference.Difference;
+import com.sun.hotspot.igv.util.LookupHistory;
 import org.openide.nodes.Node;
 import org.openide.util.Lookup;
+import org.openide.util.Utilities;
 
 /**
  *
@@ -37,19 +40,31 @@
 public class DiffGraphCookie implements Node.Cookie {
 
     private InputGraph a;
-    private InputGraph b;
+
+    public DiffGraphCookie(InputGraph a) {
+        this.a = a;
+    }
 
-    public DiffGraphCookie(InputGraph a, InputGraph b) {
-        this.a = a;
-        this.b = b;
+    private InputGraph getCurrentGraph() {
+        
+        InputGraphProvider graphProvider = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
+        if (graphProvider != null) {
+            return graphProvider.getGraph();
+        }
+
+        return null;
+    }
+
+    public boolean isPossible() {
+        return getCurrentGraph() != null;
     }
 
     public void openDiff() {
-
+        
         final GraphViewer viewer = Lookup.getDefault().lookup(GraphViewer.class);
-
+        InputGraph other = getCurrentGraph();
         if(viewer != null) {
-            InputGraph diffGraph = Difference.createDiffGraph(a, b);
+            InputGraph diffGraph = Difference.createDiffGraph(other, a);
             viewer.view(diffGraph);
         }
     }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -12,7 +12,7 @@
     <attr name="Actions\Edit\org-openide-actions-RedoAction.instance\position" intvalue="1900"/>
     <attr name="Actions\Edit\org-openide-actions-ReplaceAction.instance\position" intvalue="2000"/>
     <attr name="Actions\Edit\org-openide-actions-UndoAction.instance\position" intvalue="2100"/>
-
+    
     <folder name="Actions">
         <folder name="File">
             <file name="com-sun-hotspot-igv-coordinator-actions-SaveAsAction.instance">
@@ -26,7 +26,7 @@
             </file>
         </folder>
         <folder name="Edit">
-
+            
             <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance">
                 <attr name="position" intvalue="1200"/>
             </file>
@@ -57,7 +57,7 @@
                 <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
                 <attr name="position" intvalue="500"/>
             </file>
-
+            
             <file name="org-netbeans-modules-openfile-OpenFileAction.instance_hidden"/>
             <file name="org-openide-actions-PageSetupAction.instance_hidden"/>
             <file name="org-openide-actions-PrintAction.instance_hidden"/>
@@ -98,13 +98,22 @@
         </folder>
     </folder>
     <folder name="Toolbars">
-        <file name="Standard.xml" url="StandardConfiguration.xml"/>
+        
+        <folder name="QuickSearch">
+            <attr name="SystemFileSystem.localizingBundle" stringvalue="com.sun.hotspot.igv.coordinator.Bundle"/>
+            <file name="org-netbeans-modules-quicksearch-QuickSearchAction.shadow">
+                <attr name="originalFile"
+                stringvalue="Actions/Edit/org-netbeans-modules-quicksearch-QuickSearchAction.instance"/>
+            </file>
+        </folder>
+        <!--<file name="Standard.xml" url="StandardConfiguration.xml"/>-->
+
     </folder>
     <folder name="Windows2">
         <folder name="Components">
             <file name="OutlineTopComponent.settings" url="OutlineTopComponentSettings.xml"/>
         </folder>
-        <folder name="Modes">
+        <folder name="Modes">  
             <file name="customLeft.wsmode" url="customLeftWsmode.xml"/>
             <folder name="customLeft">
                 <file name="OutlineTopComponent.wstcref" url="OutlineTopComponentWstcref.xml"/>
--- a/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.properties	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -1,2 +1,8 @@
 javac.source=1.5
 javac.compilerargs=-Xlint -Xlint:-serial
+src.dir=src
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+test.src.dir=test
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
--- a/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -6,6 +6,19 @@
             <code-name-base>com.sun.hotspot.igv.data</code-name-base>
             <suite-component/>
             <module-dependencies/>
+            <test-dependencies>
+                <test-type>
+                    <name>unit</name>
+                    <test-dependency>
+                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
+                        <compile-dependency/>
+                    </test-dependency>
+                    <test-dependency>
+                        <code-name-base>org.openide.util</code-name-base>
+                        <compile-dependency/>
+                    </test-dependency>
+                </test-type>
+            </test-dependencies>
             <public-packages>
                 <package>com.sun.hotspot.igv.data</package>
                 <package>com.sun.hotspot.igv.data.serialization</package>
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java	Wed Jun 08 17:26:49 2011 +0200
@@ -24,16 +24,17 @@
 package com.sun.hotspot.igv.data;
 
 /**
- *
+ * Class representing a generic changed event.
  * @author Thomas Wuerthinger
+ * @param <T>
  */
 public class ChangedEvent<T> extends Event<ChangedListener<T>> {
 
     private T object;
 
-    public ChangedEvent() {
-    }
-
+    /**
+     * Creates a new event with the specific object as the one for which the event gets fired.
+     */
     public ChangedEvent(T object) {
         this.object = object;
     }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEventProvider.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEventProvider.java	Wed Jun 08 17:26:49 2011 +0200
@@ -25,10 +25,14 @@
 package com.sun.hotspot.igv.data;
 
 /**
- *
+ * Provides a changed event object.
  * @author Thomas Wuerthinger
+ * @param <T> Class for which the changed event fires.
  */
 public interface ChangedEventProvider<T> {
 
-    public ChangedEvent<T> getChangedEvent();
+    /**
+     * Returns the changed event object. Should always return the same instance.
+     */
+    ChangedEvent<T> getChangedEvent();
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedListener.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedListener.java	Wed Jun 08 17:26:49 2011 +0200
@@ -24,10 +24,15 @@
 package com.sun.hotspot.igv.data;
 
 /**
- *
+ * Listens to changed events.
  * @author Thomas Wuerthinger
+ * @param <T> Class for which the changed event fires.
  */
 public interface ChangedListener<T> {
 
-    public void changed(T source);
+    /**
+     * This method is called everytime a changed event is fired.
+     * @param source Object that has changed.
+     */
+    void changed(T source);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ControllableChangedListener.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class ControllableChangedListener<T> implements ChangedListener<T>{
+
+	private boolean enabled;
+
+	
+	public ControllableChangedListener() {
+		enabled = true;
+	}
+
+	public boolean isEnabled() {
+		return enabled;
+	}
+
+	public void setEnabled(boolean b) {
+		enabled = b;
+	}
+
+	public void changed(T source) {
+		if(enabled) {
+			filteredChanged(source);
+		}
+	}
+
+	public abstract void filteredChanged(T source);
+}
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Event.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Event.java	Wed Jun 08 17:26:49 2011 +0200
@@ -33,25 +33,50 @@
 public abstract class Event<L> {
 
     private List<L> listener;
-
+    private boolean fireEvents;
+    private boolean eventWasFired;
+    
     public Event() {
         listener = new ArrayList<L>();
+        fireEvents = true;
     }
 
     public void addListener(L l) {
         listener.add(l);
     }
 
-    public void removeListener(L l) {
+    /**
+     * Remove listener
+     * @param l
+     */
+    public void removeListener(final L l) {
         listener.remove(l);
     }
 
     public void fire() {
-        List<L> tmpList = new ArrayList<L>(listener);
-        for (L l : tmpList) {
-            fire(l);
+        if(fireEvents) {
+            List<L> tmpList = new ArrayList<L>(listener);
+            for (L l : tmpList) {
+                fire(l);
+            }
+        } else {
+            eventWasFired = true;
         }
     }
 
+    public void beginAtomic() {
+        assert fireEvents : "endAtomic has to be called before another beginAtomic may be called";
+        this.fireEvents = false;
+        this.eventWasFired = false;
+    }
+
+    public void endAtomic() {
+        assert !fireEvents : "beginAtomic has to be called first";
+        this.fireEvents = true;
+        if(eventWasFired) {
+            fire();
+        }
+    }
+    
     protected abstract void fire(L l);
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Wed Jun 08 17:26:49 2011 +0200
@@ -55,14 +55,12 @@
     }
 
     public void addGroup(Group group) {
-        group.setDocument(this);
         groups.add(group);
         getChangedEvent().fire();
     }
 
     public void removeGroup(Group group) {
         if (groups.contains(group)) {
-            group.setDocument(null);
             groups.remove(group);
             getChangedEvent().fire();
         }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,10 +23,6 @@
  */
 package com.sun.hotspot.igv.data;
 
-import com.sun.hotspot.igv.data.ChangedEvent;
-import com.sun.hotspot.igv.data.ChangedEventProvider;
-import com.sun.hotspot.igv.data.Properties;
-import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
@@ -40,18 +36,17 @@
 public class Group extends Properties.Entity implements ChangedEventProvider<Group> {
 
     private List<InputGraph> graphs;
-    private transient ChangedEvent<Group> changedEvent;
-    private GraphDocument document;
     private InputMethod method;
     private String assembly;
+    private transient ChangedEvent<Group> changedEvent;
 
     public Group() {
         graphs = new ArrayList<InputGraph>();
-        init();
-    }
+        changedEvent = new ChangedEvent<Group>(this);
 
-    private void init() {
-        changedEvent = new ChangedEvent<Group>(this);
+        // Ensure that name and type are never null
+        getProperties().setProperty("name", "");
+        getProperties().setProperty("type", "");
     }
 
     public void fireChangedEvent() {
@@ -74,14 +69,6 @@
         return method;
     }
 
-    void setDocument(GraphDocument document) {
-        this.document = document;
-    }
-
-    public GraphDocument getDocument() {
-        return document;
-    }
-
     public ChangedEvent<Group> getChangedEvent() {
         return changedEvent;
     }
@@ -90,11 +77,15 @@
         return Collections.unmodifiableList(graphs);
     }
 
-    public void addGraph(InputGraph g) {
-        assert g != null;
-        assert !graphs.contains(g);
+    public InputGraph addGraph(String name) {
+        return addGraph(name, null);
+    }
+
+    public InputGraph addGraph(String name, Pair<InputGraph, InputGraph> pair) {
+        InputGraph g = new InputGraph(graphs.size(), this, name, pair);
         graphs.add(g);
         changedEvent.fire();
+        return g;
     }
 
     public void removeGraph(InputGraph g) {
@@ -110,20 +101,10 @@
         for (InputGraph g : graphs) {
             Set<Integer> ids = g.getNodesAsSet();
             result.addAll(g.getNodesAsSet());
-            for (Integer i : ids) {
-                result.add(-i);
-            }
         }
         return result;
     }
 
-    public InputGraph getLastAdded() {
-        if (graphs.size() == 0) {
-            return null;
-        }
-        return graphs.get(graphs.size() - 1);
-    }
-
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -138,4 +119,8 @@
     public String getName() {
         return getProperties().get("name");
     }
+
+    public String getType() {
+        return getProperties().get("type");
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,10 +23,10 @@
  */
 package com.sun.hotspot.igv.data;
 
-import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -37,46 +37,57 @@
 public class InputBlock {
 
     private List<InputNode> nodes;
-    private List<String> successorNames;
     private String name;
     private InputGraph graph;
-    private Rectangle bounds;
     private Set<InputBlock> successors;
-    private Set<InputBlock> predecessors;
-    private Set<InputBlockEdge> inputs;
-    private Set<InputBlockEdge> outputs;
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+
+        if (o == this) {
+            return true;
+        }
 
-    public InputBlock(InputGraph graph, String name) {
+        if (o == null || (!(o instanceof InputBlock))) {
+            return false;
+        }
+        
+        final InputBlock b = (InputBlock)o;
+        final boolean result = b.nodes.equals(nodes) && b.name.equals(name) && b.successors.size() == successors.size();
+        if (!result) {
+            return false;
+        }
+
+        final HashSet<String> s = new HashSet<String>();
+        for (InputBlock succ : successors) {
+            s.add(succ.name);
+        }
+
+        for (InputBlock succ : b.successors) {
+            if (!s.contains(succ.name)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    InputBlock(InputGraph graph, String name) {
         this.graph = graph;
         this.name = name;
         nodes = new ArrayList<InputNode>();
-        successorNames = new ArrayList<String>();
-        successors = new HashSet<InputBlock>();
-        predecessors = new HashSet<InputBlock>();
-        inputs = new HashSet<InputBlockEdge>();
-        outputs = new HashSet<InputBlockEdge>();
-    }
-
-    public void removeSuccessor(InputBlock b) {
-        if (successors.contains(b)) {
-            successors.remove(b);
-            b.predecessors.remove(this);
-            InputBlockEdge e = new InputBlockEdge(this, b);
-            assert outputs.contains(e);
-            outputs.remove(e);
-            assert b.inputs.contains(e);
-            b.inputs.remove(e);
-        }
+        successors = new LinkedHashSet<InputBlock>(2);
     }
 
     public String getName() {
         return name;
     }
 
-    public void setName(String s) {
-        name = s;
-    }
-
     public List<InputNode> getNodes() {
         return Collections.unmodifiableList(nodes);
     }
@@ -85,56 +96,24 @@
         InputNode n = graph.getNode(id);
         assert n != null;
         graph.setBlock(n, this);
-        addNode(graph.getNode(id));
-    }
-
-    public void addNode(InputNode node) {
+        final InputNode node = graph.getNode(id);
+        assert node != null;
         assert !nodes.contains(node);
         nodes.add(node);
     }
 
-    public Set<InputBlock> getPredecessors() {
-        return Collections.unmodifiableSet(predecessors);
-    }
-
     public Set<InputBlock> getSuccessors() {
         return Collections.unmodifiableSet(successors);
     }
 
-    public Set<InputBlockEdge> getInputs() {
-        return Collections.unmodifiableSet(inputs);
-    }
-
-    public Set<InputBlockEdge> getOutputs() {
-        return Collections.unmodifiableSet(outputs);
-    }
-
-    // resolveBlockLinks must be called afterwards
-    public void addSuccessor(String name) {
-        successorNames.add(name);
+    @Override
+    public String toString() {
+        return "Block " + this.getName();
     }
 
-    public void resolveBlockLinks() {
-        for (String s : successorNames) {
-            InputBlock b = graph.getBlock(s);
-            addSuccessor(b);
-        }
-
-        successorNames.clear();
-    }
-
-    public void addSuccessor(InputBlock b) {
+    void addSuccessor(InputBlock b) {
         if (!successors.contains(b)) {
             successors.add(b);
-            b.predecessors.add(this);
-            InputBlockEdge e = new InputBlockEdge(this, b);
-            outputs.add(e);
-            b.inputs.add(e);
         }
     }
-
-    @Override
-    public String toString() {
-        return this.getName();
-    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlockEdge.java	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.data;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class InputBlockEdge {
-
-    private InputBlock from;
-    private InputBlock to;
-
-    public InputBlockEdge(InputBlock from, InputBlock to) {
-        assert from != null;
-        assert to != null;
-        this.from = from;
-        this.to = to;
-    }
-
-    public InputBlock getFrom() {
-        return from;
-    }
-
-    public InputBlock getTo() {
-        return to;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (obj instanceof InputBlockEdge && obj != null) {
-            InputBlockEdge e = (InputBlockEdge) obj;
-            return e.from.equals(from) && e.to.equals(to);
-        }
-        return super.equals(obj);
-    }
-
-    @Override
-    public int hashCode() {
-        int hash = from.hashCode();
-        hash = 59 * hash + to.hashCode();
-        return hash;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,6 +23,8 @@
  */
 package com.sun.hotspot.igv.data;
 
+import java.util.Comparator;
+
 /**
  *
  * @author Thomas Wuerthinger
@@ -35,15 +37,41 @@
         NEW,
         DELETED
     }
+    
+    public static final Comparator<InputEdge> OUTGOING_COMPARATOR = new Comparator<InputEdge>(){
+
+            public int compare(InputEdge o1, InputEdge o2) {
+                if(o1.getFromIndex() == o2.getFromIndex()) {
+                    return o1.getTo() - o2.getTo();
+                }
+                return o1.getFromIndex() - o2.getFromIndex();
+            }
+    };
+    
+    
+    public static final Comparator<InputEdge> INGOING_COMPARATOR = new Comparator<InputEdge>(){
+
+            public int compare(InputEdge o1, InputEdge o2) {
+                if(o1.getToIndex() == o2.getToIndex()) {
+                    return o1.getFrom() - o2.getFrom();
+                }
+                return o1.getToIndex() - o2.getToIndex();
+            }
+    };
+        
+    private char toIndex;
     private char fromIndex;
-    private char toIndex;
     private int from;
     private int to;
     private State state;
+    
+    public InputEdge(char toIndex, int from, int to) {
+        this((char)0, toIndex, from, to);
+    }
 
     public InputEdge(char fromIndex, char toIndex, int from, int to) {
+        this.toIndex = toIndex;
         this.fromIndex = fromIndex;
-        this.toIndex = toIndex;
         this.from = from;
         this.to = to;
         this.state = State.SAME;
@@ -57,14 +85,14 @@
         this.state = x;
     }
 
+    public char getToIndex() {
+        return toIndex;
+    }
+    
     public char getFromIndex() {
         return fromIndex;
     }
 
-    public char getToIndex() {
-        return toIndex;
-    }
-
     public String getName() {
         return "in" + toIndex;
     }
@@ -83,16 +111,16 @@
             return false;
         }
         InputEdge conn2 = (InputEdge) o;
-        return conn2.toIndex == toIndex && conn2.from == from && conn2.to == to;
+        return conn2.fromIndex == fromIndex && conn2.toIndex == toIndex && conn2.from == from && conn2.to == to;
     }
 
     @Override
     public String toString() {
-        return "Edge from " + from + " to " + to + "(" + (int) toIndex + ") ";
+        return "Edge from " + from + " to " + to + "(" + (int) fromIndex + ", " + (int) toIndex + ") ";
     }
 
     @Override
     public int hashCode() {
-        return (from << 20 | to << 8 | toIndex);
+        return (from << 20 | to << 8 | toIndex << 4 | fromIndex);
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Wed Jun 08 17:26:49 2011 +0200
@@ -26,9 +26,12 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashMap;
 import java.util.HashSet;
-import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 
 /**
@@ -37,51 +40,129 @@
  */
 public class InputGraph extends Properties.Entity {
 
-    private HashMap<Integer, InputNode> nodes;
+    private LinkedHashMap<Integer, InputNode> nodes;
     private ArrayList<InputEdge> edges;
     private Group parent;
-    private HashMap<String, InputBlock> blocks;
-    private HashMap<Integer, InputBlock> nodeToBlock;
-    private boolean isDifferenceGraph;
+    private LinkedHashMap<String, InputBlock> blocks;
+    private LinkedHashMap<Integer, InputBlock> nodeToBlock;
+    private Pair<InputGraph, InputGraph> sourceGraphs;
+    private int parentIndex;
 
-    public InputGraph(Group parent) {
-        this(parent, null);
+    InputGraph(int parentIndex, Group parent, String name, Pair<InputGraph, InputGraph> sourceGraphs) {
+        this.parentIndex = parentIndex;
+        this.parent = parent;
+        this.sourceGraphs = sourceGraphs;
+        setName(name);
+        nodes = new LinkedHashMap<Integer, InputNode>();
+        edges = new ArrayList<InputEdge>();
+        blocks = new LinkedHashMap<String, InputBlock>();
+        nodeToBlock = new LinkedHashMap<Integer, InputBlock>();
+    }
+
+    public void addBlockConnection(InputBlock left, InputBlock right) {
+        left.addSuccessor(right);
     }
 
-    public InputGraph(Group parent, InputGraph last) {
-        this(parent, last, "");
+    public Pair<InputGraph, InputGraph> getSourceGraphs() {
+        return sourceGraphs;
+    }
+    
+    public List<InputNode> findRootNodes() {
+        List<InputNode> result = new ArrayList<InputNode>();
+        Set<Integer> nonRoot = new HashSet<Integer>();
+        for(InputEdge curEdges : getEdges()) {
+            nonRoot.add(curEdges.getTo());
+        }
+        
+        for(InputNode node : getNodes()) {
+            if(!nonRoot.contains(node.getId())) {
+                result.add(node);
+            }
+        }
+        
+        return result;
+    }
+    
+    public Map<InputNode, List<InputEdge>> findAllOutgoingEdges() {
+        
+        Map<InputNode, List<InputEdge>> result = new HashMap<InputNode, List<InputEdge>>(getNodes().size());
+        for(InputNode n : this.getNodes()) {
+            result.put(n, new ArrayList<InputEdge>());
+        }
+        
+        for(InputEdge e : this.edges) {
+            int from = e.getFrom();
+            InputNode fromNode = this.getNode(from);
+            List<InputEdge> fromList = result.get(fromNode);
+            assert fromList != null;
+            fromList.add(e);
+        }
+        
+        for(InputNode n : this.getNodes()) {
+            List<InputEdge> list = result.get(n);
+            Collections.sort(list, InputEdge.OUTGOING_COMPARATOR);
+        }
+        
+        return result;
+    }
+    
+    public Map<InputNode, List<InputEdge>> findAllIngoingEdges() {
+        
+        Map<InputNode, List<InputEdge>> result = new HashMap<InputNode, List<InputEdge>>(getNodes().size());
+        for(InputNode n : this.getNodes()) {
+            result.put(n, new ArrayList<InputEdge>());
+        }
+        
+        for(InputEdge e : this.edges) {
+            int to = e.getTo();
+            InputNode toNode = this.getNode(to);
+            List<InputEdge> toList = result.get(toNode);
+            assert toList != null;
+            toList.add(e);
+        }
+        
+        for(InputNode n : this.getNodes()) {
+            List<InputEdge> list = result.get(n);
+            Collections.sort(list, InputEdge.INGOING_COMPARATOR);
+        }
+        
+        return result;
+    }
+    
+    public List<InputEdge> findOutgoingEdges(InputNode n) {
+        List<InputEdge> result = new ArrayList<InputEdge>();
+        
+        for(InputEdge e : this.edges) {
+            if(e.getFrom() == n.getId()) {
+                result.add(e);
+            }
+        }
+        
+        Collections.sort(result, InputEdge.OUTGOING_COMPARATOR);
+        
+        return result;
     }
 
-    private void clearBlocks() {
+    public void clearBlocks() {
         blocks.clear();
         nodeToBlock.clear();
     }
-
-    public InputGraph(Group parent, InputGraph last, String name) {
-        this.parent = parent;
-        setName(name);
-        nodes = new HashMap<Integer, InputNode>();
-        edges = new ArrayList<InputEdge>();
-        blocks = new HashMap<String, InputBlock>();
-        nodeToBlock = new HashMap<Integer, InputBlock>();
-        if (last != null) {
-
-            for (InputNode n : last.getNodes()) {
-                addNode(n);
-            }
-
-            for (InputEdge c : last.getEdges()) {
-                addEdge(c);
-            }
+    
+    public void setEdge(int fromIndex, int toIndex, int from, int to) {
+        assert fromIndex == ((char)fromIndex) : "Downcast must be safe";
+        assert toIndex == ((char)toIndex) : "Downcast must be safe";
+        
+        InputEdge edge = new InputEdge((char)fromIndex, (char)toIndex, from, to);
+        if(!this.getEdges().contains(edge)) {
+            this.addEdge(edge);
         }
     }
 
-    public void schedule(Collection<InputBlock> newBlocks) {
-        clearBlocks();
-        InputBlock noBlock = new InputBlock(this, "no block");
+    public void ensureNodesInBlocks() {
+        InputBlock noBlock = null;
         Set<InputNode> scheduledNodes = new HashSet<InputNode>();
 
-        for (InputBlock b : newBlocks) {
+        for (InputBlock b : getBlocks()) {
             for (InputNode n : b.getNodes()) {
                 assert !scheduledNodes.contains(n);
                 scheduledNodes.add(n);
@@ -91,17 +172,13 @@
         for (InputNode n : this.getNodes()) {
             assert nodes.get(n.getId()) == n;
             if (!scheduledNodes.contains(n)) {
+                if (noBlock == null) {
+                    noBlock = this.addBlock("no block");
+                }
                 noBlock.addNode(n.getId());
             }
         }
 
-        if (noBlock.getNodes().size() != 0) {
-            newBlocks.add(noBlock);
-        }
-        for (InputBlock b : newBlocks) {
-            addBlock(b);
-        }
-
         for (InputNode n : this.getNodes()) {
             assert this.getBlock(n) != null;
         }
@@ -116,47 +193,37 @@
     }
 
     public InputBlock getBlock(InputNode node) {
+        assert nodes.containsKey(node.getId());
+        assert nodes.get(node.getId()).equals(node);
         return getBlock(node.getId());
     }
 
     public InputGraph getNext() {
         List<InputGraph> list = parent.getGraphs();
-        if (!list.contains(this)) {
-            return null;
-        }
-        int index = list.indexOf(this);
-        if (index == list.size() - 1) {
+        if (parentIndex == list.size() - 1) {
             return null;
         } else {
-            return list.get(index + 1);
+            return list.get(parentIndex + 1);
         }
     }
 
     public InputGraph getPrev() {
         List<InputGraph> list = parent.getGraphs();
-        if (!list.contains(this)) {
-            return null;
-        }
-        int index = list.indexOf(this);
-        if (index == 0) {
+        if (parentIndex == 0) {
             return null;
         } else {
-            return list.get(index - 1);
+            return list.get(parentIndex - 1);
         }
     }
 
+    private void setName(String name) {
+        this.getProperties().setProperty("name", name);
+    }
+
     public String getName() {
         return getProperties().get("name");
     }
 
-    public String getAbsoluteName() {
-        String result = getName();
-        if (this.parent != null) {
-            result = parent.getName() + ": " + result;
-        }
-        return result;
-    }
-
     public Collection<InputNode> getNodes() {
         return Collections.unmodifiableCollection(nodes.values());
     }
@@ -192,8 +259,11 @@
     }
 
     public void addEdge(InputEdge c) {
-        assert !edges.contains(c);
-        edges.add(c);
+        
+        // Be tolerant with duplicated edges.
+        if(!edges.contains(c)) {
+            edges.add(c);
+        }
         assert edges.contains(c);
     }
 
@@ -214,35 +284,22 @@
             sb.append(c.toString());
             sb.append("\n");
         }
+
+        for (InputBlock b : getBlocks()) {
+            sb.append(b.toString());
+            sb.append("\n");
+        }
+
         return sb.toString();
     }
 
-    public void addBlock(InputBlock b) {
+    public InputBlock addBlock(String name) {
+        final InputBlock b = new InputBlock(this, name);
         blocks.put(b.getName(), b);
-        for (InputNode n : b.getNodes()) {
-            this.nodeToBlock.put(n.getId(), b);
-        }
-    }
-
-    public void resolveBlockLinks() {
-        for (InputBlock b : blocks.values()) {
-            b.resolveBlockLinks();
-        }
-    }
-
-    public void setName(String s) {
-        getProperties().setProperty("name", s);
+        return b;
     }
 
     public InputBlock getBlock(String s) {
         return blocks.get(s);
     }
-
-    public boolean isDifferenceGraph() {
-        return this.isDifferenceGraph;
-    }
-
-    public void setIsDifferenceGraph(boolean b) {
-        isDifferenceGraph = b;
-    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,7 +23,6 @@
  */
 package com.sun.hotspot.igv.data;
 
-import com.sun.hotspot.igv.data.Properties;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -42,6 +41,29 @@
     private Group group;
     private List<InputBytecode> bytecodes;
 
+    @Override
+    public int hashCode() {
+        int result = name.hashCode();
+        result = result * 31 + bci;
+        result = result * 31 + shortName.hashCode();
+        result = result * 31 + inlined.hashCode();
+        result = result * 31 + bytecodes.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || (!(o instanceof InputMethod))) {
+            return false;
+        }
+
+        final InputMethod im = (InputMethod)o;
+        return name.equals(im.name) && bci == im.bci && shortName.equals(im.shortName) &&
+               inlined.equals(im.inlined) && bytecodes.equals(im.bytecodes);
+    }
+
+
+
     /** Creates a new instance of InputMethod */
     public InputMethod(Group parent, String name, String shortName, int bci) {
         this.group = parent;
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,6 +23,8 @@
  */
 package com.sun.hotspot.igv.data;
 
+import java.util.Comparator;
+
 /**
  *
  * @author Thomas Wuerthinger
@@ -31,6 +33,34 @@
 
     private int id;
 
+    public static final Comparator<InputNode> COMPARATOR = new Comparator<InputNode>() {
+        public int compare(InputNode o1, InputNode o2) {
+            return o1.getId() - o2.getId();
+        }
+    };
+
+    public static Comparator<InputNode> getPropertyComparator(final String propertyName) {
+        return new Comparator<InputNode>() {
+
+            public int compare(InputNode o1, InputNode o2) {
+
+                int i1 = 0;
+                try {
+                    i1 = Integer.parseInt(o1.getProperties().get(propertyName));
+                } catch(NumberFormatException e) {
+                }
+
+                int i2 = 0;
+                try {
+                    i2 = Integer.parseInt(o2.getProperties().get(propertyName));
+                } catch(NumberFormatException e) {
+                }
+
+                return i1 - i2;
+            }
+        };
+    }
+
     public InputNode(InputNode n) {
         super(n);
         setId(n.id);
@@ -55,15 +85,12 @@
             return false;
         }
         InputNode n = (InputNode) o;
-        if (n.id != id) {
-            return false;
-        }
-        return getProperties().equals(n.getProperties());
+        return n.id == id;
     }
 
     @Override
     public int hashCode() {
-        return id;
+        return id * 13;
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Pair.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Pair.java	Wed Jun 08 17:26:49 2011 +0200
@@ -58,15 +58,30 @@
 
     @Override
     public boolean equals(Object o) {
-        if (!(o instanceof Pair)) {
+        if (o == null || !(o instanceof Pair)) {
             return false;
         }
         Pair obj = (Pair) o;
-        return l.equals(obj.l) && r.equals(obj.r);
+        boolean b1 = (l == obj.l);
+        if (l != null) {
+            b1 = l.equals(obj.l);
+        }
+
+        boolean b2 = (r == obj.r);
+        if (r != null) {
+            b2 = r.equals(obj.r);
+        }
+        
+        return b1 && b2;
     }
 
     @Override
     public int hashCode() {
-        return l.hashCode() * 71 + r.hashCode();
+        return ((l == null) ? 0 : l.hashCode()) * 71 + ((r == null) ? 0 : r.hashCode());
+    }
+
+    @Override
+    public String toString() {
+        return "[" + l + "/" + r + "]";
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Wed Jun 08 17:26:49 2011 +0200
@@ -26,11 +26,13 @@
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
+import java.util.regex.PatternSyntaxException;
 
 /**
  *
@@ -58,13 +60,30 @@
                 return false;
             }
         }
+
+        for (Property prop : p) {
+            String value = this.get(prop.getName());
+            if (value == null || !value.equals(prop.getValue())) {
+                return false;
+            }
+        }
+
         return true;
     }
 
     @Override
     public int hashCode() {
         int hash = 5;
-        hash = 83 * hash + (this.map != null ? this.map.hashCode() : 0);
+
+        if (map != null) {
+            for (int i = 0; i < this.map.length; i++) {
+                if (map[i] == null) {
+                    i++;
+                } else {
+                    hash = hash * 83 + map[i].hashCode();
+                }
+            }
+        }
         return hash;
     }
 
@@ -85,7 +104,7 @@
 
     public Properties(Properties p) {
         map = new String[p.map.length];
-        System.arraycopy(map, 0, p.map, 0, p.map.length);
+        System.arraycopy(p.map, 0, map, 0, p.map.length);
     }
 
     public static class Entity implements Provider {
@@ -105,14 +124,6 @@
         }
     }
 
-    private String getProperty(String key) {
-        for (int i = 0; i < map.length; i += 2)
-            if (map[i] != null && map[i].equals(key)) {
-                return map[i + 1];
-            }
-        return null;
-    }
-
     public interface PropertyMatcher {
 
         String getName();
@@ -133,6 +144,9 @@
         }
 
         public boolean match(String p) {
+            if (p == null) {
+                return false;
+            }
             return !matcher.match(p);
         }
     }
@@ -143,6 +157,12 @@
         private String value;
 
         public StringPropertyMatcher(String name, String value) {
+            if (name == null) {
+                throw new IllegalArgumentException("Property name must not be null!");
+            }
+            if (value == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
             this.name = name;
             this.value = value;
         }
@@ -152,6 +172,9 @@
         }
 
         public boolean match(String p) {
+            if (p == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
             return p.equals(value);
         }
     }
@@ -162,8 +185,22 @@
         private Pattern valuePattern;
 
         public RegexpPropertyMatcher(String name, String value) {
+
+            if (name == null) {
+                throw new IllegalArgumentException("Property name must not be null!");
+            }
+
+            if (value == null) {
+                throw new IllegalArgumentException("Property value pattern must not be null!");
+            }
+
             this.name = name;
-            valuePattern = Pattern.compile(value);
+
+            try {
+                valuePattern = Pattern.compile(value);
+            } catch (PatternSyntaxException e) {
+                throw new IllegalArgumentException("Bad pattern: " + value);
+            }
         }
 
         public String getName() {
@@ -171,21 +208,26 @@
         }
 
         public boolean match(String p) {
+            if (p == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
             Matcher m = valuePattern.matcher(p);
             return m.matches();
         }
     }
 
     public Property selectSingle(PropertyMatcher matcher) {
+
+        final String name = matcher.getName();
         String value = null;
         for (int i = 0; i < map.length; i += 2) {
-            if (map[i] != null && matcher.getName().equals(map[i]))  {
+            if (map[i] != null && name.equals(map[i])) {
                 value = map[i + 1];
                 break;
             }
         }
         if (value != null && matcher.match(value)) {
-            return new Property(matcher.getName(), value);
+            return new Property(name, value);
         } else {
             return null;
         }
@@ -198,13 +240,31 @@
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("[");
+        List<String[]> pairs = new ArrayList<String[]>();
         for (int i = 0; i < map.length; i += 2) {
             if (map[i + 1] != null) {
-                String p = map[i + 1];
-                sb.append(map[i] + " = " + map[i + 1] + "; ");
+                pairs.add(new String[]{map[i], map[i + 1]});
+            }
+        }
+
+        Collections.sort(pairs, new Comparator<String[]>() {
+            public int compare(String[] o1, String[] o2) {
+                assert o1.length == 2;
+                assert o2.length == 2;
+                return o1[0].compareTo(o2[0]);
             }
+        });
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        boolean first = true;
+        for (String[] p : pairs) {
+            if (first) {
+                first = false;
+            } else {
+                sb.append(", ");
+            }
+            sb.append(p[0] + "=" + p[1]);
         }
         return sb.append("]").toString();
     }
@@ -217,10 +277,6 @@
             this.objects = objects;
         }
 
-        public T selectSingle(final String name, final String value) {
-            return selectSingle(new StringPropertyMatcher(name, value));
-        }
-
         public T selectSingle(PropertyMatcher matcher) {
 
             for (T t : objects) {
@@ -233,18 +289,16 @@
             return null;
         }
 
-        public List<T> selectMultiple(final String name, final String value) {
-            return selectMultiple(new StringPropertyMatcher(name, value));
-        }
-
         public List<T> selectMultiple(PropertyMatcher matcher) {
             List<T> result = new ArrayList<T>();
+
             for (T t : objects) {
                 Property p = t.getProperties().selectSingle(matcher);
                 if (p != null) {
                     result.add(t);
                 }
             }
+
             return result;
         }
     }
@@ -259,6 +313,7 @@
     }
 
     public void setProperty(String name, String value) {
+
         for (int i = 0; i < map.length; i += 2) {
             if (map[i] != null && map[i].equals(name)) {
                 String p = map[i + 1];
@@ -289,31 +344,20 @@
         map = newMap;
     }
 
-    public  Iterator<Property> getProperties() {
-        return iterator();
-    }
-
     public void add(Properties properties) {
         for (Property p : properties) {
-            add(p);
+            setProperty(p.getName(), p.getValue());
         }
     }
 
-    public void add(Property property) {
-        assert property.getName() != null;
-        assert property.getValue() != null;
-        setProperty(property.getName(), property.getValue());
-    }
-    class PropertiesIterator implements Iterator<Property>, Iterable<Property> {
-        public Iterator<Property> iterator() {
-                return this;
-        }
+    private class PropertiesIterator implements Iterator<Property> {
 
         int index;
 
         public boolean hasNext() {
-            while (index < map.length && map[index + 1] == null)
+            while (index < map.length && map[index + 1] == null) {
                 index += 2;
+            }
             return index < map.length;
         }
 
@@ -328,8 +372,8 @@
         public void remove() {
             throw new UnsupportedOperationException("Not supported yet.");
         }
+    }
 
-    }
     public Iterator<Property> iterator() {
         return new PropertiesIterator();
     }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Wed Jun 08 17:26:49 2011 +0200
@@ -32,25 +32,20 @@
 public class Property implements Serializable {
 
     public static final long serialVersionUID = 1L;
-
     private String name;
     private String value;
 
-    private Property() {
-        this(null, null);
-    }
-
-    private Property(Property p) {
-        this(p.getName(), p.getValue());
-    }
-
-    private Property(String name) {
-        this(name, null);
-    }
-
-    public Property(String name, String value) {
+    Property(String name, String value) {
         this.name = name;
         this.value = value;
+
+        if (value == null) {
+            throw new IllegalArgumentException("Property value must not be null!");
+        }
+
+        if (name == null) {
+            throw new IllegalArgumentException("Property name must not be null!");
+        }
     }
 
     public String getName() {
@@ -63,17 +58,20 @@
 
     @Override
     public String toString() {
-        return name + " = " + value + "; ";
+        return name + "=" + value;
     }
 
     @Override
     public boolean equals(Object o) {
-        if (!(o instanceof Property)) return false;
-        Property p2 = (Property)o;
+        if (!(o instanceof Property)) {
+            return false;
+        }
+        Property p2 = (Property) o;
         return name.equals(p2.name) && value.equals(p2.value);
     }
+
     @Override
     public int hashCode() {
-        return name.hashCode() + value == null ? 0 : value.hashCode();
+        return name.hashCode() * 13 + value.hashCode();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Source.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Source {
+
+    private List<InputNode> sourceNodes;
+    private Set<Integer> set;
+
+    public Source() {
+        sourceNodes = new ArrayList<InputNode>(1);
+        set = new LinkedHashSet<Integer>(1);
+    }
+
+    public List<InputNode> getSourceNodes() {
+        return Collections.unmodifiableList(sourceNodes);
+    }
+
+    public Set<Integer> getSourceNodesAsSet() {
+        return Collections.unmodifiableSet(set);
+    }
+
+    public void addSourceNode(InputNode n) {
+        if (!set.contains(n.getId())) {
+            sourceNodes.add(n);
+            set.add(n.getId());
+        }
+    }
+
+    public interface Provider {
+
+        public Source getSource();
+    }
+
+    public void addSourceNodes(Source s) {
+        for (InputNode n : s.getSourceNodes()) {
+            addSourceNode(n);
+        }
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Wed Jun 08 17:26:49 2011 +0200
@@ -30,6 +30,7 @@
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.InputMethod;
 import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Pair;
 import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.data.Property;
 import com.sun.hotspot.igv.data.services.GroupCallback;
@@ -38,7 +39,9 @@
 import com.sun.hotspot.igv.data.serialization.XMLParser.ParseMonitor;
 import com.sun.hotspot.igv.data.serialization.XMLParser.TopElementHandler;
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import org.xml.sax.XMLReader;
@@ -63,6 +66,7 @@
     public static final String REMOVE_EDGE_ELEMENT = "removeEdge";
     public static final String REMOVE_NODE_ELEMENT = "removeNode";
     public static final String METHOD_NAME_PROPERTY = "name";
+    public static final String GROUP_NAME_PROPERTY = "name";
     public static final String METHOD_IS_PUBLIC_PROPERTY = "public";
     public static final String METHOD_IS_STATIC_PROPERTY = "static";
     public static final String TRUE_VALUE = "true";
@@ -92,6 +96,7 @@
     private boolean difference;
     private GroupCallback groupCallback;
     private HashMap<String, Integer> idCache = new HashMap<String, Integer>();
+    private ArrayList<Pair<String, String>> blockConnections = new ArrayList<Pair<String, String>>();
     private int maxId = 0;
 
     private int lookupID(String i) {
@@ -197,19 +202,67 @@
         protected InputGraph start() throws SAXException {
 
             String name = readAttribute(GRAPH_NAME_PROPERTY);
-            InputGraph previous = getParentObject().getLastAdded();
-            if (!difference) {
-                previous = null;
+            InputGraph curGraph = getParentObject().addGraph(name);
+            if (difference) {
+
+                List<InputGraph> list = getParentObject().getGraphs();
+                if (list.size() > 1) {
+                    InputGraph previous = list.get(list.size() - 2);
+                    for (InputNode n : previous.getNodes()) {
+                        curGraph.addNode(n);
+                    }
+                    for (InputEdge e : previous.getEdges()) {
+                        curGraph.addEdge(e);
+                    }
+                }
             }
-            InputGraph curGraph = new InputGraph(getParentObject(), previous, name);
             this.graph = curGraph;
             return curGraph;
         }
 
         @Override
         protected void end(String text) throws SAXException {
-            getParentObject().addGraph(graph);
-            graph.resolveBlockLinks();
+
+            // Recover from control flow input with missing information
+            if (graph.getBlocks().size() > 0) {
+                boolean blockContainsNodes = false;
+                for (InputBlock b : graph.getBlocks()) {
+                    if (b.getNodes().size() > 0) {
+                        blockContainsNodes = true;
+                        break;
+                    }
+                }
+
+                if (!blockContainsNodes) {
+                    graph.clearBlocks();
+                    blockConnections.clear();
+                } else {
+                    
+                    InputBlock noBlock = null;
+                    
+                    for (InputNode n : graph.getNodes()) {
+                        if (graph.getBlock(n) == null) {
+                            if (noBlock == null) {
+                                noBlock = graph.addBlock("none");
+                            }
+                            
+                            noBlock.addNode(n.getId());
+                        }
+
+                        assert graph.getBlock(n) != null;
+                    }
+                }
+            }
+
+            // Resolve block successors
+            for (Pair<String, String> p : blockConnections) {
+                final InputBlock left = graph.getBlock(p.getLeft());
+                assert left != null;
+                final InputBlock right = graph.getBlock(p.getRight());
+                assert right != null;
+                graph.addBlockConnection(left, right);
+            }
+            blockConnections.clear();
         }
     };
     // <nodes>
@@ -223,8 +276,10 @@
         protected InputBlock start() throws SAXException {
             InputGraph graph = getParentObject();
             String name = readRequiredAttribute(BLOCK_NAME_PROPERTY).intern();
-            InputBlock b = new InputBlock(getParentObject(), name);
-            graph.addBlock(b);
+            InputBlock b = graph.addBlock(name);
+            for (InputNode n : b.getNodes()) {
+                assert graph.getBlock(n).equals(b);
+            }
             return b;
         }
     };
@@ -255,7 +310,7 @@
         @Override
         protected InputBlock start() throws SAXException {
             String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
-            getParentObject().addSuccessor(name);
+            blockConnections.add(new Pair<String, String>(getParentObject().getName(), name));
             return getParentObject();
         }
     };
@@ -372,7 +427,7 @@
         @Override
         public String start() throws SAXException {
             return readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
-        }
+         }
 
         @Override
         public void end(String text) {
@@ -430,7 +485,7 @@
     }
 
     // Returns a new GraphDocument object deserialized from an XML input source.
-    public GraphDocument parse(XMLReader reader, InputSource source, XMLParser.ParseMonitor monitor) throws SAXException {
+    public synchronized GraphDocument parse(XMLReader reader, InputSource source, XMLParser.ParseMonitor monitor) throws SAXException {
         reader.setContentHandler(new XMLParser(xmlDocument, monitor));
         try {
             reader.parse(source);
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Wed Jun 08 17:26:49 2011 +0200
@@ -34,6 +34,7 @@
 import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.data.Property;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.Writer;
 import java.util.HashSet;
 import java.util.Set;
@@ -44,6 +45,16 @@
  */
 public class Printer {
 
+    private InputStream in;
+
+    public Printer() {
+        this(null);
+    }
+
+    public Printer(InputStream inputStream) {
+        this.in = inputStream;
+    }
+
     public void export(Writer writer, GraphDocument document) {
 
         XMLWriter xmlWriter = new XMLWriter(writer);
@@ -71,14 +82,24 @@
         writer.startTag(Parser.GROUP_ELEMENT, attributes);
         writer.writeProperties(g.getProperties());
 
-        if (g.getMethod() != null) {
-            export(writer, g.getMethod());
+        boolean shouldExport = true;
+        if (in != null) {
+            char c = (char) in.read();
+            if (c != 'y') {
+                shouldExport = false;
+            }
         }
 
-        InputGraph previous = null;
-        for (InputGraph graph : g.getGraphs()) {
-            export(writer, graph, previous, true);
-            previous = graph;
+        if (shouldExport) {
+            if (g.getMethod() != null) {
+                export(writer, g.getMethod());
+            }
+
+            InputGraph previous = null;
+            for (InputGraph graph : g.getGraphs()) {
+                export(writer, graph, previous, true);
+                previous = graph;
+            }
         }
 
         writer.endTag();
@@ -153,23 +174,25 @@
 
         writer.startTag(Parser.CONTROL_FLOW_ELEMENT);
         for (InputBlock b : graph.getBlocks()) {
-
             writer.startTag(Parser.BLOCK_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, b.getName()));
-
-            writer.startTag(Parser.SUCCESSORS_ELEMENT);
-            for (InputBlock s : b.getSuccessors()) {
-                writer.simpleTag(Parser.SUCCESSOR_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, s.getName()));
+            
+            if (b.getSuccessors().size() > 0) {
+                writer.startTag(Parser.SUCCESSORS_ELEMENT);
+                for (InputBlock s : b.getSuccessors()) {
+                    writer.simpleTag(Parser.SUCCESSOR_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, s.getName()));
+                }
+                writer.endTag();
             }
-            writer.endTag();
 
+            if (b.getNodes().size() > 0) {
             writer.startTag(Parser.NODES_ELEMENT);
-            for (InputNode n : b.getNodes()) {
-                writer.simpleTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, n.getId() + ""));
+                for (InputNode n : b.getNodes()) {
+                    writer.simpleTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, n.getId() + ""));
+                }
+                writer.endTag();
             }
+            
             writer.endTag();
-
-            writer.endTag();
-
         }
 
         writer.endTag();
@@ -199,8 +222,8 @@
             b.append(" ");
             b.append(code.getName());
             b.append("\n");
-
         }
+        
         b.append("]]>");
         w.write(b.toString());
         w.endTag();
@@ -209,8 +232,12 @@
 
     private Properties createProperties(InputEdge edge) {
         Properties p = new Properties();
-        p.setProperty(Parser.FROM_INDEX_PROPERTY, Integer.toString(edge.getFromIndex()));
-        p.setProperty(Parser.TO_INDEX_PROPERTY, Integer.toString(edge.getToIndex()));
+        if (edge.getToIndex() != 0) {
+            p.setProperty(Parser.TO_INDEX_PROPERTY, Integer.toString(edge.getToIndex()));
+        }
+        if (edge.getFromIndex() != 0) {
+            p.setProperty(Parser.FROM_INDEX_PROPERTY, Integer.toString(edge.getFromIndex()));
+        }
         p.setProperty(Parser.TO_PROPERTY, Integer.toString(edge.getTo()));
         p.setProperty(Parser.FROM_PROPERTY, Integer.toString(edge.getFrom()));
         return p;
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Wed Jun 08 17:26:49 2011 +0200
@@ -111,7 +111,7 @@
     }
 
     public void writeProperties(Properties props) throws IOException {
-        if (props.getProperties().hasNext() == false) {
+        if (props.iterator().hasNext() == false) {
             return;
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/ChangedEventTest.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ChangedEventTest {
+
+    public ChangedEventTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of addListener method, of class Event.
+     */
+    @Test
+    public void testBase() {
+
+        ChangedEvent<Integer> e = new ChangedEvent(5);
+        final int[] fireCount = new int[1];
+
+        e.addListener(new ChangedListener<Integer>() {
+            public void changed(Integer s) {
+                assertEquals(s.intValue(), 5);
+                fireCount[0]++;
+            }
+        });
+
+        e.fire();
+        assertEquals(1, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.beginAtomic();
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.endAtomic();
+        assertEquals(3, fireCount[0]);
+
+    }
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/ControllableChangedListenerTest.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ControllableChangedListenerTest {
+
+    public ControllableChangedListenerTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of isEnabled method, of class ControllableChangedListener.
+     */
+    @Test
+    public void testBase() {
+
+        final boolean[] hasFired = new boolean[1];
+        final boolean[] shouldFire = new boolean[1];
+        final Integer[] valueToFire = new Integer[1];
+        ControllableChangedListener<Integer> l = new ControllableChangedListener<Integer>() {
+
+            @Override
+            public void filteredChanged(Integer value) {
+                assertTrue(shouldFire[0]);
+                assertEquals(valueToFire[0], value);
+                hasFired[0] = true;
+            }
+        };
+
+        shouldFire[0] = true;
+        valueToFire[0] = 1;
+        hasFired[0] = false;
+        l.changed(1);
+        assertTrue(hasFired[0]);
+
+        shouldFire[0] = false;
+        hasFired[0] = false;
+        l.setEnabled(false);
+        l.changed(1);
+        assertFalse(hasFired[0]);
+
+        shouldFire[0] = true;
+        valueToFire[0] = 1;
+        hasFired[0] = false;
+        l.setEnabled(true);
+        l.changed(1);
+        assertTrue(hasFired[0]);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/GroupTest.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class GroupTest {
+
+    public GroupTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getAllNodes method, of class Group.
+     */
+    @Test
+    public void testGetAllNodes() {
+        final Group g = new Group();
+        final InputGraph graph1 = g.addGraph("1");
+        final InputGraph graph2 = g.addGraph("2");
+        graph1.addNode(new InputNode(1));
+        graph1.addNode(new InputNode(2));
+        graph2.addNode(new InputNode(2));
+        graph2.addNode(new InputNode(3));
+        assertEquals(g.getAllNodes(), new HashSet(Arrays.asList(1, 2, 3)));
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/InputGraphTest.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputGraphTest {
+
+    /**
+     *    1
+     *   / \
+     *  2   3
+     *   \  |  5
+     *    \ | /
+     *      4
+     */
+    private static InputGraph referenceGraph;
+
+    private static InputGraph emptyGraph;
+
+    private static final InputNode N1 = new InputNode(1);
+    private static final InputNode N2 = new InputNode(2);
+    private static final InputNode N3 = new InputNode(3);
+    private static final InputNode N4 = new InputNode(4);
+    private static final InputNode N5 = new InputNode(5);
+    private static final InputEdge E12 = new InputEdge((char)0, 1, 2);
+    private static final InputEdge E13 = new InputEdge((char)0, 1, 3);
+    private static final InputEdge E24 = new InputEdge((char)0, 2, 4);
+    private static final InputEdge E34 = new InputEdge((char)0, 3, 4);
+    private static final InputEdge E54 = new InputEdge((char)0, 5, 4);
+
+    public InputGraphTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        Group group = new Group();
+
+        emptyGraph = group.addGraph("emptyGraph");
+
+        referenceGraph = group.addGraph("referenceGraph");
+        referenceGraph.addNode(N1);
+        referenceGraph.addNode(N2);
+        referenceGraph.addNode(N3);
+        referenceGraph.addNode(N4);
+        referenceGraph.addNode(N5);
+
+        referenceGraph.addEdge(E12);
+        referenceGraph.addEdge(E13);
+        referenceGraph.addEdge(E24);
+        referenceGraph.addEdge(E34);
+        referenceGraph.addEdge(E54);
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of equals method, of class InputGraph.
+     */
+    @Test
+    public void testEquals() {
+
+        Group parentA = new Group();
+        InputGraph a = parentA.addGraph("graph");
+
+        Group parentB = new Group();
+        InputGraph b = parentB.addGraph("graph");
+
+        InputGraph c = parentB.addGraph("graph");
+
+        Util.assertGraphEquals(a, b);
+        Util.assertGraphEquals(b, c);
+
+        a.addNode(new InputNode(1));
+        Util.assertGraphNotEquals(a, b);
+
+        b.addNode(new InputNode(1));
+        Util.assertGraphEquals(a, b);
+    }
+
+    /**
+     * Test of findRootNodes method, of class InputGraph.
+     */
+    @Test
+    public void testFindRootNodes() {
+        assertTrue(emptyGraph.findRootNodes().size() == 0);
+
+        List<InputNode> result = referenceGraph.findRootNodes();
+        assertTrue(result.size() == 2);
+        assertTrue(result.contains(N1));
+        assertTrue(result.contains(N5));
+    }
+
+    /**
+     * Test of findAllOutgoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindAllOutgoingEdges() {
+        assertTrue(emptyGraph.findAllOutgoingEdges().size() == 0);
+
+        Map<InputNode, List<InputEdge>> result = referenceGraph.findAllOutgoingEdges();
+        assertTrue(result.size() == 5);
+        assertEquals(result.get(N1), Arrays.asList(E12, E13));
+        assertEquals(result.get(N2), Arrays.asList(E24));
+        assertEquals(result.get(N3), Arrays.asList(E34));
+        assertEquals(result.get(N4), Arrays.asList());
+        assertEquals(result.get(N5), Arrays.asList(E54));
+    }
+
+    /**
+     * Test of findAllIngoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindAllIngoingEdges() {
+        assertTrue(emptyGraph.findAllIngoingEdges().size() == 0);
+
+        Map<InputNode, List<InputEdge>> result = referenceGraph.findAllIngoingEdges();
+        assertTrue(result.size() == 5);
+        assertEquals(result.get(N1), Arrays.asList());
+        assertEquals(result.get(N2), Arrays.asList(E12));
+        assertEquals(result.get(N3), Arrays.asList(E13));
+        assertEquals(result.get(N4), Arrays.asList(E24, E34, E54));
+        assertEquals(result.get(N5), Arrays.asList());
+    }
+
+    /**
+     * Test of findOutgoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindOutgoingEdges() {
+        assertTrue(emptyGraph.findOutgoingEdges(new InputNode(1)).size() == 0);
+
+        assertEquals(referenceGraph.findOutgoingEdges(N1), Arrays.asList(E12, E13));
+        assertEquals(referenceGraph.findOutgoingEdges(N2), Arrays.asList(E24));
+        assertEquals(referenceGraph.findOutgoingEdges(N3), Arrays.asList(E34));
+        assertEquals(referenceGraph.findOutgoingEdges(N4), Arrays.asList());
+        assertEquals(referenceGraph.findOutgoingEdges(N5), Arrays.asList(E54));
+    }
+
+    /**
+     * Test of getNext method, of class InputGraph.
+     */
+    @Test
+    public void testGetNextPrev() {
+        final Group group = new Group();
+
+        final InputGraph a = group.addGraph("a");
+
+        final InputGraph b = group.addGraph("b");
+
+        final InputGraph c = group.addGraph("c");
+
+        assertEquals(null, a.getPrev());
+        assertEquals(b, a.getNext());
+
+        assertEquals(a, b.getPrev());
+        assertEquals(c, b.getNext());
+
+        assertEquals(b, c.getPrev());
+        assertEquals(null, c.getNext());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/InputMethodTest.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.hamcrest.CoreMatchers.*;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Thomas
+ */
+public class InputMethodTest {
+
+    public InputMethodTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+
+    /**
+     * Test of getBytecodes method, of class InputMethod.
+     */
+    @Test
+    public void testGetSetBytecodes() {
+
+        final String input = "0 iload_0\n" +
+                             "1 iconst_1\n" +
+                             "2 if_icmpne 7\n" +
+                             "5 iconst_1\n" +
+                             "6 ireturn\n" +
+                             "7 iconst_0\n" +
+                             "8 ireturn";
+
+        final Group g = new Group();
+        InputMethod m = new InputMethod(g, "name", "shortName", -1);
+        m.setBytecodes(input);
+
+        assertThat(m.getBytecodes().size(), is(7));
+
+        assertThat(m.getBytecodes().get(0).getBci(), is(0));
+        assertThat(m.getBytecodes().get(1).getBci(), is(1));
+        assertThat(m.getBytecodes().get(2).getBci(), is(2));
+        assertThat(m.getBytecodes().get(3).getBci(), is(5));
+
+        assertThat(m.getBytecodes().get(0).getName(), is("iload_0"));
+        assertThat(m.getBytecodes().get(1).getName(), is("iconst_1"));
+        assertThat(m.getBytecodes().get(2).getName(), is("if_icmpne 7"));
+        assertThat(m.getBytecodes().get(6).getName(), is("ireturn"));
+
+        assertThat(m.getBytecodes().get(2).getInlined(), nullValue());
+        assertThat(m.getBytecodes().get(6).getInlined(), nullValue());
+    }
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PairTest.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.data;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PairTest {
+
+    public PairTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getLeft method, of class Pair.
+     */
+    @Test
+    public void testBase() {
+        Pair p = new Pair();
+        assertTrue(p.getLeft() == null);
+        assertTrue(p.getRight() == null);
+        assertEquals("[null/null]", p.toString());
+        assertFalse(p.equals(null));
+
+        Pair<Integer, Integer> p2 = new Pair(1, 2);
+        assertTrue(p2.getLeft().intValue() == 1);
+        assertTrue(p2.getRight().intValue() == 2);
+        assertFalse(p.equals(p2));
+        assertFalse(p2.equals(p));
+        assertFalse(p.hashCode() == p2.hashCode());
+        assertEquals("[1/2]", p2.toString());
+
+        Pair p3 = new Pair(1, 2);
+        assertTrue(p2.equals(p3));
+        assertTrue(p2.hashCode() == p3.hashCode());
+
+        p2.setLeft(2);
+        assertFalse(p2.equals(p3));
+        assertTrue(p2.getLeft().intValue() == 2);
+        assertTrue(p2.getRight().intValue() == 2);
+        assertFalse(p2.hashCode() == p3.hashCode());
+        assertEquals("[2/2]", p2.toString());
+
+        p2.setRight(1);
+        assertFalse(p2.equals(p3));
+        assertTrue(p2.getLeft().intValue() == 2);
+        assertTrue(p2.getRight().intValue() == 1);
+        assertFalse(p2.hashCode() == p3.hashCode());
+        assertEquals("[2/1]", p2.toString());
+
+        p3.setLeft(2);
+        p3.setRight(1);
+        assertTrue(p2.hashCode() == p3.hashCode());
+        assertTrue(p2.equals(p3));
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PropertiesTest.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,397 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.data;
+
+import com.sun.hotspot.igv.data.Properties.InvertPropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.PropertySelector;
+import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import junit.framework.TestCase;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PropertiesTest extends TestCase {
+
+
+    
+    public PropertiesTest(String testName) {
+        super(testName);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Test of equals method, of class Properties.
+     */
+    public void testEquals() {
+        Properties a = new Properties();
+        assertFalse(a.equals(null));
+        assertTrue(a.equals(a));
+        
+        Properties b = new Properties();
+        assertTrue(a.equals(b));
+        assertTrue(a.hashCode() == b.hashCode());
+
+        a.setProperty("p1", "1");
+        assertFalse(a.equals(b));
+        assertFalse(b.equals(a));
+        assertFalse(a.hashCode() == b.hashCode());
+
+        b.setProperty("p1", "1");
+        assertTrue(a.equals(b));
+        assertTrue(a.hashCode() == b.hashCode());
+
+        Properties c = new Properties(a);
+        assertTrue(c.equals(a));
+        assertTrue(c.equals(b));
+
+        c.setProperty("p1", "2");
+        assertFalse(c.equals(b));
+        assertFalse(c.hashCode() == b.hashCode());
+        assertFalse(c.equals(a));
+        assertFalse(c.hashCode() == a.hashCode());
+
+        a.setProperty("p2", "2");
+        Properties d = new Properties();
+        d.setProperty("p2", "2");
+        d.setProperty("p1", "1");
+        assertTrue(d.equals(a));
+    }
+
+    /**
+     * Test of selectSingle method, of class Properties.
+     */
+    public void testSelectSingle() {
+        
+        final boolean[] called = new boolean[1];
+        final String v = "2";
+        final String n = "p2";
+        
+        PropertyMatcher matcher = new PropertyMatcher() {
+
+            public String getName() {
+                assertFalse(called[0]);
+                called[0] = true;
+                return n;
+            }
+
+            public boolean match(String value) {
+                assertTrue(v.equals(value));
+                return true;
+            }
+        };
+
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        instance.setProperty(n, v);
+        instance.setProperty("p3", "3");
+        Property result = instance.selectSingle(matcher);
+        assertEquals(result, new Property(n, v));
+
+
+        called[0] = false;
+        PropertyMatcher matcher2 = new PropertyMatcher() {
+
+            public String getName() {
+                assertFalse(called[0]);
+                called[0] = true;
+                return n;
+            }
+
+            public boolean match(String value) {
+                return false;
+            }
+        };
+
+
+        Property result2 = instance.selectSingle(matcher2);
+        assertTrue(result2 == null);
+    }
+
+    /**
+     * Test of get method, of class Properties.
+     */
+    public void testGet() {
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        assertEquals("1", instance.get("p1"));
+        assertEquals(null, instance.get("p2"));
+    }
+
+    /**
+     * Test of getProperties method, of class Properties.
+     */
+    public void testIterator() {
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        instance.setProperty("p2", "2");
+        Iterator<Property> result = instance.iterator();
+        assertTrue(result.hasNext());
+        assertEquals(new Property("p1", "1"), result.next());
+        assertTrue(result.hasNext());
+        assertEquals(new Property("p2", "2"), result.next());
+        assertFalse(result.hasNext());
+        assertTrue(result.next() == null);
+
+        try {
+            result.remove();
+            fail();
+        } catch(UnsupportedOperationException e) {}
+    }
+
+    /**
+     * Test of add method, of class Properties.
+     */
+    public void testAdd() {
+        Properties a = new Properties();
+        a.setProperty("p1", "1");
+        a.setProperty("p2", "2");
+
+        Properties b = new Properties();
+        b.setProperty("p1", "1");
+
+        Properties c = new Properties();
+        c.setProperty("p2", "2");
+
+        assertFalse(a.equals(b));
+        b.add(c);
+
+        assertTrue(a.equals(b));
+        
+        b.setProperty("p3", null);
+        assertTrue(a.equals(b));
+    
+        Properties empty = new Properties();
+        b.add(empty);
+        assertTrue(a.equals(b));
+        
+        empty.add(b);
+        assertTrue(a.equals(empty));
+    }
+
+
+    /**
+     * Test the multiple argument constructors.
+     */
+    public void testConstructors() {
+        Properties a = new Properties("p1", "1", "p2", "2", "p3", "3");
+        Properties b = new Properties("p1", "1", "p2", "2");
+        Properties c = new Properties("p1", "1");
+
+        assertTrue(a.get("p3").equals("3"));
+        assertTrue(b.get("p2").equals("2"));
+        assertTrue(b.get("p1").equals("1"));
+
+        b.setProperty("p3", "3");
+        c.setProperty("p2", "2");
+        c.setProperty("p3", "3");
+
+        assertTrue(a.equals(b));
+        assertTrue(a.equals(c));
+    }
+
+    /**
+     * Test Entity class
+     */
+    public void testEntity() {
+
+        Properties p = new Properties();
+
+        Properties.Entity entity = new Properties.Entity();
+        assertEquals(entity.getProperties(), p);
+
+        entity.getProperties().setProperty("p1", "1");
+        Properties.Entity entity2 = new Properties.Entity(entity);
+        assertEquals(entity.getProperties(), entity2.getProperties());
+    }
+
+    /**
+     * Test property selector
+     */
+    public void testPropertySelector() {
+        final Collection<Properties.Entity> c = new ArrayList<Properties.Entity>();
+
+        final Properties.Entity e1 = new Properties.Entity();
+        e1.getProperties().setProperty("p1", "1");
+        e1.getProperties().setProperty("p2", "2");
+        c.add(e1);
+
+        final Properties.Entity e2 = new Properties.Entity();
+        e2.getProperties().setProperty("p2", "2");
+        e2.getProperties().setProperty("p1", "1");
+        e2.getProperties().setProperty("p3", "3");
+        c.add(e2);
+
+        final Properties.Entity e3 = new Properties.Entity();
+        e3.getProperties().setProperty("p3", "3");
+        e3.getProperties().setProperty("p4", "4");
+        c.add(e3);
+
+        final PropertySelector<Properties.Entity> sel = new PropertySelector<Properties.Entity>(c);
+
+        final StringPropertyMatcher matcher1 = new StringPropertyMatcher("p2", "2");
+        assertTrue(sel.selectMultiple(matcher1).size() == 2);
+        assertTrue(sel.selectMultiple(matcher1).contains(e1));
+        assertTrue(sel.selectMultiple(matcher1).contains(e2));
+        assertTrue(sel.selectSingle(matcher1).equals(e1) || sel.selectSingle(matcher1).equals(e2));
+
+        final StringPropertyMatcher matcher2 = new StringPropertyMatcher("p3", "3");
+        assertTrue(sel.selectMultiple(matcher2).size() == 2);
+        assertTrue(sel.selectMultiple(matcher2).contains(e2));
+        assertTrue(sel.selectMultiple(matcher2).contains(e3));
+        assertTrue(sel.selectSingle(matcher2).equals(e2) || sel.selectSingle(matcher2).equals(e3));
+
+        final StringPropertyMatcher matcher3 = new StringPropertyMatcher("p4", "4");
+        assertTrue(sel.selectMultiple(matcher3).size() == 1);
+        assertTrue(sel.selectMultiple(matcher3).contains(e3));
+        assertTrue(sel.selectSingle(matcher3).equals(e3));
+
+        final StringPropertyMatcher matcher4 = new StringPropertyMatcher("p5", "5");
+        assertTrue(sel.selectMultiple(matcher4).size() == 0);
+        assertTrue(sel.selectSingle(matcher4) == null);
+    }
+
+    public void testRemoveProperty() {
+        final Properties p = new Properties();
+        p.setProperty("p1", "1");
+        p.setProperty("p2", "2");
+
+        assertTrue(p.get("p1").equals("1"));
+        assertTrue(p.get("p2").equals("2"));
+
+        p.setProperty("p1", null);
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2").equals("2"));
+
+        p.setProperty("p2", null);
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2") == null);
+
+        p.setProperty("p3", "3");
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2") == null);
+        assertTrue(p.get("p3").equals("3"));
+    }
+
+    /**
+     * Test property matchers
+     */
+    public void testPropertyMatchers() {
+        final StringPropertyMatcher matcher = new StringPropertyMatcher("p1", "1");
+        assertTrue(matcher.getName().equals("p1"));
+        assertTrue(matcher.match("1"));
+        assertFalse(matcher.match("2"));
+        try {
+            matcher.match(null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new StringPropertyMatcher(null, "**");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new StringPropertyMatcher("p1", null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        final RegexpPropertyMatcher matcher2 = new RegexpPropertyMatcher("p1", "C.*");
+        assertTrue(matcher2.getName().equals("p1"));
+        assertTrue(matcher2.match("C"));
+        assertTrue(matcher2.match("Casdf"));
+        assertFalse(matcher2.match(" C"));
+        assertFalse(matcher2.match("c"));
+        assertFalse(matcher2.match("asdfC"));
+        
+        try {
+            matcher2.match(null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher("p1", "**");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher(null, "1");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher("p1", null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+        
+        final InvertPropertyMatcher matcher3 = new InvertPropertyMatcher(matcher);
+        assertTrue(matcher3.getName().equals("p1"));
+        assertFalse(matcher3.match("1"));
+        assertTrue(matcher3.match("2"));
+        assertFalse(matcher3.match(null));
+    }
+
+    public void testToString() {
+        Properties p = new Properties();
+        assertEquals(p.toString(), "[]");
+
+        p.setProperty("p1", "1");
+        assertEquals(p.toString(), "[p1=1]");
+
+        Properties p2 = new Properties();
+        p2.setProperty("p1", "1");
+        p2.setProperty("p2", "2");
+        assertEquals(p2.toString(), "[p1=1, p2=2]");
+
+        Properties p3 = new Properties();
+        p3.setProperty("p2", "2");
+        p3.setProperty("p1", "1");
+        assertEquals(p3.toString(), "[p1=1, p2=2]");
+        
+        p3.setProperty("p0", "0");
+        assertEquals(p3.toString(), "[p0=0, p1=1, p2=2]");
+
+        p2.setProperty("p1", null);
+        assertEquals(p2.toString(), "[p2=2]");
+
+        p2.setProperty("p2", null);
+        assertEquals(p2.toString(), "[]");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PropertyTest.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,120 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.data;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PropertyTest {
+
+    public PropertyTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getName method, of class Property.
+     */
+    @Test
+    public void testGetNameAndValue() {
+        final Property p = new Property("name", "value");
+        assertEquals(p.getName(), "name");
+        assertEquals(p.getValue(), "value");
+
+        try {
+            new Property(null, "value");
+            fail();
+        } catch(IllegalArgumentException e) {
+        }
+
+
+        try {
+            new Property("name", null);
+            fail();
+        } catch(IllegalArgumentException e) {
+        }
+    }
+
+    /**
+     * Test of toString method, of class Property.
+     */
+    @Test
+    public void testToString() {
+        final Property p = new Property("name", "value");
+        assertEquals(p.toString(), "name=value");
+    }
+
+    /**
+     * Test of equals method, of class Property.
+     */
+    @Test
+    public void testEquals() {
+        final Property p = new Property("name", "value");
+        final Object o = new Object();
+        assertFalse(p.equals(o));
+        assertFalse(p.equals(null));
+        assertTrue(p.equals(p));
+
+        final Property p2 = new Property("name", "value1");
+        assertFalse(p.equals(p2));
+        assertTrue(p.hashCode() != p2.hashCode());
+
+        final Property p3 = new Property("name2", "value");
+        assertFalse(p.equals(p3));
+        assertTrue(p.hashCode() != p3.hashCode());
+        assertTrue(p2.hashCode() != p3.hashCode());
+
+        final Property p4 = new Property("name", "value");
+        assertEquals(p, p4);
+        assertEquals(p.hashCode(), p4.hashCode());
+    
+        final Property p5 = new Property("value", "name");
+        assertFalse(p.equals(p5));
+        assertTrue(p.hashCode() != p5.hashCode());
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/SourceTest.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import java.lang.Integer;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.*;
+import static org.hamcrest.CoreMatchers.*;
+
+/**
+ *
+ * @author Thomas
+ */
+public class SourceTest {
+
+    public SourceTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getSourceNodes method, of class Source.
+     */
+    @Test
+    public void testBase() {
+        final Source s = new Source();
+
+        final InputNode N1 = new InputNode(1);
+        final InputNode N2 = new InputNode(2);
+
+        s.addSourceNode(N1);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<Integer>(Arrays.asList(1)));
+
+        s.addSourceNode(N2);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1, N2));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<Integer>(Arrays.asList(1, 2)));
+
+        s.addSourceNode(N1);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1, N2));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<Integer>(Arrays.asList(1, 2)));
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/Util.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Util {
+
+    public static void assertGraphDocumentNotEquals(GraphDocument a, GraphDocument b) {
+        try {
+            assertGraphDocumentEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Graphs documents are equal!");
+    }
+
+    public static void assertGraphDocumentEquals(GraphDocument a, GraphDocument b) {
+
+        if (a.getGroups().size() != b.getGroups().size()) {
+            fail();
+        }
+
+        int z = 0;
+        for (Group g : b.getGroups()) {
+
+            Group thisG = a.getGroups().get(z);
+            assertGroupEquals(thisG, g);
+            z++;
+        }
+    }
+
+    public static void assertGroupNotEquals(Group a, Group b) {
+        try {
+            assertGroupEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Groups are equal!");
+    }
+
+    public static void assertGroupEquals(Group a, Group b) {
+
+        if (a.getGraphs().size() != b.getGraphs().size()) {
+            fail();
+        }
+
+        int z = 0;
+        for (InputGraph graph : a.getGraphs()) {
+            InputGraph otherGraph = b.getGraphs().get(z);
+            assertGraphEquals(graph, otherGraph);
+            z++;
+        }
+
+        if (a.getMethod() == null || b.getMethod() == null) {
+            if (a.getMethod() != b.getMethod()) {
+                fail();
+            }
+        } else {
+            if (!a.getMethod().equals(b.getMethod())) {
+                fail();
+            }
+        }
+
+        if (a.getAssembly() == null || b.getAssembly() == null) {
+            if (a.getAssembly() != b.getAssembly()) {
+                fail();
+            }
+        } else {
+            if (!a.getAssembly().equals(b.getAssembly())) {
+                fail();
+            }
+        }
+    }
+
+    public static void assertGraphNotEquals(InputGraph a, InputGraph b) {
+        try {
+            assertGraphEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Graphs are equal!");
+    }
+
+    public static void assertGraphEquals(InputGraph a, InputGraph b) {
+        
+        if(!a.getNodesAsSet().equals(b.getNodesAsSet())) {
+            fail();
+        }
+        
+        if (!a.getEdges().equals(b.getEdges())) {
+            fail();
+        }
+        
+        if (a.getBlocks().equals(b.getBlocks())) {
+            fail();
+        }
+
+        for (InputNode n : a.getNodes()) {
+            assertEquals(a.getBlock(n), b.getBlock(n));
+        }
+
+        assertEquals(a.getSourceGraphs(), b.getSourceGraphs());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/serialization/ParserTest.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,232 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.GraphDocument;
+import com.sun.hotspot.igv.data.Group;
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.data.InputEdge;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputMethod;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Util;
+import java.io.CharArrayWriter;
+import java.io.StringReader;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openide.xml.XMLUtil;
+import static org.junit.Assert.*;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ParserTest {
+
+    public ParserTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    private void test(GraphDocument document) {
+        final Printer printer = new Printer();
+        final CharArrayWriter writer = new CharArrayWriter();
+        printer.export(writer, document);
+        test(document, writer.toString());
+    }
+
+    private void test(GraphDocument document, String xmlString) {
+        
+        StringReader sr = new StringReader(xmlString);
+        InputSource is = new InputSource(sr);
+
+        try {
+            XMLReader reader = XMLUtil.createXMLReader();
+            Parser parser = new Parser();
+            final GraphDocument parsedDocument = parser.parse(reader, is, null);
+            Util.assertGraphDocumentEquals(document, parsedDocument);
+        } catch (SAXException ex) {
+            fail(ex.toString());
+        }
+    }
+
+    private void testBoth(GraphDocument document, String xmlString) {
+        test(document);
+        test(document, xmlString);
+    }
+
+    /**
+     * Test of graph document serialization
+     */
+    @Test
+    public void testSerialization() {
+        final GraphDocument doc = new GraphDocument();
+
+        test(doc);
+
+        final Group group1 = new Group();
+        doc.addGroup(group1);
+        test(doc);
+
+        final Group group2 = new Group();
+        doc.addGroup(group2);
+        test(doc);
+
+        final InputGraph graph = group1.addGraph("");
+        test(doc);
+
+        graph.addNode(new InputNode(0));
+        test(doc);
+
+        graph.addNode(new InputNode(1));
+        test(doc);
+
+        graph.addNode(new InputNode(2));
+        test(doc);
+
+        graph.addNode(new InputNode(3));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)0, (char)0, 0, 1));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)1, (char)1, 0, 1));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)0, (char)0, 1, 2));
+        test(doc);
+        
+        graph.addEdge(new InputEdge((char)0, (char)0, 2, 3));
+        test(doc);
+
+        group1.setMethod(new InputMethod(group1, "testMethod", "tM", 1));
+        test(doc);
+
+        final InputBlock b1 = graph.addBlock("1");
+        b1.addNode(0);
+        b1.addNode(1);
+
+        final InputBlock b2 = graph.addBlock("2");
+        b2.addNode(2);
+        b2.addNode(3);
+        test(doc);
+
+        final GraphDocument document2 = new GraphDocument();
+        doc.addGraphDocument(document2);
+        test(doc);
+        assertTrue(doc.getGroups().size() == 2);
+
+        final Group group3 = new Group();
+        document2.addGroup(group3);
+        doc.addGraphDocument(document2);
+        assertTrue(doc.getGroups().size() == 3);
+        assertTrue(document2.getGroups().size() == 0);
+
+        doc.clear();
+        test(doc);
+        Util.assertGraphDocumentEquals(doc, new GraphDocument());
+    }
+
+	@Test
+	public void testSimpleExport() {
+		GraphDocument document = new GraphDocument();
+		Group g = new Group();
+		document.addGroup(g);
+        
+		InputGraph graph = g.addGraph("TestGraph");
+		graph.getProperties().setProperty("testName", "testValue");
+
+		InputNode n1 = new InputNode(0);
+		InputNode n2 = new InputNode(1);
+		InputEdge e1 = new InputEdge((char)0, 0, 1);
+		InputEdge e2 = new InputEdge((char)1, 0, 1);
+		graph.addNode(n1);
+		graph.addNode(n2);
+		graph.addEdge(e1);
+		graph.addEdge(e2);
+        
+        test(document);
+	}
+
+	@Test
+	public void testComplexExport() {
+
+		GraphDocument document = new GraphDocument();
+		Group g = new Group();
+		document.addGroup(g);
+
+		InputGraph graph = g.addGraph("TestGraph");
+		graph.getProperties().setProperty("testName", "testValue");
+
+		InputNode n1 = new InputNode(0);
+		InputNode n2 = new InputNode(1);
+		InputEdge e1 = new InputEdge((char)0, 0, 0);
+		InputEdge e2 = new InputEdge((char)1, 1, 1);
+		graph.addNode(n1);
+		graph.addNode(n2);
+		graph.addEdge(e1);
+		graph.addEdge(e2);
+
+		InputGraph graph2 = g.addGraph("TestGraph2");
+		graph2.addNode(n1);
+		InputNode n3 = new InputNode(2);
+		graph2.addNode(n3);
+		InputEdge e3 = new InputEdge((char)0, 0, 2);
+		graph2.addEdge(e3);
+
+        test(document);
+	}
+
+
+    /**
+     * Test of parse method, of class Parser.
+     */
+    @Test
+    public void testParse() {
+        testBoth(new GraphDocument(), "<graphDocument></graphDocument>");
+    }
+
+}
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Wed Jun 08 17:26:49 2011 +0200
@@ -28,6 +28,7 @@
 import com.sun.hotspot.igv.data.InputEdge;
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Pair;
 import com.sun.hotspot.igv.data.Property;
 import java.util.Collection;
 import java.util.HashMap;
@@ -60,14 +61,14 @@
     }
 
     private static InputGraph createDiffSameGroup(InputGraph a, InputGraph b) {
-        Map<Integer, InputNode> keyMapB = new HashMap<Integer, InputNode>();
+        Map<Integer, InputNode> keyMapB = new HashMap<Integer, InputNode>(b.getNodes().size());
         for (InputNode n : b.getNodes()) {
             Integer key = n.getId();
             assert !keyMapB.containsKey(key);
             keyMapB.put(key, n);
         }
 
-        Set<Pair> pairs = new HashSet<Pair>();
+        Set<NodePair> pairs = new HashSet<NodePair>();
 
         for (InputNode n : a.getNodes()) {
             Integer key = n.getId();
@@ -75,30 +76,28 @@
 
             if (keyMapB.containsKey(key)) {
                 InputNode nB = keyMapB.get(key);
-                pairs.add(new Pair(n, nB));
+                pairs.add(new NodePair(n, nB));
             }
         }
 
         return createDiff(a, b, pairs);
     }
 
-    private static InputGraph createDiff(InputGraph a, InputGraph b, Set<Pair> pairs) {
+    private static InputGraph createDiff(InputGraph a, InputGraph b, Set<NodePair> pairs) {
         Group g = new Group();
         g.setMethod(a.getGroup().getMethod());
         g.setAssembly(a.getGroup().getAssembly());
         g.getProperties().setProperty("name", "Difference");
-        InputGraph graph = new InputGraph(g, null);
-        graph.setName(a.getName() + ", " + b.getName());
-        graph.setIsDifferenceGraph(true);
+        InputGraph graph = g.addGraph(a.getName() + ", " + b.getName(), new Pair<InputGraph, InputGraph>(a, b));
 
         Set<InputNode> nodesA = new HashSet<InputNode>(a.getNodes());
         Set<InputNode> nodesB = new HashSet<InputNode>(b.getNodes());
 
-        Map<InputNode, InputNode> inputNodeMap = new HashMap<InputNode, InputNode>();
-        for (Pair p : pairs) {
-            InputNode n = p.getN1();
+        Map<InputNode, InputNode> inputNodeMap = new HashMap<InputNode, InputNode>(pairs.size());
+        for (NodePair p : pairs) {
+            InputNode n = p.getLeft();
             assert nodesA.contains(n);
-            InputNode nB = p.getN2();
+            InputNode nB = p.getRight();
             assert nodesB.contains(nB);
 
             nodesA.remove(n);
@@ -113,15 +112,22 @@
         for (InputNode n : nodesA) {
             InputNode n2 = new InputNode(n);
             graph.addNode(n2);
-            markAsNew(n2);
+            markAsDeleted(n2);
             inputNodeMap.put(n, n2);
         }
 
+        int curIndex = 0;
         for (InputNode n : nodesB) {
             InputNode n2 = new InputNode(n);
-            n2.setId(-n2.getId());
+            
+            // Find new ID for node of b, does not change the id property
+            while (graph.getNode(curIndex) != null) {
+                curIndex++;
+            }
+
+            n2.setId(curIndex);
             graph.addNode(n2);
-            markAsDeleted(n2);
+            markAsNew(n2);
             inputNodeMap.put(n, n2);
         }
 
@@ -140,7 +146,7 @@
 
             InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
             if (!newEdges.contains(newEdge)) {
-                markAsNew(newEdge);
+                markAsDeleted(newEdge);
                 newEdges.add(newEdge);
                 graph.addEdge(newEdge);
             }
@@ -156,7 +162,7 @@
 
             InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId());
             if (!newEdges.contains(newEdge)) {
-                markAsDeleted(newEdge);
+                markAsNew(newEdge);
                 newEdges.add(newEdge);
                 graph.addEdge(newEdge);
             } else {
@@ -168,24 +174,20 @@
             }
         }
 
-        g.addGraph(graph);
         return graph;
     }
 
-    private static class Pair {
+    private static class NodePair extends Pair<InputNode, InputNode> {
+
 
-        private InputNode n1;
-        private InputNode n2;
-
-        public Pair(InputNode n1, InputNode n2) {
-            this.n1 = n1;
-            this.n2 = n2;
+        public NodePair(InputNode n1, InputNode n2) {
+            super(n1, n2);
         }
 
         public double getValue() {
 
             double result = 0.0;
-            for (Property p : n1.getProperties()) {
+            for (Property p : getLeft().getProperties()) {
                 double faktor = 1.0;
                 for (String forbidden : IGNORE_PROPERTIES) {
                     if (p.getName().equals(forbidden)) {
@@ -193,7 +195,7 @@
                         break;
                     }
                 }
-                String p2 = n2.getProperties().get(p.getName());
+                String p2 = getRight().getProperties().get(p.getName());
                 result += evaluate(p.getValue(), p2) * faktor;
             }
 
@@ -210,21 +212,13 @@
                 return (double) (Math.abs(p.length() - p2.length())) / p.length() + 0.5;
             }
         }
-
-        public InputNode getN1() {
-            return n1;
-        }
-
-        public InputNode getN2() {
-            return n2;
-        }
     }
 
     private static InputGraph createDiff(InputGraph a, InputGraph b) {
 
         Set<InputNode> matched = new HashSet<InputNode>();
 
-        Set<Pair> pairs = new HashSet<Pair>();
+        Set<NodePair> pairs = new HashSet<NodePair>();
         for (InputNode n : a.getNodes()) {
             String s = n.getProperties().get(MAIN_PROPERTY);
             if (s == null) {
@@ -237,18 +231,18 @@
                 }
 
                 if (s.equals(s2)) {
-                    Pair p = new Pair(n, n2);
+                    NodePair p = new NodePair(n, n2);
                     pairs.add(p);
                 }
             }
         }
 
-        Set<Pair> selectedPairs = new HashSet<Pair>();
+        Set<NodePair> selectedPairs = new HashSet<NodePair>();
         while (pairs.size() > 0) {
 
             double min = Double.MAX_VALUE;
-            Pair minPair = null;
-            for (Pair p : pairs) {
+            NodePair minPair = null;
+            for (NodePair p : pairs) {
                 double cur = p.getValue();
                 if (cur < min) {
                     minPair = p;
@@ -261,9 +255,9 @@
             } else {
                 selectedPairs.add(minPair);
 
-                Set<Pair> toRemove = new HashSet<Pair>();
-                for (Pair p : pairs) {
-                    if (p.getN1() == minPair.getN1() || p.getN2() == minPair.getN2()) {
+                Set<NodePair> toRemove = new HashSet<NodePair>();
+                for (NodePair p : pairs) {
+                    if (p.getLeft() == minPair.getLeft() || p.getRight() == minPair.getRight()) {
                         toRemove.add(p);
                     }
                 }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.filter.JavaSE6ScriptEngine
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CombineFilter.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CombineFilter.java	Wed Jun 08 17:26:49 2011 +0200
@@ -77,7 +77,7 @@
                         }
 
                         assert slot != null;
-                        slot.setName(f.getProperties().get("dump_spec"));
+                        slot.setText(f.getProperties().get("dump_spec"));
                         if (f.getProperties().get("short_name") != null) {
                             slot.setShortName(f.getProperties().get("short_name"));
                         } else {
@@ -122,7 +122,7 @@
                                     pos = Integer.parseInt(succ.getProperties().get("con"));
                                 }
                                 OutputSlot slot = f.createOutputSlot(pos);
-                                slot.setName(succ.getProperties().get("dump_spec"));
+                                slot.setText(succ.getProperties().get("dump_spec"));
                                 if (succ.getProperties().get("short_name") != null) {
                                     slot.setShortName(succ.getProperties().get("short_name"));
                                 } else {
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Wed Jun 08 17:26:49 2011 +0200
@@ -89,7 +89,9 @@
     public boolean openInEditor() {
         EditFilterDialog dialog = new EditFilterDialog(CustomFilter.this);
         dialog.setVisible(true);
-        return dialog.wasAccepted();
+        boolean result = dialog.wasAccepted();
+        this.getChangedEvent().fire();
+        return result;
     }
 
     @Override
@@ -100,18 +102,12 @@
     public static ScriptEngineAbstraction getEngine() {
         if (engine == null) {
 
+            Collection<? extends ScriptEngineAbstraction> list = Lookup.getDefault().lookupAll(ScriptEngineAbstraction.class);
             ScriptEngineAbstraction chosen = null;
-            try {
-                Collection<? extends ScriptEngineAbstraction> list = Lookup.getDefault().lookupAll(ScriptEngineAbstraction.class);
-                for (ScriptEngineAbstraction s : list) {
-                    if (s.initialize(getJsHelperText())) {
-                        if (chosen == null || !(chosen instanceof JavaSE6ScriptEngine)) {
-                            chosen = s;
-                        }
-                    }
+            for (ScriptEngineAbstraction s : list) {
+                if (s.initialize(getJsHelperText())) {
+                    chosen = s;
                 }
-            } catch (NoClassDefFoundError ncdfe) {
-                Logger.getLogger("global").log(Level.SEVERE, null, ncdfe);
             }
 
             if (chosen == null) {
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.java	Wed Jun 08 17:26:49 2011 +0200
@@ -137,17 +137,17 @@
     }// </editor-fold>//GEN-END:initComponents
 
 private void okButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonClicked
-        this.customFilter.setName(this.nameTextField.getText());
-        this.customFilter.setCode(this.sourceTextArea.getText());
-        accepted = true;
-        setVisible(false);
+	this.customFilter.setName(this.nameTextField.getText());
+	this.customFilter.setCode(this.sourceTextArea.getText());
+	accepted = true;
+	setVisible(false);
 }//GEN-LAST:event_okButtonClicked
 
 private void cancelButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonClicked
-        setVisible(false);
+	setVisible(false);
 }//GEN-LAST:event_cancelButtonClicked
-
-
+	
+	
     // Variables declaration - do not modify//GEN-BEGIN:variables
     private javax.swing.JButton cancelButton;
     private javax.swing.JScrollPane jScrollPane1;
@@ -157,5 +157,5 @@
     private javax.swing.JLabel sourceLabel;
     private javax.swing.JTextArea sourceTextArea;
     // End of variables declaration//GEN-END:variables
-
+	
 }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChain.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChain.java	Wed Jun 08 17:26:49 2011 +0200
@@ -26,6 +26,7 @@
 import com.sun.hotspot.igv.graph.Diagram;
 import com.sun.hotspot.igv.data.ChangedEvent;
 import com.sun.hotspot.igv.data.ChangedEventProvider;
+import com.sun.hotspot.igv.data.ChangedListener;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -38,18 +39,21 @@
 
     private List<Filter> filters;
     private transient ChangedEvent<FilterChain> changedEvent;
-    private boolean fireEvents;
+    
+    private ChangedListener<Filter> changedListener = new ChangedListener<Filter>() {
+        public void changed(Filter source) {
+            changedEvent.fire();
+        }
+    };
 
     public FilterChain() {
         filters = new ArrayList<Filter>();
         changedEvent = new ChangedEvent<FilterChain>(this);
-        this.fireEvents = true;
     }
 
     public FilterChain(FilterChain f) {
         this.filters = new ArrayList<Filter>(f.filters);
         changedEvent = new ChangedEvent<FilterChain>(this);
-        this.fireEvents = true;
     }
 
     public ChangedEvent<FilterChain> getChangedEvent() {
@@ -84,29 +88,12 @@
         }
     }
 
-    public void beginAtomic() {
-        this.fireEvents = false;
-    }
-
-    public void endAtomic() {
-        this.fireEvents = true;
-        changedEvent.fire();
-    }
 
     public void addFilter(Filter filter) {
         assert filter != null;
         filters.add(filter);
-        if (fireEvents) {
-            changedEvent.fire();
-        }
-    }
-
-    public void addFilterSameSequence(Filter filter) {
-        assert filter != null;
-        filters.add(filter);
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        filter.getChangedEvent().addListener(changedListener);
+        changedEvent.fire();
     }
 
     public boolean containsFilter(Filter filter) {
@@ -116,9 +103,8 @@
     public void removeFilter(Filter filter) {
         assert filters.contains(filter);
         filters.remove(filter);
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        filter.getChangedEvent().removeListener(changedListener);
+        changedEvent.fire();
     }
 
     public void moveFilterUp(Filter filter) {
@@ -128,9 +114,7 @@
             filters.remove(index);
             filters.add(index - 1, filter);
         }
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        changedEvent.fire();
     }
 
     public void moveFilterDown(Filter filter) {
@@ -140,16 +124,10 @@
             filters.remove(index);
             filters.add(index + 1, filter);
         }
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        changedEvent.fire();
     }
 
     public List<Filter> getFilters() {
         return Collections.unmodifiableList(filters);
     }
-
-    public void clear() {
-        filters.clear();
-    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/JavaSE6ScriptEngine.java	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.hotspot.igv.filter;
-
-import com.sun.hotspot.igv.graph.Diagram;
-import javax.script.Bindings;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import org.openide.util.Exceptions;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class JavaSE6ScriptEngine implements ScriptEngineAbstraction {
-
-    private ScriptEngine engine;
-    private Bindings bindings;
-
-    public boolean initialize(String jsHelperText) {
-        try {
-            ScriptEngineManager sem = new ScriptEngineManager();
-            ScriptEngine e = sem.getEngineByName("ECMAScript");
-            engine = e;
-            e.eval(jsHelperText);
-            Bindings b = e.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
-            b.put("IO", System.out);
-            bindings = b;
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    public void execute(Diagram d, String code) {
-        try {
-            Bindings b = bindings;
-            b.put("graph", d);
-            engine.eval(code, b);
-        } catch (ScriptException ex) {
-            Exceptions.printStackTrace(ex);
-        }
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveInputsFilter.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveInputsFilter.java	Wed Jun 08 17:26:49 2011 +0200
@@ -73,7 +73,7 @@
                         }
                         is.removeAllConnections();
                         is.setShortName("X");
-                        is.setName(sb.toString());
+                        is.setText(sb.toString());
                         last.add(is);
                     } else {
                         last.clear();
@@ -91,10 +91,10 @@
                         if (i != 0) {
                             sb.append("<BR>");
                         }
-                        sb.append(is2.getName());
+                        sb.append(is2.getText());
                     }
 
-                    first.setName(sb.toString());
+                    first.setText(sb.toString());
 
                     for (int i = 1; i < last.size(); i++) {
                         f.removeSlot(last.get(i));
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveSelfLoopsFilter.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveSelfLoopsFilter.java	Wed Jun 08 17:26:49 2011 +0200
@@ -72,7 +72,7 @@
                     }
 
                     c.getInputSlot().setShortName("O");
-                    c.getInputSlot().setName("Self Loop");
+                    c.getInputSlot().setText("Self Loop");
                 }
             }
         }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Wed Jun 08 17:26:49 2011 +0200
@@ -39,25 +39,50 @@
 
     private String name;
     private Selector selector;
+    private String propertyName;
 
-    public SplitFilter(String name, Selector selector) {
+    public SplitFilter(String name, Selector selector, String propertyName) {
         this.name = name;
         this.selector = selector;
+        this.propertyName = propertyName;
     }
 
     public String getName() {
         return name;
     }
-
+    
     public void apply(Diagram d) {
         List<Figure> list = selector.selected(d);
 
         for (Figure f : list) {
+            
+            for (InputSlot is : f.getInputSlots()) {
+                for (Connection c : is.getConnections()) {
+                    OutputSlot os = c.getOutputSlot();
+                    if (f.getSource().getSourceNodes().size() > 0) {
+                        os.getSource().addSourceNodes(f.getSource());
+                        os.setAssociatedNode(f.getSource().getSourceNodes().get(0));
+                        os.setColor(f.getColor());
+                    }
+
+
+                    String s = Figure.resolveString(propertyName, f.getProperties());
+                    if (s != null) {
+                        os.setShortName(s);
+                    }
+
+                }
+            }
             for (OutputSlot os : f.getOutputSlots()) {
                 for (Connection c : os.getConnections()) {
                     InputSlot is = c.getInputSlot();
-                    is.setName(f.getProperties().get("dump_spec"));
-                    String s = f.getProperties().get("short_name");
+                    if (f.getSource().getSourceNodes().size() > 0) {
+                        is.getSource().addSourceNodes(f.getSource());
+                        is.setAssociatedNode(f.getSource().getSourceNodes().get(0));
+                        is.setColor(f.getColor());
+                    }
+
+                    String s = Figure.resolveString(propertyName, f.getProperties());
                     if (s != null) {
                         is.setShortName(s);
                     }
--- a/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js	Wed Jun 08 17:26:49 2011 +0200
@@ -21,16 +21,16 @@
  * questions.
  *
  */
-
+ 
  /**
  *
  * @author Thomas Wuerthinger
  */
-
+ 
 function colorize(property, regexp, color) {
     var f = new ColorFilter("");
     f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), color));
-    f.apply(graph);
+    f.apply(graph); 
 }
 
 function remove(property, regexp) {
@@ -39,8 +39,11 @@
     f.apply(graph);
 }
 
-function split(property, regexp) {
-    var f = new SplitFilter("", new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)));
+function split(property, regexp, propertyName) {
+    if (propertyName == undefined) {
+        propertyName = graph.getNodeText();
+    }
+    var f = new SplitFilter("", new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), propertyName);
     f.apply(graph);
 }
 
@@ -68,4 +71,4 @@
 var pink = Color.pink
 var red = Color.red;
 var yellow = Color.yellow;
-var white = Color.white;
+var white = Color.white;
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/genfiles.properties	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/genfiles.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -1,6 +1,3 @@
-build.xml.data.CRC32=09ba2a87
-build.xml.script.CRC32=9c158403
-build.xml.stylesheet.CRC32=a56c6a5b@1.45.1
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
 nbproject/build-impl.xml.data.CRC32=09ba2a87
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.form	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.form	Wed Jun 08 17:26:49 2011 +0200
@@ -3,6 +3,7 @@
 <Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java	Wed Jun 08 17:26:49 2011 +0200
@@ -84,7 +84,7 @@
 import org.openide.filesystems.FileObject;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
 public final class FilterTopComponent extends TopComponent implements LookupListener, ExplorerManager.Provider {
@@ -139,7 +139,7 @@
 
         if (s != customFilterSetting) {
             FilterChain chain = getFilterChain();
-            chain.beginAtomic();
+            chain.getChangedEvent().beginAtomic();
             List<Filter> toRemove = new ArrayList<Filter>();
             for (Filter f : chain.getFilters()) {
                 if (!s.containsFilter(f)) {
@@ -156,7 +156,7 @@
                 }
             }
 
-            chain.endAtomic();
+            chain.getChangedEvent().endAtomic();
             filterSettingsChangedEvent.fire();
         } else {
             this.updateComboBoxSelection();
@@ -269,8 +269,6 @@
 
     private class FilterChildren extends Children.Keys implements ChangedListener<CheckNode> {
 
-        //private Node[] oldSelection;
-        //private ArrayList<Node> newSelection;
         private HashMap<Object, Node> nodeHash = new HashMap<Object, Node>();
 
         protected Node[] createNodes(Object object) {
@@ -280,7 +278,7 @@
 
             assert object instanceof Filter;
             Filter filter = (Filter) object;
-            com.sun.hotspot.igv.filterwindow.FilterNode node = new com.sun.hotspot.igv.filterwindow.FilterNode(filter);
+            FilterNode node = new FilterNode(filter);
             node.getSelectionChangedEvent().addListener(this);
             nodeHash.put(object, node);
             return new Node[]{node};
@@ -322,12 +320,7 @@
     }
 
     public FilterChain getFilterChain() {
-        return filterChain;/*
-    EditorTopComponent tc = EditorTopComponent.getActive();
-    if (tc == null) {
-    return filterChain;
-    }
-    return tc.getFilterChain();*/
+        return filterChain;
     }
 
     private FilterTopComponent() {
@@ -566,7 +559,6 @@
         return PREFERRED_ID;
     }
 
-    @Override
     public ExplorerManager getExplorerManager() {
         return manager;
     }
@@ -586,11 +578,6 @@
 
     public void resultChanged(LookupEvent lookupEvent) {
         setChain(Utilities.actionsGlobalContext().lookup(FilterChain.class));
-    /*
-    EditorTopComponent tc = EditorTopComponent.getActive();
-    if (tc != null) {
-    setChain(tc.getFilterChain());
-    }*/
     }
 
     public void setChain(FilterChain chain) {
@@ -610,6 +597,24 @@
     }
 
     @Override
+    public boolean requestFocus(boolean temporary) {
+        view.requestFocus();
+        return super.requestFocus(temporary);
+    }
+
+    @Override
+    protected boolean requestFocusInWindow(boolean temporary) {
+        view.requestFocus();
+        return super.requestFocusInWindow(temporary);
+    }
+
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        view.requestFocus();
+    }
+
+    @Override
     public void writeExternal(ObjectOutput out) throws IOException {
         super.writeExternal(out);
 
--- a/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/Bundle.properties	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -1,10 +1,7 @@
-# To change this template, choose Tools | Templates
-# and open the template in the editor.
-
-CTL_FilterAction=Open Filter Window
+CTL_FilterAction=Open Filter Window 
+CTL_MoveFilterUpAction=Move upwards
 CTL_MoveFilterDownAction=Move downwards
-CTL_MoveFilterUpAction=Move upwards
-CTL_NewFilterAction=New filter...
 CTL_RemoveFilterAction=Remove
 CTL_RemoveFilterSettingsAction=Remove filter setting
 CTL_SaveFilterSettingsAction=Save filter settings...
+CTL_NewFilterAction=New filter...
--- a/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -25,6 +25,7 @@
             </module-dependencies>
             <public-packages>
                 <package>com.sun.hotspot.igv.graph</package>
+                <package>com.sun.hotspot.igv.graph.services</package>
             </public-packages>
         </data>
     </configuration>
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Block.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Block.java	Wed Jun 08 17:26:49 2011 +0200
@@ -60,14 +60,6 @@
         return succs;
     }
 
-    public Set<? extends Cluster> getPredecessors() {
-        Set<Block> succs = new HashSet<Block>();
-        for (InputBlock b : inputBlock.getPredecessors()) {
-            succs.add(diagram.getBlock(b));
-        }
-        return succs;
-    }
-
     public void setBounds(Rectangle r) {
         this.bounds = r;
     }
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Connection.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Connection.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,6 +23,7 @@
  */
 package com.sun.hotspot.igv.graph;
 
+import com.sun.hotspot.igv.data.Source;
 import com.sun.hotspot.igv.layout.Link;
 import com.sun.hotspot.igv.layout.Port;
 import java.awt.Color;
@@ -31,7 +32,7 @@
 import java.util.List;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
 public class Connection implements Source.Provider, Link {
@@ -99,6 +100,10 @@
         outputSlot.getFigure().removeSuccessor(inputSlot.getFigure());
         outputSlot.connections.remove(this);
     }
+    
+    public String getToolTipText() {
+        return "From " + this.getOutputSlot().getFigure().toString() + " to " + this.getInputSlot().getFigure();
+    }
 
     @Override
     public String toString() {
@@ -121,3 +126,4 @@
         controlPoints = list;
     }
 }
+
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Wed Jun 08 17:26:49 2011 +0200
@@ -28,6 +28,7 @@
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
 import java.awt.Font;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -35,7 +36,8 @@
 import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -52,19 +54,26 @@
     private int curId;
     private String nodeText;
     private Font font;
+    private Font slotFont;
 
     public Font getFont() {
         return font;
     }
 
+    public Font getSlotFont() {
+        return slotFont;
+    }
+    
     private Diagram() {
         figures = new ArrayList<Figure>();
-        blocks = new HashMap<InputBlock, Block>();
+        blocks = new LinkedHashMap<InputBlock, Block>(8);
         this.nodeText = "";
-        this.font = new Font("Serif", Font.PLAIN, 14);
+        this.font = new Font("Arial", Font.PLAIN, 13);
+        this.slotFont = new Font("Arial", Font.PLAIN, 10);
     }
 
     public Block getBlock(InputBlock b) {
+        assert blocks.containsKey(b);
         return blocks.get(b);
     }
 
@@ -72,12 +81,7 @@
         return nodeText;
     }
 
-    public void schedule(Collection<InputBlock> newBlocks) {
-        graph.schedule(newBlocks);
-        updateBlocks();
-    }
-
-    private void updateBlocks() {
+    public void updateBlocks() {
         blocks.clear();
         for (InputBlock b : graph.getBlocks()) {
             Block curBlock = new Block(b, this);
@@ -113,6 +117,22 @@
         assert outputSlot.getFigure().getDiagram() == this;
         return new Connection(inputSlot, outputSlot);
     }
+    
+    public Map<InputNode, Set<Figure>> calcSourceToFigureRelation() {
+        Map<InputNode, Set<Figure>> map = new HashMap<InputNode, Set<Figure>>();
+        
+        for(InputNode node : this.getGraph().getNodes()) {
+            map.put(node, new HashSet<Figure>());
+        }
+        
+        for(Figure f : this.getFigures()) {
+            for(InputNode node : f.getSource().getSourceNodes()) {
+                map.get(node).add(f);
+            }
+        }
+        
+        return map;
+    }
 
     public static Diagram createDiagram(InputGraph graph, String nodeText) {
         if (graph == null) {
@@ -126,7 +146,7 @@
         d.updateBlocks();
 
         Collection<InputNode> nodes = graph.getNodes();
-        HashMap<Integer, Figure> figureHash = new HashMap<Integer, Figure>();
+        Hashtable<Integer, Figure> figureHash = new Hashtable<Integer, Figure>();
         for (InputNode n : nodes) {
             Figure f = d.createFigure();
             f.getSource().addSourceNode(n);
@@ -141,6 +161,8 @@
             Figure fromFigure = figureHash.get(from);
             Figure toFigure = figureHash.get(to);
             assert fromFigure != null && toFigure != null;
+            
+            if(fromFigure == null || toFigure == null) continue;
 
             int fromIndex = e.getFromIndex();
             while (fromFigure.getOutputSlots().size() <= fromIndex) {
@@ -230,9 +252,9 @@
 
     public Figure getRootFigure() {
         Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(figures);
-        Figure root = selector.selectSingle("name", "Root");
+        Figure root = selector.selectSingle(new StringPropertyMatcher("name", "Root"));
         if (root == null) {
-            root = selector.selectSingle("name", "Start");
+            root = selector.selectSingle(new StringPropertyMatcher("name", "Start"));
         }
         if (root == null) {
             List<Figure> rootFigures = getRootFigures();
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,16 +23,21 @@
  */
 package com.sun.hotspot.igv.graph;
 
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.data.Source;
+import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.layout.Cluster;
 import com.sun.hotspot.igv.layout.Vertex;
 import com.sun.hotspot.igv.data.Properties;
 import java.awt.Color;
 import java.awt.Dimension;
+import java.awt.Font;
 import java.awt.FontMetrics;
 import java.awt.Graphics;
 import java.awt.Point;
 import java.awt.image.BufferedImage;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
@@ -44,9 +49,11 @@
  */
 public class Figure extends Properties.Entity implements Source.Provider, Vertex {
 
-    public static final int INSET = 6;
-    public static final int SLOT_WIDTH = 10;
-    public static final int SLOT_START = 3;
+    public static final int INSET = 12;
+    public static int SLOT_WIDTH = 12;
+    public static final int OVERLAPPING = 6;
+    public static final int SLOT_START = 4;
+    public static final int SLOT_OFFSET = 8;
     public static final boolean VERTICAL_LAYOUT = true;
     protected List<InputSlot> inputSlots;
     protected List<OutputSlot> outputSlots;
@@ -66,28 +73,49 @@
         if (heightCash == -1) {
             BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
             Graphics g = image.getGraphics();
-            g.setFont(diagram.getFont());
+            g.setFont(diagram.getFont().deriveFont(Font.BOLD));
             FontMetrics metrics = g.getFontMetrics();
             String nodeText = diagram.getNodeText();
             heightCash = nodeText.split("\n").length * metrics.getHeight() + INSET;
         }
         return heightCash;
     }
+    
+    public static <T> List<T> getAllBefore(List<T> inputList, T tIn) {
+        List<T> result = new ArrayList<T>();
+        for(T t : inputList) {
+            if(t.equals(tIn)) {
+                break;
+            }
+            result.add(t);
+        }
+        return result;
+    }
+    
+    public static int getSlotsWidth(Collection<? extends Slot> slots) {
+        int result = Figure.SLOT_OFFSET;
+        for(Slot s : slots) {
+            result += s.getWidth() + Figure.SLOT_OFFSET;
+        }
+        return result;
+    }
 
     public int getWidth() {
         if (widthCash == -1) {
             int max = 0;
             BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
             Graphics g = image.getGraphics();
-            g.setFont(diagram.getFont());
+            g.setFont(diagram.getFont().deriveFont(Font.BOLD));
             FontMetrics metrics = g.getFontMetrics();
-            for (String s : lines) {
+            for (String s : getLines()) {
                 int cur = metrics.stringWidth(s);
                 if (cur > max) {
                     max = cur;
                 }
             }
             widthCash = max + INSET;
+            widthCash = Math.max(widthCash, Figure.getSlotsWidth(inputSlots));
+            widthCash = Math.max(widthCash, Figure.getSlotsWidth(outputSlots));
         }
         return widthCash;
     }
@@ -221,6 +249,13 @@
     public List<InputSlot> getInputSlots() {
         return Collections.unmodifiableList(inputSlots);
     }
+    
+    public Set<Slot> getSlots() {
+        Set<Slot> result = new HashSet<Slot>();
+        result.addAll(getInputSlots());
+        result.addAll(getOutputSlots());
+        return result;
+    }
 
     public List<OutputSlot> getOutputSlots() {
         return Collections.unmodifiableList(outputSlots);
@@ -248,13 +283,13 @@
         String[] result = new String[strings.length];
 
         for (int i = 0; i < strings.length; i++) {
-            result[i] = resolveString(strings[i]);
+            result[i] = resolveString(strings[i], getProperties());
         }
 
         lines = result;
     }
 
-    private String resolveString(String string) {
+    public static final String resolveString(String string, Properties properties) {
 
         StringBuilder sb = new StringBuilder();
         boolean inBrackets = false;
@@ -264,7 +299,7 @@
             char c = string.charAt(i);
             if (inBrackets) {
                 if (c == ']') {
-                    String value = getProperties().get(curIdent.toString());
+                    String value = properties.get(curIdent.toString());
                     if (value == null) {
                         value = "";
                     }
@@ -289,10 +324,12 @@
     public Dimension getSize() {
         if (VERTICAL_LAYOUT) {
             int width = Math.max(getWidth(), Figure.SLOT_WIDTH * (Math.max(inputSlots.size(), outputSlots.size()) + 1));
-            int height = getHeight() + 2 * Figure.SLOT_WIDTH;
+            int height = getHeight() + 2 * Figure.SLOT_WIDTH - 2 * Figure.OVERLAPPING;
+            
+            
             return new Dimension(width, height);
         } else {
-            int width = getWidth() + 2 * Figure.SLOT_WIDTH;
+            int width = getWidth() + 2 * Figure.SLOT_WIDTH - 2*Figure.OVERLAPPING;
             int height = Figure.SLOT_WIDTH * (Math.max(inputSlots.size(), outputSlots.size()) + 1);
             return new Dimension(width, height);
         }
@@ -308,15 +345,19 @@
             assert false : "Should never reach here, every figure must have at least one source node!";
             return null;
         } else {
-            Cluster result = diagram.getBlock(diagram.getGraph().getBlock(getSource().getSourceNodes().get(0)));
+            final InputBlock inputBlock = diagram.getGraph().getBlock(getSource().getSourceNodes().get(0));
+            assert inputBlock != null;
+            Cluster result = diagram.getBlock(inputBlock);
             assert result != null;
             return result;
         }
     }
 
     public boolean isRoot() {
-        if (source.getSourceNodes().size() > 0 && source.getSourceNodes().get(0).getProperties().get("name").equals("Root")) {
-            return true;
+  
+        List<InputNode> sourceNodes = source.getSourceNodes();
+        if (sourceNodes.size() > 0 && sourceNodes.get(0).getProperties().get("name") != null) {
+            return source.getSourceNodes().get(0).getProperties().get("name").equals("Root");
         } else {
             return false;
         }
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InputSlot.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InputSlot.java	Wed Jun 08 17:26:49 2011 +0200
@@ -27,7 +27,7 @@
 import java.util.List;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
 public class InputSlot extends Slot {
@@ -45,9 +45,12 @@
         InputSlot s = inputSlots.remove(position);
         inputSlots.add(position, s);
     }
-
     public Point getRelativePosition() {
-        return new Point(getFigure().getWidth() * (getPosition() + 1) / (getFigure().getInputSlots().size() + 1), Figure.SLOT_WIDTH - Figure.SLOT_START);
+        int gap = getFigure().getWidth() - Figure.getSlotsWidth(getFigure().getInputSlots());
+        double gapRatio = (double)gap / (double)(getFigure().getInputSlots().size() + 1);
+        int gapAmount = (int)((getPosition() + 1)*gapRatio);
+        return new Point(gapAmount + Figure.getSlotsWidth(Figure.getAllBefore(getFigure().getInputSlots(), this)) + getWidth()/2, -Figure.SLOT_START);
+        //return new Point((getFigure().getWidth() / (getFigure().getInputSlots().size() * 2)) * (getPosition() * 2 + 1), -Figure.SLOT_START);
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OutputSlot.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OutputSlot.java	Wed Jun 08 17:26:49 2011 +0200
@@ -26,7 +26,7 @@
 import java.awt.Point;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
 public class OutputSlot extends Slot {
@@ -45,7 +45,13 @@
     }
 
     public Point getRelativePosition() {
-        return new Point(getFigure().getWidth() * (getPosition() + 1) / (getFigure().getOutputSlots().size() + 1), getFigure().getSize().height - Figure.SLOT_WIDTH + Figure.SLOT_START);
+        int gap = getFigure().getWidth() - Figure.getSlotsWidth(getFigure().getOutputSlots());
+        if(gap < 0) {
+            gap = 0;
+        }
+        double gapRatio = (double)gap / (double)(getFigure().getOutputSlots().size() + 1);
+        int gapAmount = (int)((getPosition() + 1)*gapRatio);
+        return new Point(gapAmount + Figure.getSlotsWidth(Figure.getAllBefore(getFigure().getOutputSlots(), this)) + getWidth()/2, Figure.SLOT_START);
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,103 +23,168 @@
  */
 package com.sun.hotspot.igv.graph;
 
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Source;
 import com.sun.hotspot.igv.layout.Port;
 import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Comparator;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
-public abstract class Slot implements Port, Source.Provider {
-
-    private int wantedIndex;
-    private String name;
-    private String shortName; // 1 - 2 characters
-    private Source source;
-    protected List<Connection> connections;
-    private Figure figure;
+public abstract class Slot implements Port, Source.Provider, Properties.Provider {
 
-    protected Slot(Figure figure, int wantedIndex) {
-        this.figure = figure;
-        connections = new ArrayList<Connection>(2);
-        source = new Source();
-        this.wantedIndex = wantedIndex;
-        name = "";
-        shortName = "";
-        assert figure != null;
-    }
-    public static final Comparator<Slot> slotIndexComparator = new Comparator<Slot>() {
+	private int wantedIndex;
+	private Source source;
+	protected List<Connection> connections;
+	private InputNode associatedNode;
+	private Color color;
+	private String text;
+	private String shortName;
+	private Figure figure;
+
+	protected Slot(Figure figure, int wantedIndex) {
+		this.figure = figure;
+		connections = new ArrayList<Connection>(2);
+		source = new Source();
+		this.wantedIndex = wantedIndex;
+		text = "";
+		shortName = "";
+		assert figure != null;
+	}
 
-        public int compare(Slot o1, Slot o2) {
-            return o1.wantedIndex - o2.wantedIndex;
-        }
-    };
-    public static final Comparator<Slot> slotFigureComparator = new Comparator<Slot>() {
+	public Properties getProperties() {
+		Properties p = new Properties();
+		if (source.getSourceNodes().size() > 0) {
+			for (InputNode n : source.getSourceNodes()) {
+				p.add(n.getProperties());
+			}
+		} else {
+			p.setProperty("name", "Slot");
+			p.setProperty("figure", figure.getProperties().get("name"));
+			p.setProperty("connectionCount", Integer.toString(connections.size()));
+		}
+		return p;
+	}
+	public static final Comparator<Slot> slotIndexComparator = new Comparator<Slot>() {
 
-        public int compare(Slot o1, Slot o2) {
-            return o1.figure.getId() - o2.figure.getId();
-        }
-    };
+		public int compare(Slot o1, Slot o2) {
+			return o1.wantedIndex - o2.wantedIndex;
+		}
+	};
+	public static final Comparator<Slot> slotFigureComparator = new Comparator<Slot>() {
 
-    public int getWantedIndex() {
-        return wantedIndex;
-    }
+		public int compare(Slot o1, Slot o2) {
+			return o1.figure.getId() - o2.figure.getId();
+		}
+	};
+
+	public InputNode getAssociatedNode() {
+		return associatedNode;
+	}
+
+	public void setAssociatedNode(InputNode node) {
+		associatedNode = node;
+	}
 
-    public Source getSource() {
-        return source;
-    }
+	public int getWidth() {
+		if (shortName == null || shortName.length() <= 1) {
+			return Figure.SLOT_WIDTH;
+		} else {
+			BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
+			Graphics g = image.getGraphics();
+			g.setFont(figure.getDiagram().getSlotFont().deriveFont(Font.BOLD));
+			FontMetrics metrics = g.getFontMetrics();
+			return Math.max(Figure.SLOT_WIDTH, metrics.stringWidth(shortName) + 6);
+		}
+	}
 
-    public String getName() {
-        return name;
-    }
+	public int getWantedIndex() {
+		return wantedIndex;
+	}
 
-    public void setShortName(String s) {
-        assert s != null;
-        assert s.length() <= 2;
-        this.shortName = s;
+	public Source getSource() {
+		return source;
+	}
 
-    }
+	public String getText() {
+		return text;
+	}
 
-    public String getShortName() {
-        return shortName;
-    }
+	public void setShortName(String s) {
+		assert s != null;
+//        assert s.length() <= 2;
+		this.shortName = s;
+
+	}
 
-    public boolean getShowName() {
-        return getShortName() != null && getShortName().length() > 0;
-    }
+	public String getShortName() {
+		return shortName;
+	}
+
+	public String getToolTipText() {
+		StringBuilder sb = new StringBuilder();
+		sb.append(text);
 
-    public void setName(String s) {
-        if (s == null) {
-            s = "";
-        }
-        this.name = s;
-    }
+		for (InputNode n : getSource().getSourceNodes()) {
+			sb.append("Node (ID=" + n.getId() + "): " + n.getProperties().get("name"));
+			sb.append("<br>");
+		}
+
+		return sb.toString();
+	}
+
+	public boolean shouldShowName() {
+		return getShortName() != null && getShortName().length() > 0;
+	}
 
-    public Figure getFigure() {
-        assert figure != null;
-        return figure;
-    }
+	public void setText(String s) {
+		if (s == null) {
+			s = "";
+		}
+		this.text = s;
+	}
 
-    public List<Connection> getConnections() {
-        return Collections.unmodifiableList(connections);
-    }
+	public Figure getFigure() {
+		assert figure != null;
+		return figure;
+	}
+
+	public Color getColor() {
+		return this.color;
+	}
+
+	public void setColor(Color c) {
+		color = c;
+	}
 
-    public void removeAllConnections() {
-        List<Connection> connectionsCopy = new ArrayList<Connection>(this.connections);
-        for (Connection c : connectionsCopy) {
-            c.remove();
-        }
-    }
+	public List<Connection> getConnections() {
+		return Collections.unmodifiableList(connections);
+	}
 
-    public Vertex getVertex() {
-        return figure;
-    }
+	public void removeAllConnections() {
+		List<Connection> connectionsCopy = new ArrayList<Connection>(this.connections);
+		for (Connection c : connectionsCopy) {
+			c.remove();
+		}
+	}
 
-    public abstract int getPosition();
+	public Vertex getVertex() {
+		return figure;
+	}
 
-    public abstract void setPosition(int position);
+	public abstract int getPosition();
+
+	public abstract void setPosition(int position);
 }
+
--- a/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Source.java	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.graph;
-
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.InputNode;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class Source {
-
-    private List<InputNode> sourceNodes;
-    private Set<Integer> set;
-
-    public Source() {
-        sourceNodes = new ArrayList<InputNode>(1);
-    }
-
-    public List<InputNode> getSourceNodes() {
-        return Collections.unmodifiableList(sourceNodes);
-    }
-
-    public Set<Integer> getSourceNodesAsSet() {
-        if (set == null) {
-            set = new HashSet<Integer>();
-            for (InputNode n : sourceNodes) {
-                int id = n.getId();
-                //if(id < 0) id = -id;
-                set.add(id);
-            }
-        }
-        return set;
-    }
-
-    public void addSourceNode(InputNode n) {
-        sourceNodes.add(n);
-        set = null;
-    }
-
-    public void removeSourceNode(InputNode n) {
-        sourceNodes.remove(n);
-        set = null;
-    }
-
-    public interface Provider {
-
-        public Source getSource();
-    }
-
-    public void setSourceNodes(List<InputNode> sourceNodes) {
-        this.sourceNodes = sourceNodes;
-        set = null;
-    }
-
-    public void addSourceNodes(Source s) {
-        for (InputNode n : s.getSourceNodes()) {
-            sourceNodes.add(n);
-        }
-        set = null;
-    }
-
-    public boolean isInBlock(InputGraph g, InputBlock blockNode) {
-
-        for (InputNode n : this.getSourceNodes()) {
-            if (g.getBlock(n) == blockNode) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/services/DiagramProvider.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.graph.services;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.graph.Diagram;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface DiagramProvider {
+    Diagram getDiagram();
+    ChangedEvent<DiagramProvider> getChangedEvent();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/build.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.graphtexteditor" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.graphtexteditor.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/manifest.mf	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.graphtexteditor
+OpenIDE-Module-Layer: com/sun/hotspot/igv/graphtexteditor/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/graphtexteditor/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/nbproject/build-impl.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.graphtexteditor-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/nbproject/genfiles.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,5 @@
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=ac7a776e
+nbproject/build-impl.xml.script.CRC32=9388e04e
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/nbproject/project.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.graphtexteditor</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graphtotext</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.selectioncoordinator</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.structuredtext</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.texteditor</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.12.0.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.20</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/nbproject/suite.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/src/com/sun/hotspot/igv/graphtexteditor/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,4 @@
+CTL_TextAction=Open Text Window
+CTL_TextTopComponent=Text Window
+HINT_TextTopComponent=This is a Text window
+OpenIDE-Module-Name=GraphTextEditor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/src/com/sun/hotspot/igv/graphtexteditor/TextAction.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.graphtexteditor;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+
+/**
+ * Action which shows Text component.
+ */
+public class TextAction extends AbstractAction {
+
+    public TextAction() {
+        super(NbBundle.getMessage(TextAction.class, "CTL_TextAction"));
+
+        System.out.println("Text action initialized!!!");
+//        putValue(SMALL_ICON, new ImageIcon(Utilities.loadImage(TextTopComponent.ICON_PATH, true)));
+    }
+
+    public void actionPerformed(ActionEvent evt) {
+        TopComponent win = TextTopComponent.findInstance();
+        win.open();
+        win.requestActive();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/src/com/sun/hotspot/igv/graphtexteditor/TextTopComponent.form	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.4" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+  </AuxValues>
+
+  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/src/com/sun/hotspot/igv/graphtexteditor/TextTopComponent.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,300 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.graphtexteditor;
+
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.texteditor.*;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.services.DiagramProvider;
+import com.sun.hotspot.igv.graphtotext.services.GraphToTextConverter;
+import com.sun.hotspot.igv.selectioncoordinator.SelectionCoordinator;
+import com.sun.hotspot.igv.structuredtext.StructuredText;
+import com.sun.hotspot.igv.util.LookupHistory;
+import java.awt.BorderLayout;
+import java.awt.CardLayout;
+import java.awt.Color;
+import java.io.Serializable;
+import java.util.Collection;
+import java.util.logging.Logger;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSplitPane;
+import org.openide.util.Lookup;
+import org.openide.util.LookupEvent;
+import org.openide.util.LookupListener;
+import org.openide.util.NbBundle;
+import org.openide.util.Utilities;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ * @author Thomas Wuerthinger
+ */
+final class TextTopComponent extends TopComponent implements LookupListener {
+
+    private static TextTopComponent instance;
+    private Lookup.Result result = null;
+    private static final String PREFERRED_ID = "TextTopComponent";
+    private Diagram lastDiagram;
+    private TextEditor leftEditor;
+    private TextEditor rightEditor;
+    private TextEditor singleEditor;
+    private JSplitPane splitPane;
+    private CardLayout cardLayout;
+    private JPanel cardLayoutPanel;
+    private boolean firstTimeSlider = true;
+
+    private static final String TWO_GRAPHS = "twoGraphs";
+    private static final String ONE_GRAPH = "oneGraph";
+    private static final String NO_GRAPH = "noGraph";
+
+    private DiagramProvider currentDiagramProvider;
+
+    private TextTopComponent() {
+        initComponents();
+        setName(NbBundle.getMessage(TextTopComponent.class, "CTL_TextTopComponent"));
+        setToolTipText(NbBundle.getMessage(TextTopComponent.class, "HINT_TextTopComponent"));
+
+        // Card layout for three different views.
+        cardLayout = new CardLayout();
+        cardLayoutPanel = new JPanel(cardLayout);
+        this.setLayout(new BorderLayout());
+        this.add(cardLayoutPanel, BorderLayout.CENTER);
+
+        // No graph selected.
+        JLabel noGraphLabel = new JLabel("No graph opened");
+        noGraphLabel.setBackground(Color.red);
+        //noGraphPanel.add(noGraphLabel);
+        cardLayoutPanel.add(noGraphLabel, NO_GRAPH);
+
+        // Single graph selected.
+        singleEditor = new TextEditor();
+        cardLayoutPanel.add(singleEditor.getComponent(), ONE_GRAPH);
+
+        // Graph difference => show split pane with two graphs.
+        splitPane = new JSplitPane();
+        leftEditor = new TextEditor();
+        splitPane.setLeftComponent(leftEditor.getComponent());
+        rightEditor = new TextEditor();
+        splitPane.setRightComponent(rightEditor.getComponent());
+        cardLayoutPanel.add(splitPane, TWO_GRAPHS);
+    }
+
+
+    private StructuredText convert(InputGraph graph, Diagram diagram) {
+        Collection<? extends GraphToTextConverter> converters = Lookup.getDefault().lookupAll(GraphToTextConverter.class);
+        StructuredText text = null;
+        if (converters.size() == 0) {
+            text = new StructuredText(graph.getName());
+            text.println("No graph-to-text converter exists!");
+            return text;
+        }
+
+        for (GraphToTextConverter converter : converters) {
+            if (converter.canConvert(graph)) {
+                text = converter.convert(graph, diagram);
+                if (text == null) {
+                    text = new StructuredText(graph.getName());
+                    text.println("Class " + converter.getClass().getName() + " misbehaved and returned null on graph-to-text conversion!");
+                }
+                return text;
+            }
+        }
+
+        text = new StructuredText(graph.getName());
+        text.println("No appropriate graph-to-text converter found!");
+        return text;
+    }
+
+    private void updateDiagram(Diagram diagram) {
+
+        if (diagram == lastDiagram) {
+            // No change => return.
+            return;
+        }
+
+        lastDiagram = diagram;
+
+        if (diagram == null) {
+            showCard(NO_GRAPH);
+        } else if (diagram.getGraph().getSourceGraphs() != null) {
+            showCard(TWO_GRAPHS);
+            if (firstTimeSlider) {
+                splitPane.setDividerLocation(0.5);
+            }
+            firstTimeSlider = false;
+            Pair<InputGraph, InputGraph> graphs = diagram.getGraph().getSourceGraphs();
+            leftEditor.setStructuredText(convert(graphs.getLeft(), diagram));
+            rightEditor.setStructuredText(convert(graphs.getRight(), diagram));
+
+            // TODO: Hack to update view - remove
+            SelectionCoordinator.getInstance().getHighlightedChangedEvent().fire();
+        } else {
+            showCard(ONE_GRAPH);
+            StructuredText text = convert(diagram.getGraph(), diagram);
+            singleEditor.setStructuredText(text);
+
+            // TODO: Hack to update view - remove
+            SelectionCoordinator.getInstance().getHighlightedChangedEvent().fire();
+        }
+    }
+    
+    private ChangedListener<DiagramProvider> diagramChangedListener = new ChangedListener<DiagramProvider>() {
+
+        public void changed(DiagramProvider source) {
+            updateDiagram(source.getDiagram());
+        }
+        
+    };
+
+    private void updateDiagramProvider(DiagramProvider provider) {
+
+        if (provider == currentDiagramProvider) {
+            return;
+        }
+
+        if (currentDiagramProvider != null) {
+            currentDiagramProvider.getChangedEvent().removeListener(diagramChangedListener);
+        }
+
+        currentDiagramProvider = provider;
+
+        if (currentDiagramProvider != null) {
+            currentDiagramProvider.getChangedEvent().addListener(diagramChangedListener);
+            updateDiagram(currentDiagramProvider.getDiagram());
+        } else {
+            updateDiagram(null);
+        }
+    }
+
+    private void showCard(final String card) {
+        cardLayout.show(cardLayoutPanel, card);
+    }
+
+    public void resultChanged(LookupEvent lookupEvent) {
+        DiagramProvider p = Utilities.actionsGlobalContext().lookup(DiagramProvider.class);
+
+        if (p == null) {
+            p = LookupHistory.getLast(DiagramProvider.class);
+        }
+
+        updateDiagramProvider(p);
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        setLayout(new java.awt.BorderLayout());
+    }// </editor-fold>//GEN-END:initComponents
+
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    // End of variables declaration//GEN-END:variables
+    /**
+     * Gets default instance. Do not use directly: reserved for *.settings files only,
+     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
+     * To obtain the singleton instance, use {@link findInstance}.
+     */
+    public static synchronized TextTopComponent getDefault() {
+        if (instance == null) {
+            instance = new TextTopComponent();
+        }
+        return instance;
+    }
+
+    /**
+     * Obtain the TextTopComponent instance. Never call {@link #getDefault} directly!
+     */
+    public static synchronized TextTopComponent findInstance() {
+        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+        if (win == null) {
+            Logger.getLogger(TextTopComponent.class.getName()).warning(
+                    "Cannot find " + PREFERRED_ID + " component. It will not be located properly in the window system.");
+            return getDefault();
+        }
+        if (win instanceof TextTopComponent) {
+            return (TextTopComponent) win;
+        }
+        Logger.getLogger(TextTopComponent.class.getName()).warning(
+                "There seem to be multiple components with the '" + PREFERRED_ID +
+                "' ID. That is a potential source of errors and unexpected behavior.");
+        return getDefault();
+    }
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_ALWAYS;
+    }
+
+    @Override
+    public void componentOpened() {
+
+        DiagramProvider p = LookupHistory.getLast(DiagramProvider.class);
+        updateDiagramProvider(p);
+
+        Lookup.Template tpl = new Lookup.Template(DiagramProvider.class);
+        result = Utilities.actionsGlobalContext().lookup(tpl);
+        result.addLookupListener(this);
+    }
+
+    @Override
+    public void componentClosed() {
+        result.removeLookupListener(this);
+        result = null;
+        updateDiagramProvider(null);
+    }
+
+    /** replaces this in object stream */
+    @Override
+    public Object writeReplace() {
+        return new ResolvableHelper();
+    }
+
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        cardLayoutPanel.requestFocus();
+    }
+
+    final static class ResolvableHelper implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        public Object readResolve() {
+            return TextTopComponent.getDefault();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/src/com/sun/hotspot/igv/graphtexteditor/TextTopComponentSettings.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
+<settings version="1.0">
+    <module name="com.sun.hotspot.igv.graphtexteditor" spec="1.0"/>
+    <instanceof class="org.openide.windows.TopComponent"/>
+    <instanceof class="com.sun.hotspot.igv.graphtexteditor.TextTopComponent"/>
+    <instance class="com.sun.hotspot.igv.graphtexteditor.TextTopComponent" method="getDefault"/>
+</settings>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/src/com/sun/hotspot/igv/graphtexteditor/TextTopComponentWstcref.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+To change this template, choose Tools | Templates
+and open the template in the editor.
+-->
+<!DOCTYPE tc-ref PUBLIC "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN" "http://www.netbeans.org/dtds/tc-ref2_0.dtd">
+<tc-ref version="2.0" >
+    <module name="com.sun.hotspot.igv.graphtexteditor" spec="1.0"/>
+    <tc-id id="TextTopComponent"/>
+    <state opened="true"/>
+</tc-ref>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphTextEditor/src/com/sun/hotspot/igv/graphtexteditor/layer.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+    <folder name="Actions">
+        <folder name="Window">
+            <file name="com-sun-hotspot-igv-graphtexteditor-TextAction.instance"/>
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <folder name="Window">
+            <file name="TextAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-graphtexteditor-TextAction.instance"/>
+            </file>
+        </folder>
+    </folder>
+    <folder name="Windows2">
+        <folder name="Components">
+            <file name="TextTopComponent.settings" url="TextTopComponentSettings.xml"/>
+        </folder>
+        <folder name="Modes">
+            <folder name="customRightTopMode">
+                <file name="TextTopComponent.wstcref" url="TextTopComponentWstcref.xml"/>
+            </folder>
+        </folder>
+    </folder>
+    
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/build.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.graphtotext" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.graphtotext.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/manifest.mf	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.graphtotext
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/graphtotext/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/nbproject/build-impl.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.graphtotext-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/nbproject/genfiles.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,5 @@
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=10eff8f6
+nbproject/build-impl.xml.script.CRC32=b176ca1a
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/nbproject/platform.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,175 @@
+cluster.path=\
+    ${nbplatform.active.dir}/ide:\
+    ${nbplatform.active.dir}/platform
+disabled.modules=\
+    org.apache.xml.resolver,\
+    org.mozilla.rhino.patched,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.java.classpath,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.browser,\
+    org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.multiview,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.lib.terminalemulator,\
+    org.netbeans.libs.antlr3.runtime,\
+    org.netbeans.libs.bugtracking,\
+    org.netbeans.libs.bugzilla,\
+    org.netbeans.libs.bytelist,\
+    org.netbeans.libs.commons_codec,\
+    org.netbeans.libs.commons_logging,\
+    org.netbeans.libs.commons_net,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jakarta_oro,\
+    org.netbeans.libs.jaxb,\
+    org.netbeans.libs.jsch,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.jvyamlb,\
+    org.netbeans.libs.jzlib,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.smack,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.svnClientAdapter.javahl,\
+    org.netbeans.libs.svnClientAdapter.svnkit,\
+    org.netbeans.libs.swingx,\
+    org.netbeans.libs.xerces,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.bugtracking,\
+    org.netbeans.modules.bugtracking.bridge,\
+    org.netbeans.modules.bugzilla,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.csl.api,\
+    org.netbeans.modules.css.editor,\
+    org.netbeans.modules.css.visual,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.dataview,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.metadata.model,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.derby,\
+    org.netbeans.modules.diff,\
+    org.netbeans.modules.dlight.nativeexecution,\
+    org.netbeans.modules.dlight.terminal,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.errorstripe,\
+    org.netbeans.modules.editor.errorstripe.api,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.indent.project,\
+    org.netbeans.modules.editor.kit,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.plain,\
+    org.netbeans.modules.editor.plain.lib,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.extexecution,\
+    org.netbeans.modules.extexecution.destroy,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.glassfish.common,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.gsf.codecoverage,\
+    org.netbeans.modules.gsf.testrunner,\
+    org.netbeans.modules.html,\
+    org.netbeans.modules.html.editor,\
+    org.netbeans.modules.html.editor.lib,\
+    org.netbeans.modules.html.lexer,\
+    org.netbeans.modules.html.parser,\
+    org.netbeans.modules.html.validation,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.hudson,\
+    org.netbeans.modules.hudson.mercurial,\
+    org.netbeans.modules.hudson.subversion,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javascript.editing,\
+    org.netbeans.modules.javascript.hints,\
+    org.netbeans.modules.javascript.kit,\
+    org.netbeans.modules.javascript.refactoring,\
+    org.netbeans.modules.jellytools.ide,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.yaml,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.options.editor,\
+    org.netbeans.modules.parsing.api,\
+    org.netbeans.modules.parsing.lucene,\
+    org.netbeans.modules.print.editor,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectapi,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectui.buildmenu,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.spellchecker,\
+    org.netbeans.modules.spellchecker.apimodule,\
+    org.netbeans.modules.spellchecker.bindings.htmlxml,\
+    org.netbeans.modules.spellchecker.bindings.properties,\
+    org.netbeans.modules.spellchecker.dictionary_en,\
+    org.netbeans.modules.spellchecker.kit,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.swing.validation,\
+    org.netbeans.modules.target.iterator,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.terminal,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.indexingbridge,\
+    org.netbeans.modules.versioning.system.cvss,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.client.tools.api,\
+    org.netbeans.modules.web.common,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.jaxb.api,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
+    org.openide.compat,\
+    org.openide.execution,\
+    org.openide.options,\
+    org.openide.util.enumerations
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/nbproject/project.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.graphtotext</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.structuredtext</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.graphtotext</package>
+                <package>com.sun.hotspot.igv.graphtotext.services</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/nbproject/suite.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/src/com/sun/hotspot/igv/graphtotext/BFSGraphToTextConverter.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.graphtotext;
+
+import com.sun.hotspot.igv.data.InputEdge;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graphtotext.services.GraphToTextVisitor;
+import com.sun.hotspot.igv.structuredtext.Element;
+import com.sun.hotspot.igv.structuredtext.StructuredText;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas
+ */
+public class BFSGraphToTextConverter {
+    
+    private GraphToTextVisitor visitor;
+    private Map<Properties.PropertyMatcher, GraphToTextVisitor> visitorMap;
+    private InputGraph graph;
+    private Diagram diagram;
+    
+    public BFSGraphToTextConverter(GraphToTextVisitor visitor) {
+        this.visitor = visitor;
+        visitorMap = new HashMap<Properties.PropertyMatcher, GraphToTextVisitor>();
+    }
+    
+    public void registerVisitor(GraphToTextVisitor visitor, Properties.PropertyMatcher matcher) {
+        visitorMap.put(matcher, visitor);
+    }
+    
+    private GraphToTextVisitor chooseVisitor(GraphToTextVisitor defaultVisitor, InputNode node) {
+        for(Properties.PropertyMatcher matcher : visitorMap.keySet()) {
+            if(node.getProperties().selectSingle(matcher) != null) {
+                return visitorMap.get(matcher);
+            }
+        }
+        
+        return defaultVisitor;
+    }
+
+    private Element cyclicVisit(GraphToTextVisitor visitor, InputNode node, List<InputEdge> path) {
+        return chooseVisitor(visitor, node).cyclicVisit(node, path);
+    }
+    
+    private Element visit(GraphToTextVisitor visitor, InputNode node, List<InputEdge> path, List<Pair<InputEdge, Element>> children) {
+        return chooseVisitor(visitor, node).visit(node, path, children);
+    }
+    
+    protected Diagram getDiagram() {
+        return diagram;
+    }
+    
+    public StructuredText convert(InputGraph graph, Diagram diagram) {
+        
+        this.graph = graph;
+        this.diagram = diagram;
+        StructuredText text = new StructuredText(graph.getName());
+        
+        Map<InputNode, List<InputEdge>> outgoing = graph.findAllOutgoingEdges();
+        Map<InputNode, List<InputEdge>> pathMap = new HashMap<InputNode, List<InputEdge>>();
+        Queue<InputNode> queue = new LinkedList<InputNode>();
+        List<InputNode> rootNodes = graph.findRootNodes();
+        queue.addAll(rootNodes);
+        for(InputNode node : rootNodes) {
+            pathMap.put(node, new ArrayList<InputEdge>());
+        }
+        
+        Set<InputNode> visited = new HashSet<InputNode>();
+        visited.addAll(rootNodes);
+        
+        Set<InputEdge> fullEdges = new HashSet<InputEdge>();
+        List<InputNode> visitOrder = new ArrayList<InputNode>();
+        while(!queue.isEmpty()) {
+            
+            InputNode current = queue.remove();
+            visitOrder.add(current);
+            List<InputEdge> path = pathMap.get(current);
+            
+            List<InputEdge> edges = outgoing.get(current);
+            for(InputEdge e : edges) {
+                InputNode dest = graph.getNode(e.getTo());
+                if(!visited.contains(dest)) {
+                    queue.add(dest);
+                    visited.add(dest);
+                    List<InputEdge> curPath = new ArrayList<InputEdge>(path);
+                    curPath.add(e);
+                    pathMap.put(dest, curPath);
+                    fullEdges.add(e);
+                }
+            }
+        }
+        
+        
+        
+        Map<InputNode, Element> fullVisitCache = new HashMap<InputNode, Element>();
+        for(int i=visitOrder.size() - 1; i>=0; i--) {
+            InputNode current = visitOrder.get(i);
+            List<InputEdge> path = pathMap.get(current);
+            List<InputEdge> edges = outgoing.get(current);
+            List<Pair<InputEdge, Element>> list = new ArrayList<Pair<InputEdge, Element>>();
+            for(InputEdge e : edges) {
+                if(fullEdges.contains(e)) {
+                    assert fullVisitCache.containsKey(graph.getNode(e.getTo()));
+                    list.add(new Pair<InputEdge, Element>(e, fullVisitCache.get(graph.getNode(e.getTo()))));
+                } else {
+//                    assert fullVisitCache.containsKey(graph.getNode(e.getTo()));
+                    List<InputEdge> curPath = new ArrayList<InputEdge>(path);
+                    curPath.add(e);
+                    list.add(new Pair<InputEdge, Element>(e, cyclicVisit(visitor, graph.getNode(e.getTo()), curPath)));
+                }
+            }
+            
+            Element e = visit(visitor, current, pathMap.get(current), list);
+            fullVisitCache.put(current, e);
+        }
+        
+        for(InputNode node : rootNodes) {
+            text.addChild(fullVisitCache.get(node));
+        }
+        
+        return text;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/src/com/sun/hotspot/igv/graphtotext/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=GraphToText
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/src/com/sun/hotspot/igv/graphtotext/services/AbstractGraphToTextVisitor.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.graphtotext.services;
+
+import com.sun.hotspot.igv.data.InputEdge;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.structuredtext.Element;
+import com.sun.hotspot.igv.structuredtext.SimpleElement;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas
+ */
+public class AbstractGraphToTextVisitor implements GraphToTextVisitor {
+
+    public Element cyclicVisit(InputNode node, List<InputEdge> path) {
+        return SimpleElement.EMPTY;
+    }
+
+    public Element visit(InputNode node, List<InputEdge> path, List<Pair<InputEdge, Element>> children) {
+        return cyclicVisit(node, path);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/src/com/sun/hotspot/igv/graphtotext/services/GraphToTextConverter.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.graphtotext.services;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.structuredtext.StructuredText;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface GraphToTextConverter {
+    StructuredText convert(InputGraph graph, Diagram diagram);
+    boolean canConvert(InputGraph graph);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/GraphToText/src/com/sun/hotspot/igv/graphtotext/services/GraphToTextVisitor.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.graphtotext.services;
+
+import com.sun.hotspot.igv.data.InputEdge;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.structuredtext.Element;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas
+ */
+public interface GraphToTextVisitor {
+
+    Element cyclicVisit(InputNode node, List<InputEdge> path);
+    Element visit(InputNode node, List<InputEdge> path, List<Pair<InputEdge, Element>> children);
+}
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java	Wed Jun 08 17:26:49 2011 +0200
@@ -93,7 +93,7 @@
         outputSlot = new Port() {
 
             public Point getRelativePosition() {
-                return new Point(size.width / 2, size.height);
+                return new Point(size.width / 2, 0);//size.height);
             }
 
             public Vertex getVertex() {
@@ -183,7 +183,7 @@
 
         for (Link e : subEdges) {
             List<Point> arr = e.getControlPoints();
-            ArrayList<Point> newArr = new ArrayList<Point>();
+            ArrayList<Point> newArr = new ArrayList<Point>(arr.size());
             for (Point p : arr) {
                 if (p != null) {
                     Point p2 = new Point(p);
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutputSlotNode.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutputSlotNode.java	Wed Jun 08 17:26:49 2011 +0200
@@ -88,7 +88,7 @@
             public Point getRelativePosition() {
                 Point p = new Point(thisNode.getPosition());
                 p.x += ClusterNode.BORDER;
-                p.y = thisBlockNode.getSize().height;
+                p.y = 0;//thisBlockNode.getSize().height;
                 return p;
             }
 
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java	Wed Jun 08 17:26:49 2011 +0200
@@ -116,7 +116,7 @@
 
         for (Vertex v : graph.getVertices()) {
             Cluster c = v.getCluster();
-            assert c != null;
+            assert c != null : "Cluster of vertex " + v + " is null!";
             clusterNodes.get(c).addSubNode(v);
         }
 
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java	Wed Jun 08 17:26:49 2011 +0200
@@ -101,11 +101,13 @@
         public int yOffset;
         public int bottomYOffset;
         public Vertex vertex; // Only used for non-dummy nodes, otherwise null
+
         public List<LayoutEdge> preds = new ArrayList<LayoutEdge>();
         public List<LayoutEdge> succs = new ArrayList<LayoutEdge>();
         public HashMap<Integer, Integer> outOffsets = new HashMap<Integer, Integer>();
         public HashMap<Integer, Integer> inOffsets = new HashMap<Integer, Integer>();
         public int pos = -1; // Position within layer
+
         public int crossingNumber;
 
         @Override
@@ -276,10 +278,10 @@
                     if (e.link != null) {
                         ArrayList<Point> points = new ArrayList<Point>();
 
-                        Point p = new Point(e.to.x + e.relativeTo, e.to.y + e.to.yOffset);
+                        Point p = new Point(e.to.x + e.relativeTo, e.to.y + e.to.yOffset + e.link.getTo().getRelativePosition().y);
                         points.add(p);
                         if (e.to.inOffsets.containsKey(e.relativeTo)) {
-                            points.add(new Point(p.x, p.y + e.to.inOffsets.get(e.relativeTo)));
+                            points.add(new Point(p.x, p.y + e.to.inOffsets.get(e.relativeTo) + e.link.getTo().getRelativePosition().y));
                         }
 
                         LayoutNode cur = e.from;
@@ -299,9 +301,9 @@
                             cur = curEdge.from;
                         }
 
-                        p = new Point(cur.x + curEdge.relativeFrom, cur.y + cur.height - cur.bottomYOffset);
+                        p = new Point(cur.x + curEdge.relativeFrom, cur.y + cur.height - cur.bottomYOffset + (curEdge.link == null ? 0 : curEdge.link.getFrom().getRelativePosition().y));
                         if (curEdge.from.outOffsets.containsKey(curEdge.relativeFrom)) {
-                            points.add(new Point(p.x, p.y + curEdge.from.outOffsets.get(curEdge.relativeFrom)));
+                            points.add(new Point(p.x, p.y + curEdge.from.outOffsets.get(curEdge.relativeFrom) + (curEdge.link == null ? 0 : curEdge.link.getFrom().getRelativePosition().y)));
                         }
                         points.add(p);
 
@@ -360,10 +362,10 @@
                 for (LayoutEdge e : n.succs) {
                     if (e.link != null) {
                         ArrayList<Point> points = new ArrayList<Point>();
-                        Point p = new Point(e.from.x + e.relativeFrom, e.from.y + e.from.height - e.from.bottomYOffset);
+                        Point p = new Point(e.from.x + e.relativeFrom, e.from.y + e.from.height - e.from.bottomYOffset + e.link.getFrom().getRelativePosition().y);
                         points.add(p);
                         if (e.from.outOffsets.containsKey(e.relativeFrom)) {
-                            points.add(new Point(p.x, p.y + e.from.outOffsets.get(e.relativeFrom)));
+                            points.add(new Point(p.x, p.y + e.from.outOffsets.get(e.relativeFrom) + e.link.getFrom().getRelativePosition().y));
                         }
 
                         LayoutNode cur = e.to;
@@ -387,10 +389,10 @@
                         }
 
 
-                        p = new Point(cur.x + curEdge.relativeTo, cur.y + cur.yOffset);
+                        p = new Point(cur.x + curEdge.relativeTo, cur.y + cur.yOffset + ((curEdge.link == null) ? 0 : curEdge.link.getTo().getRelativePosition().y));
                         points.add(p);
                         if (curEdge.to.inOffsets.containsKey(curEdge.relativeTo)) {
-                            points.add(new Point(p.x, p.y + curEdge.to.inOffsets.get(curEdge.relativeTo)));
+                            points.add(new Point(p.x, p.y + curEdge.to.inOffsets.get(curEdge.relativeTo) + ((curEdge.link == null) ? 0 : curEdge.link.getTo().getRelativePosition().y)));
                         }
 
 
@@ -643,6 +645,7 @@
                     result += cur;
                 }
                 return result / size; //median(values);
+
             }
         }
 
@@ -1112,7 +1115,6 @@
                 layers[i] = new ArrayList<LayoutNode>();
             }
 
-
             // Generate initial ordering
             HashSet<LayoutNode> visited = new HashSet<LayoutNode>();
             for (LayoutNode n : nodes) {
@@ -1146,10 +1148,6 @@
                 downSweep();
                 upSweep();
             }
-
-        /*for(int i=0; i<CROSSING_ITERATIONS; i++) {
-        doubleSweep();
-        }*/
         }
 
         private void initX() {
@@ -1251,44 +1249,6 @@
                 }
             }
         }
-        /*
-        private void doubleSweep() {
-        // Downsweep
-        for(int i=0; i<layerCount*2; i++) {
-        int index = i;
-        if(index >= layerCount) {
-        index = 2*layerCount - i - 1;
-        }
-        for(LayoutNode n : layers[index]) {
-        float sum = 0.0f;
-        for(LayoutEdge e : n.preds) {
-        float cur = e.from.pos;
-        if(e.from.width != 0 && e.relativeFrom != 0) {
-        cur += (float)e.relativeFrom / (float)(e.from.width);
-        }
-        sum += cur;
-        }
-        for(LayoutEdge e : n.succs) {
-        float cur = e.to.pos;
-        if(e.to.width != 0 && e.relativeTo != 0) {
-        cur += (float)e.relativeTo / (float)(e.to.width);
-        }
-        sum += cur;
-        }
-        if(n.preds.size() + n.succs.size() > 0) {
-        sum /= n.preds.size() + n.succs.size();
-        n.crossingNumber = sum;
-        }
-        }
-        Collections.sort(layers[index], crossingNodeComparator);
-        updateXOfLayer(index);
-        int z = 0;
-        for(LayoutNode n : layers[index]) {
-        n.pos = z;
-        z++;
-        }
-        }
-        }*/
 
         private void upSweep() {
             // Upsweep
@@ -1303,7 +1263,7 @@
                     int sum = 0;
                     for (LayoutEdge e : n.succs) {
                         int cur = e.to.x + e.relativeTo;//pos;
-                                                /*
+						/*
                         if(e.to.width != 0 && e.relativeTo != 0) {
                         cur += (float)e.relativeTo / (float)(e.to.width);
                         }*/
@@ -1331,11 +1291,6 @@
             }
         }
 
-        private int evaluate() {
-            // TODO: Implement efficient evaluate / crossing min
-            return 0;
-        }
-
         @Override
         public void postCheck() {
 
@@ -1355,7 +1310,7 @@
 
         protected void run() {
             int curY = 0;
-            //maxLayerHeight = new int[layers.length];
+
             for (int i = 0; i < layers.length; i++) {
                 int maxHeight = 0;
                 int baseLine = 0;
@@ -1383,8 +1338,6 @@
                     }
                 }
 
-                //maxLayerHeight[i] = maxHeight + baseLine + bottomBaseLine;
-
                 curY += maxHeight + baseLine + bottomBaseLine;
                 curY += layerOffset + (int) Math.sqrt(maxXOffset);
             }
@@ -1649,10 +1602,14 @@
         }
 
         protected void run() {
+
+            List<LayoutNode> insertOrder = new ArrayList<LayoutNode>();
+
             HashSet<LayoutNode> set = new HashSet<LayoutNode>();
             for (LayoutNode n : nodes) {
                 if (n.preds.size() == 0) {
                     set.add(n);
+                    insertOrder.add(n);
                     n.layer = 0;
                 }
             }
@@ -1691,6 +1648,7 @@
 
                 for (LayoutNode n : newSet) {
                     n.layer = z;
+                    insertOrder.add(n);
                 }
 
                 // Swap sets
@@ -1700,7 +1658,7 @@
                 z += minLayerDifference;
             }
 
-            optimize(set);
+            optimize(insertOrder);
 
             layerCount = z - minLayerDifference;
 
@@ -1714,23 +1672,22 @@
             for (Vertex v : firstLayerHint) {
                 LayoutNode n = vertexToLayoutNode.get(v);
                 assert n.preds.size() == 0;
+                n.layer = 0;
                 assert n.layer == 0;
             }
         }
 
-        public void optimize(HashSet<LayoutNode> set) {
-
-            for (LayoutNode n : set) {
-                if (n.preds.size() == 0 && n.succs.size() > 0) {
-                    int minLayer = n.succs.get(0).to.layer;
-                    for (LayoutEdge e : n.succs) {
+        public void optimize(List<LayoutNode> insertOrder) {
+            for (int i = insertOrder.size() - 1; i >= 0; i--) {
+                LayoutNode cur = insertOrder.get(i);
+                if (cur.succs.size() > cur.preds.size()) {
+                    int minLayer = cur.succs.get(0).to.layer;
+                    for (LayoutEdge e : cur.succs) {
                         minLayer = Math.min(minLayer, e.to.layer);
                     }
-
-                    n.layer = minLayer - 1;
+                    cur.layer = minLayer - 1;
                 }
             }
-
         }
 
         @Override
@@ -1752,7 +1709,7 @@
 
         protected void run() {
 
-            // Remove self-edges, TODO: Special treatment
+            // Remove self-edges
             for (LayoutNode node : nodes) {
                 ArrayList<LayoutEdge> succs = new ArrayList<LayoutEdge>(node.succs);
                 for (LayoutEdge e : succs) {
@@ -2105,6 +2062,6 @@
     }
 
     public void doRouting(LayoutGraph graph) {
-    // Do nothing for now
+        // Do nothing for now
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/OldHierarchicalLayoutManager.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/OldHierarchicalLayoutManager.java	Wed Jun 08 17:26:49 2011 +0200
@@ -754,7 +754,6 @@
 
     private void assignCoordinates(ArrayList<Node<NodeData, EdgeData>> layers[]) {
 
-        // TODO: change this
         for (int i = 0; i < layers.length; i++) {
             ArrayList<Node<NodeData, EdgeData>> curArray = layers[i];
             int curY = 0;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Java6ScriptingProxy/build.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.java6scriptingproxy" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.java6scriptingproxy.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Java6ScriptingProxy/manifest.mf	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.java6scriptingproxy
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/java6scriptingproxy/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Java6ScriptingProxy/nbproject/build-impl.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.java6scriptingproxy-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Java6ScriptingProxy/nbproject/genfiles.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,5 @@
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=485d21b4
+nbproject/build-impl.xml.script.CRC32=341e7d1e
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Java6ScriptingProxy/nbproject/project.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Java6ScriptingProxy/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.java6scriptingproxy</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.filter</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.java6scriptingproxy</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Java6ScriptingProxy/nbproject/suite.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Java6ScriptingProxy/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.java6scriptingproxy.JavaSE6ScriptEngine
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Java6ScriptingProxy/src/com/sun/hotspot/igv/java6scriptingproxy/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Java6ScriptingProxy
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Java6ScriptingProxy/src/com/sun/hotspot/igv/java6scriptingproxy/JavaSE6ScriptEngine.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.java6scriptingproxy;
+
+import com.sun.hotspot.igv.filter.*;
+import com.sun.hotspot.igv.graph.Diagram;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class JavaSE6ScriptEngine implements ScriptEngineAbstraction {
+
+    private Object engine;
+    private Object bindings;
+    private Method Bindings_put;
+    private Method ScriptEngine_eval;
+
+    public boolean initialize(String jsHelperText) {
+        try {
+            
+            ClassLoader cl = JavaSE6ScriptEngine.class.getClassLoader();
+            Class managerClass = cl.loadClass("javax.script.ScriptEngineManager");
+            Class engineClass = cl.loadClass("javax.script.ScriptEngine");
+            Class bindingsClass = cl.loadClass("javax.script.Bindings");
+            Class contextClass = cl.loadClass("javax.script.ScriptContext");
+            
+            Object manager = managerClass.newInstance();
+            Method getEngineByName = managerClass.getMethod("getEngineByName", String.class);
+            engine = getEngineByName.invoke(manager, "ECMAScript");
+            Method eval = engineClass.getMethod("eval", String.class);
+            ScriptEngine_eval = engineClass.getMethod("eval", String.class, bindingsClass);
+            eval.invoke(engine, jsHelperText);
+            Method getContext = engineClass.getMethod("getContext");
+            Object context = getContext.invoke(engine);
+            Method getBindings = contextClass.getMethod("getBindings", Integer.TYPE);
+            Field f = contextClass.getField("ENGINE_SCOPE");
+            bindings = getBindings.invoke(context, f.getInt(null));
+            Bindings_put = bindingsClass.getMethod("put", String.class, Object.class);
+            Bindings_put.invoke(bindings, "IO", System.out);
+            
+            /*
+             * Non-reflective code: 
+            ScriptEngineManager sem = new ScriptEngineManager();
+            ScriptEngine e = sem.getEngineByName("ECMAScript");
+            engine = e;
+            e.eval(jsHelperText);
+            Bindings b = e.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
+            b.put("IO", System.out);
+            bindings = b;
+             */
+            
+            return true;
+        } catch (Exception e) {
+            e.printStackTrace();
+            return false;
+        }
+    }
+
+    public void execute(Diagram d, String code) {
+        try {
+            Bindings_put.invoke(bindings, "graph", d);
+            ScriptEngine_eval.invoke(engine, code, bindings);
+        } catch (Exception ex) {
+            ex.printStackTrace();
+        }
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Cluster.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Cluster.java	Wed Jun 08 17:26:49 2011 +0200
@@ -37,6 +37,4 @@
     public void setBounds(Rectangle r);
 
     public Set<? extends Cluster> getSuccessors();
-
-    public Set<? extends Cluster> getPredecessors();
 }
--- a/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Wed Jun 08 17:26:49 2011 +0200
@@ -50,9 +50,9 @@
         assert verify();
 
         vertices = new TreeSet<Vertex>();
-        portLinks = new HashMap<Port, Set<Link>>();
-        inputPorts = new HashMap<Vertex, Set<Port>>();
-        outputPorts = new HashMap<Vertex, Set<Port>>();
+        portLinks = new HashMap<Port, Set<Link>>(links.size());
+        inputPorts = new HashMap<Vertex, Set<Port>>(links.size());
+        outputPorts = new HashMap<Vertex, Set<Port>>(links.size());
 
         for (Link l : links) {
             Port p = l.getFrom();
@@ -148,7 +148,7 @@
 
     // Returns a set of vertices with the following properties:
     // - All Vertices in the set startingRoots are elements of the set.
-    // - When starting a DFS at every vertex in the set, every vertex of the
+    // - When starting a DFS at every vertex in the set, every vertex of the 
     //   whole graph is visited.
     public Set<Vertex> findRootVertices(Set<Vertex> startingRoots) {
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/build.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.maxine" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.maxine.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/manifest.mf	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.maxine
+OpenIDE-Module-Layer: com/sun/hotspot/igv/maxine/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/maxine/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/nbproject/build-impl.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.maxine-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/nbproject/genfiles.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,5 @@
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=44af392c
+nbproject/build-impl.xml.script.CRC32=1a1fcc4d
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/nbproject/project.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.maxine</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graphtotext</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.structuredtext</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/nbproject/suite.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/src/META-INF/services/com.sun.hotspot.igv.graphtotext.services.GraphToTextConverter	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.maxine.CirGraphToTextConverter
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/src/com/sun/hotspot/igv/maxine/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Maxine
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/src/com/sun/hotspot/igv/maxine/CirGraphToTextConverter.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.maxine;
+
+import com.sun.hotspot.igv.data.InputEdge;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graphtotext.BFSGraphToTextConverter;
+import com.sun.hotspot.igv.graphtotext.services.AbstractGraphToTextVisitor;
+import com.sun.hotspot.igv.graphtotext.services.GraphToTextConverter;
+import com.sun.hotspot.igv.graphtotext.services.GraphToTextVisitor;
+import com.sun.hotspot.igv.structuredtext.Element;
+import com.sun.hotspot.igv.structuredtext.MultiElement;
+import com.sun.hotspot.igv.structuredtext.SimpleElement;
+import com.sun.hotspot.igv.structuredtext.StructuredText;
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.swing.text.Style;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyleContext;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class CirGraphToTextConverter implements GraphToTextConverter {
+
+    private static final String CALL_OPERATOR = " \u2022 ";
+
+    private Map<InputNode, Set<Figure>> map;
+    private InputGraph graph;
+
+    public StructuredText convert(InputGraph graph, Diagram diagram) {
+        map = diagram.calcSourceToFigureRelation();
+        this.graph = graph;
+        
+        BFSGraphToTextConverter converter = new BFSGraphToTextConverter(nodeVisitor);
+        converter.registerVisitor(localVariableVisitor, new StringPropertyMatcher("type", "LocalVariable"));
+        converter.registerVisitor(parameterVisitor, new StringPropertyMatcher("type", "Parameter"));
+        converter.registerVisitor(closureVisitor, new RegexpPropertyMatcher("type", "Closure"));
+        converter.registerVisitor(continuationVisitor, new RegexpPropertyMatcher("type", "Continuation"));
+        converter.registerVisitor(callVisitor, new RegexpPropertyMatcher("type", "Call"));
+        converter.registerVisitor(blockVisitor, new RegexpPropertyMatcher("type", "Block"));
+        return converter.convert(graph, diagram);
+    }
+    private GraphToTextVisitor nodeVisitor = new NodeVisitor();
+    private GraphToTextVisitor localVariableVisitor = new NodeVisitor();
+    private GraphToTextVisitor parameterVisitor = new NodeVisitor();
+    private GraphToTextVisitor closureVisitor = new ClosureVisitor("proc");
+    private GraphToTextVisitor continuationVisitor = new ClosureVisitor("cont");
+    private GraphToTextVisitor callVisitor = new CallVisitor();
+    private GraphToTextVisitor blockVisitor = new BlockVisitor();
+
+    private void printOffset(List<InputEdge> path, MultiElement elem) {
+        for (int i = 0; i < path.size(); i++) {
+            InputEdge cur = path.get(i);
+            InputNode fromNode = graph.getNode(cur.getFrom());
+            SimpleElement simpleElem = new SimpleElement(" ", calcStyle(fromNode));
+            simpleElem.addSource(fromNode.getId());
+            elem.addChild(simpleElem);
+        }
+    }
+
+    private class NodeVisitor extends AbstractGraphToTextVisitor {
+
+        @Override
+        public Element cyclicVisit(InputNode node, List<InputEdge> path) {
+            SimpleElement elem = new SimpleElement(node.getProperties().get("name"), calcStyle(node));
+            elem.addSource(node.getId());
+            return elem;
+        }
+    }
+    
+    private Color calcColor(InputNode node) {
+        Set<Figure> figureSet = this.map.get(node);
+        if(figureSet != null && figureSet.size() == 1) {
+            return figureSet.iterator().next().getColor();
+        } else {
+            return Color.WHITE;
+        }
+    }
+    
+    private Style calcStyle(InputNode node) {
+        Color c = calcColor(node);
+        Style defaultStyle = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
+        Style newStyle = StyleContext.getDefaultStyleContext().addStyle(null, defaultStyle);
+        
+        StyleConstants.setBackground(newStyle, c);
+        return newStyle;
+    }
+
+    private class ClosureVisitor extends AbstractGraphToTextVisitor {
+
+        private String label;
+
+        protected String getLabel(InputNode node) {
+                return label;
+        }
+
+        public ClosureVisitor(String label) {
+            this.label = label;
+        }
+
+        @Override
+        public Element cyclicVisit(InputNode node, List<InputEdge> path) {
+            return SimpleElement.EMPTY;
+        }
+
+        @Override
+        public Element visit(InputNode node, List<InputEdge> path, List<Pair<InputEdge, Element>> children) {
+            MultiElement e = new MultiElement(calcStyle(node));
+            e.print("{", node.getId());
+            e.print(getLabel(node), node.getId());
+
+            e.print("[", node.getId());
+            for (int i = 0; i < children.size() - 1; i++) {
+                Pair<InputEdge, Element> p = children.get(i);
+                e.addChild(p.getRight());
+                if (i != children.size() - 2) {
+                    e.print("|", node.getId());
+                }
+            }
+            e.print("]", node.getId());
+            e.print(CALL_OPERATOR, node.getId());
+            e.println();
+            List<InputEdge> newPath = new ArrayList<InputEdge>(path);
+            newPath.add(children.get(children.size() - 1).getLeft());
+            printOffset(newPath, e);
+            
+            MultiElement childElement = new MultiElement("...");
+            childElement.addChild(children.get(children.size() - 1).getRight());
+            e.addChild(childElement);
+            
+            e.println();
+            printOffset(path, e);
+            e.print("}", node.getId());
+            MultiElement resElem = new MultiElement();
+            resElem.addChild(e);
+            return resElem;
+        }
+    }
+
+    private class CallVisitor extends AbstractGraphToTextVisitor {
+
+        @Override
+        public Element cyclicVisit(InputNode node, List<InputEdge> path) {
+            return SimpleElement.EMPTY;
+        }
+
+        @Override
+        public Element visit(InputNode node, List<InputEdge> path, List<Pair<InputEdge, Element>> children) {
+            MultiElement e = new MultiElement(calcStyle(node));
+            e.print("(", node.getId());
+            for (int i = 0; i < children.size(); i++) {
+                Pair<InputEdge, Element> p = children.get(i);
+                e.addChild(p.getRight());
+                if (i != children.size() - 1) {
+                    e.print("|", node.getId());
+                }
+            }
+            e.print(")", node.getId());
+            MultiElement resElem = new MultiElement();
+            resElem.addChild(e);
+            return resElem;
+        }
+    }
+
+    private class BlockVisitor extends ClosureVisitor {
+
+        public BlockVisitor() {
+            super("block");
+        }
+        
+        @Override
+        protected String getLabel(InputNode node) {
+            return node.getProperties().get("name");
+        }
+
+        @Override
+        public Element cyclicVisit(InputNode node, List<InputEdge> path) {
+            MultiElement e = new MultiElement(calcStyle(node));
+            e.print(getLabel(node), node);
+            return e;
+        }
+
+        @Override
+        public Element visit(InputNode node, List<InputEdge> path, List<Pair<InputEdge, Element>> children) {
+            return super.visit(node, path, children);
+        }
+    }
+
+    private static final PropertyMatcher MATCHER = new Properties.RegexpPropertyMatcher("type", ".*CIR.*");
+    public boolean canConvert(InputGraph graph) {
+        return graph.getGroup().getProperties().selectSingle(MATCHER) != null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/src/com/sun/hotspot/igv/maxine/filters/color.filter	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,9 @@
+colorize("name", ".*", white);
+colorize("name", "cont",new  java.awt.Color(1.0, 0.8, 0.8));
+colorize("name", "proc", new  java.awt.Color(0.8, 0.8, 1.0));
+colorize("name", "call", new  java.awt.Color(0.9, 0.9, 0.9));
+colorize("name", "block", new java.awt.Color(1.0, 1.0, 0.6)); 
+colorize("class", ".*Constant", new java.awt.Color(0.7, 1.0, 0.9)); 
+colorize("class", ".*Parameter", new java.awt.Color(0.9, 1.0, 0.7)); 
+colorize("class", ".*Variable", new java.awt.Color(0.7, 1.0, 0.7)); 
+colorize("class", ".*cir\.snippet.*", yellow); 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/src/com/sun/hotspot/igv/maxine/filters/structural.filter	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,7 @@
+split("class", ".*Constant");
+split("class", ".*Variable");
+split("class", ".*Parameter");
+split("class", ".*Snippet");
+split("class", ".*Switch");
+split("class", ".*cir\.snippet.*"); 
+split("class", ".*cir\.builtin.*"); 
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Maxine/src/com/sun/hotspot/igv/maxine/layer.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+      <folder name="Filters">
+        <file name="Maxine CIR Coloring" url="filters/color.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        <file name="Maxine CIR Structural Filter" url="filters/structural.filter">
+            <attr name="enabled" boolvalue="false"/>
+            <attr name="after" stringvalue="Maxine CIR Coloring"/>
+        </file>
+    </folder>	
+</filesystem>
--- a/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/genfiles.properties	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/genfiles.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -1,6 +1,3 @@
-build.xml.data.CRC32=5a0e591e
-build.xml.script.CRC32=a265137e
-build.xml.stylesheet.CRC32=a56c6a5b@1.45.1
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
 nbproject/build-impl.xml.data.CRC32=5a0e591e
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/build-impl.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/build-impl.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -4,6 +4,13 @@
 ***         EDIT ../build.xml INSTEAD         ***
 -->
 <project name="com.sun.hotspot.igv.rhino-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
     <property file="nbproject/private/suite-private.properties"/>
     <property file="nbproject/suite.properties"/>
     <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
@@ -16,13 +23,21 @@
             <property name="@{name}" value="${@{value}}"/>
         </sequential>
     </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
     <property file="${user.properties.file}"/>
     <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
         <condition>
             <not>
-                <available file="${harness.dir}" type="dir"/>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
             </not>
         </condition>
     </fail>
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/genfiles.properties	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/genfiles.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -1,8 +1,5 @@
-build.xml.data.CRC32=0c3e7912
-build.xml.script.CRC32=44d0050c
-build.xml.stylesheet.CRC32=79c3b980
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
 nbproject/build-impl.xml.data.CRC32=0c3e7912
-nbproject/build-impl.xml.script.CRC32=7aab3f52
-nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
+nbproject/build-impl.xml.script.CRC32=87376d18
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- a/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/RhinoScriptEngine.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/RhinoScriptEngine.java	Wed Jun 08 17:26:49 2011 +0200
@@ -52,14 +52,12 @@
             Class scriptable = cl.loadClass("org.mozilla.javascript.Scriptable");
             importerTopLevel = cl.loadClass("org.mozilla.javascript.ImporterTopLevel");
             importer = importerTopLevel.getDeclaredConstructor(context);
-            scope_put = importerTopLevel.getMethod("put", new Class[]{String.class, scriptable, Object.class});
-            cx_evaluateString = context.getDeclaredMethod("evaluateString", new Class[]{scriptable, String.class, String.class, Integer.TYPE, Object.class});
-            context_enter = context.getDeclaredMethod("enter", new Class[0]);
-            context_exit = context.getDeclaredMethod("exit", new Class[0]);
+            scope_put = importerTopLevel.getMethod("put", String.class, scriptable, Object.class);
+            cx_evaluateString = context.getDeclaredMethod("evaluateString", scriptable, String.class, String.class, Integer.TYPE, Object.class);
+            context_enter = context.getDeclaredMethod("enter");
+            context_exit = context.getDeclaredMethod("exit");
             return true;
-        } catch (NoSuchMethodException nsme) {
-            return false;
-        } catch (ClassNotFoundException cnfe) {
+        } catch (Exception e) {
             return false;
         }
     }
@@ -77,9 +75,8 @@
                 // Exit from the context.
                 context_exit.invoke(null, (Object[]) null);
             }
-        } catch (InvocationTargetException iae) {
-        } catch (IllegalAccessException iae) {
-        } catch (InstantiationException iae) {
+        } catch (Exception e) {
+            e.printStackTrace();
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/build.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.selectioncoordinator" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.selectioncoordinator.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/manifest.mf	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.selectioncoordinator
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/selectioncoordinator/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/build-impl.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.selectioncoordinator-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/genfiles.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,5 @@
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=13553862
+nbproject/build-impl.xml.script.CRC32=3db87c68
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/platform.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,129 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    gsf1,\
+    harness,\
+    java2,\
+    nb6.1,\
+    profiler3
+disabled.modules=\
+    org.apache.xml.resolver,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.nativeaccess,\
+    org.netbeans.core.output2,\
+    org.netbeans.insane,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.libs.commons_logging,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jna,\
+    org.netbeans.libs.jsch,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.xerces,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.classfile,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.diff,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.errorstripe,\
+    org.netbeans.modules.editor.errorstripe.api,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.highlights,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.plain,\
+    org.netbeans.modules.editor.plain.lib,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.bat,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.sh,\
+    org.netbeans.modules.lexer.editorbridge,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.progress.ui,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.templates,\
+    org.netbeans.modules.timers,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.system.cvss,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.flyingsaucer,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
+    org.openide.compat,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    ide9,\
+    platform8
+nbjdk.active=default
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/project.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.selectioncoordinator</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.selectioncoordinator</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/suite.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/src/com/sun/hotspot/igv/selectioncoordinator/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=SelectionCoordinator
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/src/com/sun/hotspot/igv/selectioncoordinator/SelectionCoordinator.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.selectioncoordinator;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas
+ */
+public class SelectionCoordinator {
+
+    private static SelectionCoordinator singleInstance = new SelectionCoordinator();
+    private Set<Object> selectedObjects;
+    private Set<Object> highlightedObjects;
+    private ChangedEvent<SelectionCoordinator> selectedChangedEvent;
+    private ChangedEvent<SelectionCoordinator> highlightedChangedEvent;
+
+    public static SelectionCoordinator getInstance() {
+        return singleInstance;
+    }
+
+    private SelectionCoordinator() {
+        selectedChangedEvent = new ChangedEvent<SelectionCoordinator>(this);
+        highlightedChangedEvent = new ChangedEvent<SelectionCoordinator>(this);
+        selectedObjects = new HashSet<Object>();
+        highlightedObjects = new HashSet<Object>();
+    }
+
+    public Set<Object> getSelectedObjects() {
+        return Collections.unmodifiableSet(selectedObjects);
+    }
+
+    public Set<Object> getHighlightedObjects() {
+        return Collections.unmodifiableSet(highlightedObjects);
+    }
+
+    public ChangedEvent<SelectionCoordinator> getHighlightedChangedEvent() {
+        return highlightedChangedEvent;
+    }
+
+    public ChangedEvent<SelectionCoordinator> getSelectedChangedEvent() {
+        return selectedChangedEvent;
+    }
+
+    public void addHighlighted(Object o) {
+        if (!highlightedObjects.contains(o)) {
+            highlightedObjects.add(o);
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void removeHighlighted(Object o) {
+        if (highlightedObjects.contains(o)) {
+            highlightedObjects.remove(o);
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void addAllHighlighted(Set<? extends Object> s) {
+        int oldSize = highlightedObjects.size();
+        highlightedObjects.addAll(s);
+        if (oldSize != highlightedObjects.size()) {
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void removeAllHighlighted(Set<? extends Object> s) {
+        int oldSize = highlightedObjects.size();
+        highlightedObjects.removeAll(s);
+        if (oldSize != highlightedObjects.size()) {
+            highlightedObjectsChanged();
+        }
+    }
+
+    private void highlightedObjectsChanged() {
+        highlightedChangedEvent.fire();
+
+    }
+
+    public void addAllSelected(Set<? extends Object> s) {
+        int oldSize = selectedObjects.size();
+        selectedObjects.addAll(s);
+        if (oldSize != selectedObjects.size()) {
+            selectedObjectsChanged();
+        }
+    }
+
+    public void removeAllSelected(Set<? extends Object> s) {
+        int oldSize = selectedObjects.size();
+        selectedObjects.removeAll(s);
+        if (oldSize != selectedObjects.size()) {
+            selectedObjectsChanged();
+        }
+    }
+
+    public void setSelectedObjects(Set<? extends Object> s) {
+        assert s != null;
+        selectedObjects.clear();
+        selectedObjects.addAll(s);
+        selectedObjectsChanged();
+    }
+
+    private void selectedObjectsChanged() {
+        selectedChangedEvent.fire();
+    }
+
+    public void setHighlightedObjects(Set<? extends Object> s) {
+        assert s != null;
+        this.highlightedObjects.clear();
+        this.highlightedObjects.addAll(s);
+        highlightedObjectsChanged();
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -14,6 +14,30 @@
                         <specification-version>1.0</specification-version>
                     </run-dependency>
                 </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graphtotext</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.structuredtext</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
             </module-dependencies>
             <public-packages/>
         </data>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/META-INF/services/com.sun.hotspot.igv.graphtotext.services.GraphToTextConverter	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.servercompiler.ServerCompilerGraphToTextConverter
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/JavaGroupOrganizer.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/JavaGroupOrganizer.java	Wed Jun 08 17:26:49 2011 +0200
@@ -68,7 +68,7 @@
     }
 
     private void buildResult(List<Pair<String, List<Group>>> result, List<Group> groups, NameProvider provider) {
-        HashMap<String, List<Group>> map = new HashMap<String, List<Group>>();
+        HashMap<String, List<Group>> map = new HashMap<String, List<Group>>(groups.size());
         for (Group g : groups) {
             String s = provider.getName(g);
 
@@ -113,7 +113,7 @@
             }
 
             int current = firstPoint;
-            while (current > 0 && name.charAt(current) != ' ') {
+            while (current >= 0 && name.charAt(current) != ' ') {
                 current--;
             }
 
@@ -145,10 +145,10 @@
             }
 
             int current = firstPoint;
-            while (current > 0 && name.charAt(current) != ' ') {
+            while (current >= 0 && name.charAt(current) != ' ') {
                 current--;
             }
-
+            
             String fullClassName = name.substring(current + 1, firstParenthese);
             int lastPoint = fullClassName.lastIndexOf(".");
             if (lastPoint == -1) {
@@ -182,7 +182,7 @@
             }
 
             int current = firstPoint;
-            while (current > 0 && name.charAt(current) != ' ') {
+            while (current >= 0 && name.charAt(current) != ' ') {
                 current--;
             }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/ServerCompilerGraphToTextConverter.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.servercompiler;
+
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.data.InputEdge;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.PropertySelector;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graphtotext.services.GraphToTextConverter;
+import com.sun.hotspot.igv.structuredtext.Element;
+import com.sun.hotspot.igv.structuredtext.MultiElement;
+import com.sun.hotspot.igv.structuredtext.SimpleElement;
+import com.sun.hotspot.igv.structuredtext.StructuredText;
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.swing.text.Style;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyleContext;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ServerCompilerGraphToTextConverter implements GraphToTextConverter {
+
+
+    private Map<InputNode, Set<Figure>> map;
+    private Map<InputNode, List<InputEdge>> ingoingEdges;
+    private Map<InputNode, List<InputEdge>> outgoingEdges;
+    private InputGraph graph;
+
+    private Collection<InputNode> sortNodes(Collection<InputNode> nodes) {
+        List<InputNode> result = new ArrayList<InputNode>(nodes);
+
+        Collections.sort(result, InputNode.getPropertyComparator("idx"));
+
+
+        return result;
+    }
+
+    public StructuredText convert(InputGraph graph, Diagram diagram) {
+
+        this.graph = graph;
+        map = diagram.calcSourceToFigureRelation();
+        ingoingEdges = graph.findAllIngoingEdges();
+        outgoingEdges = graph.findAllOutgoingEdges();
+
+        final StructuredText result = new StructuredText(graph.getName());
+
+        for (InputBlock b : graph.getBlocks()) {
+            result.addChild(new SimpleElement("Block " + b.getName() + "\n"));
+            for (InputNode n : sortNodes(b.getNodes())) {
+                result.addChild(getNodeElement(n));
+            }
+        }
+
+        boolean first = true;
+        for (InputNode n : sortNodes(graph.getNodes())) {
+            if (graph.getBlock(n) == null) {
+                if (first) {
+                    first = false;
+                    result.addChild(new SimpleElement("No block: \n"));
+                }
+                result.addChild(getNodeElement(n));
+            }
+        }
+
+
+        return result;
+    }
+
+    private Element getNodeNameElement(InputNode n) {
+
+        final SimpleElement name = new SimpleElement(n.getProperties().get("idx") + " " + n.getProperties().get("name"), calcStyle(n));
+        name.addSource(n.getId());
+        return name;
+    }
+
+    private Element getNodeSmallElement(InputNode n) {
+        final SimpleElement id = new SimpleElement(n.getProperties().get("idx"), calcStyle(n));
+        id.addSource(n.getId());
+        return id;
+    }
+
+    private Element getNodeElement(InputNode n) {
+
+        final MultiElement result = new MultiElement();
+
+        result.print("\t");
+        result.addChild(getNodeNameElement(n));
+
+        result.print(" === ");
+        
+        for (InputEdge e : outgoingEdges.get(n)) {
+            result.print(" ");
+            result.addChild(getNodeSmallElement(graph.getNode(e.getTo())));
+            result.print(" ");
+        }
+
+        result.print(" [[");
+
+        for (InputEdge e : ingoingEdges.get(n)) {
+            result.print(" ");
+            result.addChild(getNodeSmallElement(graph.getNode(e.getFrom())));
+            result.print(" ");
+        }
+
+        result.print("]] ");
+        
+        result.print(n.getProperties().get("dump_spec"));
+
+        result.print("\n");
+
+        return result;
+    }
+    
+    private static final PropertyMatcher MATCHER = new Properties.RegexpPropertyMatcher("name", "Root");
+    public boolean canConvert(InputGraph graph) {
+        return new PropertySelector(graph.getNodes()).selectSingle(MATCHER) != null;
+    }
+
+    private Color calcColor(InputNode node) {
+        Set<Figure> figureSet = this.map.get(node);
+        if(figureSet != null && figureSet.size() == 1) {
+            return figureSet.iterator().next().getColor();
+        } else {
+            return Color.WHITE;
+        }
+    }
+
+    private Color lessColor(Color c) {
+        return new Color(255 - (255 - c.getRed()) / 4, 255 - (255 - c.getGreen()) / 4, 255 - (255 - c.getBlue()) / 4);
+    }
+
+    private Style calcStyle(InputNode node) {
+        Color c = calcColor(node);
+        Style defaultStyle = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
+        Style newStyle = StyleContext.getDefaultStyleContext().addStyle(null, defaultStyle);
+
+        StyleConstants.setBackground(newStyle, lessColor(c));
+        return newStyle;
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java	Wed Jun 08 17:26:49 2011 +0200
@@ -93,7 +93,7 @@
 
             if (!visited.contains(parent)) {
                 visited.add(parent);
-                InputBlock block = new InputBlock(graph, "" + blockCount);
+                InputBlock block = graph.addBlock(Integer.toString(blockCount));
                 blocks.add(block);
                 if (parent == root) {
                     rootBlock = block;
@@ -125,7 +125,7 @@
                                 n = n.preds.get(0);
                             }
                             if (n.block != null) {
-                                n.block.addSuccessor(block);
+                                graph.addBlockConnection(n.block, block);
                             }
                         }
                     }
@@ -136,12 +136,12 @@
                         for (Node n2 : n.succs) {
 
                             if (n2 != parent && n2.block != null && n2.block != rootBlock) {
-                                block.addSuccessor(n2.block);
+                                graph.addBlockConnection(block, n2.block);
                             }
                         }
                     } else {
                         if (n != parent && n.block != null && n.block != rootBlock) {
-                            block.addSuccessor(n.block);
+                            graph.addBlockConnection(block, n.block);
                         }
                     }
                 }
@@ -161,7 +161,7 @@
                 }
 
                 if (pushed == 0 && p == root) {
-                // TODO: special handling when root backedges are not built yet
+                    // TODO: special handling when root backedges are not built yet
                 }
             }
         }
@@ -174,7 +174,7 @@
         }
 
         int z = 0;
-        blockIndex = new HashMap<InputBlock, Integer>();
+        blockIndex = new HashMap<InputBlock, Integer>(blocks.size());
         for (InputBlock b : blocks) {
             blockIndex.put(b, z);
             z++;
@@ -191,14 +191,14 @@
             for (InputNode n : tmpNodes) {
                 String block = getBlockName(n);
                 if (graph.getBlock(n) == null) {
-                    graph.getBlock(block).addNode(n);
+                    graph.getBlock(block).addNode(n.getId());
                     assert graph.getBlock(n) != null;
                 }
             }
             return graph.getBlocks();
         } else {
             nodes = new ArrayList<Node>();
-            inputNodeToNode = new HashMap<InputNode, Node>();
+            inputNodeToNode = new HashMap<InputNode, Node>(graph.getNodes().size());
 
             this.graph = graph;
             buildUpGraph();
@@ -207,7 +207,17 @@
             buildCommonDominators();
             scheduleLatest();
 
+
+            InputBlock noBlock = null;
             for (InputNode n : graph.getNodes()) {
+                if (graph.getBlock(n) == null) {
+                    if (noBlock == null) {
+                        noBlock = graph.addBlock("none");
+                        blocks.add(noBlock);
+                    }
+                    
+                    graph.setBlock(n, noBlock);
+                }
                 assert graph.getBlock(n) != null;
             }
 
@@ -219,6 +229,10 @@
 
 
         Node root = findRoot();
+        if(root == null) {
+            assert false : "No root found!";
+            return;
+        }
 
         // Mark all nodes reachable in backward traversal from root
         Set<Node> reachable = new HashSet<Node>();
@@ -374,12 +388,12 @@
     }
 
     public void buildDominators() {
-        dominatorMap = new HashMap<InputBlock, InputBlock>();
+        dominatorMap = new HashMap<InputBlock, InputBlock>(graph.getBlocks().size());
         if (blocks.size() == 0) {
             return;
         }
-        Vector<BlockIntermediate> intermediate = new Vector<BlockIntermediate>();
-        Map<InputBlock, BlockIntermediate> map = new HashMap<InputBlock, BlockIntermediate>();
+        Vector<BlockIntermediate> intermediate = new Vector<BlockIntermediate>(graph.getBlocks().size());
+        Map<InputBlock, BlockIntermediate> map = new HashMap<InputBlock, BlockIntermediate>(graph.getBlocks().size());
         int z = 0;
         for (InputBlock b : blocks) {
             BlockIntermediate bi = new BlockIntermediate();
@@ -538,22 +552,21 @@
     }
 
     private Node findRoot() {
-        Node node0 = null;
 
+        Node alternativeRoot = null;
         for (Node n : nodes) {
             InputNode inputNode = n.inputNode;
-            if(inputNode.getProperties().get("name") == null) {
-                System.out.println("NO name !! " + inputNode);
+            String s = inputNode.getProperties().get("name");
+            if (s != null && s.equals("Root")) {
+                return n;
             }
-            if (inputNode != null && inputNode.getProperties().get("name") != null && inputNode.getProperties().get("name").equals("Root")) {
-                return n;
-            } else if (inputNode.getId() == 0) {
-                // use as fallback in case no root node is found
-                node0 = n;
+
+            if (n.preds.size() == 0) {
+                alternativeRoot = n;
             }
         }
 
-        return node0;
+        return alternativeRoot;
     }
 
     public void buildUpGraph() {
@@ -569,7 +582,7 @@
             inputNodeToNode.put(n, node);
         }
 
-        Map<Integer, List<InputEdge>> edgeMap = new HashMap<Integer, List<InputEdge>>();
+        Map<Integer, List<InputEdge>> edgeMap = new HashMap<Integer, List<InputEdge>>(graph.getEdges().size());
         for (InputEdge e : graph.getEdges()) {
 
             int to = e.getTo();
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/color.filter	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/color.filter	Wed Jun 08 17:26:49 2011 +0200
@@ -1,5 +1,18 @@
 colorize("name", ".*", yellow);
 colorize("name", "Catch.*", blue);
-
 colorize("name", "Region|Loop|CountedLoop|Root", red);
 colorize("name", "CProj|IfFalse|IfTrue|JProj|CatchProj", magenta);
+colorize("name", "Con.*", orange);
+colorize("name", "Parm|Proj", lightGray);
+
+// Nodes with bci
+colorize("bci", "..*", magenta);
+
+// Line style
+var f = new ColorFilter("Line Style filter");
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "int:")), null, Color.BLUE, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "control")), null, Color.RED, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "memory")), null, Color.GREEN, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "tuple:")), null, Color.MAGENTA, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "bottom")), null, Color.LIGHT_GRAY, null));
+f.apply(graph);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/combine.filter	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-var f = new CombineFilter("Combine Filter");
-f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", ".*"), new Properties.RegexpPropertyMatcher("name", "Proj|IfFalse|IfTrue|JProj|MachProj|JumpProj|CatchProj")));
-f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", "Cmp.*"), new Properties.RegexpPropertyMatcher("name", "Bool")));
-f.apply(graph);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/extendedColor.filter	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-colorize("name", "Con.*", orange);
-colorize("name", "Parm|Proj", lightGray);
-colorize("bci", "..*", magenta);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/linestyle.filter	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-var f = new ColorFilter("Line Style filter");
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "int:")), null, Color.BLUE, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "control")), null, Color.RED, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "memory")), null, Color.GREEN, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "tuple:")), null, Color.MAGENTA, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "bottom")), null, Color.LIGHT_GRAY, null));
-f.apply(graph);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/register.filter	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/register.filter	Wed Jun 08 17:26:49 2011 +0200
@@ -1,4 +1,5 @@
+// Register coloring
 colorize("reg", "EAX", green);
 colorize("reg", "EFLAGS", gray);
 colorize("reg", "EBP", orange);
-colorize("reg", "ECX", cyan);
+colorize("reg", "ECX", cyan);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/remove.filter	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/remove.filter	Wed Jun 08 17:26:49 2011 +0200
@@ -1,1 +1,8 @@
-remove("dump_spec", "FramePtr|ReturnAdr|I_O"); 
\ No newline at end of file
+remove("dump_spec", "FramePtr|ReturnAdr|I_O"); 
+removeInputs("name", "Root");
+var f = new RemoveSelfLoopsFilter("Remove Self-Loops");
+f.apply(graph);
+removeInputs("name", "SafePoint|CallStaticJava|CallDynamicJava|CallJava|CallLeaf|CallRuntime|AbstractLock|CallLeafNoFP|Call|CallStaticJavaDirect", 5);
+removeInputs("name", "Unlock|Lock", 7);
+removeInputs("name", "Allocate", 7);
+removeInputs("name", "AllocateArray", 9);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeMemory.filter	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-
-//var f = new RemoveFilter("Remove Memory");
-//f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("dump_spec", "Memory")), false));
-//f.addRule(new RemoveFilter.RemoveRule(new AndSelector(new MatcherSelector(new Properties.StringPropertyMatcher("name", "Proj")), new MatcherSelector(new Properties.StringPropertyMatcher("type", "memory"))), false));
-//f.apply(graph);
-
-remove("dump_spec", "Memory");
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeRootInputs.filter	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-removeInputs("name", "Root");
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSafepointInputs.filter	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-removeInputs("name", "SafePoint|CallStaticJava|CallDynamicJava|CallJava|CallLeaf|CallRuntime|AbstractLock|CallLeafNoFP|Call|CallStaticJavaDirect", 5);
-removeInputs("name", "Unlock|Lock", 7);
-removeInputs("name", "Allocate", 7);
-removeInputs("name", "AllocateArray", 9);
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSelfLoops.filter	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-var f = new RemoveSelfLoopsFilter("Remove Self-Loops");
-f.apply(graph);
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/split.filter	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-split("name", "BoxLock");
-split("name", "(Con.*)|(loadCon.*)");
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/structural.filter	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,6 @@
+var f = new CombineFilter("Combine Filter");
+f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", ".*"), new Properties.RegexpPropertyMatcher("name", "Proj|IfFalse|IfTrue|JProj|MachProj|JumpProj|CatchProj")));
+f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", "Cmp.*"), new Properties.RegexpPropertyMatcher("name", "Bool")));
+f.apply(graph);
+split("name", "BoxLock");
+split("name", "(Con.*)|(loadCon.*)", "[dump_spec]");
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -2,60 +2,28 @@
 <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
 <filesystem>
       <folder name="Filters">
-        <file name="Basic Coloring" url="filters/color.filter">
-            <attr name="enabled" boolvalue="true"/>
-        </file>
-        <file name="Matcher Flags Coloring" url="filters/matchingFlags.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Basic Coloring"/>
-        </file>
-        <file name="Register Coloring" url="filters/register.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Matcher Flags Coloring"/>
+        <file name="C2 Basic Coloring" url="filters/color.filter">
+            <attr name="enabled" boolvalue="false"/>
         </file>
-        <file name="Extended Coloring" url="filters/extendedColor.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Register Coloring"/>
-        </file>
-        <file name="Line Coloring" url="filters/linestyle.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Extended Coloring"/>
+        <file name="C2 Matcher Flags Coloring" url="filters/matchingFlags.filter">
+            <attr name="enabled" boolvalue="false"/>
+            <attr name="after" stringvalue="C2 Basic Coloring"/>
         </file>
-        <file name="Difference Coloring" url="filters/difference.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Line Coloring"/>
-        </file>
-        <file name="Only Control Flow" url="filters/onlyControlFlow.filter">
+        <file name="C2 Register Coloring" url="filters/register.filter">
             <attr name="enabled" boolvalue="false"/>
-            <attr name="after" stringvalue="Difference Coloring"/>
+            <attr name="after" stringvalue="C2 Matcher Flags Coloring"/>
         </file>
-        <file name="Remove FramePtr, I_O and Return Address" url="filters/remove.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Only Control Flow"/>
-        </file>
-        <file name="Remove Memory" url="filters/removeMemory.filter">
+        <file name="C2 Only Control Flow" url="filters/onlyControlFlow.filter">
             <attr name="enabled" boolvalue="false"/>
-            <attr name="after" stringvalue="Remove FramePtr, I_O and Return Address"/>
-        </file>
-        <file name="Remove Root Inputs" url="filters/removeRootInputs.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Memory"/>
+            <attr name="after" stringvalue="C2 Register Coloring"/>
         </file>
-        <file name="Remove Safepoint Inputs" url="filters/removeSafepointInputs.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Root Inputs"/>
-        </file>
-        <file name="Remove Self Loops" url="filters/removeSelfLoops.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Safepoint Inputs"/>
+        <file name="C2 Remove Filter" url="filters/remove.filter">
+            <attr name="enabled" boolvalue="false"/>
+            <attr name="after" stringvalue="C2 Only Control Flow"/>
         </file>
-        <file name="Combine" url="filters/combine.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Self Loops"/>
+        <file name="C2 Structural" url="filters/structural.filter">
+            <attr name="enabled" boolvalue="false"/>
+            <attr name="after" stringvalue="C2 Remove Filter"/>
         </file>
-        <file name="Split" url="filters/split.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Combine"/>
-        </file>
-    </folder>
+    </folder>	
 </filesystem>
--- a/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/layer.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/layer.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -2,8 +2,8 @@
 <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
 <filesystem>
     <folder name="OptionsDialog">
-        <file name="Advanced.instance_hidden"/>
-        <file name="General.instance_hidden"/>
+      <!-- <file name="Advanced.instance_hidden"/>
+        <file name="General.instance_hidden"/>-->
         <file name="com-sun-hotspot-igv-settings-ViewOptionsCategory.instance"/>
     </folder>
 </filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/build.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.structuredtext" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.structuredtext.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/manifest.mf	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.structuredtext
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/structuredtext/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/nbproject/build-impl.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.structuredtext-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/nbproject/genfiles.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,5 @@
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=216fc635
+nbproject/build-impl.xml.script.CRC32=6022dc85
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/nbproject/platform.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,129 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    gsf1,\
+    harness,\
+    java2,\
+    nb6.1,\
+    profiler3
+disabled.modules=\
+    org.apache.xml.resolver,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.nativeaccess,\
+    org.netbeans.core.output2,\
+    org.netbeans.insane,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.libs.commons_logging,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jna,\
+    org.netbeans.libs.jsch,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.xerces,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.classfile,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.diff,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.errorstripe,\
+    org.netbeans.modules.editor.errorstripe.api,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.highlights,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.plain,\
+    org.netbeans.modules.editor.plain.lib,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.bat,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.sh,\
+    org.netbeans.modules.lexer.editorbridge,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.progress.ui,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.templates,\
+    org.netbeans.modules.timers,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.system.cvss,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.flyingsaucer,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
+    org.openide.compat,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    ide9,\
+    platform8
+nbjdk.active=default
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/nbproject/project.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.structuredtext</code-name-base>
+            <suite-component/>
+            <module-dependencies/>
+            <public-packages>
+                <package>com.sun.hotspot.igv.structuredtext</package>
+                <package>com.sun.hotspot.igv.structuredtext.services</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/nbproject/suite.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/src/com/sun/hotspot/igv/structuredtext/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=StructuredText
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/src/com/sun/hotspot/igv/structuredtext/Element.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.structuredtext;
+
+import com.sun.hotspot.igv.structuredtext.services.ElementVisitor;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+import javax.swing.text.Style;
+import javax.swing.text.StyleContext;
+
+/**
+ *
+ * @author Thomas
+ */
+public abstract class Element {
+    
+    private Set<Object> source;
+    private Style style;
+    private Style highlightedStyle;
+    
+    public Element() {
+        source = new HashSet<Object>();
+        style = null;
+        highlightedStyle = null;
+    }
+    
+    public Style getStyle() {
+        return style;
+    }
+
+    public Style getHighlightedStyle() {
+        return highlightedStyle;
+    }
+    
+    public void setStyle(Style style) {
+        this.style = style;
+    }
+
+    public void setHighlightedStyle(Style style) {
+        this.highlightedStyle = style;
+    }
+    
+    public void setStyleRecursive(Style style) {
+        this.style = style;
+    }
+
+    public void setHighlightedStyleRecursive(Style style) {
+        this.highlightedStyle = style;
+    }
+    
+    public Set<Object> getSource() {
+        return Collections.unmodifiableSet(source);
+    }
+    
+    public void addSource(Object o) {
+        source.add(o);
+    }
+    
+    public abstract void accept(ElementVisitor visitor);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/src/com/sun/hotspot/igv/structuredtext/MultiElement.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.structuredtext;
+
+import com.sun.hotspot.igv.structuredtext.services.ElementVisitor;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import javax.swing.text.Style;
+
+/**
+ *
+ * @author Thomas
+ */
+public class MultiElement extends Element {
+
+    private List<Element> children;
+    private String foldString;
+    
+    public MultiElement() {
+        this((String)null);
+    }
+       
+    public MultiElement(String foldString) {
+        this(foldString, null);
+    }
+    
+    public MultiElement(Style style) {
+        this(null, style);
+    }
+    
+    public MultiElement(String foldString, Style style) {
+        setStyle(style);
+        this.foldString = foldString;
+        children = new ArrayList<Element>();
+    }
+    
+    public void print(String s) {
+        print(s, null);
+    }
+
+    @Override
+    public void setStyleRecursive(Style style) {
+        super.setStyleRecursive(style);
+        for(Element elem : this.getChildren()) {
+            elem.setStyleRecursive(style);
+        }
+    }
+
+    @Override
+    public void setHighlightedStyleRecursive(Style style) {
+        super.setStyleRecursive(style);
+        for(Element elem : this.getChildren()) {
+            elem.setHighlightedStyleRecursive(style);
+        }
+    }
+    
+    public void print(String s, Object source) {
+        if (s == null) {
+            s = "";
+        }
+        SimpleElement elem = new SimpleElement(s);
+        if(source != null) {
+            elem.addSource(source);
+        }
+        addChild(elem);
+    }
+
+    public void print(String s, Object source, int padding) {
+        if (s == null) {
+            s = "";
+        }
+        StringBuffer sb = new StringBuffer(s);
+        while(sb.length() < padding) {
+            sb.insert(0, ' ');
+        }
+
+        print(sb.toString(), source);
+
+    }
+    
+    public void println() {
+        println("");
+    }
+    
+    public void println(String s) {
+        print(s + "\n");
+    }
+    
+    public void println(String s, Object source) {
+        print(s + "\n", source);
+    }
+    
+    
+    public void println(String s, Object source, int padding) {
+        print(s + "\n", source, padding);
+    }
+    
+    public void addChild(Element element) {
+        assert element != null;
+        this.children.add(element);
+    }
+    
+    public String getFoldString() {
+        return foldString;
+    }
+    
+    public void setFoldString(String s) {
+        this.foldString = s;
+    }
+    
+    public List<Element> getChildren() {
+        return Collections.unmodifiableList(children);
+    }
+    
+    public void accept(ElementVisitor visitor) {
+        visitor.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/src/com/sun/hotspot/igv/structuredtext/Range.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.structuredtext;
+
+/**
+ *
+ * @author Thomas
+ */
+public class Range {
+    
+    private int start;
+    private int length;
+    
+    public Range(int start, int length) {
+        this.start = start;
+        this.length = length;
+    }
+    
+    public int getStart() {
+        return start;
+    }
+    
+    public boolean overlaps(Range r2) {
+        if(start < r2.start) {
+            return start + length > r2.start;
+        } else {
+            return r2.start + r2.length > start;
+        }
+    }
+    
+    public int getLength() {
+        return length;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/src/com/sun/hotspot/igv/structuredtext/SimpleElement.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.structuredtext;
+
+import com.sun.hotspot.igv.structuredtext.services.ElementVisitor;
+import javax.swing.text.Style;
+import javax.swing.text.StyleContext;
+
+/**
+ *
+ * @author Thomas
+ */
+public class SimpleElement extends Element {
+
+    public static final Element EMPTY = new SimpleElement("");
+    public static final Element LN = new SimpleElement("\n");
+    public static final Element TAB = new SimpleElement("\t");
+    
+    private String text;
+    
+    public SimpleElement(String s) {
+        this(s, null);
+    }
+    
+    public SimpleElement(String s, Style style) {
+        setText(s);
+        setStyle(style);
+        assert text != null;
+    }
+    
+    private static String addPadding(String s, int minLength) {
+        
+        StringBuilder sb = new StringBuilder(s);
+        while(sb.length() < minLength) {
+            sb.insert(0, ' ');
+        }
+        return sb.toString();
+    }
+    
+    public SimpleElement(String s, int length) {
+        this(addPadding(s, length));
+    }
+    
+    
+    public String getText() {
+        return text;
+    }
+    
+    public void setText(String s) {
+        this.text = s;
+    }
+    
+    public void accept(ElementVisitor visitor) {
+        visitor.visit(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/src/com/sun/hotspot/igv/structuredtext/StructuredText.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.structuredtext;
+
+import com.sun.hotspot.igv.structuredtext.services.ElementVisitor;
+import java.util.HashMap;
+import java.util.Map;
+
+
+/**
+ *
+ * @author Thomas
+ */
+public class StructuredText extends MultiElement {
+    
+    private String name;
+    
+    public StructuredText(String name) {
+        this.name = name;
+    }
+    
+    public String getName() {
+        return name;
+    }
+    
+    public Element findElementAt(final int searchIndex) {
+        
+        final Element[] result = new Element[1];
+        this.accept(new ElementVisitor() {
+            
+            private int index;
+            
+            @Override
+            public void visit(MultiElement element) {
+                int startIndex = index;
+                super.visit(element);
+            }
+
+            @Override
+            public void visit(SimpleElement element) {
+                if(searchIndex >= index && searchIndex < index + element.getText().length()) {
+                    assert result[0] == null;
+                    result[0] = element;
+                }
+                index += element.getText().length();
+            }
+        });
+        
+        return result[0];
+    }
+    
+    public Map<Element, Range> calculateRanges() {
+        
+        final Map<Element, Range> result = new HashMap<Element, Range>();
+        
+        this.accept(new ElementVisitor() {
+            
+            private int index;
+            
+            @Override
+            public void visit(MultiElement element) {
+                int startIndex = index;
+                super.visit(element);
+                result.put(element, new Range(startIndex, index - startIndex));
+            }
+
+            @Override
+            public void visit(SimpleElement element) {
+                result.put(element, new Range(index, element.getText().length()));
+                index += element.getText().length();
+            }
+        });
+        
+        
+        return result;
+        
+    }
+    
+    public String convertToString() {
+        final StringBuilder result = new StringBuilder();
+        this.accept(new ElementVisitor() {
+            @Override
+            public void visit(SimpleElement element) {
+                result.append(element.getText());
+            }
+        }
+        );
+        return result.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/src/com/sun/hotspot/igv/structuredtext/ToolTipProvider.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.structuredtext;
+
+/**
+ *
+ * @author thomas
+ */
+public interface ToolTipProvider {
+
+        String getToolTip();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/StructuredText/src/com/sun/hotspot/igv/structuredtext/services/ElementVisitor.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.structuredtext.services;
+
+import com.sun.hotspot.igv.structuredtext.Element;
+import com.sun.hotspot.igv.structuredtext.MultiElement;
+import com.sun.hotspot.igv.structuredtext.SimpleElement;
+
+/**
+ *
+ * @author Thomas
+ */
+public abstract class ElementVisitor {
+
+    public void visit(MultiElement element) {
+        
+        for(Element e : element.getChildren()) {
+            e.accept(this);
+        }
+    }
+    public abstract void visit(SimpleElement element);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/build.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.texteditor" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.texteditor.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/manifest.mf	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.texteditor
+OpenIDE-Module-Layer: com/sun/hotspot/igv/texteditor/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/texteditor/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/nbproject/build-impl.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.texteditor-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/nbproject/genfiles.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,5 @@
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=2b80dbe4
+nbproject/build-impl.xml.script.CRC32=122053f6
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/nbproject/platform.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,129 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    gsf1,\
+    harness,\
+    java2,\
+    nb6.1,\
+    profiler3
+disabled.modules=\
+    org.apache.xml.resolver,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.nativeaccess,\
+    org.netbeans.core.output2,\
+    org.netbeans.insane,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.libs.commons_logging,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jna,\
+    org.netbeans.libs.jsch,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.xerces,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.classfile,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.diff,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.errorstripe,\
+    org.netbeans.modules.editor.errorstripe.api,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.highlights,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.plain,\
+    org.netbeans.modules.editor.plain.lib,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.bat,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.sh,\
+    org.netbeans.modules.lexer.editorbridge,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.progress.ui,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.templates,\
+    org.netbeans.modules.timers,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.system.cvss,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.flyingsaucer,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
+    org.openide.compat,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    ide9,\
+    platform8
+nbjdk.active=default
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/nbproject/project.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.texteditor</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.selectioncoordinator</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.structuredtext</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.editor</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>3</release-version>
+                        <specification-version>1.42.2.3.9.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.editor.fold</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.8</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>3</release-version>
+                        <specification-version>3.8.1.13.9</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.11.2.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.text</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.18</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.12.0.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.20</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.texteditor</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/nbproject/suite.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/src/com/sun/hotspot/igv/texteditor/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,2 @@
+
+OpenIDE-Module-Name=TextEditor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/src/com/sun/hotspot/igv/texteditor/SyntaxLayer.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.texteditor;
+
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.selectioncoordinator.SelectionCoordinator;
+import com.sun.hotspot.igv.structuredtext.MultiElement;
+import com.sun.hotspot.igv.structuredtext.SimpleElement;
+import com.sun.hotspot.igv.structuredtext.StructuredText;
+import com.sun.hotspot.igv.structuredtext.Element;
+import com.sun.hotspot.igv.structuredtext.Range;
+import com.sun.hotspot.igv.structuredtext.ToolTipProvider;
+import com.sun.hotspot.igv.structuredtext.services.ElementVisitor;
+import java.awt.Color;
+import java.awt.Cursor;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Stack;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.Style;
+import javax.swing.text.StyleConstants;
+import javax.swing.text.StyleContext;
+import org.netbeans.spi.editor.highlighting.HighlightsLayerFactory;
+import org.netbeans.spi.editor.highlighting.HighlightsSequence;
+import org.netbeans.spi.editor.highlighting.support.AbstractHighlightsContainer;
+
+/**
+ *
+ * @author Thomas
+ */
+public class SyntaxLayer extends AbstractHighlightsContainer implements ChangedListener<SelectionCoordinator> {
+
+    private HighlightsLayerFactory.Context context;
+
+    public SyntaxLayer(final HighlightsLayerFactory.Context context) {
+        this.context = context;
+
+        context.getDocument().addDocumentListener(new DocumentListener() {
+
+            public void insertUpdate(DocumentEvent arg0) {
+                update();
+            }
+
+            public void removeUpdate(DocumentEvent arg0) {
+            }
+
+            public void changedUpdate(DocumentEvent arg0) {
+            }
+        });
+
+        SelectionCoordinator.getInstance().getSelectedChangedEvent().addListener(this);
+        SelectionCoordinator.getInstance().getHighlightedChangedEvent().addListener(this);
+
+        context.getComponent().addMouseMotionListener(new MouseMotionListener() {
+
+            public void mouseDragged(MouseEvent e) {
+            }
+
+            public void mouseMoved(MouseEvent e) {
+                // [tw] hack to prevent sidebar mouse over
+                if (e.getPoint().getX() < 15) return;
+
+                int index = context.getComponent().viewToModel(e.getPoint());
+                Element elem = indexToElement(index);
+                if (elem != null) {
+                    Set<Object> highlightedSource = new HashSet<Object>(elem.getSource());
+                    SelectionCoordinator.getInstance().setHighlightedObjects(highlightedSource);
+                    context.getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+                }
+            }
+        });
+
+        context.getComponent().addMouseListener(new MouseListener() {
+
+            public void mouseClicked(MouseEvent e) {
+                
+                int index = context.getComponent().viewToModel(e.getPoint());
+                Element elem = indexToElement(index);
+                if (elem != null) {
+                    Set<Object> selectedSource = new HashSet<Object>(elem.getSource());
+
+                    for (Object o : selectedSource) {
+                        if (o instanceof ToolTipProvider) {
+                            String toolTip = ((ToolTipProvider) o).getToolTip();
+                        }
+                    }
+
+                    if ((e.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0) {
+
+                        SelectionCoordinator.getInstance().addAllSelected(selectedSource);
+                    } else {
+                        SelectionCoordinator.getInstance().setSelectedObjects(selectedSource);
+                    }
+                    context.getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+                } else {
+                    context.getComponent().setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
+
+                }
+            }
+
+            public void mousePressed(MouseEvent e) {
+            }
+
+            public void mouseReleased(MouseEvent e) {
+            }
+
+            public void mouseEntered(MouseEvent e) {
+            }
+
+            public void mouseExited(MouseEvent e) {
+                SelectionCoordinator.getInstance().setHighlightedObjects(new HashSet<Object>());
+            }
+        });
+    }
+
+    public void changed(SelectionCoordinator source) {
+        update();
+    }
+
+    private void update() {
+        fireHighlightsChange(0, context.getDocument().getLength());
+    }
+
+    private Element indexToElement(int index) {
+        StructuredText text = (StructuredText) context.getDocument().getProperty(StructuredText.class);
+        if (text == null) {
+            return null;
+        }
+        return text.findElementAt(index);
+    }
+
+    private static class HighlightsRange {
+
+        private int start;
+        private int end;
+        private AttributeSet attributes;
+
+        public HighlightsRange(int start, int length, AttributeSet attributes) {
+            this.start = start;
+            this.end = start + length;
+            this.attributes = attributes;
+        }
+
+        public int getStart() {
+            return start;
+        }
+
+        public int getEnd() {
+            return end;
+        }
+
+        public AttributeSet getAttributes() {
+            return attributes;
+        }
+    }
+
+    private static class HighlightsSequenceImpl implements HighlightsSequence {
+
+        private List<HighlightsRange> ranges;
+        private int currentIndex;
+
+        public HighlightsSequenceImpl() {
+            this(new ArrayList<HighlightsRange>());
+        }
+
+        public HighlightsSequenceImpl(List<HighlightsRange> ranges) {
+            this.ranges = ranges;
+            this.currentIndex = -1;
+        }
+
+        public boolean moveNext() {
+            currentIndex++;
+            return currentIndex < ranges.size();
+        }
+
+        public int getStartOffset() {
+            return ranges.get(currentIndex).getStart();
+        }
+
+        public int getEndOffset() {
+            return ranges.get(currentIndex).getEnd();
+        }
+
+        public AttributeSet getAttributes() {
+            return ranges.get(currentIndex).getAttributes();
+        }
+    }
+
+    private boolean intersects(Set<Object> s1, Set<Object> s2) {
+        for (Object o : s1) {
+            if (s2.contains(o)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public HighlightsSequence getHighlights(final int start, final int end) {
+
+        StructuredText text = (StructuredText) context.getDocument().getProperty(StructuredText.class);
+        if (text == null) {
+            return new HighlightsSequenceImpl();
+        }
+        final Map<Element, Range> ranges = text.calculateRanges();
+        final List<HighlightsRange> highlightsRanges = new ArrayList<HighlightsRange>();
+        final Range baseRange = new Range(start, end - start);
+
+        text.accept(new ElementVisitor() {
+            
+            private Stack<Style> styleStack = new Stack<Style>();
+            private Stack<Style> highlightedStyleStack = new Stack<Style>();
+            private Stack<MultiElement> parentElements = new Stack<MultiElement>();
+            
+            @Override
+            public void visit(MultiElement element) {
+                Style curStyle = element.getStyle();
+                Style curHighlightedStyle = element.getHighlightedStyle();
+                if(curStyle != null) {
+                    styleStack.push(curStyle);
+                }
+                if (curHighlightedStyle != null) {
+                    highlightedStyleStack.push(curHighlightedStyle);
+                }
+                parentElements.push(element);
+                super.visit(element);
+                if(curStyle != null) {
+                    styleStack.pop();
+                }
+                if (curHighlightedStyle != null) {
+                    highlightedStyleStack.pop();
+                }
+                parentElements.pop();
+            }
+            
+
+            @Override
+            public void visit(SimpleElement element) {
+                Range curRange = ranges.get(element);
+                if (baseRange.overlaps(curRange)) {
+                    Style style = element.getStyle();
+                    if(style == null) {
+                        if(styleStack.size() > 0) {
+                            style = styleStack.peek();
+                        } else {
+                            style = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
+                            StyleConstants.setBackground(style, Color.WHITE);
+                        }
+                    }
+                    
+                    
+                    Style highlightedStyle = element.getHighlightedStyle();
+                    if (highlightedStyle == null) {
+                        if (highlightedStyleStack.size() > 0) {
+                            highlightedStyle = highlightedStyleStack.peek();
+                        }
+                    }
+
+                    Set<Object> highlightedSource = SelectionCoordinator.getInstance().getHighlightedObjects();
+                    if (highlightedSource != null) {
+                        
+                        boolean doesIntersect = intersects(element.getSource(), highlightedSource);
+                        for (MultiElement parentElement : parentElements) {
+                            if (doesIntersect) {
+                                break;
+                            }
+
+                            doesIntersect = intersects(parentElement.getSource(), highlightedSource);
+                        }
+
+                        if (doesIntersect) {
+
+                            if (highlightedStyle != null) {
+                                style = highlightedStyle;
+                            } else {
+                                style = StyleContext.getDefaultStyleContext().addStyle(null, style);
+                                Color bg = StyleConstants.getBackground(style);
+                                Color fg = StyleConstants.getForeground(style);
+                                StyleConstants.setBackground(style, new Color(255 - bg.getRed(), 255 - bg.getGreen(), 255 - bg.getBlue()));
+                                StyleConstants.setForeground(style, new Color(255 - fg.getRed(), 255 - fg.getGreen(), 255 - fg.getBlue()));
+                            }
+                        }
+                    }
+
+                    Set<Object> selectedSource = SelectionCoordinator.getInstance().getSelectedObjects();
+                    if (selectedSource != null && intersects(element.getSource(), selectedSource)) {
+                        style = StyleContext.getDefaultStyleContext().addStyle(null, style);
+                        StyleConstants.setBold(style, true);
+                    }
+
+                    highlightsRanges.add(new HighlightsRange(curRange.getStart(), curRange.getLength(), style));
+                }
+            }
+        });
+
+        return new HighlightsSequenceImpl(highlightsRanges);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/src/com/sun/hotspot/igv/texteditor/TextEditor.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.texteditor;
+
+import com.sun.hotspot.igv.structuredtext.Element;
+import com.sun.hotspot.igv.structuredtext.MultiElement;
+import com.sun.hotspot.igv.structuredtext.SimpleElement;
+import com.sun.hotspot.igv.structuredtext.StructuredText;
+import com.sun.hotspot.igv.structuredtext.services.ElementVisitor;
+import java.awt.Component;
+import java.util.HashSet;
+import java.util.Set;
+import javax.swing.JEditorPane;
+import javax.swing.SwingUtilities;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.Position;
+import javax.swing.text.SimpleAttributeSet;
+import org.netbeans.modules.editor.NbEditorDocument;
+import org.netbeans.modules.editor.NbEditorUtilities;
+import org.openide.text.Annotation;
+import org.openide.text.Line;
+import org.openide.util.Exceptions;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class TextEditor {
+    
+    private JEditorPane editorPane;
+    private Component component;
+    private Set<Annotation> addedAnnotations;
+    
+    public TextEditor() {
+        editorPane = new JEditorPane();
+        component = createEditor(editorPane);
+        addedAnnotations = new HashSet<Annotation>();
+        
+    }
+    
+    public Component getComponent() {
+        return component;
+    }
+
+    public void setStructuredText(StructuredText text) {
+        assert text != null;
+        
+        setStructuredText(text, null);
+    }
+    
+    public void setStructuredText(final StructuredText text, final Element focusedElement) {
+        
+        assert text != null;
+
+        SwingUtilities.invokeLater(new Runnable() {
+
+            public void run() {
+                Document doc = editorPane.getDocument();
+                doc.putProperty(StructuredText.class, text);
+
+                for (Annotation a : addedAnnotations) {
+                    ((NbEditorDocument) editorPane.getDocument()).removeAnnotation(a);
+                }
+
+                try {
+                    editorPane.getDocument().remove(0, editorPane.getDocument().getLength());
+                    editorPane.getDocument().insertString(0, text.convertToString(), SimpleAttributeSet.EMPTY);
+
+                    text.accept(new ElementVisitor() {
+
+                        private int pos = 0;
+
+                        private void checkForFocus(Element element) {
+                            if (element == focusedElement) {
+                                editorPane.setCaretPosition(pos);
+                            }
+                        }
+
+                        @Override
+                        public void visit(MultiElement element) {
+                            super.visit(element);
+                            checkForFocus(element);
+                        }
+
+                        @Override
+                        public void visit(SimpleElement element) {
+                            checkForFocus(element);
+                            for (Object o : element.getSource()) {
+                                if (o instanceof Annotation) {
+                                    Annotation a = (Annotation) o;
+                                    final Line line = NbEditorUtilities.getLine(editorPane.getDocument(), pos, false);
+
+                                    ((NbEditorDocument) editorPane.getDocument()).addAnnotation(new PositionImpl(pos), element.getText().length(), a);
+                                    addedAnnotations.add(a);
+                                }
+                            }
+                            pos += element.getText().length();
+                        }
+
+                        class PositionImpl implements Position {
+
+                            private int position;
+
+                            public PositionImpl(int position) {
+                                this.position = position;
+                            }
+
+                            public int getOffset() {
+                                return position;
+                            }
+                        }
+                    });
+
+                } catch (BadLocationException ex) {
+                    Exceptions.printStackTrace(ex);
+                }
+                
+            }
+        });
+       
+    }
+
+    private Component createEditor(JEditorPane pane) {
+        TextEditorKit kit = new TextEditorKit();
+        pane.setEditable(false);
+        NbEditorDocument doc = (NbEditorDocument) kit.createDefaultDocument();
+        pane.setEditorKit(kit);
+        pane.setDocument(doc);
+        return doc.createEditor(pane);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/src/com/sun/hotspot/igv/texteditor/TextEditorKit.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.texteditor;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.swing.Action;
+import org.netbeans.editor.BaseDocument;
+import org.netbeans.modules.editor.NbEditorKit;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class TextEditorKit extends NbEditorKit {
+
+    public static final String MIME_TYPE = "text/text-igv";
+    
+    /**
+     * Actions to be not available in the editor.
+     */
+    private static final String[] ACTION_FILTER = {
+        NbEditorKit.shiftLineLeftAction,
+        NbEditorKit.shiftLineRightAction,
+        NbEditorKit.jumpListNextAction,
+        NbEditorKit.jumpListNextComponentAction,
+        NbEditorKit.jumpListPrevAction,
+        NbEditorKit.jumpListPrevComponentAction,
+        NbEditorKit.pasteAction,
+        NbEditorKit.removeLineAction,
+        NbEditorKit.cutAction,
+        NbEditorKit.findAction,
+        NbEditorKit.findNextAction,
+        NbEditorKit.findPreviousAction,
+        NbEditorKit.toggleHighlightSearchAction,
+        NbEditorKit.findSelectionAction,
+        "jump-list-last-edit"
+    };
+    
+    @Override
+    protected Action[] createActions() {
+        Action[] actions = super.createActions();
+        List<Action> returnedActions = new ArrayList<Action>();
+        for(Action a : actions) {
+            System.out.println("action: " + a.getValue(Action.NAME));
+            
+            boolean found = false;
+            for(String s : ACTION_FILTER) {
+                if(s.equals(a.getValue(Action.NAME))) {
+                    found = true;
+                }
+            }
+            if(!found) {
+                returnedActions.add(a);
+            }
+        }
+        
+        Action[] result = new Action[returnedActions.size()];
+        for(int i=0; i<returnedActions.size(); i++) {
+            result[i] = returnedActions.get(i);
+        }
+        
+        return result;
+    }
+
+    @Override
+    protected void initDocument(BaseDocument doc) {
+        super.initDocument(doc);
+        System.out.println("Initializing document: " + doc);
+        
+    }
+
+    @Override
+    public String getContentType() {
+        return MIME_TYPE;
+    }
+    
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/src/com/sun/hotspot/igv/texteditor/TextFoldManager.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.texteditor;
+
+import com.sun.hotspot.igv.structuredtext.MultiElement;
+import com.sun.hotspot.igv.structuredtext.SimpleElement;
+import javax.swing.event.DocumentEvent;
+import javax.swing.text.BadLocationException;
+import org.netbeans.api.editor.fold.Fold;
+import org.netbeans.spi.editor.fold.FoldHierarchyTransaction;
+import org.netbeans.spi.editor.fold.FoldManager;
+import org.netbeans.spi.editor.fold.FoldOperation;
+import com.sun.hotspot.igv.structuredtext.Element;
+import com.sun.hotspot.igv.structuredtext.Range;
+import com.sun.hotspot.igv.structuredtext.StructuredText;
+import com.sun.hotspot.igv.structuredtext.services.ElementVisitor;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+import javax.swing.text.Document;
+import org.netbeans.api.editor.fold.FoldType;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class TextFoldManager implements FoldManager {
+
+    private FoldOperation operation;
+    private final FoldType defaultFoldType = new FoldType("default");
+    private Set<Fold> currentFolds;
+
+    public TextFoldManager() {
+        currentFolds = new HashSet<Fold>();
+    }
+
+    public void init(FoldOperation operation) {
+        this.operation = operation;
+    }
+
+    public void initFolds(final FoldHierarchyTransaction transaction) {
+    }
+
+    private void update(Document document, final FoldHierarchyTransaction transaction) {
+
+        
+        StructuredText text = (StructuredText) document.getProperty(StructuredText.class);
+        if (text == null) {
+            // No StructuredText object behind the document object.
+            return;
+        }
+        
+        if(document.getLength() == 0) {
+            return;
+        }
+        
+        final Map<Element, Range> ranges = text.calculateRanges();
+        currentFolds.clear();
+
+        text.accept(new ElementVisitor() {
+            @Override
+            public void visit(MultiElement element) {
+                super.visit(element);
+                Range curRange = ranges.get(element);
+
+                if (element.getFoldString() != null) {
+                    try {
+                        Fold f = operation.addToHierarchy(defaultFoldType, element.getFoldString(), false,
+                                curRange.getStart(), curRange.getStart() + curRange.getLength(), 0, 0,
+                                null, transaction);
+                        currentFolds.add(f);
+                    } catch (BadLocationException ex) {
+                        assert false : "Structured text not in sync with document content " + ex.getStackTrace();
+                    }
+                }
+            }
+
+            @Override
+            public void visit(SimpleElement element) {
+            }
+        });
+    }
+
+    public void insertUpdate(DocumentEvent event, FoldHierarchyTransaction transaction) {
+        update(event.getDocument(), transaction);
+    }
+
+    public void removeUpdate(DocumentEvent event, FoldHierarchyTransaction transaction) {
+        update(event.getDocument(), transaction);
+    }
+
+    public void changedUpdate(DocumentEvent event, FoldHierarchyTransaction transaction) {
+//        update(event.getDocument(), transaction);
+    }
+
+    public void removeEmptyNotify(Fold arg0) {
+    }
+
+    public void removeDamagedNotify(Fold arg0) {
+    }
+
+    public void expandNotify(Fold arg0) {
+    }
+
+    public void release() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/src/com/sun/hotspot/igv/texteditor/TextFoldManagerFactory.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.texteditor;
+
+import org.netbeans.spi.editor.fold.FoldManager;
+import org.netbeans.spi.editor.fold.FoldManagerFactory;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class TextFoldManagerFactory implements FoldManagerFactory{
+    public FoldManager createFoldManager() {
+        return new TextFoldManager();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/src/com/sun/hotspot/igv/texteditor/TextHighlightsLayerFactory.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.texteditor;
+
+import org.netbeans.spi.editor.highlighting.HighlightsLayer;
+import org.netbeans.spi.editor.highlighting.HighlightsLayerFactory;
+import org.netbeans.spi.editor.highlighting.ZOrder;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class TextHighlightsLayerFactory implements HighlightsLayerFactory {
+    public HighlightsLayer[] createLayers(HighlightsLayerFactory.Context context) {
+        return new HighlightsLayer[] {
+            HighlightsLayer.create("com.sun.hotspot.igv.texteditor.SyntaxLayer", ZOrder.TOP_RACK, true, new SyntaxLayer(context))
+        };
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/src/com/sun/hotspot/igv/texteditor/TextSideBarFactory.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.texteditor;
+
+import javax.swing.JComponent;
+import javax.swing.text.JTextComponent;
+import org.netbeans.editor.CodeFoldingSideBar;
+import org.netbeans.editor.SideBarFactory;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class TextSideBarFactory implements SideBarFactory {
+    public JComponent createSideBar(JTextComponent text) {
+        return new CodeFoldingSideBar(text);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/src/com/sun/hotspot/igv/texteditor/layer.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+    
+    <folder name="Editors">
+        <folder name="Preferences"/>
+        <folder name="text">
+            <folder name="text-igv">
+                <file name="EditorKit.instance">
+                <attr name="instanceClass" stringvalue="com.sun.hotspot.igv.texteditor.TextEditorKit"/>
+                </file>
+                <folder name="FoldManager">
+                    <file name="com-sun-hotspot-igv-texteditor-TextFoldManagerFactory.instance"/>
+                </folder>
+                <folder name="Preferences">
+                    <file name="org-netbeans-modules-editor-preferences.xml" url="org-netbeans-modules-editor-preferences.xml"/>
+                </folder>
+                <folder name="SideBar">
+                    <file name="com-sun-hotspot-igv-texteditor-TextSideBarFactory.instance">
+                        <attr name="position" intvalue="1500"/>
+                    </file>
+                </folder>
+                <file name="com-sun-hotspot-igv-texteditor-TextHighlightsLayerFactory.instance"/>
+                </folder>
+        </folder>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/TextEditor/src/com/sun/hotspot/igv/texteditor/org-netbeans-modules-editor-preferences.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+<!--
+DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+
+Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
+
+
+The contents of this file are subject to the terms of either the GNU
+General Public License Version 2 only ("GPL") or the Common
+Development and Distribution License("CDDL") (collectively, the
+"License"). You may not use this file except in compliance with the
+License. You can obtain a copy of the License at
+http://www.netbeans.org/cddl-gplv2.html
+or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+specific language governing permissions and limitations under the
+License.  When distributing the software, include this License Header
+Notice in each file and include the License file at
+nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
+particular file as subject to the "Classpath" exception as provided
+by Sun in the GPL Version 2 section of the License file that
+accompanied this code. If applicable, add the following below the
+License Header, with the fields enclosed by brackets [] replaced by
+your own identifying information:
+"Portions Copyrighted [year] [name of copyright owner]"
+
+Contributor(s):
+
+The Original Software is NetBeans. The Initial Developer of the Original
+Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
+Microsystems, Inc. All Rights Reserved.
+
+If you wish your version of this file to be governed by only the CDDL
+or only the GPL Version 2, indicate your decision by adding
+"[Contributor] elects to include this software in this distribution
+under the [CDDL or GPL Version 2] license." If you do not indicate a
+single choice of license, a recipient has the option to distribute
+your version of this file under either the CDDL, the GPL Version 2 or
+to extend the choice of license to its licensees as provided above.
+However, if you add GPL Version 2 code and therefore, elected the GPL
+Version 2 license, then the option applies only if the new code is
+made subject to such option by the copyright holder.
+-->
+<!DOCTYPE editor-preferences PUBLIC "-//NetBeans//DTD Editor Preferences 1.0//EN" "http://www.netbeans.org/dtds/EditorPreferences-1_0.dtd">
+
+<editor-preferences>
+    <entry name="toolbarVisible" value="false" javaType="java.lang.Boolean" />
+    <entry name="line-number-visible" value="false" javaType="java.lang.Boolean" />
+    <entry name="code-folding-enable" value="true" javaType="java.lang.Boolean" />
+    <entry name="status-bar-visible" value="false" javaType="java.lang.Boolean" />
+    <entry name="text-limit-line-visible" value="false" javaType="java.lang.Boolean" />
+</editor-preferences>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/LookupHistory.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.util;
+
+import java.util.Hashtable;
+import java.util.Map;
+import org.openide.util.Lookup.Result;
+import org.openide.util.LookupEvent;
+import org.openide.util.LookupListener;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author Thomas
+ */
+public class LookupHistory {
+
+    private static Map<Class, LookupHistoryImpl> cache = new Hashtable<Class, LookupHistoryImpl>();
+
+    private static class LookupHistoryImpl<T> implements LookupListener {
+
+        private Class<T> klass;
+        private Result<T> result;
+
+        private T last;
+
+        public LookupHistoryImpl(Class<T> klass) {
+            this.klass = klass;
+            result = Utilities.actionsGlobalContext().lookupResult(klass);
+            result.addLookupListener(this);
+            last = Utilities.actionsGlobalContext().lookup(klass);
+        }
+
+        public T getLast() {
+            return last;
+        }
+
+        public void resultChanged(LookupEvent ev) {
+            T current = Utilities.actionsGlobalContext().lookup(klass);
+            if (current != null) {
+                last = current;
+            }
+        }
+    }
+
+
+    public static void init(Class klass) {
+
+        if (!cache.containsKey(klass)) {
+            cache.put(klass, new LookupHistoryImpl(klass));
+        }
+    }
+
+    public static <T> T getLast(Class<T> klass) {
+
+        init(klass);
+
+        assert cache.containsKey(klass);
+
+        return (T) cache.get(klass).getLast();
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Wed Jun 08 17:26:49 2011 +0200
@@ -69,16 +69,17 @@
         this.colorChangedEvent = new ChangedEvent<RangeSliderModel>(this);
         setPositions(positions);
     }
-
+    
     protected void setPositions(List<String> positions) {
         this.positions = positions;
-        colors = new ArrayList<Color>();
-        for (int i = 0; i < positions.size(); i++) {
-            colors.add(Color.black);
-        }
+         colors = new ArrayList<Color>();
+         for (int i = 0; i < positions.size(); i++) {
+             colors.add(Color.black);
+         }
         changedEvent.fire();
         colorChangedEvent.fire();
-    }
+     }
+
 
     public void setColors(List<Color> colors) {
         this.colors = colors;
--- a/src/share/tools/IdealGraphVisualizer/View/nbproject/project.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/nbproject/project.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -55,6 +55,14 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>com.sun.hotspot.igv.selectioncoordinator</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>com.sun.hotspot.igv.settings</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
@@ -87,6 +95,14 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>org.netbeans.spi.quicksearch</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>org.openide.actions</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
--- a/src/share/tools/IdealGraphVisualizer/View/src/META-INF/services/com.sun.hotspot.igv.data.services.InputGraphProvider	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.view.EditorInputGraphProvider
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/Bundle.properties	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -1,3 +1,4 @@
-HINT_EditorTopComponent=This is a Editor window
-OpenIDE-Module-Name=View
-CTL_EditorTopComponent=Editor Window
+HINT_EditorTopComponent=This is a Editor window
+OpenIDE-Module-Name=View
+CTL_EditorTopComponent=Editor Window
+QuickSearch/Nodes/com-sun-hotspot-igv-view-NodeQuickSearch.instance=Nodes
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ConnectionAnchor.java	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view;
-
-import com.sun.hotspot.igv.view.widgets.SlotWidget;
-import java.awt.Point;
-import java.awt.Rectangle;
-import org.netbeans.api.visual.anchor.Anchor;
-import org.netbeans.api.visual.anchor.Anchor.Entry;
-import org.netbeans.api.visual.anchor.Anchor.Result;
-import org.netbeans.api.visual.widget.Widget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class ConnectionAnchor extends Anchor {
-
-    public enum HorizontalAlignment {
-
-        Left,
-        Center,
-        Right
-    }
-    private HorizontalAlignment alignment;
-
-    public ConnectionAnchor(Widget widget) {
-        this(HorizontalAlignment.Center, widget);
-    }
-
-    public ConnectionAnchor(HorizontalAlignment alignment, Widget widget) {
-        super(widget);
-        this.alignment = alignment;
-    }
-
-    public Result compute(Entry entry) {
-        return new Result(getRelatedSceneLocation(), Anchor.DIRECTION_ANY);
-    }
-
-    @Override
-    public Point getRelatedSceneLocation() {
-        Point p = null;
-        Widget w = getRelatedWidget();
-        if (w != null) {
-            if (w instanceof SlotWidget) {
-                p = ((SlotWidget) w).getAnchorPosition();
-            } else {
-                Rectangle r = w.convertLocalToScene(w.getBounds());
-                int y = r.y + r.height / 2;
-                int x = r.x;
-                if (alignment == HorizontalAlignment.Center) {
-                    x = r.x + r.width / 2;
-                } else if (alignment == HorizontalAlignment.Right) {
-                    x = r.x + r.width;
-                }
-
-                p = new Point(x, y);
-            }
-        }
-
-        return p;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java	Wed Jun 08 17:26:49 2011 +0200
@@ -31,39 +31,41 @@
 import com.sun.hotspot.igv.graph.Connection;
 import com.sun.hotspot.igv.graph.Diagram;
 import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
 import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Slot;
 import com.sun.hotspot.igv.hierarchicallayout.HierarchicalClusterLayoutManager;
 import com.sun.hotspot.igv.hierarchicallayout.OldHierarchicalLayoutManager;
 import com.sun.hotspot.igv.hierarchicallayout.HierarchicalLayoutManager;
 import com.sun.hotspot.igv.view.widgets.FigureWidget;
+import com.sun.hotspot.igv.layout.LayoutGraph;
+import com.sun.hotspot.igv.data.services.Scheduler;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.data.ControllableChangedListener;
+import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.Block;
+import com.sun.hotspot.igv.graph.InputSlot;
+import com.sun.hotspot.igv.graph.Slot;
+import com.sun.hotspot.igv.selectioncoordinator.SelectionCoordinator;
+import com.sun.hotspot.igv.util.ColorIcon;
+import com.sun.hotspot.igv.util.PropertiesSheet;
 import com.sun.hotspot.igv.view.widgets.InputSlotWidget;
 import com.sun.hotspot.igv.view.widgets.OutputSlotWidget;
 import com.sun.hotspot.igv.view.widgets.SlotWidget;
-import com.sun.hotspot.igv.layout.LayoutGraph;
-import com.sun.hotspot.igv.data.services.Scheduler;
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.graph.Block;
-import com.sun.hotspot.igv.util.ColorIcon;
-import com.sun.hotspot.igv.util.ExtendedSelectAction;
 import java.awt.Color;
+import java.awt.Component;
 import java.awt.Dimension;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.event.ActionEvent;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
 import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
 import java.awt.event.MouseWheelEvent;
 import java.awt.event.MouseWheelListener;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -74,8 +76,6 @@
 import javax.swing.JPopupMenu;
 import javax.swing.JScrollPane;
 import javax.swing.SwingUtilities;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
 import javax.swing.event.UndoableEditEvent;
 import javax.swing.undo.AbstractUndoableEdit;
 import javax.swing.undo.CannotRedoException;
@@ -84,16 +84,20 @@
 import org.netbeans.api.visual.action.PopupMenuProvider;
 import org.netbeans.api.visual.action.RectangularSelectDecorator;
 import org.netbeans.api.visual.action.RectangularSelectProvider;
-import org.netbeans.api.visual.action.SelectProvider;
 import org.netbeans.api.visual.action.WidgetAction;
 import org.netbeans.api.visual.animator.SceneAnimator;
 import org.netbeans.api.visual.layout.LayoutFactory;
-import org.netbeans.api.visual.widget.ConnectionWidget;
+import org.netbeans.api.visual.model.ObjectScene;
+import org.netbeans.api.visual.model.ObjectSceneEvent;
+import org.netbeans.api.visual.model.ObjectSceneEventType;
+import org.netbeans.api.visual.model.ObjectSceneListener;
+import org.netbeans.api.visual.model.ObjectState;
 import org.netbeans.api.visual.widget.LayerWidget;
-import org.netbeans.api.visual.widget.Scene;
 import org.netbeans.api.visual.widget.Widget;
-import org.netbeans.api.visual.widget.LabelWidget;
 import org.openide.awt.UndoRedo;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Sheet;
 import org.openide.util.Lookup;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
@@ -102,15 +106,10 @@
  *
  * @author Thomas Wuerthinger
  */
-public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> {
+public class DiagramScene extends ObjectScene implements DiagramViewer {
 
-    private HashMap<Figure, FigureWidget> figureWidgets;
-    private HashMap<Slot, SlotWidget> slotWidgets;
-    private HashMap<Connection, ConnectionWidget> connectionWidgets;
-    private HashMap<InputBlock, BlockWidget> blockWidgets;
-    private Widget hoverWidget;
     private WidgetAction hoverAction;
-    private List<FigureWidget> selectedWidgets;
+    private WidgetAction selectAction;
     private Lookup lookup;
     private InstanceContent content;
     private Action[] actions;
@@ -118,22 +117,24 @@
     private JScrollPane scrollPane;
     private UndoRedo.Manager undoRedoManager;
     private LayerWidget mainLayer;
-    private LayerWidget slotLayer;
     private LayerWidget blockLayer;
-    private double realZoomFactor;
-    private BoundedZoomAction zoomAction;
-    private WidgetAction panAction;
     private Widget topLeft;
     private Widget bottomRight;
-    private LayerWidget startLayer;
-    private LabelWidget startLabel;
     private DiagramViewModel model;
     private DiagramViewModel modelCopy;
-    public static final int AFTER = 1;
-    public static final int BEFORE = 1;
+    private WidgetAction zoomAction;
+    
+    /**
+     * The alpha level of partially visible figures.
+     */
     public static final float ALPHA = 0.4f;
-    public static final int GRID_SIZE = 30;
+    
+    /**
+     * The offset of the graph to the border of the window showing it.
+     */
     public static final int BORDER_SIZE = 20;
+    
+    
     public static final int UNDOREDO_LIMIT = 100;
     public static final int SCROLL_UNIT_INCREMENT = 80;
     public static final int SCROLL_BLOCK_INCREMENT = 400;
@@ -142,6 +143,7 @@
     public static final float ZOOM_INCREMENT = 1.5f;
     public static final int SLOT_OFFSET = 6;
     public static final int ANIMATION_LIMIT = 40;
+    
     private PopupMenuProvider popupMenuProvider = new PopupMenuProvider() {
 
         public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
@@ -157,6 +159,90 @@
             return widget;
         }
     };
+
+    @SuppressWarnings("unchecked")
+    public <T> T getWidget(Object o) {
+        Widget w = this.findWidget(o);
+        return (T) w;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T getWidget(Object o, Class<T> klass) {
+        Widget w = this.findWidget(o);
+        return (T) w;
+    }
+
+    private static boolean intersects(Set<? extends Object> s1, Set<? extends Object> s2) {
+        for (Object o : s1) {
+            if (s2.contains(o)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void zoomOut() {
+        double zoom = getZoomFactor();
+        Point viewPosition = getScrollPane().getViewport().getViewPosition();
+        double newZoom = zoom / DiagramScene.ZOOM_INCREMENT;
+        if (newZoom > DiagramScene.ZOOM_MIN_FACTOR) {
+            setZoomFactor(newZoom);
+            validate();
+            getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x / DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y / DiagramScene.ZOOM_INCREMENT)));
+        }
+    }
+
+    public void zoomIn() {
+
+        double zoom = getZoomFactor();
+        Point viewPosition = getScrollPane().getViewport().getViewPosition();
+        double newZoom = zoom * DiagramScene.ZOOM_INCREMENT;
+        if (newZoom < DiagramScene.ZOOM_MAX_FACTOR) {
+            setZoomFactor(newZoom);
+            validate();
+            getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x * DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y * DiagramScene.ZOOM_INCREMENT)));
+        }
+    }
+
+
+    public void centerFigures(List<Figure> list) {
+
+        boolean b = getUndoRedoEnabled();
+        setUndoRedoEnabled(false);
+        gotoFigures(list);
+        setUndoRedoEnabled(b);
+    }
+
+    private Set<Object> getObjectsFromIdSet(Set<Object> set) {
+        Set<Object> selectedObjects = new HashSet<Object>();
+        for (Figure f : getModel().getDiagramToView().getFigures()) {
+            if (intersects(f.getSource().getSourceNodesAsSet(), set)) {
+                selectedObjects.add(f);
+            }
+
+            for (Slot s : f.getSlots()) {
+                if (intersects(s.getSource().getSourceNodesAsSet(), set)) {
+                    selectedObjects.add(s);
+                }
+            }
+        }
+        return selectedObjects;
+    }
+    private ControllableChangedListener<SelectionCoordinator> highlightedCoordinatorListener = new ControllableChangedListener<SelectionCoordinator>() {
+
+        public void filteredChanged(SelectionCoordinator source) {
+            DiagramScene.this.setHighlightedObjects(getObjectsFromIdSet(source.getHighlightedObjects()));
+            DiagramScene.this.validate();
+        }
+    };
+    private ControllableChangedListener<SelectionCoordinator> selectedCoordinatorListener = new ControllableChangedListener<SelectionCoordinator>() {
+
+        public void filteredChanged(SelectionCoordinator source) {
+            DiagramScene.this.gotoSelection(source.getSelectedObjects());
+            DiagramScene.this.validate();
+        }
+    };
+
     private RectangularSelectProvider rectangularSelectProvider = new RectangularSelectProvider() {
 
         public void performSelection(Rectangle rectangle) {
@@ -170,168 +256,41 @@
                 rectangle.height *= -1;
             }
 
-            boolean updated = false;
+            Set<Object> selectedObjects = new HashSet<Object>();
             for (Figure f : getModel().getDiagramToView().getFigures()) {
-                FigureWidget w = figureWidgets.get(f);
-                Rectangle r = new Rectangle(w.getBounds());
-                r.setLocation(w.getLocation());
-                if (r.intersects(rectangle)) {
-                    if (!selectedWidgets.contains(w)) {
-                        addToSelection(w);
-                        updated = true;
+                FigureWidget w = getWidget(f);
+                if (w != null) {
+                    Rectangle r = new Rectangle(w.getBounds());
+                    r.setLocation(w.getLocation());
+
+                    if (r.intersects(rectangle)) {
+                        selectedObjects.add(f);
+                    }
+
+                    for (Slot s : f.getSlots()) {
+                        SlotWidget sw = getWidget(s);
+                        Rectangle r2 = new Rectangle(sw.getBounds());
+                        r2.setLocation(sw.convertLocalToScene(new Point(0, 0)));
+
+                        if (r2.intersects(rectangle)) {
+                            selectedObjects.add(s);
+                        }
                     }
                 } else {
-                    if (selectedWidgets.contains(w)) {
-                        selectedWidgets.remove(w);
-                        content.remove(w.getNode());
-                        w.setState(w.getState().deriveSelected(false));
-                        updated = true;
-                    }
-                }
-            }
-
-            if (updated) {
-                selectionUpdated();
-            }
-        }
-    };
-    private SelectProvider selectProvider = new SelectProvider() {
-
-        public boolean isAimingAllowed(Widget widget, Point point, boolean b) {
-            return false;
-        }
-
-        public boolean isSelectionAllowed(Widget widget, Point point, boolean b) {
-            return widget instanceof FigureWidget || widget == DiagramScene.this;
-        }
-
-        public void select(Widget w, Point point, boolean change) {
-
-            boolean updated = false;
-
-            if (w == DiagramScene.this) {
-                if (DiagramScene.this.selectedWidgets.size() != 0) {
-                    clearSelection();
-                    selectionUpdated();
-                }
-                return;
-            }
-
-            FigureWidget widget = (FigureWidget) w;
-
-
-            if (change) {
-                if (widget.getState().isSelected()) {
-                    assert selectedWidgets.contains(widget);
-                    widget.setState(widget.getState().deriveSelected(false));
-                    selectedWidgets.remove(widget);
-                    content.remove(widget.getNode());
-                    updated = true;
-                } else {
-                    assert !selectedWidgets.contains(widget);
-                    addToSelection(widget);
-                    updated = true;
-                    assert widget.getState().isSelected();
-                }
-            } else {
-
-                if (widget.getState().isSelected()) {
-                    assert selectedWidgets.contains(widget);
-                } else {
-
-                    assert !selectedWidgets.contains(widget);
-                    clearSelection();
-                    addToSelection(widget);
-                    updated = true;
-                    assert widget.getState().isSelected();
+                    assert false : "w should not be null here!";
                 }
             }
 
-            if (updated) {
-                selectionUpdated();
-            }
-
+            setSelectedObjects(selectedObjects);
         }
     };
-
-    private FigureWidget getFigureWidget(Figure f) {
-        return figureWidgets.get(f);
-    }
-    private FocusListener focusListener = new FocusListener() {
-
-        public void focusGained(FocusEvent e) {
-            DiagramScene.this.getView().requestFocus();
-        }
-
-        public void focusLost(FocusEvent e) {
-        }
-    };
+    
     private MouseWheelListener mouseWheelListener = new MouseWheelListener() {
 
         public void mouseWheelMoved(MouseWheelEvent e) {
-            DiagramScene.this.zoomAction.mouseWheelMoved(DiagramScene.this, new WidgetAction.WidgetMouseWheelEvent(0, e));
-            DiagramScene.this.validate();
-        }
-    };
-    private MouseListener mouseListener = new MouseListener() {
-
-        public void mouseClicked(MouseEvent e) {
-            DiagramScene.this.panAction.mouseClicked(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mousePressed(MouseEvent e) {
-            DiagramScene.this.panAction.mousePressed(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseReleased(MouseEvent e) {
-            DiagramScene.this.panAction.mouseReleased(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseEntered(MouseEvent e) {
-            DiagramScene.this.panAction.mouseEntered(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseExited(MouseEvent e) {
-            DiagramScene.this.panAction.mouseExited(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
+            DiagramScene.this.relayoutWithoutLayout(null);
         }
     };
-    private MouseMotionListener mouseMotionListener = new MouseMotionListener() {
-
-        public void mouseDragged(MouseEvent e) {
-            DiagramScene.this.panAction.mouseDragged(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseMoved(MouseEvent e) {
-        }
-    };
-    private ScrollChangeListener scrollChangeListener = new ScrollChangeListener();
-
-    private class ScrollChangeListener implements ChangeListener {
-
-        private Map<Widget, Point> relativePositions = new HashMap<Widget, Point>();
-        private Point oldPosition;
-
-        public void register(Widget w, Point p) {
-            relativePositions.put(w, p);
-        }
-
-        public void unregister(Widget w) {
-            relativePositions.remove(w);
-        }
-
-        public void stateChanged(ChangeEvent e) {
-            Point p = DiagramScene.this.getScrollPane().getViewport().getViewPosition();
-            if (oldPosition == null || !p.equals(oldPosition)) {
-                for (Widget w : relativePositions.keySet()) {
-                    Point curPoint = relativePositions.get(w);
-                    Point newPoint = new Point(p.x + curPoint.x, p.y + curPoint.y);
-                    w.setPreferredLocation(newPoint);
-                    DiagramScene.this.validate();
-                }
-                oldPosition = p;
-            }
-        }
-    }
 
     public Point getScrollPosition() {
         return getScrollPane().getViewport().getViewPosition();
@@ -341,43 +300,118 @@
         getScrollPane().getViewport().setViewPosition(p);
     }
 
-    public DiagramScene(Action[] actions, DiagramViewModel model) {
-        this.actions = actions;
-        selectedWidgets = new ArrayList<FigureWidget>();
-        content = new InstanceContent();
-        lookup = new AbstractLookup(content);
-        this.setCheckClipping(true);
-        this.getInputBindings().setZoomActionModifiers(0);
-
+    private JScrollPane createScrollPane() {
         JComponent comp = this.createView();
         comp.setDoubleBuffered(true);
         comp.setBackground(Color.WHITE);
         comp.setOpaque(true);
-
         this.setBackground(Color.WHITE);
         this.setOpaque(true);
-        scrollPane = new JScrollPane(comp);
-        scrollPane.setBackground(Color.WHITE);
-        scrollPane.getVerticalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
-        scrollPane.getVerticalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
-        scrollPane.getHorizontalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
-        scrollPane.getHorizontalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
-        scrollPane.getViewport().addChangeListener(scrollChangeListener);
-        hoverAction = this.createWidgetHoverAction();
+        JScrollPane result = new JScrollPane(comp);
+        result.setBackground(Color.WHITE);
+        result.getVerticalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
+        result.getVerticalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
+        result.getHorizontalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
+        result.getHorizontalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
+        return result;
+    }
+    private ObjectSceneListener selectionChangedListener = new ObjectSceneListener() {
+
+        public void objectAdded(ObjectSceneEvent arg0, Object arg1) {
+        }
+
+        public void objectRemoved(ObjectSceneEvent arg0, Object arg1) {
+        }
+
+        public void objectStateChanged(ObjectSceneEvent e, Object o, ObjectState oldState, ObjectState newState) {
+        }
+
+        public void selectionChanged(ObjectSceneEvent e, Set<Object> oldSet, Set<Object> newSet) {
+            content.set(newSet, null);
+
+            Set<Integer> nodeSelection = new HashSet<Integer>();
+            for (Object o : newSet) {
+                if (o instanceof Properties.Provider) {
+                    final Properties.Provider provider = (Properties.Provider) o;
+                    AbstractNode node = new AbstractNode(Children.LEAF) {
+
+                        @Override
+                        protected Sheet createSheet() {
+                            Sheet s = super.createSheet();
+                            PropertiesSheet.initializeSheet(provider.getProperties(), s);
+                            return s;
+                        }
+                    };
+                    node.setDisplayName(provider.getProperties().get("name"));
+                    content.add(node);
+                }
+
+
+                if (o instanceof Figure) {
+                    nodeSelection.addAll(((Figure) o).getSource().getSourceNodesAsSet());
+                } else if (o instanceof Slot) {
+                    nodeSelection.addAll(((Slot) o).getSource().getSourceNodesAsSet());
+                }
+            }
+            getModel().setSelectedNodes(nodeSelection);
+
+            boolean b = selectedCoordinatorListener.isEnabled();
+            selectedCoordinatorListener.setEnabled(false);
+            SelectionCoordinator.getInstance().setSelectedObjects(nodeSelection);
+            selectedCoordinatorListener.setEnabled(b);
+
+        }
+
+        public void highlightingChanged(ObjectSceneEvent e, Set<Object> oldSet, Set<Object> newSet) {
+            Set<Integer> nodeHighlighting = new HashSet<Integer>();
+            for (Object o : newSet) {
+                if (o instanceof Figure) {
+                    nodeHighlighting.addAll(((Figure) o).getSource().getSourceNodesAsSet());
+                } else if (o instanceof Slot) {
+                    nodeHighlighting.addAll(((Slot) o).getSource().getSourceNodesAsSet());
+                }
+            }
+            boolean b = highlightedCoordinatorListener.isEnabled();
+            highlightedCoordinatorListener.setEnabled(false);
+            SelectionCoordinator.getInstance().setHighlightedObjects(nodeHighlighting);
+            highlightedCoordinatorListener.setEnabled(true);
+        }
+
+        public void hoverChanged(ObjectSceneEvent e, Object oldObject, Object newObject) {
+            Set<Object> newHighlightedObjects = new HashSet<Object>(DiagramScene.this.getHighlightedObjects());
+            if (oldObject != null) {
+                newHighlightedObjects.remove(oldObject);
+            }
+            if (newObject != null) {
+                newHighlightedObjects.add(newObject);
+            }
+            DiagramScene.this.setHighlightedObjects(newHighlightedObjects);
+        }
+
+        public void focusChanged(ObjectSceneEvent arg0, Object arg1, Object arg2) {
+        }
+    };
+
+    public DiagramScene(Action[] actions, DiagramViewModel model) {
+
+        this.actions = actions;
+
+        content = new InstanceContent();
+        lookup = new AbstractLookup(content);
+
+        this.setCheckClipping(true);
+
+        this.getInputBindings().setZoomActionModifiers(0);
+
+        scrollPane = createScrollPane();
+        this.getActions().addAction(ActionFactory.createPanAction());
+        hoverAction = createObjectHoverAction();
+        selectAction = createSelectAction();
+        this.getActions().addAction(selectAction);
 
         blockLayer = new LayerWidget(this);
         this.addChild(blockLayer);
 
-        startLayer = new LayerWidget(this);
-        this.addChild(startLayer);
-        // TODO: String startLabelString = "Loading graph with " + originalDiagram.getFigures().size() + " figures and " + originalDiagram.getConnections().size() + " connections...";
-        String startLabelString = "";
-        LabelWidget w = new LabelWidget(this, startLabelString);
-        scrollChangeListener.register(w, new Point(10, 10));
-        w.setAlignment(LabelWidget.Alignment.CENTER);
-        startLabel = w;
-        startLayer.addChild(w);
-
         mainLayer = new LayerWidget(this);
         this.addChild(mainLayer);
 
@@ -385,14 +419,10 @@
         topLeft.setPreferredLocation(new Point(-BORDER_SIZE, -BORDER_SIZE));
         this.addChild(topLeft);
 
-
         bottomRight = new Widget(this);
         bottomRight.setPreferredLocation(new Point(-BORDER_SIZE, -BORDER_SIZE));
         this.addChild(bottomRight);
 
-        slotLayer = new LayerWidget(this);
-        this.addChild(slotLayer);
-
         connectionLayer = new LayerWidget(this);
         this.addChild(connectionLayer);
 
@@ -401,52 +431,34 @@
 
         this.setLayout(LayoutFactory.createAbsoluteLayout());
 
-        this.getActions().addAction(hoverAction);
-        zoomAction = new BoundedZoomAction(1.1, false);
-        zoomAction.setMaxFactor(ZOOM_MAX_FACTOR);
-        zoomAction.setMinFactor(ZOOM_MIN_FACTOR);
-        this.getActions().addAction(ActionFactory.createMouseCenteredZoomAction(1.1));
-        panAction = new ExtendedPanAction();
-        this.getActions().addAction(panAction);
+        zoomAction = ActionFactory.createMouseCenteredZoomAction(1.2);
+        this.getActions().addAction(zoomAction);
+        this.getView().addMouseWheelListener(mouseWheelListener);
         this.getActions().addAction(ActionFactory.createPopupMenuAction(popupMenuProvider));
 
         LayerWidget selectLayer = new LayerWidget(this);
         this.addChild(selectLayer);
         this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));
 
-        blockWidgets = new HashMap<InputBlock, BlockWidget>();
-
         boolean b = this.getUndoRedoEnabled();
         this.setUndoRedoEnabled(false);
         this.setNewModel(model);
         this.setUndoRedoEnabled(b);
-    }
-
-    private void selectionUpdated() {
-        getModel().setSelectedNodes(this.getSelectedNodes());
-        addUndo();
+        this.addObjectSceneListener(selectionChangedListener, ObjectSceneEventType.OBJECT_SELECTION_CHANGED, ObjectSceneEventType.OBJECT_HIGHLIGHTING_CHANGED, ObjectSceneEventType.OBJECT_HOVER_CHANGED);
     }
 
     public DiagramViewModel getModel() {
         return model;
     }
 
-    public void setRealZoomFactor(double d) {
-        this.realZoomFactor = d;
-    }
-
-    public double getRealZoomFactor() {
-        if (realZoomFactor == 0.0) {
-            return getZoomFactor();
-        } else {
-            return realZoomFactor;
-        }
-    }
-
     public JScrollPane getScrollPane() {
         return scrollPane;
     }
 
+    public Component getComponent() {
+        return scrollPane;
+    }
+    
     public boolean isAllVisible() {
         return getModel().getHiddenNodes().size() == 0;
     }
@@ -469,7 +481,7 @@
         if (f.getCluster() != null) {
             name += "B" + f.getCluster().toString();
         }
-        if (!this.getFigureWidget(f).isVisible()) {
+        if (!this.getWidget(f, FigureWidget.class).isVisible()) {
             if (f.getCluster() != null) {
                 name += ", ";
             }
@@ -481,100 +493,58 @@
     }
 
     public void setNewModel(DiagramViewModel model) {
-        if (this.model != null) {
-            this.model.getDiagramChangedEvent().removeListener(this);
-            this.model.getViewPropertiesChangedEvent().removeListener(this);
-        }
+        assert this.model == null : "can set model only once!";
         this.model = model;
+        this.modelCopy = null;
 
-        if (this.model == null) {
-            this.modelCopy = null;
-        } else {
-            this.modelCopy = this.model.copy();
-        }
-
-        model.getDiagramChangedEvent().addListener(this);
-        model.getViewPropertiesChangedEvent().addListener(this);
-
+        model.getDiagramChangedEvent().addListener(fullChange);
+        model.getViewPropertiesChangedEvent().addListener(fullChange);
+        model.getViewChangedEvent().addListener(selectionChange);
+        model.getHiddenNodesChangedEvent().addListener(hiddenNodesChange);
         update();
     }
 
     private void update() {
-
-        /*if (startLabel != null) {
-        // Animate fade-out
-        final LabelWidget labelWidget = this.startLabel;
-        labelWidget.setVisible(true);
-        RequestProcessor.getDefault().post(new Runnable() {
-        public void run() {
-        final int Sleep = 200;
-        final int Progress = 10;
-        for (int i = 0; i < 255 / Progress + 1; i++) {
-        try {
-        SwingUtilities.invokeAndWait(new Runnable() {
-        public void run() {
-        Color c = labelWidget.getForeground();
-        int v = c.getRed();
-        v += Progress;
-        if (v > 255) {
-        v = 255;
-        }
-        labelWidget.setForeground(new Color(v, v, v, 255 - v));
-        labelWidget.getScene().validate();
-        }
-        });
-        } catch (InterruptedException ex) {
-        } catch (InvocationTargetException ex) {
-        }
-        try {
-        Thread.sleep(Sleep);
-        } catch (InterruptedException ex) {
-        }
-        }
-        labelWidget.setVisible(false);
-        DiagramScene.this.scrollChangeListener.unregister(labelWidget);
-        }
-        }, 1000);
-        startLabel = null;
-        }*/
-
-        slotLayer.removeChildren();
         mainLayer.removeChildren();
         blockLayer.removeChildren();
 
-        blockWidgets.clear();
-        figureWidgets = new HashMap<Figure, FigureWidget>();
-        slotWidgets = new HashMap<Slot, SlotWidget>();
-        connectionWidgets = new HashMap<Connection, ConnectionWidget>();
+        Collection<Object> objects = new ArrayList<Object>(this.getObjects());
+        for (Object o : objects) {
+            this.removeObject(o);
+        }
 
-        WidgetAction selectAction = new ExtendedSelectAction(selectProvider);
         Diagram d = getModel().getDiagramToView();
 
-        if (getModel().getShowBlocks()) {
+        if (d.getGraph().getBlocks().size() == 0) {
             Scheduler s = Lookup.getDefault().lookup(Scheduler.class);
-            Collection<InputBlock> newBlocks = new ArrayList<InputBlock>(s.schedule(d.getGraph()));
-            d.schedule(newBlocks);
+            d.getGraph().clearBlocks();
+            s.schedule(d.getGraph());
+            d.getGraph().ensureNodesInBlocks();
+            d.updateBlocks();
         }
 
         for (Figure f : d.getFigures()) {
-            FigureWidget w = new FigureWidget(f, this, mainLayer);
+            FigureWidget w = new FigureWidget(f, hoverAction, selectAction, this, mainLayer);
+            w.getActions().addAction(ActionFactory.createPopupMenuAction(w));
             w.getActions().addAction(selectAction);
             w.getActions().addAction(hoverAction);
-            w.getActions().addAction(ActionFactory.createPopupMenuAction(w));
-            w.getActions().addAction(new DoubleClickAction(w));
             w.setVisible(false);
 
-            figureWidgets.put(f, w);
+            this.addObject(f, w);
 
             for (InputSlot s : f.getInputSlots()) {
-                SlotWidget sw = new InputSlotWidget(s, this, slotLayer, w);
-                slotWidgets.put(s, sw);
+                SlotWidget sw = new InputSlotWidget(s, this, w, w);
+                addObject(s, sw);
+                sw.getActions().addAction(new DoubleClickAction(sw));
+                sw.getActions().addAction(hoverAction);
                 sw.getActions().addAction(selectAction);
             }
 
             for (OutputSlot s : f.getOutputSlots()) {
-                SlotWidget sw = new OutputSlotWidget(s, this, slotLayer, w);
-                slotWidgets.put(s, sw);
+                SlotWidget sw = new OutputSlotWidget(s, this, w, w);
+                addObject(s, sw);
+                sw.getActions().addAction(new DoubleClickAction(sw));
+                sw.getActions().addAction(hoverAction);
                 sw.getActions().addAction(selectAction);
             }
         }
@@ -583,7 +553,7 @@
             for (InputBlock bn : d.getGraph().getBlocks()) {
                 BlockWidget w = new BlockWidget(this, d, bn);
                 w.setVisible(false);
-                blockWidgets.put(bn, w);
+                this.addObject(bn, w);
                 blockLayer.addChild(w);
             }
         }
@@ -594,17 +564,17 @@
 
     private void smallUpdate(boolean relayout) {
 
+        System.out.println("smallUpdate " + relayout);
         this.updateHiddenNodes(model.getHiddenNodes(), relayout);
         boolean b = this.getUndoRedoEnabled();
         this.setUndoRedoEnabled(false);
-        this.setSelection(getModel().getSelectedNodes());
         this.setUndoRedoEnabled(b);
         this.validate();
     }
 
     private boolean isVisible(Connection c) {
-        FigureWidget w1 = figureWidgets.get(c.getInputSlot().getFigure());
-        FigureWidget w2 = figureWidgets.get(c.getOutputSlot().getFigure());
+        FigureWidget w1 = getWidget(c.getInputSlot().getFigure());
+        FigureWidget w2 = getWidget(c.getOutputSlot().getFigure());
 
         if (w1.isVisible() && w2.isVisible()) {
             return true;
@@ -614,13 +584,14 @@
     }
 
     private void relayout(Set<Widget> oldVisibleWidgets) {
+        System.out.println("relayout called with old visible widgets: " + oldVisibleWidgets);
 
         Diagram diagram = getModel().getDiagramToView();
 
         HashSet<Figure> figures = new HashSet<Figure>();
 
         for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             if (w.isVisible()) {
                 figures.add(f);
             }
@@ -649,10 +620,20 @@
             manager.doLayout(new LayoutGraph(edges, figures));
         }
 
+        relayoutWithoutLayout(oldVisibleWidgets);
+    }
+    private Set<Pair<Point, Point>> lineCache = new HashSet<Pair<Point, Point>>();
+
+    private void relayoutWithoutLayout(Set<Widget> oldVisibleWidgets) {
+
+        System.out.println("relayout without layout with visible widgets: " + oldVisibleWidgets);
+
+        Diagram diagram = getModel().getDiagramToView();
+
         int maxX = -BORDER_SIZE;
         int maxY = -BORDER_SIZE;
         for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             if (w.isVisible()) {
                 Point p = f.getPosition();
                 Dimension d = f.getSize();
@@ -663,8 +644,8 @@
 
         for (Connection c : diagram.getConnections()) {
             List<Point> points = c.getControlPoints();
-            FigureWidget w1 = figureWidgets.get((Figure) c.getTo().getVertex());
-            FigureWidget w2 = figureWidgets.get((Figure) c.getFrom().getVertex());
+            FigureWidget w1 = getWidget((Figure) c.getTo().getVertex());
+            FigureWidget w2 = getWidget((Figure) c.getFrom().getVertex());
             if (w1.isVisible() && w2.isVisible()) {
                 for (Point p : points) {
                     if (p != null) {
@@ -677,7 +658,7 @@
 
         if (getModel().getShowBlocks()) {
             for (Block b : diagram.getBlocks()) {
-                BlockWidget w = blockWidgets.get(b.getInputBlock());
+                BlockWidget w = getWidget(b.getInputBlock());
                 if (w != null && w.isVisible()) {
                     Rectangle r = b.getBounds();
                     maxX = Math.max(maxX, r.x + r.width);
@@ -693,6 +674,8 @@
         int curHeight = maxY + 2 * BORDER_SIZE;
 
         Rectangle bounds = this.getScrollPane().getBounds();
+        bounds.width /= getZoomFactor();
+        bounds.height /= getZoomFactor();
         if (curWidth < bounds.width) {
             offx = (bounds.width - curWidth) / 2;
         }
@@ -708,62 +691,61 @@
         connectionLayer.removeChildren();
         int visibleFigureCount = 0;
         for (Figure f : diagram.getFigures()) {
-            if (figureWidgets.get(f).isVisible()) {
+            if (getWidget(f, FigureWidget.class).isVisible()) {
                 visibleFigureCount++;
             }
         }
 
+
+        Set<Pair<Point, Point>> lastLineCache = lineCache;
+        lineCache = new HashSet<Pair<Point, Point>>();
+        for (Figure f : diagram.getFigures()) {
+            for (OutputSlot s : f.getOutputSlots()) {
+                SceneAnimator anim = animator;
+                if (visibleFigureCount > ANIMATION_LIMIT || oldVisibleWidgets == null) {
+                    anim = null;
+                }
+                processOutputSlot(lastLineCache, s, s.getConnections(), 0, null, null, offx2, offy2, anim);
+            }
+        }
+
         for (Figure f : diagram.getFigures()) {
-            for (OutputSlot s : f.getOutputSlots()) {
-                SceneAnimator anim = animator;
-                if (visibleFigureCount > ANIMATION_LIMIT) {
-                    anim = null;
-                }
-                processOutputSlot(s, s.getConnections(), 0, null, null, offx2, offy2, anim);
-            }
-        }
-
-        for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             if (w.isVisible()) {
                 Point p = f.getPosition();
                 Point p2 = new Point(p.x + offx2, p.y + offy2);
-                Rectangle r = new Rectangle(p.x + offx2, p.y + offy2, f.getSize().width, f.getSize().height);
-                if (oldVisibleWidgets.contains(w)) {
-                    if (visibleFigureCount > ANIMATION_LIMIT) {
-                        w.setPreferredLocation(p2);
-                    } else {
-                        animator.animatePreferredLocation(w, p2);
-                    }
+                if ((visibleFigureCount <= ANIMATION_LIMIT && oldVisibleWidgets != null && oldVisibleWidgets.contains(w))) {
+                    animator.animatePreferredLocation(w, p2);
                 } else {
                     w.setPreferredLocation(p2);
+                    animator.animatePreferredLocation(w, p2);
                 }
             }
         }
 
         if (getModel().getShowBlocks()) {
             for (Block b : diagram.getBlocks()) {
-                BlockWidget w = blockWidgets.get(b.getInputBlock());
+                BlockWidget w = getWidget(b.getInputBlock());
                 if (w != null && w.isVisible()) {
                     Point location = new Point(b.getBounds().x + offx2, b.getBounds().y + offy2);
                     Rectangle r = new Rectangle(location.x, location.y, b.getBounds().width, b.getBounds().height);
-                    if (oldVisibleWidgets.contains(w)) {
-                        if (visibleFigureCount > ANIMATION_LIMIT) {
-                            w.setPreferredBounds(r);
-                        } else {
-                            animator.animatePreferredBounds(w, r);
-                        }
+                    
+                    if ((visibleFigureCount <= ANIMATION_LIMIT && oldVisibleWidgets != null && oldVisibleWidgets.contains(w))) {
+                        animator.animatePreferredBounds(w, r);
                     } else {
                         w.setPreferredBounds(r);
+                        animator.animatePreferredBounds(w, r);
                     }
                 }
             }
         }
+
+        this.validate();
     }
     private final Point specialNullPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
 
-    private void processOutputSlot(OutputSlot s, List<Connection> connections, int controlPointIndex, Point lastPoint, LineWidget predecessor, int offx, int offy, SceneAnimator animator) {
-        Map<Point, List<Connection>> pointMap = new HashMap<Point, List<Connection>>();
+    private void processOutputSlot(Set<Pair<Point, Point>> lastLineCache, OutputSlot s, List<Connection> connections, int controlPointIndex, Point lastPoint, LineWidget predecessor, int offx, int offy, SceneAnimator animator) {
+        Map<Point, List<Connection>> pointMap = new HashMap<Point, List<Connection>>(connections.size());
 
         for (Connection c : connections) {
 
@@ -779,9 +761,9 @@
             Point cur = controlPoints.get(controlPointIndex);
             if (cur == null) {
                 cur = specialNullPoint;
-            } else if (controlPointIndex == 0 && !s.getShowName()) {
+            } else if (controlPointIndex == 0 && !s.shouldShowName()) {
                 cur = new Point(cur.x, cur.y - SLOT_OFFSET);
-            } else if (controlPointIndex == controlPoints.size() - 1 && !c.getInputSlot().getShowName()) {
+            } else if (controlPointIndex == controlPoints.size() - 1 && !c.getInputSlot().shouldShowName()) {
                 cur = new Point(cur.x, cur.y + SLOT_OFFSET);
             }
 
@@ -814,44 +796,62 @@
 
             LineWidget newPredecessor = predecessor;
             if (p == specialNullPoint) {
-
             } else if (lastPoint == specialNullPoint) {
-
             } else if (lastPoint != null) {
                 Point p1 = new Point(lastPoint.x + offx, lastPoint.y + offy);
                 Point p2 = new Point(p.x + offx, p.y + offy);
-                LineWidget w = new LineWidget(this, s, connectionList, p1, p2, predecessor, animator, isBold, isDashed);
+
+                Pair<Point, Point> curPair = new Pair<Point, Point>(p1, p2);
+                SceneAnimator curAnimator = animator;
+                if (lastLineCache.contains(curPair)) {
+                    curAnimator = null;
+                }
+                LineWidget w = new LineWidget(this, s, connectionList, p1, p2, predecessor, curAnimator, isBold, isDashed);
+                lineCache.add(curPair);
+
                 newPredecessor = w;
                 connectionLayer.addChild(w);
+                this.addObject(new ConnectionSet(connectionList), w);
                 w.getActions().addAction(hoverAction);
             }
 
-            processOutputSlot(s, connectionList, controlPointIndex + 1, p, newPredecessor, offx, offy, animator);
+            processOutputSlot(lastLineCache, s, connectionList, controlPointIndex + 1, p, newPredecessor, offx, offy, animator);
         }
     }
 
-    private void clearSelection() {
-        if (selectedWidgets.size() == 0) {
-            return;
+    private class ConnectionSet {
+
+        private Set<Connection> connections;
+
+        public ConnectionSet(Collection<Connection> connections) {
+            connections = new HashSet<Connection>(connections);
         }
-        for (FigureWidget w : selectedWidgets) {
-            assert w.getState().isSelected();
-            w.setState(w.getState().deriveSelected(false));
-            content.remove(w.getNode());
+
+        public Set<Connection> getConnectionSet() {
+            return Collections.unmodifiableSet(connections);
         }
-        selectedWidgets.clear();
     }
 
+    @Override
     public Lookup getLookup() {
         return lookup;
     }
 
+    public void initialize() {
+        Figure f = getModel().getDiagramToView().getRootFigure();
+        if (f != null) {
+            setUndoRedoEnabled(false);
+            gotoFigure(f);
+            setUndoRedoEnabled(true);
+        }
+    }
+
     public void gotoFigures(final List<Figure> figures) {
         Rectangle overall = null;
-        showFigures(figures);
+        getModel().showFigures(figures);
         for (Figure f : figures) {
 
-            FigureWidget fw = getFigureWidget(f);
+            FigureWidget fw = getWidget(f);
             if (fw != null) {
                 Rectangle r = fw.getBounds();
                 Point p = fw.getLocation();
@@ -869,6 +869,54 @@
         }
     }
 
+    private Set<Object> idSetToObjectSet(Set<Object> ids) {
+
+        Set<Object> result = new HashSet<Object>();
+        for (Figure f : getModel().getDiagramToView().getFigures()) {
+            if (DiagramScene.doesIntersect(f.getSource().getSourceNodesAsSet(), ids)) {
+                result.add(f);
+            }
+
+            for (Slot s : f.getSlots()) {
+                if (DiagramScene.doesIntersect(s.getSource().getSourceNodesAsSet(), ids)) {
+                    result.add(s);
+                }
+            }
+        }
+        return result;
+    }
+
+    public void gotoSelection(Set<Object> ids) {
+
+        Rectangle overall = null;
+        Set<Integer> hiddenNodes = new HashSet<Integer>(this.getModel().getHiddenNodes());
+        hiddenNodes.removeAll(ids);
+        this.getModel().showNot(hiddenNodes);
+
+        Set<Object> objects = idSetToObjectSet(ids);
+        for (Object o : objects) {
+
+            Widget w = getWidget(o);
+            if (w != null) {
+                Rectangle r = w.getBounds();
+                Point p = w.convertLocalToScene(new Point(0, 0));
+
+                Rectangle r2 = new Rectangle(p.x, p.y, r.width, r.height);
+
+                if (overall == null) {
+                    overall = r2;
+                } else {
+                    overall = overall.union(r2);
+                }
+            }
+        }
+        if (overall != null) {
+            centerRectangle(overall);
+        }
+
+        setSelectedObjects(objects);
+    }
+
     private Point calcCenter(Rectangle r) {
 
         Point center = new Point((int) r.getCenterX(), (int) r.getCenterY());
@@ -909,63 +957,8 @@
         }
     }
 
-    private void addToSelection(Figure f) {
-        FigureWidget w = getFigureWidget(f);
-        addToSelection(w);
-    }
-
-    private void addToSelection(FigureWidget w) {
-        assert !selectedWidgets.contains(w);
-        selectedWidgets.add(w);
-        content.add(w.getNode());
-        w.setState(w.getState().deriveSelected(true));
-    }
-
-    private void setSelection(Set<Integer> nodes) {
-        clearSelection();
-        for (Figure f : getModel().getDiagramToView().getFigures()) {
-            if (doesIntersect(f.getSource().getSourceNodesAsSet(), nodes)) {
-                addToSelection(f);
-            }
-        }
-        selectionUpdated();
-        this.validate();
-    }
-
     public void setSelection(Collection<Figure> list) {
-        clearSelection();
-        for (Figure f : list) {
-            addToSelection(f);
-        }
-
-        selectionUpdated();
-        this.validate();
-    }
-
-    public Set<Figure> getSelectedFigures() {
-        Set<Figure> result = new HashSet<Figure>();
-        for (Widget w : selectedWidgets) {
-            if (w instanceof FigureWidget) {
-                FigureWidget fw = (FigureWidget) w;
-                if (fw.getState().isSelected()) {
-                    result.add(fw.getFigure());
-                }
-            }
-        }
-        return result;
-    }
-
-    public Set<Integer> getSelectedNodes() {
-        Set<Integer> result = new HashSet<Integer>();
-        for (Widget w : selectedWidgets) {
-            if (w instanceof FigureWidget) {
-                FigureWidget fw = (FigureWidget) w;
-                if (fw.getState().isSelected()) {
-                    result.addAll(fw.getFigure().getSource().getSourceNodesAsSet());
-                }
-            }
-        }
-        return result;
+        super.setSelectedObjects(new HashSet<Figure>(list));
     }
 
     private UndoRedo.Manager getUndoRedoManager() {
@@ -990,7 +983,7 @@
         return true;
     }
 
-    private boolean doesIntersect(Set s1, Set s2) {
+    public static boolean doesIntersect(Set s1, Set s2) {
         if (s1.size() > s2.size()) {
             Set tmp = s1;
             s1 = s2;
@@ -1006,18 +999,19 @@
         return false;
     }
 
-    public void showNot(final Set<Integer> nodes) {
-        updateHiddenNodes(nodes, true);
+    public void componentHidden() {
+        SelectionCoordinator.getInstance().getHighlightedChangedEvent().removeListener(highlightedCoordinatorListener);
+        SelectionCoordinator.getInstance().getSelectedChangedEvent().removeListener(selectedCoordinatorListener);
     }
 
-    public void showOnly(final Set<Integer> nodes) {
-        HashSet<Integer> allNodes = new HashSet<Integer>(getModel().getGraphToView().getGroup().getAllNodes());
-        allNodes.removeAll(nodes);
-        updateHiddenNodes(allNodes, true);
+    public void componentShowing() {
+        SelectionCoordinator.getInstance().getHighlightedChangedEvent().addListener(highlightedCoordinatorListener);
+        SelectionCoordinator.getInstance().getSelectedChangedEvent().addListener(selectedCoordinatorListener);
     }
 
     private void updateHiddenNodes(Set<Integer> newHiddenNodes, boolean doRelayout) {
 
+        System.out.println("newHiddenNodes: " + newHiddenNodes);
         Set<InputBlock> visibleBlocks = new HashSet<InputBlock>();
 
         Diagram diagram = getModel().getDiagramToView();
@@ -1026,7 +1020,7 @@
         Set<Widget> oldVisibleWidgets = new HashSet<Widget>();
 
         for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             if (w.isVisible()) {
                 oldVisibleWidgets.add(w);
             }
@@ -1034,7 +1028,7 @@
 
         if (getModel().getShowBlocks()) {
             for (InputBlock b : diagram.getGraph().getBlocks()) {
-                BlockWidget w = blockWidgets.get(b);
+                BlockWidget w = getWidget(b);
                 if (w.isVisible()) {
                     oldVisibleWidgets.add(w);
                 }
@@ -1044,7 +1038,7 @@
         for (Figure f : diagram.getFigures()) {
             boolean hiddenAfter = doesIntersect(f.getSource().getSourceNodesAsSet(), newHiddenNodes);
 
-            FigureWidget w = this.figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             w.setBoundary(false);
             if (!hiddenAfter) {
                 // Figure is shown
@@ -1061,14 +1055,14 @@
         if (getModel().getShowNodeHull()) {
             List<FigureWidget> boundaries = new ArrayList<FigureWidget>();
             for (Figure f : diagram.getFigures()) {
-                FigureWidget w = this.figureWidgets.get(f);
+                FigureWidget w = getWidget(f);
                 if (!w.isVisible()) {
                     Set<Figure> set = new HashSet<Figure>(f.getPredecessorSet());
                     set.addAll(f.getSuccessorSet());
 
                     boolean b = false;
                     for (Figure neighbor : set) {
-                        FigureWidget neighborWidget = figureWidgets.get(neighbor);
+                        FigureWidget neighborWidget = getWidget(neighbor);
                         if (neighborWidget.isVisible()) {
                             b = true;
                             break;
@@ -1097,7 +1091,7 @@
 
                 boolean visibleAfter = visibleBlocks.contains(b);
 
-                BlockWidget w = blockWidgets.get(b);
+                BlockWidget w = getWidget(b);
                 if (visibleAfter) {
                     // Block must be shown
                     w.setVisible(true);
@@ -1108,7 +1102,6 @@
             }
         }
 
-        getModel().setHiddenNodes(newHiddenNodes);
         if (doRelayout) {
             relayout(oldVisibleWidgets);
         }
@@ -1116,27 +1109,29 @@
         addUndo();
     }
 
-    private void showFigures(Collection<Figure> f) {
-        HashSet<Integer> newHiddenNodes = new HashSet<Integer>(getModel().getHiddenNodes());
-        for (Figure fig : f) {
-            newHiddenNodes.removeAll(fig.getSource().getSourceNodesAsSet());
-        }
-        updateHiddenNodes(newHiddenNodes, true);
-    }
-
     private void showFigure(Figure f) {
         HashSet<Integer> newHiddenNodes = new HashSet<Integer>(getModel().getHiddenNodes());
         newHiddenNodes.removeAll(f.getSource().getSourceNodesAsSet());
         updateHiddenNodes(newHiddenNodes, true);
     }
 
-    public void showAll(final Collection<Figure> f) {
-        showFigures(f);
-
+    public void show(final Figure f) {
+        showFigure(f);
     }
 
-    public void show(final Figure f) {
-        showFigure(f);
+    public void setSelectedObjects(Object... args) {
+        Set<Object> set = new HashSet<Object>();
+        for (Object o : args) {
+            set.add(o);
+        }
+        super.setSelectedObjects(set);
+    }
+
+    private void centerWidget(Widget w) {
+        Rectangle r = w.getBounds();
+        Point p = w.getLocation();
+        centerRectangle(new Rectangle(p.x, p.y, r.width, r.height));
+
     }
 
     public void gotoFigure(final Figure f) {
@@ -1145,16 +1140,10 @@
             showFigure(f);
         }
 
-        FigureWidget fw = getFigureWidget(f);
+        FigureWidget fw = getWidget(f);
         if (fw != null) {
-            Rectangle r = fw.getBounds();
-            Point p = fw.getLocation();
-            centerRectangle(new Rectangle(p.x, p.y, r.width, r.height));
-
-            // Select figure
-            clearSelection();
-            addToSelection(fw);
-            selectionUpdated();
+            centerWidget(fw);
+            getModel().setSelectedNodes(f.getSource().getSourceNodesAsSet());
         }
     }
 
@@ -1218,7 +1207,7 @@
 
         public void changed(DiagramViewModel source) {
             scene.getModel().getViewChangedEvent().removeListener(this);
-            if (oldModel.getSelectedNodes().equals(newModel.getHiddenNodes())) {
+            if (oldModel.getHiddenNodes().equals(newModel.getHiddenNodes())) {
                 scene.smallUpdate(false);
             } else {
                 scene.smallUpdate(true);
@@ -1235,11 +1224,30 @@
         return undoRedoEnabled;
     }
 
-    public void changed(DiagramViewModel source) {
-        assert source == model : "Receive only changed event from current model!";
-        assert source != null;
-        update();
-    }
+    private final ChangedListener<DiagramViewModel> fullChange = new ChangedListener<DiagramViewModel>() {
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            update();
+        }
+    };
+
+    private final ChangedListener<DiagramViewModel> hiddenNodesChange = new ChangedListener<DiagramViewModel>() {
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            smallUpdate(true);
+        }
+    };
+
+    private final ChangedListener<DiagramViewModel> selectionChange = new ChangedListener<DiagramViewModel>() {
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            smallUpdate(false);
+        }
+    };
+
 
     private void addUndo() {
 
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Wed Jun 08 17:26:49 2011 +0200
@@ -38,8 +38,11 @@
 import java.util.List;
 import java.util.Set;
 import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.filter.CustomFilter;
+import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.settings.Settings;
 import java.awt.Color;
+import java.util.Collection;
 
 /**
  *
@@ -55,9 +58,11 @@
     private FilterChain filterChain;
     private FilterChain sequenceFilterChain;
     private Diagram diagram;
+    private InputGraph inputGraph;
     private ChangedEvent<DiagramViewModel> groupChangedEvent;
     private ChangedEvent<DiagramViewModel> diagramChangedEvent;
     private ChangedEvent<DiagramViewModel> viewChangedEvent;
+    private ChangedEvent<DiagramViewModel> hiddenNodesChangedEvent;
     private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
     private boolean showBlocks;
     private boolean showNodeHull;
@@ -100,7 +105,7 @@
         viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
         this.showNodeHull = newModel.showNodeHull;
 
-        if(groupChanged) {
+        if (groupChanged) {
             groupChangedEvent.fire();
         }
 
@@ -149,7 +154,9 @@
         super.getChangedEvent().addListener(this);
         diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this);
         viewChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+        hiddenNodesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
         viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+
         groupChangedEvent = new ChangedEvent<DiagramViewModel>(this);
         groupChangedEvent.addListener(groupChangedListener);
         groupChangedEvent.fire();
@@ -157,21 +164,18 @@
         filterChain.getChangedEvent().addListener(filterChainChangedListener);
         sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
     }
-
     private final ChangedListener<DiagramViewModel> groupChangedListener = new ChangedListener<DiagramViewModel>() {
 
         private Group oldGroup;
 
         public void changed(DiagramViewModel source) {
-            if(oldGroup != null) {
+            if (oldGroup != null) {
                 oldGroup.getChangedEvent().removeListener(groupContentChangedListener);
             }
             group.getChangedEvent().addListener(groupContentChangedListener);
             oldGroup = group;
         }
     };
-
-
     private final ChangedListener<Group> groupContentChangedListener = new ChangedListener<Group>() {
 
         public void changed(Group source) {
@@ -179,7 +183,6 @@
             setPositions(calculateStringList(source));
             setSelectedNodes(selectedNodes);
         }
-
     };
 
     public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
@@ -190,20 +193,24 @@
         return viewChangedEvent;
     }
 
+    public ChangedEvent<DiagramViewModel> getHiddenNodesChangedEvent() {
+        return hiddenNodesChangedEvent;
+    }
+
     public ChangedEvent<DiagramViewModel> getViewPropertiesChangedEvent() {
         return viewPropertiesChangedEvent;
     }
 
     public Set<Integer> getSelectedNodes() {
-        return Collections.unmodifiableSet(selectedNodes);
+        return selectedNodes;
     }
 
     public Set<Integer> getHiddenNodes() {
-        return Collections.unmodifiableSet(hiddenNodes);
+        return hiddenNodes;
     }
 
     public Set<Integer> getOnScreenNodes() {
-        return Collections.unmodifiableSet(onScreenNodes);
+        return onScreenNodes;
     }
 
     public void setSelectedNodes(Set<Integer> nodes) {
@@ -248,9 +255,45 @@
         viewChangedEvent.fire();
     }
 
+    public void showNot(final Set<Integer> nodes) {
+        System.out.println("Shownot called with " + nodes);
+        setHiddenNodes(nodes);
+    }
+
+    public void showFigures(Collection<Figure> f) {
+        HashSet<Integer> newHiddenNodes = new HashSet<Integer>(getHiddenNodes());
+        for (Figure fig : f) {
+            newHiddenNodes.removeAll(fig.getSource().getSourceNodesAsSet());
+        }
+        setHiddenNodes(newHiddenNodes);
+    }
+
+
+    public Set<Figure> getSelectedFigures() {
+        Set<Figure> result = new HashSet<Figure>();
+        for (Figure f : diagram.getFigures()) {
+            for (InputNode node : f.getSource().getSourceNodes()) {
+                if (getSelectedNodes().contains(node.getId())) {
+                    result.add(f);
+                }
+            }
+        }
+        return result;
+    }
+
+    public void showAll(final Collection<Figure> f) {
+        showFigures(f);
+    }
+
+    public void showOnly(final Set<Integer> nodes) {
+        final HashSet<Integer> allNodes = new HashSet<Integer>(getGraphToView().getGroup().getAllNodes());
+        allNodes.removeAll(nodes);
+        setHiddenNodes(allNodes);
+    }
+
     public void setHiddenNodes(Set<Integer> nodes) {
         this.hiddenNodes = nodes;
-        viewChangedEvent.fire();
+        hiddenNodesChangedEvent.fire();
     }
 
     public void setOnScreenNodes(Set<Integer> onScreenNodes) {
@@ -319,22 +362,41 @@
         if (diagram == null) {
             diagram = Diagram.createDiagram(getGraphToView(), Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT));
             getFilterChain().apply(diagram, getSequenceFilterChain());
+            if (diagram.getGraph().getSourceGraphs() != null) {
+                CustomFilter f = new CustomFilter(
+                        "difference", "colorize('state', 'same', white);" +
+                        "colorize('state', 'changed', orange);" +
+                        "colorize('state', 'new', green);" +
+                        "colorize('state', 'deleted', red);");
+                f.apply(diagram);
+            }
         }
 
         return diagram;
     }
 
     public InputGraph getGraphToView() {
-        if (getFirstGraph() != getSecondGraph()) {
-            InputGraph inputGraph = Difference.createDiffGraph(getSecondGraph(), getFirstGraph());
-            return inputGraph;
-        } else {
-            InputGraph inputGraph = getFirstGraph();
-            return inputGraph;
+        if (inputGraph == null) {
+            if (getFirstGraph() != getSecondGraph()) {
+                inputGraph = Difference.createDiffGraph(getFirstGraph(), getSecondGraph());
+            } else {
+                inputGraph = getFirstGraph();
+            }
         }
+
+        return inputGraph;
     }
 
     public void changed(RangeSliderModel source) {
+        inputGraph = null;
         diagramChanged();
     }
+
+    void setSelectedFigures(List<Figure> list) {
+        Set<Integer> newSelectedNodes = new HashSet<Integer>();
+        for (Figure f : list) {
+            newSelectedNodes.addAll(f.getSource().getSourceNodesAsSet());
+        }
+        this.setSelectedNodes(newSelectedNodes);
+    }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewer.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.view;
+
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.Component;
+import java.awt.Graphics2D;
+import java.util.List;
+import javax.swing.JComponent;
+import org.openide.awt.UndoRedo;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+interface DiagramViewer {
+
+    public void paint(Graphics2D svgGenerator);
+
+    public Lookup getLookup();
+
+    public JComponent createSatelliteView();
+
+    public Component getComponent();
+
+    public void zoomOut();
+
+    public void zoomIn();
+
+    public UndoRedo getUndoRedo();
+
+    public void componentHidden();
+
+    public void componentShowing();
+
+    public void initialize();
+
+    public void centerFigures(List<Figure> list);
+
+}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java	Wed Jun 08 17:26:49 2011 +0200
@@ -35,18 +35,17 @@
  */
 public class EditorInputGraphProvider implements InputGraphProvider {
 
+    private EditorTopComponent editor;
+    
+    public EditorInputGraphProvider(EditorTopComponent editor) {
+        this.editor = editor;
+    }
+    
     public InputGraph getGraph() {
-        EditorTopComponent e = EditorTopComponent.getActive();
-        if (e == null) {
-            return null;
-        }
-        return e.getDiagramModel().getGraphToView();
+        return editor.getDiagramModel().getGraphToView();
     }
 
     public void setSelectedNodes(Set<InputNode> nodes) {
-        EditorTopComponent e = EditorTopComponent.getActive();
-        if (e != null) {
-            e.setSelectedNodes(nodes);
-        }
+        editor.setSelectedNodes(nodes);
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.form	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.form	Wed Jun 08 17:26:49 2011 +0200
@@ -18,6 +18,8 @@
   </NonVisualComponents>
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,6 +23,7 @@
  */
 package com.sun.hotspot.igv.view;
 
+import com.sun.hotspot.igv.data.ChangedEvent;
 import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.filter.FilterChain;
 import com.sun.hotspot.igv.graph.Diagram;
@@ -33,7 +34,6 @@
 import com.sun.hotspot.igv.view.actions.ExtractAction;
 import com.sun.hotspot.igv.view.actions.HideAction;
 import com.sun.hotspot.igv.view.actions.NextDiagramAction;
-import com.sun.hotspot.igv.view.actions.NodeFindAction;
 import com.sun.hotspot.igv.view.actions.OverviewAction;
 import com.sun.hotspot.igv.view.actions.PredSuccAction;
 import com.sun.hotspot.igv.view.actions.PrevDiagramAction;
@@ -43,14 +43,16 @@
 import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import com.sun.hotspot.igv.filter.FilterChainProvider;
+import com.sun.hotspot.igv.graph.services.DiagramProvider;
+import com.sun.hotspot.igv.selectioncoordinator.SelectionCoordinator;
 import com.sun.hotspot.igv.util.RangeSlider;
-import com.sun.hotspot.igv.util.RangeSliderModel;
 import com.sun.hotspot.igv.svg.BatikSVG;
+import com.sun.hotspot.igv.util.LookupHistory;
 import java.awt.BorderLayout;
 import java.awt.CardLayout;
 import java.awt.Color;
-import java.awt.Dimension;
 import java.awt.Graphics2D;
 import java.awt.Point;
 import java.awt.event.HierarchyBoundsListener;
@@ -67,18 +69,18 @@
 import java.io.UnsupportedEncodingException;
 import java.io.Writer;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 import javax.swing.Action;
-import javax.swing.ActionMap;
+import javax.swing.JComponent;
 import javax.swing.JPanel;
 import javax.swing.JToggleButton;
 import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
 import javax.swing.border.Border;
 import org.openide.DialogDisplayer;
-import org.openide.actions.FindAction;
 import org.openide.actions.RedoAction;
 import org.openide.actions.UndoAction;
 import org.openide.awt.Toolbar;
@@ -86,8 +88,6 @@
 import org.openide.awt.UndoRedo;
 import org.openide.util.Lookup;
 import org.openide.util.NbBundle;
-import org.openide.util.actions.CallbackSystemAction;
-import org.openide.util.actions.SystemAction;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
 import org.openide.util.lookup.ProxyLookup;
@@ -97,19 +97,19 @@
 import org.openide.NotifyDescriptor;
 
 /**
- *
+ * 
  * @author Thomas Wuerthinger
  */
-public final class EditorTopComponent extends TopComponent implements ChangedListener<RangeSliderModel>, PropertyChangeListener {
+public final class EditorTopComponent extends TopComponent implements PropertyChangeListener {
 
-    private DiagramScene scene;
+    private DiagramViewer scene;
     private InstanceContent content;
-    private FindPanel findPanel;
+    private InstanceContent graphContent;
     private EnableBlockLayoutAction blockLayoutAction;
     private OverviewAction overviewAction;
     private PredSuccAction predSuccAction;
     private boolean notFirstTime;
-    private ExtendedSatelliteComponent satelliteComponent;
+    private JComponent satelliteComponent;
     private JPanel centerPanel;
     private CardLayout cardLayout;
     private RangeSlider rangeSlider;
@@ -152,12 +152,29 @@
         }
     };
 
+    private DiagramProvider diagramProvider = new DiagramProvider() {
+
+        public Diagram getDiagram() {
+            return getModel().getDiagramToView();
+        }
+
+        public ChangedEvent<DiagramProvider> getChangedEvent() {
+            return diagramChangedEvent;
+        }
+    };
+
+    private ChangedEvent<DiagramProvider> diagramChangedEvent = new ChangedEvent<DiagramProvider>(diagramProvider);
+    
+
     private void updateDisplayName() {
         setDisplayName(getDiagram().getName());
     }
 
     public EditorTopComponent(Diagram diagram) {
 
+        LookupHistory.init(InputGraphProvider.class);
+        LookupHistory.init(DiagramProvider.class);
+        this.setFocusable(true);
         FilterChain filterChain = null;
         FilterChain sequence = null;
         FilterChainProvider provider = Lookup.getDefault().lookup(FilterChainProvider.class);
@@ -190,8 +207,6 @@
 
         initComponents();
 
-        ActionMap actionMap = getActionMap();
-
         ToolbarPool.getDefault().setPreferredIconSize(16);
         Toolbar toolBar = new Toolbar();
         Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N
@@ -202,24 +217,22 @@
         container.add(BorderLayout.NORTH, toolBar);
 
         rangeSliderModel = new DiagramViewModel(diagram.getGraph().getGroup(), filterChain, sequence);
-        rangeSliderModel.selectGraph(diagram.getGraph());
         rangeSlider = new RangeSlider();
         rangeSlider.setModel(rangeSliderModel);
-        rangeSliderModel.getChangedEvent().addListener(this);
         container.add(BorderLayout.CENTER, rangeSlider);
 
         scene = new DiagramScene(actions, rangeSliderModel);
         content = new InstanceContent();
-        this.associateLookup(new ProxyLookup(new Lookup[]{scene.getLookup(), new AbstractLookup(content)}));
+        graphContent = new InstanceContent();
+        this.associateLookup(new ProxyLookup(new Lookup[]{scene.getLookup(), new AbstractLookup(graphContent), new AbstractLookup(content)}));
         content.add(exportCookie);
         content.add(rangeSliderModel);
+        content.add(diagramProvider);
+
+        rangeSliderModel.getDiagramChangedEvent().addListener(diagramChangedListener);
+        rangeSliderModel.selectGraph(diagram.getGraph());
 
 
-        findPanel = new FindPanel(diagram.getFigures());
-        findPanel.setMaximumSize(new Dimension(200, 50));
-        toolBar.add(findPanel);
-        toolBar.add(NodeFindAction.get(NodeFindAction.class));
-        toolBar.addSeparator();
         toolBar.add(NextDiagramAction.get(NextDiagramAction.class));
         toolBar.add(PrevDiagramAction.get(PrevDiagramAction.class));
         toolBar.addSeparator();
@@ -256,44 +269,37 @@
         this.add(centerPanel, BorderLayout.CENTER);
         cardLayout = new CardLayout();
         centerPanel.setLayout(cardLayout);
-        centerPanel.add(SCENE_STRING, scene.getScrollPane());
+        centerPanel.add(SCENE_STRING, scene.getComponent());
         centerPanel.setBackground(Color.WHITE);
-        satelliteComponent = new ExtendedSatelliteComponent(scene);
+        satelliteComponent = scene.createSatelliteView();
         satelliteComponent.setSize(200, 200);
         centerPanel.add(SATELLITE_STRING, satelliteComponent);
 
-        CallbackSystemAction callFindAction = (CallbackSystemAction) SystemAction.get(FindAction.class);
-        NodeFindAction findAction = NodeFindAction.get(NodeFindAction.class);
-        Object key = callFindAction.getActionMapKey();
-        actionMap.put(key, findAction);
+        // TODO: Fix the hot key for entering the satellite view
+        this.addKeyListener(keyListener);
 
-        scene.getScrollPane().addKeyListener(keyListener);
-        scene.getView().addKeyListener(keyListener);
-        satelliteComponent.addKeyListener(keyListener);
-
-        scene.getScrollPane().addHierarchyBoundsListener(new HierarchyBoundsListener() {
+        scene.getComponent().addHierarchyBoundsListener(new HierarchyBoundsListener() {
 
             public void ancestorMoved(HierarchyEvent e) {
             }
 
             public void ancestorResized(HierarchyEvent e) {
-                if (!notFirstTime && scene.getScrollPane().getBounds().width > 0) {
+                if (!notFirstTime && scene.getComponent().getBounds().width > 0) {
                     notFirstTime = true;
                     SwingUtilities.invokeLater(new Runnable() {
 
                         public void run() {
-                            Figure f = EditorTopComponent.this.scene.getModel().getDiagramToView().getRootFigure();
-                            if (f != null) {
-                                scene.setUndoRedoEnabled(false);
-                                scene.gotoFigure(f);
-                                scene.setUndoRedoEnabled(true);
-                            }
+                            EditorTopComponent.this.scene.initialize();
                         }
                     });
                 }
             }
         });
 
+        if (diagram.getGraph().getGroup().getGraphs().size() == 1) {
+            rangeSlider.setVisible(false);
+        }
+
         updateDisplayName();
     }
     private KeyListener keyListener = new KeyListener() {
@@ -317,7 +323,7 @@
     };
 
     public DiagramViewModel getDiagramModel() {
-        return scene.getModel();
+        return rangeSliderModel;
     }
 
     private void showSatellite() {
@@ -328,35 +334,15 @@
 
     private void showScene() {
         cardLayout.show(centerPanel, SCENE_STRING);
-        scene.getView().requestFocus();
-    }
-
-    public void findNode() {
-        findPanel.find();
+        scene.getComponent().requestFocus();
     }
 
     public void zoomOut() {
-        double zoom = scene.getZoomFactor();
-        Point viewPosition = scene.getScrollPane().getViewport().getViewPosition();
-        double newZoom = zoom / DiagramScene.ZOOM_INCREMENT;
-        if (newZoom > DiagramScene.ZOOM_MIN_FACTOR) {
-            scene.setZoomFactor(newZoom);
-            scene.validate();
-            scene.getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x / DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y / DiagramScene.ZOOM_INCREMENT)));
-            this.satelliteComponent.update();
-        }
+        scene.zoomOut();
     }
 
     public void zoomIn() {
-        double zoom = scene.getZoomFactor();
-        Point viewPosition = scene.getScrollPane().getViewport().getViewPosition();
-        double newZoom = zoom * DiagramScene.ZOOM_INCREMENT;
-        if (newZoom < DiagramScene.ZOOM_MAX_FACTOR) {
-            scene.setZoomFactor(newZoom);
-            scene.validate();
-            scene.getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x * DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y * DiagramScene.ZOOM_INCREMENT)));
-            this.satelliteComponent.update();
-        }
+        scene.zoomIn();
     }
 
     public void showPrevDiagram() {
@@ -370,11 +356,11 @@
     }
 
     public DiagramViewModel getModel() {
-        return scene.getModel();
+        return rangeSliderModel;
     }
 
     public FilterChain getFilterChain() {
-        return this.scene.getModel().getFilterChain();
+        return getModel().getFilterChain();
     }
 
     public static EditorTopComponent getActive() {
@@ -407,6 +393,7 @@
         // Variables declaration - do not modify//GEN-BEGIN:variables
         private javax.swing.JCheckBox jCheckBox1;
         // End of variables declaration//GEN-END:variables
+
     @Override
     public int getPersistenceType() {
         return TopComponent.PERSISTENCE_NEVER;
@@ -425,9 +412,17 @@
         return PREFERRED_ID;
     }
 
-    public void changed(RangeSliderModel model) {
-        updateDisplayName();
-    }
+    private ChangedListener<DiagramViewModel> diagramChangedListener = new ChangedListener<DiagramViewModel>() {
+
+        public void changed(DiagramViewModel source) {
+            updateDisplayName();
+            Collection<Object> list = new ArrayList<Object>();
+            list.add(new EditorInputGraphProvider(EditorTopComponent.this));
+            graphContent.set(list, null);
+            diagramProvider.getChangedEvent().fire();
+        }
+        
+    };
 
     public boolean showPredSucc() {
         return (Boolean) predSuccAction.getValue(PredSuccAction.STATE);
@@ -435,13 +430,14 @@
 
     public void setSelection(PropertyMatcher matcher) {
 
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(scene.getModel().getDiagramToView().getFigures());
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(getModel().getDiagramToView().getFigures());
         List<Figure> list = selector.selectMultiple(matcher);
-        boolean b = scene.getUndoRedoEnabled();
-        scene.setUndoRedoEnabled(false);
-        scene.gotoFigures(list);
-        scene.setUndoRedoEnabled(b);
-        scene.setSelection(list);
+        setSelectedFigures(list);
+    }
+
+    public void setSelectedFigures(List<Figure> list) {
+        getModel().setSelectedFigures(list);
+        scene.centerFigures(list);
     }
 
     public void setSelectedNodes(Set<InputNode> nodes) {
@@ -452,7 +448,7 @@
             ids.add(n.getId());
         }
 
-        for (Figure f : scene.getModel().getDiagramToView().getFigures()) {
+        for (Figure f : getModel().getDiagramToView().getFigures()) {
             for (InputNode n : f.getSource().getSourceNodes()) {
                 if (ids.contains(n.getId())) {
                     list.add(f);
@@ -461,8 +457,7 @@
             }
         }
 
-        scene.gotoFigures(list);
-        scene.setSelection(list);
+        setSelectedFigures(list);
     }
 
     public void propertyChange(PropertyChangeEvent evt) {
@@ -478,7 +473,6 @@
             }
         } else if (evt.getSource() == this.blockLayoutAction) {
             boolean b = (Boolean) blockLayoutAction.getValue(EnableBlockLayoutAction.STATE);
-            System.out.println("Showblocks = " + b);
             this.getModel().setShowBlocks(b);
         } else {
             assert false : "Unknown event source";
@@ -486,18 +480,18 @@
     }
 
     public void extract() {
-        scene.showOnly(scene.getSelectedNodes());
+        getModel().showOnly(getModel().getSelectedNodes());
     }
 
     public void hideNodes() {
-        Set<Integer> selectedNodes = this.scene.getSelectedNodes();
-        HashSet<Integer> nodes = new HashSet<Integer>(scene.getModel().getHiddenNodes());
+        Set<Integer> selectedNodes = this.getModel().getSelectedNodes();
+        HashSet<Integer> nodes = new HashSet<Integer>(getModel().getHiddenNodes());
         nodes.addAll(selectedNodes);
-        this.scene.showNot(nodes);
+        this.getModel().showNot(nodes);
     }
 
     public void expandPredecessors() {
-        Set<Figure> oldSelection = scene.getSelectedFigures();
+        Set<Figure> oldSelection = getModel().getSelectedFigures();
         Set<Figure> figures = new HashSet<Figure>();
 
         for (Figure f : this.getDiagramModel().getDiagramToView().getFigures()) {
@@ -518,11 +512,11 @@
             }
         }
 
-        scene.showAll(figures);
+        getModel().showAll(figures);
     }
 
     public void expandSuccessors() {
-        Set<Figure> oldSelection = scene.getSelectedFigures();
+        Set<Figure> oldSelection = getModel().getSelectedFigures();
         Set<Figure> figures = new HashSet<Figure>();
 
         for (Figure f : this.getDiagramModel().getDiagramToView().getFigures()) {
@@ -543,11 +537,11 @@
             }
         }
 
-        scene.showAll(figures);
+        getModel().showAll(figures);
     }
 
     public void showAll() {
-        scene.showNot(new HashSet<Integer>());
+        getModel().showNot(new HashSet<Integer>());
     }
 
     public Diagram getDiagram() {
@@ -555,23 +549,27 @@
     }
 
     @Override
-    protected void componentActivated() {
+    protected void componentHidden() {
+        super.componentHidden();
+        scene.componentHidden();
+
     }
 
     @Override
-    public void requestFocus() {
-        super.requestFocus();
-        scene.getView().requestFocus();
+    protected void componentShowing() {
+        super.componentShowing();
+        scene.componentShowing();
     }
 
     @Override
-    public boolean requestFocusInWindow() {
-        super.requestFocusInWindow();
-        return scene.getView().requestFocusInWindow();
+    public void requestActive() {
+        super.requestActive();
+        scene.getComponent().requestFocus();
     }
 
     @Override
     public UndoRedo getUndoRedo() {
         return scene.getUndoRedo();
     }
+
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedPanAction.java	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view;
-
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.Point;
-import org.netbeans.api.visual.widget.Scene;
-import org.netbeans.api.visual.widget.Widget;
-import org.netbeans.api.visual.action.WidgetAction;
-
-import java.awt.event.MouseEvent;
-import javax.swing.JComponent;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-
-/**
- * @author David Kaspar
- * @author Thomas Wuerthinger
- */
-public class ExtendedPanAction extends WidgetAction.LockedAdapter {
-
-    private Scene scene;
-    private JScrollPane scrollPane;
-    private Point lastLocation;
-
-    protected boolean isLocked() {
-        return scrollPane != null;
-    }
-
-    @Override
-    public State mousePressed(Widget widget, WidgetMouseEvent event) {
-        if (event.getButton() == MouseEvent.BUTTON2 || event.getButton() == MouseEvent.BUTTON1 && ((event.getModifiers() & MouseEvent.CTRL_MASK) != 0)) {
-            scene = widget.getScene();
-            scrollPane = findScrollPane(scene.getView());
-            if (scrollPane != null) {
-                lastLocation = scene.convertSceneToView(widget.convertLocalToScene(event.getPoint()));
-                SwingUtilities.convertPointToScreen(lastLocation, scrollPane.getViewport().getView());
-                return State.createLocked(widget, this);
-            }
-        }
-        return State.REJECTED;
-    }
-
-    private JScrollPane findScrollPane(JComponent component) {
-        for (;;) {
-            if (component == null) {
-                return null;
-            }
-            if (component instanceof JScrollPane) {
-                return ((JScrollPane) component);
-            }
-            Container parent = component.getParent();
-            if (!(parent instanceof JComponent)) {
-                return null;
-            }
-            component = (JComponent) parent;
-        }
-    }
-
-    @Override
-    public State mouseReleased(Widget widget, WidgetMouseEvent event) {
-        boolean state = pan(widget, event.getPoint());
-        if (state) {
-            scrollPane = null;
-        }
-        return state ? State.createLocked(widget, this) : State.REJECTED;
-    }
-
-    @Override
-    public State mouseDragged(Widget widget, WidgetMouseEvent event) {
-        return pan(widget, event.getPoint()) ? State.createLocked(widget, this) : State.REJECTED;
-    }
-
-    private boolean pan(Widget widget, Point newLocation) {
-        if (scrollPane == null || scene != widget.getScene()) {
-            return false;
-        }
-        newLocation = scene.convertSceneToView(widget.convertLocalToScene(newLocation));
-        SwingUtilities.convertPointToScreen(newLocation, scrollPane.getViewport().getView());
-        Point viewPosition = scrollPane.getViewport().getViewPosition();
-        Dimension viewSize = scrollPane.getViewport().getViewSize();
-        Dimension viewPortSize = scrollPane.getViewport().getSize();
-
-        int xOffset = lastLocation.x - newLocation.x;
-        int yOffset = lastLocation.y - newLocation.y;
-
-        if (viewPortSize.height == viewSize.height) {
-            yOffset = 0;
-        }
-
-        if (viewPortSize.width == viewSize.width) {
-            xOffset = 0;
-        }
-
-        if (xOffset == 0 && yOffset == 0) {
-            return true;
-        }
-        viewPosition = new Point(viewPosition.x + xOffset, viewPosition.y + yOffset);
-        viewPosition.x = Math.max(viewPosition.x, 0);
-        viewPosition.y = Math.max(viewPosition.y, 0);
-        viewPosition.x = Math.min(viewPosition.x, scrollPane.getViewport().getView().getSize().width - scrollPane.getViewport().getSize().width);
-        viewPosition.y = Math.min(viewPosition.y, scrollPane.getViewport().getView().getSize().height - scrollPane.getViewport().getSize().height);
-
-        scrollPane.getViewport().setViewPosition(viewPosition);
-        scrollPane.getViewport().getView().repaint();
-        lastLocation = newLocation;
-        return true;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedSatelliteComponent.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedSatelliteComponent.java	Wed Jun 08 17:26:49 2011 +0200
@@ -97,9 +97,10 @@
             image = this.createImage(imageWidth, imageHeight);
             Graphics2D ig = (Graphics2D) image.getGraphics();
             ig.scale(scale, scale);
-            scene.setRealZoomFactor(scale);
+	    double oldFactor = scene.getZoomFactor();
+	    scene.setZoomFactor(scale);
             scene.paint(ig);
-            scene.setRealZoomFactor(0.0);
+	    scene.setZoomFactor(oldFactor);
         }
 
         gr.drawImage(image, vx, vy, this);
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view;
-
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.data.Properties;
-import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
-import com.sun.hotspot.igv.data.Property;
-import java.awt.GridLayout;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.util.List;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import javax.swing.JComboBox;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-class FindPanel extends JPanel implements KeyListener {
-
-    private JComboBox nameComboBox;
-    private JTextField valueTextField;
-
-    public FindPanel(List<Figure> figures) {
-        createDesign();
-        updateComboBox(figures);
-    }
-
-    protected void createDesign() {
-        setLayout(new GridLayout());
-        nameComboBox = new JComboBox();
-        valueTextField = new JTextField();
-        add(nameComboBox);
-        add(valueTextField);
-        valueTextField.addKeyListener(this);
-    }
-
-    public void updateComboBox(List<Figure> figures) {
-
-        String sel = (String) nameComboBox.getSelectedItem();
-        SortedSet<String> propertyNames = new TreeSet<String>();
-
-        for (Figure f : figures) {
-            Properties prop = f.getProperties();
-            for (Property p : prop) {
-                if (!propertyNames.contains(p.getName())) {
-                    propertyNames.add(p.getName());
-                }
-            }
-        }
-
-        for (String s : propertyNames) {
-            nameComboBox.addItem(s);
-        }
-        nameComboBox.setSelectedItem(sel);
-    }
-
-    public String getNameText() {
-        return (String) nameComboBox.getSelectedItem();
-    }
-
-    public String getValueText() {
-        return valueTextField.getText();
-    }
-
-    public void keyTyped(KeyEvent e) {
-    }
-
-    public void keyPressed(KeyEvent e) {
-        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
-            find();
-        }
-    }
-
-    public void find() {
-        EditorTopComponent comp = EditorTopComponent.getActive();
-        if (comp != null) {
-            RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(getNameText(), getValueText());
-            comp.setSelection(matcher);
-        }
-    }
-
-    public void keyReleased(KeyEvent e) {
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/NodeQuickSearch.java	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.view;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import com.sun.hotspot.igv.data.Property;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.util.LookupHistory;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import org.netbeans.spi.quicksearch.SearchProvider;
+import org.netbeans.spi.quicksearch.SearchRequest;
+import org.netbeans.spi.quicksearch.SearchResponse;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class NodeQuickSearch implements SearchProvider {
+
+    /**
+     * Method is called by infrastructure when search operation was requested.
+     * Implementors should evaluate given request and fill response object with
+     * apropriate results
+     *
+     * @param request Search request object that contains information what to search for
+     * @param response Search response object that stores search results. Note that it's important to react to return value of SearchResponse.addResult(...) method and stop computation if false value is returned.
+     */
+    public void evaluate(SearchRequest request, SearchResponse response) {
+
+        final String[] parts = request.getText().split("=");
+        if (parts.length == 0) {
+            return;
+        }
+
+        String tmpName = parts[0];
+
+        String value = null;
+        if (parts.length == 2) {
+            value = parts[1];
+        }
+
+        if (parts.length == 1 && request.getText().endsWith("=")) {
+            value = ".*";
+        }
+
+        final String name = tmpName;
+
+        if (value != null) {
+            final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
+            if (p != null) {
+                final InputGraph graph = p.getGraph();
+                if (graph != null) {
+                    final RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value);
+                    final Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<InputNode>(graph.getNodes());
+                    final List<InputNode> list = selector.selectMultiple(matcher);
+                    final Set<InputNode> set = new HashSet<InputNode>(list);
+
+                    response.addResult(new Runnable() {
+
+                        public void run() {
+
+                            final EditorTopComponent comp = EditorTopComponent.getActive();
+                            if (comp != null) {
+                                comp.setSelectedNodes(set);
+                                comp.requestActive();
+                            }
+                        }
+                    }, "All " + list.size() + " matching nodes (" + name + "=" + value + ")");
+                    for (final InputNode n : list) {
+
+
+                        response.addResult(new Runnable() {
+
+                            public void run() {
+                                final EditorTopComponent comp = EditorTopComponent.getActive();
+                                if (comp != null) {
+                                    final Set<InputNode> tmpSet = new HashSet<InputNode>();
+                                    tmpSet.add(n);
+                                    comp.setSelectedNodes(tmpSet);
+                                    comp.requestActive();
+                                    comp.requestFocus();
+                                }
+                            }
+                        }, n.getProperties().get(name) + " (" + n.getId() + " " + n.getProperties().get("name") + ")");
+                    }
+                }
+
+            } else {
+                System.out.println("no input graph provider!");
+            }
+
+        } else if (parts.length == 1) {
+
+            final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
+
+            if (p != null) {
+
+                final InputGraph graph = p.getGraph();
+                if (p != null && graph != null) {
+
+                    Set<String> properties = new HashSet<String>();
+                    for (InputNode n : p.getGraph().getNodes()) {
+                        for (Property property : n.getProperties()) {
+                            properties.add(property.getName());
+                        }
+                    }
+
+                    for (final String propertyName : properties) {
+
+                        if (propertyName.startsWith(name)) {
+
+                            response.addResult(new Runnable() {
+
+                                public void run() {
+
+                                    NotifyDescriptor.InputLine d =
+                                            new NotifyDescriptor.InputLine("Value of the property?", "Property Value Input");
+                                    if (DialogDisplayer.getDefault().notify(d) == NotifyDescriptor.OK_OPTION) {
+                                        String value = d.getInputText();
+                                        final RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(propertyName, value);
+                                        final Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<InputNode>(graph.getNodes());
+                                        final List<InputNode> list = selector.selectMultiple(matcher);
+                                        final Set<InputNode> set = new HashSet<InputNode>(list);
+
+                                        final EditorTopComponent comp = EditorTopComponent.getActive();
+                                        if (comp != null) {
+                                            comp.setSelectedNodes(set);
+                                            comp.requestActive();
+                                        }
+
+                                    }
+
+
+                                }
+                            }, propertyName + "=");
+                        }
+                    }
+
+                } else {
+                    System.out.println("no input graph provider!");
+                }
+            }
+        }
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/PreferenceConstants.java	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class PreferenceConstants {
-
-    public static final String KEY_LINE_GENERATOR = "lineGenerator";
-    public static final String DEFAULT_LINE_GENERATOR = "com.sun.hotspot.igv.positioning.BasicLineGenerator";
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/SlotLayout.java	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view;
-
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.util.Collection;
-import java.util.List;
-import org.netbeans.api.visual.layout.Layout;
-import org.netbeans.api.visual.layout.LayoutFactory;
-import org.netbeans.api.visual.widget.Widget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class SlotLayout implements Layout {
-
-    public enum HorizontalAlignment {
-
-        Left,
-        Center,
-        Right
-    }
-    private Layout baseLayout;
-    private HorizontalAlignment alignment;
-    private boolean vertical;
-
-    public SlotLayout() {
-        this(HorizontalAlignment.Center, false);
-    }
-
-    public SlotLayout(HorizontalAlignment alignment, boolean vertical) {
-        this.alignment = alignment;
-        baseLayout = LayoutFactory.createVerticalFlowLayout();
-        this.vertical = vertical;
-    }
-
-    public void layout(Widget widget) {
-        if (!vertical) {
-            Collection<Widget> children = widget.getChildren();
-            int gap = 0;
-            int max = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int i = preferredBounds.width;
-                if (i > max) {
-                    max = i;
-                }
-            }
-            int pos = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int x = preferredBounds.x;
-                int y = preferredBounds.y;
-                int width = preferredBounds.width;
-                int height = preferredBounds.height;
-                if (pos == 0) {
-                    pos += height / 2;
-                }
-                int lx = -x;
-                int ly = pos - y;
-                switch (alignment) {
-                    case Center:
-                        lx += (max - width) / 2;
-                        break;
-                    case Left:
-                        break;
-                    case Right:
-                        lx += max - width;
-                        break;
-                }
-                child.resolveBounds(new Point(lx, ly), new Rectangle(x, y, width, height));
-                pos += height + gap;
-            }
-        } else {
-
-            Collection<Widget> children = widget.getChildren();
-            int gap = 0;
-            int max = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int i = preferredBounds.height;
-                if (i > max) {
-                    max = i;
-                }
-            }
-            int pos = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int x = preferredBounds.x;
-                int y = preferredBounds.y;
-                int width = preferredBounds.width;
-                int height = preferredBounds.height;
-                if (pos == 0) {
-                    pos += width / 2;
-                }
-                int lx = pos - x;
-                int ly = -y;
-                switch (alignment) {
-                    case Center:
-                        ly += (max - height) / 2;
-                        break;
-                    case Left:
-                        break;
-                    case Right:
-                        ly += max - height;
-                        break;
-                }
-                child.resolveBounds(new Point(lx, ly), new Rectangle(x, y, width, height));
-                pos += width + gap;
-            }
-
-        }
-    }
-
-    public boolean requiresJustification(Widget widget) {
-        return true;
-    }
-
-    public void justify(Widget widget) {
-        baseLayout.justify(widget);
-
-        Rectangle client = widget.getClientArea();
-        List<Widget> children = widget.getChildren();
-
-        int count = children.size();
-        int z = 0;
-
-        int maxWidth = 0;
-        for (Widget c : children) {
-            if (c.getPreferredBounds().width > maxWidth) {
-                maxWidth = c.getPreferredBounds().width;
-            }
-        }
-
-        for (Widget c : children) {
-            z++;
-            Point curLocation = c.getLocation();
-            Rectangle curBounds = c.getBounds();
-
-
-            Point location = new Point(curLocation.x, client.y + client.height * z / (count + 1) - curBounds.height / 2);
-            if (vertical) {
-                location = new Point(client.x + client.width * z / (count + 1) - maxWidth / 2, curLocation.y);
-            }
-            c.resolveBounds(location, null);
-        }
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NodeFindAction.java	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view.actions;
-
-import com.sun.hotspot.igv.view.EditorTopComponent;
-import javax.swing.Action;
-import org.openide.util.HelpCtx;
-import org.openide.util.NbBundle;
-import org.openide.util.actions.CallableSystemAction;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public final class NodeFindAction extends CallableSystemAction {
-
-    public void performAction() {
-        EditorTopComponent comp = EditorTopComponent.getActive();
-        if (comp != null) {
-            comp.findNode();
-        }
-    }
-
-    public NodeFindAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Find nodes");
-    }
-
-    public String getName() {
-        return NbBundle.getMessage(NodeFindAction.class, "CTL_NodeFindAction");
-    }
-
-    public HelpCtx getHelpCtx() {
-        return HelpCtx.DEFAULT_HELP;
-    }
-
-    @Override
-    protected boolean asynchronous() {
-        return false;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return true;
-    }
-
-    @Override
-    protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/search.gif";
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml	Wed Jun 08 17:26:49 2011 +0200
@@ -51,6 +51,17 @@
             </file>
         </folder>
     </folder>
+
+    
+    <folder name="QuickSearch">
+        <folder name="Nodes">
+            <attr name="command" stringvalue="n"/>
+            <attr name="position" intvalue="0"/>
+            <file name="com-sun-hotspot-igv-view-NodeQuickSearch.instance">
+                <attr name="SystemFileSystem.localizingBundle" stringvalue="com.sun.hotspot.igv.view.Bundle"/>
+            </file>
+        </folder>
+    </folder>
     <folder name="Toolbars">
         <folder name="Edit">
             <attr name="com-sun-hotspot-igv-view-actions-LineGeneratorAction.shadow/com-sun-hotspot-igv-coordinator-actions-OpenGraphAction.shadow" boolvalue="true"/>
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/BlockWidget.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/BlockWidget.java	Wed Jun 08 17:26:49 2011 +0200
@@ -74,7 +74,7 @@
         g.setColor(titleColor);
         g.setFont(titleFont);
 
-        String s = "B" + blockNode.toString();
+        String s = "B" + blockNode.getName();
         Rectangle2D r1 = g.getFontMetrics().getStringBounds(s, g);
         g.drawString(s, r.x + 5, r.y + (int) r1.getHeight());
         g.setStroke(old);
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/DiagramConnectionWidget.java	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view.widgets;
-
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.view.DiagramScene;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.util.ArrayList;
-import java.util.List;
-import org.netbeans.api.visual.anchor.AnchorShape;
-import org.netbeans.api.visual.model.ObjectState;
-import org.netbeans.api.visual.widget.ConnectionWidget;
-import org.netbeans.api.visual.widget.Scene;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class DiagramConnectionWidget extends ConnectionWidget {
-
-    private static Stroke DASHED_STROKE = new BasicStroke(
-            1,
-            BasicStroke.CAP_BUTT,
-            BasicStroke.JOIN_ROUND,
-            0,
-            new float[]{2},
-            0);
-    private static Stroke NORMAL_STROKE = new BasicStroke(1);
-    private static Stroke BOLD_STROKE = new BasicStroke(3);
-    public static int WHITE_FACTOR = 5;
-    private Connection connection;
-    private Color color;
-    private Point lastSourceAnchor;
-    private Point lastTargetAnchor;
-    private List<Point> controlPoints;
-    private Rectangle clientArea;
-    private boolean split;
-    private int[] xPoints;
-    private int[] yPoints;
-    private int pointCount;
-
-    /** Creates a new instance of ConnectionWidget */
-    public DiagramConnectionWidget(Connection connection, Scene scene) {
-        super(scene);
-        this.connection = connection;
-        color = connection.getColor();
-        if (connection.getStyle() == Connection.ConnectionStyle.DASHED) {
-            this.setStroke(DASHED_STROKE);
-        } else if (connection.getStyle() == Connection.ConnectionStyle.BOLD) {
-            this.setStroke(BOLD_STROKE);
-        } else {
-            this.setStroke(NORMAL_STROKE);
-        }
-        this.setCheckClipping(true);
-        clientArea = new Rectangle();
-        updateControlPoints();
-    }
-
-    public Connection getConnection() {
-        return connection;
-    }
-
-    public void updateControlPoints() {
-        List<Point> newControlPoints = connection.getControlPoints();
-        Connection c = connection;
-        Figure f = c.getInputSlot().getFigure();
-        Point p = new Point(f.getPosition());
-        p.translate(c.getInputSlot().getRelativePosition().x, f.getSize().height / 2);
-        Point p4 = new Point(f.getPosition());
-        p4.translate(c.getInputSlot().getRelativePosition().x, c.getInputSlot().getRelativePosition().y);
-
-        Figure f2 = c.getOutputSlot().getFigure();
-        Point p2 = new Point(f2.getPosition());
-        p2.translate(c.getOutputSlot().getRelativePosition().x, f2.getSize().height / 2);
-        Point p3 = new Point(f2.getPosition());
-        p3.translate(c.getOutputSlot().getRelativePosition().x, c.getOutputSlot().getRelativePosition().y);
-
-        /*if(controlPoints.size() >= 2) {
-        String className = Preferences.userNodeForPackage(PreferenceConstants.class).get(PreferenceConstants.KEY_LINE_GENERATOR, PreferenceConstants.DEFAULT_LINE_GENERATOR);
-        try {
-        LineGenerator lg = (LineGenerator)Class.forName(className).newInstance();
-        controlPoints = lg.createLine(controlPoints, p2, p);
-        } catch (InstantiationException ex) {
-        } catch (IllegalAccessException ex) {
-        } catch (ClassNotFoundException ex) {
-        }
-        }*/
-
-        this.controlPoints = newControlPoints;
-        pointCount = newControlPoints.size();
-        xPoints = new int[pointCount];
-        yPoints = new int[pointCount];
-        int minX = Integer.MAX_VALUE;
-        int maxX = Integer.MIN_VALUE;
-        int minY = Integer.MAX_VALUE;
-        int maxY = Integer.MIN_VALUE;
-        split = false;
-        for (int i = 0; i < pointCount; i++) {
-            if (newControlPoints.get(i) == null) {
-                split = true;
-            } else {
-                int curX = newControlPoints.get(i).x;
-                int curY = newControlPoints.get(i).y;
-                this.xPoints[i] = curX;
-                this.yPoints[i] = curY;
-                minX = Math.min(minX, curX);
-                maxX = Math.max(maxX, curX);
-                minY = Math.min(minY, curY);
-                maxY = Math.max(maxY, curY);
-            }
-        }
-
-        this.clientArea = new Rectangle(minX, minY, maxX - minX, maxY - minY);
-    }
-
-    @Override
-    protected void paintWidget() {
-        Graphics2D g = this.getGraphics();
-
-        if (xPoints.length == 0 || Math.abs(xPoints[0] - xPoints[xPoints.length - 1]) > 2000) {
-            return;
-        }
-
-        //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
-        //g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
-        //g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
-
-        DiagramScene ds = (DiagramScene) this.getScene();
-        boolean shouldHide = false;//ds.getShouldHide(this);
-
-        Composite oldComposite = null;
-        if (shouldHide) {
-            Color c = new Color(255 - (255 - color.getRed()) / WHITE_FACTOR, 255 - (255 - color.getGreen()) / WHITE_FACTOR, 255 - (255 - color.getBlue()) / WHITE_FACTOR);
-            g.setPaint(c);
-        } else {
-            g.setPaint(color);
-        }
-
-        if (split) {
-            for (int i = 1; i < controlPoints.size(); i++) {
-                Point prev = controlPoints.get(i - 1);
-                Point cur = controlPoints.get(i);
-                if (cur == null || prev == null) {
-                    continue;
-                }
-
-                g.drawLine(prev.x, prev.y, cur.x, cur.y);
-            }
-        } else {
-            g.drawPolyline(xPoints, yPoints, pointCount);
-        }
-
-        /*for(int i=0; i<xPoints.length; i++) {
-        int x = xPoints[i];
-        int y = yPoints[i];
-        g.fillOval(x - 2, y - 2, 4, 4);
-        }*/
-
-        if (xPoints.length >= 2) {
-            Graphics2D g2 = (Graphics2D) g.create();
-            int xOff = xPoints[xPoints.length - 2] - xPoints[xPoints.length - 1];
-            int yOff = yPoints[yPoints.length - 2] - yPoints[yPoints.length - 1];
-            if (xOff == 0 && yOff == 0 && yPoints.length >= 3) {
-                xOff = xPoints[xPoints.length - 3] - xPoints[xPoints.length - 1];
-                yOff = yPoints[yPoints.length - 3] - yPoints[yPoints.length - 1];
-            }
-            g2.translate(xPoints[xPoints.length - 1], yPoints[yPoints.length - 1]);
-            g2.rotate(Math.atan2(yOff, xOff));
-
-            g2.scale(0.55, 0.80);
-            AnchorShape.TRIANGLE_FILLED.paint(g2, false);
-        }
-    }
-
-    @Override
-    public void notifyStateChanged(ObjectState previousState, ObjectState state) {
-
-        if (previousState.isHovered() != state.isHovered()) {
-            color = connection.getColor();
-            if (state.isHovered()) {
-                this.setStroke(BOLD_STROKE);
-            } else {
-                this.setStroke(NORMAL_STROKE);
-            }
-
-            if (state.isHovered()) {
-                this.setStroke(BOLD_STROKE);
-            } else {
-                this.setStroke(NORMAL_STROKE);
-            }
-
-            repaint();
-        }
-        super.notifyStateChanged(previousState, state);
-    }
-
-    @Override
-    public List<Point> getControlPoints() {
-        if (split) {
-            ArrayList<Point> result = new ArrayList<Point>();
-            for (Point p : controlPoints) {
-                if (p != null) {
-                    result.add(p);
-                }
-            }
-            return result;
-        } else {
-            return controlPoints;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "ConnectionWidget[" + connection + "]";
-    }
-
-    @Override
-    protected Rectangle calculateClientArea() {
-        Rectangle result = new Rectangle(clientArea);
-        result.grow(10, 10);
-        return result;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java	Wed Jun 08 17:26:49 2011 +0200
@@ -25,17 +25,17 @@
 
 import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.view.DiagramScene;
-import com.sun.hotspot.igv.view.SlotLayout;
 import com.sun.hotspot.igv.util.DoubleClickHandler;
 import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.util.DoubleClickAction;
 import com.sun.hotspot.igv.util.PropertiesSheet;
 import java.awt.AlphaComposite;
 import java.awt.Color;
 import java.awt.Composite;
 import java.awt.Dimension;
 import java.awt.Font;
-import java.awt.Graphics;
 import java.awt.Point;
+import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Set;
@@ -62,7 +62,7 @@
 
     public static final boolean VERTICAL_LAYOUT = true;
     public static final int DEPTH = 5;
-    public static final int MAX_STRING_LENGTH = 20;
+    //public static final int MAX_STRING_LENGTH = 20;
     private static final double LABEL_ZOOM_FACTOR = 0.3;
     private static final double ZOOM_FACTOR = 0.1;
     private Font font;
@@ -75,6 +75,7 @@
     private DiagramScene diagramScene;
     private boolean boundary;
     private Node node;
+    private Widget dummyTop;
 
     public void setBoundary(boolean b) {
         boundary = b;
@@ -88,80 +89,69 @@
         return node;
     }
 
-    private String shortenString(String string) {
-        if (string.length() > MAX_STRING_LENGTH) {
-            StringBuilder sb = new StringBuilder();
-            for (int i = 0; i < string.length(); i++) {
-                char c = string.charAt(i);
-                if (!Character.isLetter(c) || Character.isUpperCase(c)) {
-                    sb.append(c);
-                }
-            }
-            string = sb.toString();
-        }
-        return string;
-    }
+	@Override
+	public boolean isHitAt(Point localLocation) {
+		return middleWidget.isHitAt(localLocation);
+	}
+    
 
-    public FigureWidget(final Figure f, DiagramScene s, Widget parent) {
+    public FigureWidget(final Figure f, WidgetAction hoverAction, WidgetAction selectAction, DiagramScene scene, Widget parent) {
+
+        super(scene);
 
-        super(s);
+        assert this.getScene() != null;
+        assert this.getScene().getView() != null;
 
-
+        this.figure = f;
         font = f.getDiagram().getFont();
         boldFont = f.getDiagram().getFont().deriveFont(Font.BOLD);
         this.setCheckClipping(true);
-        this.diagramScene = s;
-
+        this.diagramScene = scene;
         parent.addChild(this);
-        this.figure = f;
-        this.resolveBounds(null, calculateClientArea());
-
-        leftWidget = new Widget(s);
-        this.addChild(leftWidget);
-        leftWidget.setLayout(new SlotLayout(SlotLayout.HorizontalAlignment.Right, VERTICAL_LAYOUT));//LayoutFactory.createVerticalFlowLayout(LayoutFactory.SerialAlignment.JUSTIFY, 0));
 
-        middleWidget = new Widget(s);
-        this.addChild(middleWidget);
-
-        if (VERTICAL_LAYOUT) {
-            this.setLayout(LayoutFactory.createVerticalFlowLayout());
-        } else {
-            this.setLayout(LayoutFactory.createHorizontalFlowLayout());
-        }
-
-        middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout());
-
+	Widget outer = new Widget(scene);
+	outer.setBackground(f.getColor());
+	outer.setLayout(LayoutFactory.createOverlayLayout());
+	
+        middleWidget = new Widget(scene);
+        middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout(LayoutFactory.SerialAlignment.CENTER, 0));
         middleWidget.setBackground(f.getColor());
         middleWidget.setOpaque(true);
-        assert this.getScene() != null;
-        assert this.getScene().getView() != null;
-        middleWidget.setBorder(BorderFactory.createLineBorder(Color.BLACK));
-
+        //middleWidget.setBorder(BorderFactory.createLineBorder(Color.BLACK));
+        middleWidget.getActions().addAction(new DoubleClickAction(this));
+	middleWidget.setCheckClipping(true);
 
         labelWidgets = new ArrayList<LabelWidget>();
 
         String[] strings = figure.getLines();
 
+        dummyTop = new Widget(scene);
+        dummyTop.setMinimumSize(new Dimension(Figure.INSET / 2, 1));
+        middleWidget.addChild(dummyTop);
+
+
         for (String cur : strings) {
 
             String displayString = cur;
 
-            LabelWidget lw = new LabelWidget(s);
+            LabelWidget lw = new LabelWidget(scene);
             labelWidgets.add(lw);
             middleWidget.addChild(lw);
             lw.setLabel(displayString);
-
             lw.setFont(font);
             lw.setForeground(Color.BLACK);
             lw.setAlignment(LabelWidget.Alignment.CENTER);
             lw.setVerticalAlignment(LabelWidget.VerticalAlignment.CENTER);
-            lw.setMaximumSize(new Dimension(f.getWidth(), 20000));
-            lw.setMinimumSize(new Dimension(f.getWidth(), 20));
+	    lw.setBorder(BorderFactory.createEmptyBorder());
         }
 
-        rightWidget = new Widget(s);
-        this.addChild(rightWidget);
-        rightWidget.setLayout(new SlotLayout(SlotLayout.HorizontalAlignment.Left, VERTICAL_LAYOUT));//LayoutFactory.createVerticalLayout(LayoutFactory.SerialAlignment.JUSTIFY, 0));
+        Widget dummyBottom = new Widget(scene);
+        dummyBottom.setMinimumSize(new Dimension(Figure.INSET / 2, 1));
+        middleWidget.addChild(dummyBottom);
+
+        middleWidget.setPreferredBounds(new Rectangle(0, Figure.SLOT_WIDTH - Figure.OVERLAPPING, f.getWidth(), f.getHeight()));
+	//outer.addChild(middleWidget);
+        this.addChild(middleWidget);
 
         // Initialize node for property sheet
         node = new AbstractNode(Children.LEAF) {
@@ -175,22 +165,6 @@
         };
         node.setDisplayName(getName());
     }
-    private boolean firstTime = true;
-
-    @Override
-    protected void paintWidget() {
-        if (firstTime) {
-            firstTime = false;
-            for (LabelWidget w : labelWidgets) {
-                String cur = w.getLabel();
-                Graphics graphics = this.getGraphics();
-                if (graphics.getFontMetrics().stringWidth(cur) > figure.getWidth()) {
-                    w.setLabel(shortenString(cur));
-                }
-            }
-        }
-        super.paintWidget();
-    }
 
     public Widget getLeftWidget() {
         return leftWidget;
@@ -205,19 +179,34 @@
         super.notifyStateChanged(previousState, state);
 
         Color borderColor = Color.BLACK;
+	Color innerBorderColor = getFigure().getColor();
         int thickness = 1;
         boolean repaint = false;
         Font f = font;
-        if (state.isSelected()) {
-            thickness = 1;
+        if (state.isSelected() || state.isHighlighted()) {
+            thickness = 2;
+	}
+	if(state.isSelected()) {
             f = boldFont;
-        }
+		innerBorderColor = borderColor;
+        } else {
+	}
 
-        if (state.isHovered()) {
-            borderColor = Color.BLUE;
-        }
+        if (state.isHighlighted()) {
+		innerBorderColor = borderColor = Color.BLUE;
+		repaint = true;
+        } else {
+		repaint = true;
+	}
 
         if (state.isHovered() != previousState.isHovered()) {
+
+		/*
+            if (state.isHovered()) {
+                diagramScene.addAllHighlighted(this.getFigure().getSource().getSourceNodesAsSet());
+            } else {
+                diagramScene.removeAllHighlighted(this.getFigure().getSource().getSourceNodesAsSet());
+            }*/
             repaint = true;
         }
 
@@ -226,7 +215,7 @@
         }
 
         if (repaint) {
-            middleWidget.setBorder(BorderFactory.createLineBorder(borderColor, thickness));
+            middleWidget.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(borderColor, 1), BorderFactory.createLineBorder(innerBorderColor, 1)));
             for (LabelWidget labelWidget : labelWidgets) {
                 labelWidget.setFont(f);
             }
@@ -249,7 +238,7 @@
     @Override
     protected void paintChildren() {
 
-        if (diagramScene.getRealZoomFactor() < ZOOM_FACTOR && diagramScene.getModel().getShowBlocks()) {
+        if (diagramScene.getZoomFactor() < ZOOM_FACTOR && diagramScene.getModel().getShowBlocks()) {
             return;
         }
 
@@ -260,7 +249,7 @@
             this.getScene().getGraphics().setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
         }
 
-        if (diagramScene.getRealZoomFactor() < LABEL_ZOOM_FACTOR) {
+        if (diagramScene.getZoomFactor() < LABEL_ZOOM_FACTOR) {
 
             for (LabelWidget labelWidget : labelWidgets) {
                 labelWidget.setVisible(false);
@@ -321,8 +310,6 @@
     public void addFigureToMenu(JMenu m, final Figure f, boolean successor, int depth) {
 
         Action a = diagramScene.createGotoAction(f);
-
-
         m.add(a);
 
         if (depth > 0) {
@@ -341,18 +328,18 @@
     public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) {
 
         if (diagramScene.isAllVisible()) {
-            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
+            final Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
             hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
-            this.diagramScene.showNot(hiddenNodes);
+            this.diagramScene.getModel().showNot(hiddenNodes);
         } else if (isBoundary()) {
 
-            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getHiddenNodes());
+            final Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getHiddenNodes());
             hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
-            this.diagramScene.showNot(hiddenNodes);
+            this.diagramScene.getModel().showNot(hiddenNodes);
         } else {
-            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getHiddenNodes());
+            final Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getHiddenNodes());
             hiddenNodes.addAll(this.getFigure().getSource().getSourceNodesAsSet());
-            this.diagramScene.showNot(hiddenNodes);
+            this.diagramScene.getModel().showNot(hiddenNodes);
         }
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,6 +23,7 @@
  */
 package com.sun.hotspot.igv.view.widgets;
 
+import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.InputSlot;
 import com.sun.hotspot.igv.view.DiagramScene;
 import java.awt.Point;
@@ -40,14 +41,24 @@
     public InputSlotWidget(InputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
         super(slot, scene, parent, fw);
         inputSlot = slot;
-        init();
-        getFigureWidget().getLeftWidget().addChild(this);
+        //init();
+        //getFigureWidget().getLeftWidget().addChild(this);
+        Point p = inputSlot.getRelativePosition();
+        p.x -= this.calculateClientArea().width / 2;
+        p.y += Figure.SLOT_START;
+        this.setPreferredLocation(p);
     }
 
     public InputSlot getInputSlot() {
         return inputSlot;
     }
-
+    
+    protected int calculateSlotWidth() {
+        List<InputSlot> slots = getSlot().getFigure().getInputSlots();
+        assert slots.contains(getSlot());
+        return calculateWidth(slots.size());
+    }
+/*
     protected Point calculateRelativeLocation() {
         if (getFigureWidget().getBounds() == null) {
             return new Point(0, 0);
@@ -57,5 +68,5 @@
         List<InputSlot> slots = inputSlot.getFigure().getInputSlots();
         assert slots.contains(inputSlot);
         return new Point((int) x, (int) (calculateRelativeY(slots.size(), slots.indexOf(inputSlot))));
-    }
+    }*/
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java	Wed Jun 08 17:26:49 2011 +0200
@@ -24,6 +24,7 @@
 package com.sun.hotspot.igv.view.widgets;
 
 import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.InputSlot;
 import com.sun.hotspot.igv.graph.OutputSlot;
 import com.sun.hotspot.igv.view.DiagramScene;
@@ -35,12 +36,15 @@
 import java.awt.Stroke;
 import java.awt.geom.Line2D;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import javax.swing.JPopupMenu;
 import javax.swing.event.PopupMenuEvent;
 import javax.swing.event.PopupMenuListener;
 import org.netbeans.api.visual.action.ActionFactory;
 import org.netbeans.api.visual.action.PopupMenuProvider;
+import org.netbeans.api.visual.action.SelectProvider;
 import org.netbeans.api.visual.animator.SceneAnimator;
 import org.netbeans.api.visual.model.ObjectState;
 import org.netbeans.api.visual.widget.Widget;
@@ -51,7 +55,7 @@
  */
 public class LineWidget extends Widget implements PopupMenuProvider {
 
-    public final int BORDER = 8;
+    public final int BORDER = 5;
     public final int ARROW_SIZE = 6;
     public final int BOLD_ARROW_SIZE = 7;
     public final int HOVER_ARROW_SIZE = 8;
@@ -110,6 +114,9 @@
         if (connections.size() > 0) {
             color = connections.get(0).getColor();
         }
+        
+        this.setToolTipText(generateToolTipText(this.connections));
+        
 
         this.setCheckClipping(true);
 
@@ -120,7 +127,38 @@
             this.setBackground(Color.WHITE);
             animator.animateBackgroundColor(this, color);
         }
+
+        this.getActions().addAction(ActionFactory.createSelectAction(new SelectProvider() {
+
+            public boolean isAimingAllowed(Widget arg0, Point arg1, boolean arg2) {
+                return true;
+            }
+
+            public boolean isSelectionAllowed(Widget arg0, Point arg1, boolean arg2) {
+                return true;
+            }
+
+            public void select(Widget arg0, Point arg1, boolean arg2) {
+                Set<Figure> set = new HashSet<Figure>();
+                for (Connection c : LineWidget.this.connections) {
+                    set.add(c.getInputSlot().getFigure());
+                    set.add(c.getOutputSlot().getFigure());
+                }
+                LineWidget.this.scene.setSelectedObjects(set);
+            }
+        }));
     }
+    
+    private String generateToolTipText(List<Connection> conn) {
+        StringBuffer sb = new StringBuffer();
+        for(Connection c : conn) {
+            sb.append(c.getToolTipText());
+            sb.append("<br>");
+        }
+        return sb.toString();
+    }
+    
+    
 
     public Point getFrom() {
         return from;
@@ -141,13 +179,12 @@
 
     @Override
     protected void paintWidget() {
-        if (scene.getRealZoomFactor() < ZOOM_FACTOR) {
+        if (scene.getZoomFactor() < ZOOM_FACTOR) {
             return;
         }
 
         Graphics2D g = getScene().getGraphics();
         g.setPaint(this.getBackground());
-        ObjectState state = this.getState();
         float width = 1.0f;
 
         if (isBold) {
@@ -207,6 +244,20 @@
 
     private void setHighlighted(boolean b) {
         this.highlighted = b;
+	Set<Object> highlightedObjects = new HashSet<Object>(scene.getHighlightedObjects());
+	Set<Object> highlightedObjectsChange = new HashSet<Object>();
+        for (Connection c : connections) {
+		highlightedObjectsChange.add(c.getInputSlot().getFigure());
+		highlightedObjectsChange.add(c.getInputSlot());
+		highlightedObjectsChange.add(c.getOutputSlot().getFigure());
+		highlightedObjectsChange.add(c.getOutputSlot());
+        }
+	if(b) {
+		highlightedObjects.addAll(highlightedObjectsChange);
+	} else {
+		highlightedObjects.removeAll(highlightedObjectsChange);
+	}
+	scene.setHighlightedObjects(highlightedObjects);
         this.revalidate(true);
     }
 
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/MultiConnectionWidget.java	Wed Jun 08 17:26:22 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,281 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view.widgets;
-
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Slot;
-import com.sun.hotspot.igv.view.DiagramScene;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.awt.geom.Line2D;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import javax.swing.JPopupMenu;
-import javax.swing.event.PopupMenuEvent;
-import javax.swing.event.PopupMenuListener;
-import org.netbeans.api.visual.action.PopupMenuProvider;
-import org.netbeans.api.visual.model.ObjectState;
-import org.netbeans.api.visual.widget.Widget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class MultiConnectionWidget extends Widget implements PopupMenuProvider {
-
-    public final int BORDER = 4;
-    public final int HOVER_STROKE_WIDTH = 3;
-
-    private static class Route {
-
-        public Point from;
-        public Point to;
-        public SortedSet<InputSlot> inputSlots;
-        public boolean decorateStart;
-        public boolean decorateEnd;
-
-        public Route(Point from, Point to) {
-            assert from != null;
-            assert to != null;
-            this.from = from;
-            this.to = to;
-            this.inputSlots = new TreeSet<InputSlot>();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-
-            if (obj instanceof Route) {
-                Route r = (Route) obj;
-                return r.from.equals(from) && r.to.equals(to);
-            }
-
-            return super.equals(obj);
-        }
-
-        @Override
-        public int hashCode() {
-            return ((((from.x * 1711) + from.y) * 1711 + to.x) * 1711 + to.y);
-        }
-    }
-    private Rectangle clientArea;
-    private OutputSlot outputSlot;
-    private Map<Route, SortedSet<InputSlot>> routeMap;
-    private List<Route> routeList;
-    private Color color;
-    private DiagramScene diagramScene;
-    private boolean popupVisible;
-
-    /** Creates a new instance of MultiConnectionWidget */
-    public MultiConnectionWidget(OutputSlot outputSlot, DiagramScene scene) {
-        super(scene);
-
-        this.diagramScene = scene;
-        this.outputSlot = outputSlot;
-        this.setCheckClipping(true);
-
-        routeMap = new HashMap<Route, SortedSet<InputSlot>>();
-        routeList = new ArrayList<Route>();
-        color = Color.BLACK;
-
-        for (Connection c : outputSlot.getConnections()) {
-            List<Point> controlPoints = c.getControlPoints();
-            InputSlot inputSlot = (InputSlot) c.getTo();
-            color = c.getColor();
-
-            for (int i = 1; i < controlPoints.size(); i++) {
-                Point prev = controlPoints.get(i - 1);
-                Point cur = controlPoints.get(i);
-
-                if (prev != null && cur != null) {
-                    Route r = new Route(prev, cur);
-                    if (routeMap.containsKey(r)) {
-                        SortedSet<InputSlot> set = routeMap.get(r);
-                        set.add(inputSlot);
-                    } else {
-                        SortedSet<InputSlot> set = new TreeSet<InputSlot>(Slot.slotFigureComparator);
-                        set.add(inputSlot);
-                        routeMap.put(r, set);
-                        routeList.add(r);
-                    }
-                }
-            }
-        }
-
-        if (routeList.size() == 0) {
-            clientArea = new Rectangle();
-        } else {
-            for (Route r : routeList) {
-
-                int x = r.from.x;
-                int y = r.from.y;
-
-                int x2 = r.to.x;
-                int y2 = r.to.y;
-
-                if (x > x2) {
-                    int tmp = x;
-                    x = x2;
-                    x2 = tmp;
-                }
-
-                if (y > y2) {
-                    int tmp = y;
-                    y = y2;
-                    y2 = tmp;
-                }
-
-                int width = x2 - x + 1;
-                int height = y2 - y + 1;
-
-                Rectangle rect = new Rectangle(x, y, width, height);
-                if (clientArea == null) {
-                    clientArea = rect;
-                } else {
-                    clientArea = clientArea.union(rect);
-                }
-            }
-
-            clientArea.grow(BORDER, BORDER);
-        }
-    }
-
-    private void setHoverPosition(Point location) {
-        Route r = getNearest(location);
-    }
-
-    private Route getNearest(Point localLocation) {
-
-        double minDist = Double.MAX_VALUE;
-        Route result = null;
-        for (Route r : routeList) {
-            double dist = Line2D.ptSegDistSq((double) r.from.x, (double) r.from.y, (double) r.to.x, (double) r.to.y, (double) localLocation.x, (double) localLocation.y);
-            if (dist < minDist) {
-                result = r;
-                minDist = dist;
-            }
-        }
-
-        assert result != null;
-
-        return result;
-    }
-
-    @Override
-    public boolean isHitAt(Point localLocation) {
-        if (!super.isHitAt(localLocation)) {
-            return false;
-        }
-
-        for (Route r : routeList) {
-            double dist = Line2D.ptSegDistSq((double) r.from.x, (double) r.from.y, (double) r.to.x, (double) r.to.y, (double) localLocation.x, (double) localLocation.y);
-            if (dist < BORDER * BORDER) {
-                setHoverPosition(localLocation);
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    protected Rectangle calculateClientArea() {
-        return clientArea;
-    }
-
-    @Override
-    protected void paintWidget() {
-        Graphics2D g = getScene().getGraphics();
-        //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
-        g.setColor(this.color);
-        ObjectState state = this.getState();
-        float width = 1.0f;
-        if (state.isHovered() || this.popupVisible) {
-            width = HOVER_STROKE_WIDTH;
-        }
-
-        Stroke oldStroke = g.getStroke();
-        g.setStroke(new BasicStroke(width));
-        for (Route r : routeList) {
-            g.drawLine(r.from.x, r.from.y, r.to.x, r.to.y);
-        }
-        g.setStroke(oldStroke);
-    }
-
-    @Override
-    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
-
-        boolean repaint = false;
-
-        if (state.isHovered() != previousState.isHovered()) {
-            repaint = true;
-        }
-
-        repaint();
-    }
-
-    public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
-        JPopupMenu menu = new JPopupMenu();
-        Route r = getNearest(localLocation);
-        assert r != null;
-        assert routeMap.containsKey(r);
-
-        menu.add(diagramScene.createGotoAction(outputSlot.getFigure()));
-        menu.addSeparator();
-
-        SortedSet<InputSlot> set = this.routeMap.get(r);
-        for (InputSlot s : set) {
-            menu.add(diagramScene.createGotoAction(s.getFigure()));
-        }
-
-        final MultiConnectionWidget w = this;
-        menu.addPopupMenuListener(new PopupMenuListener() {
-
-            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
-                w.popupVisible = true;
-                w.repaint();
-            }
-
-            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
-                w.popupVisible = false;
-                w.repaint();
-            }
-
-            public void popupMenuCanceled(PopupMenuEvent e) {
-            }
-        });
-
-        return menu;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java	Wed Jun 08 17:26:49 2011 +0200
@@ -23,10 +23,12 @@
  */
 package com.sun.hotspot.igv.view.widgets;
 
+import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.OutputSlot;
 import com.sun.hotspot.igv.view.DiagramScene;
 import java.awt.Point;
 import java.util.List;
+import org.netbeans.api.visual.widget.Scene;
 import org.netbeans.api.visual.widget.Widget;
 
 /**
@@ -40,14 +42,27 @@
     public OutputSlotWidget(OutputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
         super(slot, scene, parent, fw);
         outputSlot = slot;
-        init();
-        getFigureWidget().getRightWidget().addChild(this);
+        //init();
+        //getFigureWidget().getRightWidget().addChild(this);
+        Point p = outputSlot.getRelativePosition();
+        p.y += getSlot().getFigure().getHeight() - Figure.SLOT_START;
+        p.x -= this.calculateClientArea().width / 2;
+        //p.x += this.calculateClientArea().width / 2;
+        this.setPreferredLocation(p);
     }
 
     public OutputSlot getOutputSlot() {
         return outputSlot;
     }
 
+    protected int calculateSlotWidth() {
+        
+        List<OutputSlot> slots = getSlot().getFigure().getOutputSlots();
+        assert slots.contains(getSlot());
+        return calculateWidth(slots.size());
+        
+    }
+    /*
     protected Point calculateRelativeLocation() {
         if (getFigureWidget().getBounds() == null) {
             return new Point(0, 0);
@@ -57,5 +72,5 @@
         List<OutputSlot> slots = outputSlot.getFigure().getOutputSlots();
         assert slots.contains(outputSlot);
         return new Point((int) x, (int) (calculateRelativeY(slots.size(), slots.indexOf(outputSlot))));
-    }
+    }*/
 }
--- a/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java	Wed Jun 08 17:26:49 2011 +0200
@@ -26,53 +26,52 @@
 import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.OutputSlot;
 import com.sun.hotspot.igv.graph.Slot;
-import com.sun.hotspot.igv.view.*;
+import com.sun.hotspot.igv.selectioncoordinator.SelectionCoordinator;
+import com.sun.hotspot.igv.util.DoubleClickHandler;
+import com.sun.hotspot.igv.view.DiagramScene;
 import java.awt.Color;
 import java.awt.Font;
 import java.awt.Graphics2D;
-import java.awt.Image;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.geom.Rectangle2D;
+import java.util.HashSet;
+import java.util.Set;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.model.ObjectState;
 import org.netbeans.api.visual.widget.Widget;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public abstract class SlotWidget extends Widget {
+public abstract class SlotWidget extends Widget implements DoubleClickHandler {
 
     private Slot slot;
     private FigureWidget figureWidget;
-    private Image bufferImage;
     private static double TEXT_ZOOM_FACTOR = 0.9;
     private static double ZOOM_FACTOR = 0.6;
-    private DiagramScene scene;
+    private DiagramScene diagramScene;
 
     public SlotWidget(Slot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
         super(scene);
-        this.scene = scene;
+        this.diagramScene = scene;
         this.slot = slot;
         figureWidget = fw;
-        this.setToolTipText("<HTML>" + slot.getName() + "</HTML>");
+        this.setToolTipText("<HTML>" + slot.getToolTipText() + "</HTML>");
         this.setCheckClipping(true);
-    }
-
-    public Point getAnchorPosition() {
-        Point p = new Point(figureWidget.getFigure().getPosition());
-        Point p2 = slot.getRelativePosition();
-        p.translate(p2.x, p2.y);
-        return p;
+        parent.addChild(this);
+        
+        //this.setPreferredBounds(this.calculateClientArea());
     }
-
-    protected void init() {
-
-        Point p = calculateRelativeLocation();
-        Rectangle r = calculateClientArea();
-        p = new Point(p.x, p.y - r.height / 2);
-        this.setPreferredLocation(p);
+    
+    
+    @Override
+    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
+        super.notifyStateChanged(previousState, state);
+	repaint();
     }
-
+    
     public Slot getSlot() {
         return slot;
     }
@@ -84,43 +83,96 @@
     @Override
     protected void paintWidget() {
 
-        if (scene.getRealZoomFactor() < ZOOM_FACTOR) {
+        if (getScene().getZoomFactor() < ZOOM_FACTOR) {
             return;
         }
 
-        if (bufferImage == null) {
-            Graphics2D g = this.getGraphics();
-            g.setColor(Color.DARK_GRAY);
-            int w = this.getBounds().width;
-            int h = this.getBounds().height;
+        Graphics2D g = this.getGraphics();
+       // g.setColor(Color.DARK_GRAY);
+        int w = this.getBounds().width;
+        int h = this.getBounds().height;
+
+        if(getSlot().getSource().getSourceNodes().size() > 0) {
+            final int SMALLER = 0;
+            g.setColor(getSlot().getColor());
 
-            if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0 && scene.getRealZoomFactor() >= TEXT_ZOOM_FACTOR) {
-                Font f = new Font("Arial", Font.PLAIN, 8);
-                g.setFont(f.deriveFont(7.5f));
+            int FONT_OFFSET = 2;
+            
+            int s = h - SMALLER;
+            int rectW = s;
+            
+            Font font = this.getSlot().getFigure().getDiagram().getSlotFont();
+            if(this.getState().isSelected()) {
+                font = font.deriveFont(Font.BOLD);
+            }
+            
+            if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0) {
+                g.setFont(font);
                 Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g);
-                g.drawString(getSlot().getShortName(), (int) (this.getBounds().width - r1.getWidth()) / 2, (int) (this.getBounds().height + r1.getHeight()) / 2);
+                rectW = (int)r1.getWidth() + FONT_OFFSET * 2;
+            }
+            g.fillRect(w/2 - rectW/2, 0, rectW-1, s-1);
+            
+            if(this.getState().isHighlighted()) {
+                g.setColor(Color.BLUE);
             } else {
+                g.setColor(Color.BLACK);
+            }
+            g.drawRect(w/2 - rectW/2, 0, rectW-1, s-1);
+            
+            
+            if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0 && getScene().getZoomFactor() >= TEXT_ZOOM_FACTOR) {
+                Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g);
+                g.drawString(getSlot().getShortName(), (int) (w - r1.getWidth()) / 2, g.getFontMetrics().getAscent()-1);//(int) (r1.getHeight()));
+            }
+            
+        } else {
 
-                if (slot instanceof OutputSlot) {
-                    g.fillArc(w / 4, -h / 4 - 1, w / 2, h / 2, 180, 180);
-                } else {
-                    g.fillArc(w / 4, 3 * h / 4, w / 2, h / 2, 0, 180);
-                }
+            if(this.getState().isHighlighted()) {
+                g.setColor(Color.BLUE);
+            } else {
+                g.setColor(Color.BLACK);
+            }
+            int r = 2;
+            if (slot instanceof OutputSlot) {
+                g.fillOval(w/2-r, Figure.SLOT_WIDTH - Figure.SLOT_START - r, 2*r, 2*r);
+                //g.fillArc(w / 2 - r, -r, 2*r, 2*r, 180, 180);
+            } else {
+                g.fillOval(w/2-r, Figure.SLOT_START - r, 2*r, 2*r);
+                //g.fillArc(w / 2 - r, h - r, 2*r, 2*r, 0, 180);
             }
         }
     }
 
     @Override
     protected Rectangle calculateClientArea() {
-        return new Rectangle(0, 0, Figure.SLOT_WIDTH, Figure.SLOT_WIDTH);
+        return new Rectangle(0, 0, slot.getWidth(), Figure.SLOT_WIDTH);
     }
-
-    protected abstract Point calculateRelativeLocation();
+ 
+    protected abstract int calculateSlotWidth();
+    
+    protected int calculateWidth(int count) {
+        return (int)getFigureWidget().getFigure().getWidth() / count;
+    }
+    
+    public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) {
+        Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getHiddenNodes());
+        if (diagramScene.isAllVisible()) {
+            hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
+        } 
 
-    protected double calculateRelativeY(int size, int index) {
-        assert index >= 0 && index < size;
-        assert size > 0;
-        double height = getFigureWidget().getBounds().getHeight();
-        return height * (index + 1) / (size + 1);
+        boolean progress = false;
+        for(Figure f : diagramScene.getModel().getDiagramToView().getFigures()) {
+            for(Slot s : f.getSlots()) {
+                if(DiagramScene.doesIntersect(s.getSource().getSourceNodesAsSet(), slot.getSource().getSourceNodesAsSet())) {
+                    progress = true;
+                    hiddenNodes.removeAll(f.getSource().getSourceNodesAsSet());
+                }
+            }
+        }
+
+        if(progress) {
+            this.diagramScene.getModel().showNot(hiddenNodes);
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/branding.jnlp	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc//DTD JNLP Discriptor 1.5//EN" "http://java.sun.com/dtd/JNLP-1.5.dtd">
+<jnlp spec="1.0+" codebase="$$codebase">
+  <information>
+      <title>${app.title}</title>
+      <vendor>${app.title} vendor</vendor>
+      <description>${app.name} application</description>
+      <icon href="${app.icon}"/>
+  </information>
+  ${jnlp.permissions}
+  <resources>
+    ${jnlp.branding.jars}
+  </resources>
+  <component-desc/>
+</jnlp>  
--- a/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -1,7 +1,7 @@
-currentVersion=IdealGraphVisualizer {0}
-LBL_splash_window_title=Starting IdealGraphVisualizer
-SPLASH_WIDTH=475
-SplashProgressBarBounds=0,268,473,6
-SplashProgressBarColor=0xFFFFFF
-SplashRunningTextBounds=10,281,459,12
-SplashRunningTextColor=0xFFFFFF
+currentVersion=IdealGraphVisualizer {0}
+LBL_splash_window_title=Starting IdealGraphVisualizer
+SPLASH_WIDTH=475
+SplashProgressBarBounds=0,268,473,6
+SplashProgressBarColor=0xFFFFFF
+SplashRunningTextBounds=10,281,459,12
+SplashRunningTextColor=0xFFFFFF
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/master.jnlp	Wed Jun 08 17:26:49 2011 +0200
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc//DTD JNLP Discriptor 1.5//EN" "http://java.sun.com/dtd/JNLP-1.5.dtd">
+<jnlp spec="1.0+" codebase="$$codebase">
+  <information>
+      <title>${app.title}</title>
+      <vendor>${app.title} vendor</vendor>
+      <description>${app.name} application</description>
+      <icon href="${app.icon}"/>
+  </information>
+  <security><all-permissions/></security>
+  <resources>
+    <!-- The following property is needed when running with unsigned jars: -->
+    <property name="netbeans.jnlp.fixPolicy" value="${netbeans.jnlp.fixPolicy}"/>
+    <extension name='branding' href='branding.jnlp' />
+<!-- The following line will be replaced with an automatically generated list of resources: -->
+<!--${jnlp.resources}-->
+  </resources>
+  <resources os="Mac OS X">
+      <property name="netbeans.user" value="${user.home}/Library/Application Support/${app.name}"/>
+  </resources>
+  <application-desc>
+    <argument>--branding</argument>
+    <argument>${branding.token}</argument>
+  </application-desc>
+</jnlp>  
--- a/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Wed Jun 08 17:26:22 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Wed Jun 08 17:26:49 2011 +0200
@@ -1,3 +1,4 @@
+app.icon=branding/core/core.jar/org/netbeans/core/startup/frame48.gif
 app.name=idealgraphvisualizer
 app.title=IdealGraphVisualizer
 branding.token=${app.name}
@@ -14,10 +15,18 @@
     ${project.com.sun.hotspot.igv.difference}:\
     ${project.com.sun.hotspot.igv.settings}:\
     ${project.com.sun.hotspot.igv.util}:\
+    ${project.com.sun.hotspot.igv.rhino}:\
     ${project.com.sun.hotspot.igv.svg}:\
     ${project.com.sun.hotspot.connection}:\
-    ${project.com.sun.hotspot.igv.servercompiler}:\
+    ${project.com.sun.hotspot.igv.servercompilerscheduler}:\
     ${project.com.sun.hotspot.igv.filterwindow}:\
+    ${project.com.sun.hotspot.igv.graphtotext}:\
+    ${project.com.sun.hotspot.igv.maxine}:\
+    ${project.com.sun.hotspot.igv.java6scriptingproxy}:\
+    ${project.com.sun.hotspot.igv.graphtexteditor}:\
+    ${project.com.sun.hotspot.igv.structuredtext}:\
+    ${project.com.sun.hotspot.igv.texteditor}:\
+    ${project.com.sun.hotspot.igv.selectioncoordinator}:\
     ${project.at.ssw.visualizer.texteditor}
 project.at.ssw.visualizer.texteditor=Text Editor
 project.com.sun.hotspot.connection=NetworkConnection
@@ -29,12 +38,21 @@
 project.com.sun.hotspot.igv.filter=Filter
 project.com.sun.hotspot.igv.filterwindow=FilterWindow
 project.com.sun.hotspot.igv.graph=Graph
+project.com.sun.hotspot.igv.graphtexteditor=GraphTextEditor
+project.com.sun.hotspot.igv.graphtotext=GraphToText
 project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
+project.com.sun.hotspot.igv.java6scriptingproxy=Java6ScriptingProxy
 project.com.sun.hotspot.igv.layout=Layout
-project.com.sun.hotspot.igv.servercompiler=ServerCompiler
+project.com.sun.hotspot.igv.maxine=Maxine
+project.com.sun.hotspot.igv.rhino=RhinoScriptEngineProxy
+project.com.sun.hotspot.igv.selectioncoordinator=SelectionCoordinator
+project.com.sun.hotspot.igv.servercompilerscheduler=ServerCompiler
 project.com.sun.hotspot.igv.settings=Settings
+project.com.sun.hotspot.igv.structuredtext=StructuredText
 project.com.sun.hotspot.igv.svg=BatikSVGProxy
+project.com.sun.hotspot.igv.texteditor=TextEditor
 project.com.sun.hotspot.igv.view=View
 project.com.sun.hotspot.igv.util=Util
-run.args = -J-server -J-Xms64m -J-Xmx1g -J-da
-run.args.extra = -J-server -J-Xms64m -J-Xmx1g -J-da
+project.test=module1
+run.args = -J-client -J-Xms128m -J-Xmx512m -J-ea
+debug.args = -J-client -J-Xms128m -J-Xmx512m -J-ea