changeset 8373:9e7e29a28a10

Merge
author hseigel
date Sat, 09 May 2015 07:32:49 -0400
parents 6be387512c85 08b5dfe9bcb5
children 43fee4497230
files agent/src/share/classes/sun/jvm/hotspot/compiler/OopMap.java agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/bytecode.gif src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/link.gif src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/method.gif src/share/tools/IdealGraphVisualizer/Coordinator/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphCountGroupOrganizer.java src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardGroupOrganizer.java src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/StructuredViewAction.java src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/diff.gif src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/folder.gif src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/graph.gif src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/import.gif src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/remove.gif src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/removeall.gif src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/save.gif src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/structure.gif src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupOrganizer.java src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupReceiver.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/Filter/src/com/sun/hotspot/igv/filter/NullScriptEngine.java src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ScriptEngineAbstraction.java src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/add.gif src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/delete.gif src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/down.gif src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/minus.gif src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/plus.gif src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/up.gif src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Source.java src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/OldHierarchicalLayoutManager.java src/share/tools/IdealGraphVisualizer/NetworkConnection/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupReceiver src/share/tools/IdealGraphVisualizer/README src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/build.xml src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/manifest.mf src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/build-impl.xml src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/genfiles.properties src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.properties src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.xml src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/suite.properties src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/Bundle.properties src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/RhinoScriptEngine.java src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/layer.xml src/share/tools/IdealGraphVisualizer/ServerCompiler/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/JavaGroupOrganizer.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/Settings/src/com/sun/hotspot/igv/settings/settings.gif 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/images/export.gif src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/overview.gif src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/search.gif src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoomin.gif src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoomout.gif 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 527 files changed, 13624 insertions(+), 9228 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Fri May 08 23:51:37 2015 +0200
+++ b/.hgignore	Sat May 09 07:32:49 2015 -0400
@@ -6,5 +6,7 @@
 ^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/
 ^src/share/tools/IdealGraphVisualizer/build/
 ^src/share/tools/IdealGraphVisualizer/dist/
+^src/share/tools/IdealGraphVisualizer/nbplatform/
+.igv.log
 ^.hgtip
 .DS_Store
--- a/agent/src/share/classes/sun/jvm/hotspot/HSDB.java	Fri May 08 23:51:37 2015 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/HSDB.java	Sat May 09 07:32:49 2015 -0400
@@ -27,9 +27,7 @@
 import java.io.*;
 import java.awt.*;
 import java.awt.event.*;
-import java.math.*;
 import javax.swing.*;
-import javax.swing.tree.*;
 import java.util.*;
 
 import sun.jvm.hotspot.code.*;
@@ -928,7 +926,7 @@
             boolean shouldSkipOopMaps = false;
             if (curVFrame.isCompiledFrame()) {
               CodeBlob cb = VM.getVM().getCodeCache().findBlob(curFrame.getPC());
-              OopMapSet maps = cb.getOopMaps();
+              ImmutableOopMapSet maps = cb.getOopMaps();
               if ((maps == null) || (maps.getSize() == 0)) {
                 shouldSkipOopMaps = true;
               }
@@ -977,7 +975,7 @@
             } while (nextVFrame != null && nextFrame.equals(curFrame));
 
             if (shouldSkipOopMaps) {
-              anno = anno + "\nNOTE: null or empty OopMapSet found for this CodeBlob";
+              anno = anno + "\nNOTE: null or empty ImmutableOopMapSet found for this CodeBlob";
             }
 
             if (curFrame.getFP() != null) {
--- a/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java	Fri May 08 23:51:37 2015 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java	Sat May 09 07:32:49 2015 -0400
@@ -171,17 +171,17 @@
   public boolean isLockedByVM()         { return false; }
 
   /** OopMap for frame; can return null if none available */
-  public OopMapSet getOopMaps() {
+  public ImmutableOopMapSet getOopMaps() {
     Address oopMapsAddr = oopMapsField.getValue(addr);
     if (oopMapsAddr == null) {
       return null;
     }
-    return new OopMapSet(oopMapsAddr);
+    return new ImmutableOopMapSet(oopMapsAddr);
   }
   // FIXME: not yet implementable
-  //  void set_oop_maps(OopMapSet* p);
+  //  void set_oop_maps(ImmutableOopMapSet* p);
 
-  public OopMap getOopMapForReturnAddress(Address returnAddress, boolean debugging) {
+  public ImmutableOopMap getOopMapForReturnAddress(Address returnAddress, boolean debugging) {
     Address pc = returnAddress;
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(getOopMaps() != null, "nope");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMap.java	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2000, 2004, 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 sun.jvm.hotspot.compiler;
+
+import java.util.*;
+
+import sun.jvm.hotspot.code.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+
+public class ImmutableOopMap extends VMObject {
+  private static CIntegerField countField;
+  private static long classSize;
+
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static void initialize(TypeDataBase db) {
+    Type type = db.lookupType("ImmutableOopMap");
+    countField = type.getCIntegerField("_count");
+    classSize = type.getSize();
+  }
+
+  public ImmutableOopMap(Address addr) {
+    super(addr);
+  }
+
+  //--------------------------------------------------------------------------------
+  // Internals only below this point
+  //
+
+  long getCount() {
+    return countField.getValue(addr);
+  }
+
+  public Address getData() {
+    return addr.addOffsetTo(classSize);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapPair.java	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015, 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 sun.jvm.hotspot.compiler;
+
+import sun.jvm.hotspot.debugger.Address;
+import sun.jvm.hotspot.runtime.VM;
+import sun.jvm.hotspot.types.CIntegerField;
+import sun.jvm.hotspot.types.Type;
+import sun.jvm.hotspot.types.TypeDataBase;
+
+import java.util.Observable;
+import java.util.Observer;
+
+public class ImmutableOopMapPair {
+  private static CIntegerField pcField;
+  private static CIntegerField offsetField;
+  private static long classSize;
+
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+      public void update(Observable o, Object data) {
+        initialize(VM.getVM().getTypeDataBase());
+      }
+    });
+  }
+
+  private final Address address;
+
+  public ImmutableOopMapPair(Address address) {
+    this.address = address;
+  }
+
+  public static long classSize() {
+    return classSize;
+  }
+
+  public int getPC() {
+    return (int) pcField.getValue(address);
+  }
+
+  public int getOffset() {
+    return (int) offsetField.getValue(address);
+  }
+
+  private static void initialize(TypeDataBase db) {
+    Type type = db.lookupType("ImmutableOopMapSet");
+
+    pcField = type.getCIntegerField("_pc_offset");
+    offsetField = type.getCIntegerField("_oopmap_offset");
+    classSize = type.getSize();
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/ImmutableOopMapSet.java	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2000, 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 sun.jvm.hotspot.compiler;
+
+import java.util.*;
+
+import sun.jvm.hotspot.code.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class ImmutableOopMapSet extends VMObject {
+  private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.compiler.ImmutableOopMapSet.DEBUG") != null;
+
+  private static CIntegerField countField;
+  private static CIntegerField sizeField;
+  private static AddressField omDataField;
+  private static int REG_COUNT;
+  private static int SAVED_ON_ENTRY_REG_COUNT;
+  private static int C_SAVED_ON_ENTRY_REG_COUNT;
+  private static long classSize;
+
+  private static class MyVisitor implements OopMapVisitor {
+    private AddressVisitor addressVisitor;
+
+    public MyVisitor(AddressVisitor oopVisitor) {
+      setAddressVisitor(oopVisitor);
+    }
+
+    public void setAddressVisitor(AddressVisitor addressVisitor) {
+      this.addressVisitor = addressVisitor;
+    }
+
+    public void visitOopLocation(Address oopAddr) {
+      addressVisitor.visitAddress(oopAddr);
+    }
+
+    public void visitDerivedOopLocation(Address baseOopAddr, Address derivedOopAddr) {
+      if (VM.getVM().isClientCompiler()) {
+        Assert.that(false, "should not reach here");
+      } else if (VM.getVM().isServerCompiler() &&
+          VM.getVM().useDerivedPointerTable()) {
+        Assert.that(false, "FIXME: add derived pointer table");
+      }
+    }
+
+    public void visitValueLocation(Address valueAddr) {
+    }
+
+    public void visitNarrowOopLocation(Address narrowOopAddr) {
+      addressVisitor.visitCompOopAddress(narrowOopAddr);
+    }
+  }
+
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+      public void update(Observable o, Object data) {
+        initialize(VM.getVM().getTypeDataBase());
+      }
+    });
+  }
+
+  private static void initialize(TypeDataBase db) {
+    Type type = db.lookupType("ImmutableOopMapSet");
+
+    countField = type.getCIntegerField("_count");
+    sizeField = type.getCIntegerField("_size");
+    classSize = type.getSize();
+
+    if (!VM.getVM().isCore()) {
+      REG_COUNT = db.lookupIntConstant("REG_COUNT").intValue();
+      if (VM.getVM().isServerCompiler()) {
+        SAVED_ON_ENTRY_REG_COUNT = (int) db.lookupIntConstant("SAVED_ON_ENTRY_REG_COUNT").intValue();
+        C_SAVED_ON_ENTRY_REG_COUNT = (int) db.lookupIntConstant("C_SAVED_ON_ENTRY_REG_COUNT").intValue();
+      }
+    }
+  }
+
+  public ImmutableOopMapSet(Address addr) {
+    super(addr);
+  }
+
+  /**
+   * Returns the number of OopMaps in this ImmutableOopMapSet
+   */
+  public long getSize() {
+    return countField.getValue(addr);
+  }
+
+  public int getCount() { return (int) countField.getValue(addr); }
+
+  private Address dataStart() {
+    return (addr.addOffsetTo(ImmutableOopMapSet.classSize * getCount()));
+  }
+
+  public ImmutableOopMapPair pairAt(int index) {
+    Assert.that((index >= 0) && (index < getCount()), "bad index");
+    return new ImmutableOopMapPair(addr.addOffsetTo(index * ImmutableOopMapPair.classSize()));
+  }
+
+  /**
+   * returns the OopMap at a given index
+   */
+  public ImmutableOopMap getMapAt(int index) {
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that((index >= 0) && (index <= getSize()), "bad index");
+    }
+
+    ImmutableOopMapPair immutableOopMapPair = pairAt(index);
+    return getMap(immutableOopMapPair);
+  }
+
+  public ImmutableOopMap findMapAtOffset(long pcOffset, boolean debugging) {
+    int i;
+    int len = (int) getSize();
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(len > 0, "must have pointer maps");
+    }
+
+    // Scan through oopmaps. Stop when current offset is either equal or greater
+    // than the one we are looking for.
+    for (i = 0; i < len; i++) {
+      if (pairAt(i).getPC() >= pcOffset) {
+        break;
+      }
+    }
+
+    if (!debugging) {
+      if (Assert.ASSERTS_ENABLED) {
+        Assert.that(i < len, "oopmap not found for pcOffset = " + pcOffset + "; len = " + len);
+        Assert.that(pairAt(i).getPC() == pcOffset, "oopmap not found");
+      }
+    } else {
+      if (i == len) {
+        if (DEBUG) {
+          System.out.println("can't find oopmap at " + pcOffset);
+          System.out.print("Oopmap offsets are [ ");
+          for (i = 0; i < len; i++) {
+            System.out.print(pairAt(i).getPC());
+          }
+          System.out.println("]");
+        }
+        i = len - 1;
+        return getMapAt(i);
+      }
+    }
+
+    ImmutableOopMap m = getMapAt(i);
+    return m;
+  }
+
+  /**
+   * Visitation -- iterates through the frame for a compiled method.
+   * This is a very generic mechanism that requires the Address to be
+   * dereferenced by the callee. Other, more specialized, visitation
+   * mechanisms are given below.
+   */
+  public static void oopsDo(Frame fr, CodeBlob cb, RegisterMap regMap, AddressVisitor oopVisitor, boolean debugging) {
+    allDo(fr, cb, regMap, new MyVisitor(oopVisitor), debugging);
+  }
+
+  /**
+   * Note that there are 4 required AddressVisitors: one for oops,
+   * one for derived oops, one for values, and one for dead values
+   */
+  public static void allDo(Frame fr, CodeBlob cb, RegisterMap regMap, OopMapVisitor visitor, boolean debugging) {
+    if (Assert.ASSERTS_ENABLED) {
+      CodeBlob tmpCB = VM.getVM().getCodeCache().findBlob(fr.getPC());
+      Assert.that(tmpCB != null && cb.equals(tmpCB), "wrong codeblob passed in");
+    }
+
+    ImmutableOopMapSet maps = cb.getOopMaps();
+    ImmutableOopMap map = cb.getOopMapForReturnAddress(fr.getPC(), debugging);
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(map != null, "no ptr map found");
+    }
+
+    // handle derived pointers first (otherwise base pointer may be
+    // changed before derived pointer offset has been collected)
+    OopMapValue omv;
+    {
+      for (OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE); !oms.isDone(); oms.next()) {
+        if (VM.getVM().isClientCompiler()) {
+          Assert.that(false, "should not reach here");
+        }
+        omv = oms.getCurrent();
+        Address loc = fr.oopMapRegToLocation(omv.getReg(), regMap);
+        if (loc != null) {
+          Address baseLoc = fr.oopMapRegToLocation(omv.getContentReg(), regMap);
+          Address derivedLoc = loc;
+          visitor.visitDerivedOopLocation(baseLoc, derivedLoc);
+        }
+      }
+    }
+
+    // We want narow oop, value and oop oop_types
+    OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[]{
+        OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.VALUE_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
+    };
+
+    {
+      for (OopMapStream oms = new OopMapStream(map, values); !oms.isDone(); oms.next()) {
+        omv = oms.getCurrent();
+        Address loc = fr.oopMapRegToLocation(omv.getReg(), regMap);
+        if (loc != null) {
+          if (omv.getType() == OopMapValue.OopTypes.OOP_VALUE) {
+            // This assert commented out because this will be useful
+            // to detect in the debugging system
+            // assert(Universe::is_heap_or_null(*loc), "found non oop pointer");
+            visitor.visitOopLocation(loc);
+          } else if (omv.getType() == OopMapValue.OopTypes.VALUE_VALUE) {
+            visitor.visitValueLocation(loc);
+          } else if (omv.getType() == OopMapValue.OopTypes.NARROWOOP_VALUE) {
+            visitor.visitNarrowOopLocation(loc);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * Update callee-saved register info for the following frame.
+   * Should only be called in non-core builds.
+   */
+  public static void updateRegisterMap(Frame fr, CodeBlob cb, RegisterMap regMap, boolean debugging) {
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(!VM.getVM().isCore(), "non-core builds only");
+    }
+
+    if (!VM.getVM().isDebugging()) {
+      if (Assert.ASSERTS_ENABLED) {
+        ImmutableOopMapSet maps = cb.getOopMaps();
+        Assert.that((maps != null) && (maps.getSize() > 0), "found null or empty ImmutableOopMapSet for CodeBlob");
+      }
+    } else {
+      // Hack for some topmost frames that have been found with empty
+      // OopMapSets. (Actually have not seen the null case, but don't
+      // want to take any chances.) See HSDB.showThreadStackMemory().
+      ImmutableOopMapSet maps = cb.getOopMaps();
+      if ((maps == null) || (maps.getSize() == 0)) {
+        return;
+      }
+    }
+
+    // Check if caller must update oop argument
+    regMap.setIncludeArgumentOops(cb.callerMustGCArguments());
+
+    int nofCallee = 0;
+    Address[] locs = new Address[2 * REG_COUNT + 1];
+    VMReg[] regs = new VMReg[2 * REG_COUNT + 1];
+    // ("+1" because REG_COUNT might be zero)
+
+    // Scan through oopmap and find location of all callee-saved registers
+    // (we do not do update in place, since info could be overwritten)
+    ImmutableOopMap map = cb.getOopMapForReturnAddress(fr.getPC(), debugging);
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(map != null, "no ptr map found");
+    }
+
+    OopMapValue omv = null;
+    for (OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE); !oms.isDone(); oms.next()) {
+      omv = oms.getCurrent();
+      if (Assert.ASSERTS_ENABLED) {
+        Assert.that(nofCallee < 2 * REG_COUNT, "overflow");
+      }
+      regs[nofCallee] = omv.getContentReg();
+      locs[nofCallee] = fr.oopMapRegToLocation(omv.getReg(), regMap);
+      nofCallee++;
+    }
+
+    // Check that runtime stubs save all callee-saved registers
+    // After adapter frames were deleted C2 doesn't use callee save registers at present
+    if (Assert.ASSERTS_ENABLED) {
+      if (VM.getVM().isServerCompiler()) {
+        Assert.that(!cb.isRuntimeStub() ||
+                (nofCallee >= SAVED_ON_ENTRY_REG_COUNT || nofCallee >= C_SAVED_ON_ENTRY_REG_COUNT),
+            "must save all");
+      }
+    }
+
+    // Copy found callee-saved register to reg_map
+    for (int i = 0; i < nofCallee; i++) {
+      regMap.setLocation(regs[i], locs[i]);
+    }
+  }
+
+  public ImmutableOopMapPair getPairAt(int index) {
+    return pairAt(index);
+  }
+
+  public ImmutableOopMap getMap(ImmutableOopMapPair pair) {
+    Assert.that(pair.getOffset() < (int) sizeField.getValue(), "boundary check");
+    return new ImmutableOopMap(dataStart().addOffsetTo(pair.getOffset()));
+  }
+}
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMap.java	Fri May 08 23:51:37 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2000, 2004, 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 sun.jvm.hotspot.compiler;
-
-import java.util.*;
-
-import sun.jvm.hotspot.code.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-
-public class OopMap extends VMObject {
-  private static CIntegerField pcOffsetField;
-  private static CIntegerField omvCountField;
-  private static CIntegerField omvDataSizeField;
-  private static AddressField  omvDataField;
-  private static AddressField  compressedWriteStreamField;
-
-  // This is actually a field inside class CompressedStream
-  private static AddressField  compressedStreamBufferField;
-
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static void initialize(TypeDataBase db) {
-    Type type = db.lookupType("OopMap");
-
-    pcOffsetField              = type.getCIntegerField("_pc_offset");
-    omvCountField              = type.getCIntegerField("_omv_count");
-    omvDataSizeField           = type.getCIntegerField("_omv_data_size");
-    omvDataField               = type.getAddressField("_omv_data");
-    compressedWriteStreamField = type.getAddressField("_write_stream");
-
-    type = db.lookupType("CompressedStream");
-    compressedStreamBufferField = type.getAddressField("_buffer");
-  }
-
-  public OopMap(Address addr) {
-    super(addr);
-  }
-
-  public long getOffset() {
-    return pcOffsetField.getValue(addr);
-  }
-
-  //--------------------------------------------------------------------------------
-  // Internals only below this point
-  //
-
-  // Accessors -- package private for now
-  Address getOMVData() {
-    return omvDataField.getValue(addr);
-  }
-
-  long getOMVDataSize() {
-    return omvDataSizeField.getValue(addr);
-  }
-
-  long getOMVCount() {
-    return omvCountField.getValue(addr);
-  }
-
-  CompressedWriteStream getWriteStream() {
-    Address wsAddr = compressedWriteStreamField.getValue(addr);
-    if (wsAddr == null) {
-      return null;
-    }
-    Address bufferAddr = compressedStreamBufferField.getValue(wsAddr);
-    if (bufferAddr == null) {
-      return null;
-    }
-    return new CompressedWriteStream(bufferAddr);
-  }
-}
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapSet.java	Fri May 08 23:51:37 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,289 +0,0 @@
-/*
- * Copyright (c) 2000, 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 sun.jvm.hotspot.compiler;
-
-import java.util.*;
-
-import sun.jvm.hotspot.code.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-import sun.jvm.hotspot.utilities.*;
-
-public class OopMapSet extends VMObject {
-  private static final boolean DEBUG = System.getProperty("sun.jvm.hotspot.compiler.OopMapSet.DEBUG") != null;
-
-  private static CIntegerField omCountField;
-  private static CIntegerField omSizeField;
-  private static AddressField  omDataField;
-  private static int REG_COUNT;
-  private static int SAVED_ON_ENTRY_REG_COUNT;
-  private static int C_SAVED_ON_ENTRY_REG_COUNT;
-  private static class MyVisitor implements OopMapVisitor {
-    private AddressVisitor addressVisitor;
-
-    public MyVisitor(AddressVisitor oopVisitor) {
-      setAddressVisitor(oopVisitor);
-    }
-
-    public void setAddressVisitor(AddressVisitor addressVisitor) {
-      this.addressVisitor = addressVisitor;
-    }
-
-    public void visitOopLocation(Address oopAddr) {
-      addressVisitor.visitAddress(oopAddr);
-    }
-
-    public void visitDerivedOopLocation(Address baseOopAddr, Address derivedOopAddr) {
-      if (VM.getVM().isClientCompiler()) {
-        Assert.that(false, "should not reach here");
-      } else if (VM.getVM().isServerCompiler() &&
-                 VM.getVM().useDerivedPointerTable()) {
-        Assert.that(false, "FIXME: add derived pointer table");
-      }
-    }
-
-    public void visitValueLocation(Address valueAddr) {
-    }
-
-    public void visitNarrowOopLocation(Address narrowOopAddr) {
-      addressVisitor.visitCompOopAddress(narrowOopAddr);
-    }
-  }
-
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static void initialize(TypeDataBase db) {
-    Type type = db.lookupType("OopMapSet");
-
-    omCountField  = type.getCIntegerField("_om_count");
-    omSizeField   = type.getCIntegerField("_om_size");
-    omDataField   = type.getAddressField("_om_data");
-
-    if (!VM.getVM().isCore()) {
-      REG_COUNT = db.lookupIntConstant("REG_COUNT").intValue();
-      if (VM.getVM().isServerCompiler()) {
-        SAVED_ON_ENTRY_REG_COUNT = (int) db.lookupIntConstant("SAVED_ON_ENTRY_REG_COUNT").intValue();
-        C_SAVED_ON_ENTRY_REG_COUNT = (int) db.lookupIntConstant("C_SAVED_ON_ENTRY_REG_COUNT").intValue();
-      }
-    }
-  }
-
-  public OopMapSet(Address addr) {
-    super(addr);
-  }
-
-  /** Returns the number of OopMaps in this OopMapSet */
-  public long getSize() {
-    return omCountField.getValue(addr);
-  }
-
-  /** returns the OopMap at a given index */
-  public OopMap getMapAt(int index) {
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that((index >= 0) && (index <= getSize()),"bad index");
-    }
-    Address omDataAddr = omDataField.getValue(addr);
-    Address oopMapAddr = omDataAddr.getAddressAt(index * VM.getVM().getAddressSize());
-    if (oopMapAddr == null) {
-      return null;
-    }
-    return new OopMap(oopMapAddr);
-  }
-
-  public OopMap findMapAtOffset(long pcOffset, boolean debugging) {
-    int i;
-    int len = (int) getSize();
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(len > 0, "must have pointer maps");
-    }
-
-    // Scan through oopmaps. Stop when current offset is either equal or greater
-    // than the one we are looking for.
-    for (i = 0; i < len; i++) {
-      if (getMapAt(i).getOffset() >= pcOffset) {
-        break;
-      }
-    }
-
-    if (!debugging) {
-      if (Assert.ASSERTS_ENABLED) {
-        Assert.that(i < len, "oopmap not found for pcOffset = " + pcOffset + "; len = " + len);
-        Assert.that(getMapAt(i).getOffset() == pcOffset, "oopmap not found");
-      }
-    } else {
-      if (i == len) {
-        if (DEBUG) {
-          System.out.println("can't find oopmap at " + pcOffset);
-          System.out.print("Oopmap offsets are [ ");
-          for (i = 0; i < len; i++) {
-            System.out.print(getMapAt(i).getOffset());
-          }
-          System.out.println("]");
-        }
-        i = len - 1;
-        return getMapAt(i);
-      }
-    }
-
-    OopMap m = getMapAt(i);
-    return m;
-  }
-
-  /** Visitation -- iterates through the frame for a compiled method.
-      This is a very generic mechanism that requires the Address to be
-      dereferenced by the callee. Other, more specialized, visitation
-      mechanisms are given below. */
-  public static void oopsDo(Frame fr, CodeBlob cb, RegisterMap regMap, AddressVisitor oopVisitor, boolean debugging) {
-    allDo(fr, cb, regMap, new MyVisitor(oopVisitor), debugging);
-  }
-
-  /** Note that there are 4 required AddressVisitors: one for oops,
-      one for derived oops, one for values, and one for dead values */
-  public static void allDo(Frame fr, CodeBlob cb, RegisterMap regMap, OopMapVisitor visitor, boolean debugging) {
-    if (Assert.ASSERTS_ENABLED) {
-      CodeBlob tmpCB = VM.getVM().getCodeCache().findBlob(fr.getPC());
-      Assert.that(tmpCB != null && cb.equals(tmpCB), "wrong codeblob passed in");
-    }
-
-    OopMapSet maps = cb.getOopMaps();
-    OopMap map = cb.getOopMapForReturnAddress(fr.getPC(), debugging);
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(map != null, "no ptr map found");
-    }
-
-    // handle derived pointers first (otherwise base pointer may be
-    // changed before derived pointer offset has been collected)
-    OopMapValue omv;
-    {
-      for (OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.DERIVED_OOP_VALUE); !oms.isDone(); oms.next()) {
-        if (VM.getVM().isClientCompiler()) {
-          Assert.that(false, "should not reach here");
-        }
-        omv = oms.getCurrent();
-        Address loc = fr.oopMapRegToLocation(omv.getReg(), regMap);
-        if (loc != null) {
-          Address baseLoc    = fr.oopMapRegToLocation(omv.getContentReg(), regMap);
-          Address derivedLoc = loc;
-          visitor.visitDerivedOopLocation(baseLoc, derivedLoc);
-        }
-      }
-    }
-
-    // We want narow oop, value and oop oop_types
-    OopMapValue.OopTypes[] values = new OopMapValue.OopTypes[] {
-      OopMapValue.OopTypes.OOP_VALUE, OopMapValue.OopTypes.VALUE_VALUE, OopMapValue.OopTypes.NARROWOOP_VALUE
-    };
-
-    {
-      for (OopMapStream oms = new OopMapStream(map, values); !oms.isDone(); oms.next()) {
-        omv = oms.getCurrent();
-        Address loc = fr.oopMapRegToLocation(omv.getReg(), regMap);
-        if (loc != null) {
-          if (omv.getType() == OopMapValue.OopTypes.OOP_VALUE) {
-            // This assert commented out because this will be useful
-            // to detect in the debugging system
-            // assert(Universe::is_heap_or_null(*loc), "found non oop pointer");
-            visitor.visitOopLocation(loc);
-          } else if (omv.getType() == OopMapValue.OopTypes.VALUE_VALUE) {
-            visitor.visitValueLocation(loc);
-          } else if (omv.getType() == OopMapValue.OopTypes.NARROWOOP_VALUE) {
-            visitor.visitNarrowOopLocation(loc);
-          }
-        }
-      }
-    }
-  }
-
-  /** Update callee-saved register info for the following frame.
-      Should only be called in non-core builds. */
-  public static void updateRegisterMap(Frame fr, CodeBlob cb, RegisterMap regMap, boolean debugging) {
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(!VM.getVM().isCore(), "non-core builds only");
-    }
-
-    if (!VM.getVM().isDebugging()) {
-      if (Assert.ASSERTS_ENABLED) {
-        OopMapSet maps = cb.getOopMaps();
-        Assert.that((maps != null) && (maps.getSize() > 0), "found null or empty OopMapSet for CodeBlob");
-      }
-    } else {
-      // Hack for some topmost frames that have been found with empty
-      // OopMapSets. (Actually have not seen the null case, but don't
-      // want to take any chances.) See HSDB.showThreadStackMemory().
-      OopMapSet maps = cb.getOopMaps();
-      if ((maps == null) || (maps.getSize() == 0)) {
-        return;
-      }
-    }
-
-    // Check if caller must update oop argument
-    regMap.setIncludeArgumentOops(cb.callerMustGCArguments());
-
-    int nofCallee = 0;
-    Address[] locs = new Address[2 * REG_COUNT + 1];
-    VMReg  [] regs = new VMReg  [2 * REG_COUNT + 1];
-    // ("+1" because REG_COUNT might be zero)
-
-    // Scan through oopmap and find location of all callee-saved registers
-    // (we do not do update in place, since info could be overwritten)
-    OopMap map  = cb.getOopMapForReturnAddress(fr.getPC(), debugging);
-    if (Assert.ASSERTS_ENABLED) {
-      Assert.that(map != null, "no ptr map found");
-    }
-
-    OopMapValue omv = null;
-    for(OopMapStream oms = new OopMapStream(map, OopMapValue.OopTypes.CALLEE_SAVED_VALUE); !oms.isDone(); oms.next()) {
-      omv = oms.getCurrent();
-      if (Assert.ASSERTS_ENABLED) {
-        Assert.that(nofCallee < 2 * REG_COUNT, "overflow");
-      }
-      regs[nofCallee] = omv.getContentReg();
-      locs[nofCallee] = fr.oopMapRegToLocation(omv.getReg(), regMap);
-      nofCallee++;
-    }
-
-    // Check that runtime stubs save all callee-saved registers
-    // After adapter frames were deleted C2 doesn't use callee save registers at present
-    if (Assert.ASSERTS_ENABLED) {
-      if (VM.getVM().isServerCompiler()) {
-        Assert.that(!cb.isRuntimeStub() ||
-                    (nofCallee >= SAVED_ON_ENTRY_REG_COUNT || nofCallee >= C_SAVED_ON_ENTRY_REG_COUNT),
-                    "must save all");
-      }
-    }
-
-    // Copy found callee-saved register to reg_map
-    for (int i = 0; i < nofCallee; i++) {
-      regMap.setLocation(regs[i], locs[i]);
-    }
-  }
-}
--- a/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapStream.java	Fri May 08 23:51:37 2015 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/compiler/OopMapStream.java	Sat May 09 07:32:49 2015 -0400
@@ -28,30 +28,26 @@
 
 public class OopMapStream {
   private CompressedReadStream stream;
-  private OopMap oopMap;
+  private ImmutableOopMap oopMap;
   private int mask;
   private int size;
   private int position;
   private OopMapValue omv;
   private boolean omvValid;
 
-  public OopMapStream(OopMap oopMap) {
+  public OopMapStream(ImmutableOopMap oopMap) {
     this(oopMap, (OopMapValue.OopTypes[]) null);
   }
 
-  public OopMapStream(OopMap oopMap, OopMapValue.OopTypes type) {
+  public OopMapStream(ImmutableOopMap oopMap, OopMapValue.OopTypes type) {
     this(oopMap, (OopMapValue.OopTypes[]) null);
     mask = type.getValue();
   }
 
-  public OopMapStream(OopMap oopMap, OopMapValue.OopTypes[] types) {
-    if (oopMap.getOMVData() == null) {
-      stream = new CompressedReadStream(oopMap.getWriteStream().getBuffer());
-    } else {
-      stream = new CompressedReadStream(oopMap.getOMVData());
-    }
+  public OopMapStream(ImmutableOopMap oopMap, OopMapValue.OopTypes[] types) {
+    stream = new CompressedReadStream(oopMap.getData());
     mask = computeMask(types);
-    size = (int) oopMap.getOMVCount();
+    size = (int) oopMap.getCount();
     position = 0;
     omv = new OopMapValue();
     omvValid = false;
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java	Fri May 08 23:51:37 2015 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java	Sat May 09 07:32:49 2015 -0400
@@ -26,14 +26,12 @@
 
 import java.io.*;
 import java.util.*;
-import sun.jvm.hotspot.*;
+
 import sun.jvm.hotspot.code.*;
 import sun.jvm.hotspot.compiler.*;
-import sun.jvm.hotspot.c1.*;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.interpreter.*;
 import sun.jvm.hotspot.oops.*;
-import sun.jvm.hotspot.runtime.sparc.SPARCFrame;
 import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.utilities.*;
 
@@ -626,7 +624,7 @@
       Assert.that(cb != null, "sanity check");
     }
     if (cb.getOopMaps() != null) {
-      OopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging());
+      ImmutableOopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging());
 
       // FIXME: add in traversal of argument oops (skipping this for
       // now until we have the other stuff tested)
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java	Fri May 08 23:51:37 2015 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/ppc64/PPC64Frame.java	Sat May 09 07:32:49 2015 -0400
@@ -358,7 +358,7 @@
       map.setIncludeArgumentOops(cb.callerMustGCArguments());
 
       if (cb.getOopMaps() != null) {
-        OopMapSet.updateRegisterMap(this, cb, map, true);
+        ImmutableOopMapSet.updateRegisterMap(this, cb, map, true);
       }
     }
 
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java	Fri May 08 23:51:37 2015 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java	Sat May 09 07:32:49 2015 -0400
@@ -24,8 +24,6 @@
 
 package sun.jvm.hotspot.runtime.sparc;
 
-import java.util.*;
-
 import sun.jvm.hotspot.asm.sparc.*;
 import sun.jvm.hotspot.code.*;
 import sun.jvm.hotspot.compiler.*;
@@ -34,7 +32,6 @@
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.runtime.posix.*;
-import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.utilities.*;
 
 /** Specialization of and implementation of abstract methods of the
@@ -592,7 +589,7 @@
             map.setIncludeArgumentOops(true);
           }
           if (cb.getOopMaps() != null) {
-            OopMapSet.updateRegisterMap(this, cb, map, VM.getVM().isDebugging());
+            ImmutableOopMapSet.updateRegisterMap(this, cb, map, VM.getVM().isDebugging());
           }
         }
       }
--- a/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java	Fri May 08 23:51:37 2015 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java	Sat May 09 07:32:49 2015 -0400
@@ -385,7 +385,7 @@
       map.setIncludeArgumentOops(cb.callerMustGCArguments());
 
       if (cb.getOopMaps() != null) {
-        OopMapSet.updateRegisterMap(this, cb, map, true);
+        ImmutableOopMapSet.updateRegisterMap(this, cb, map, true);
       }
 
       // Since the prolog does the save and restore of EBP there is no oopmap
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Fri May 08 23:51:37 2015 +0200
+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java	Sat May 09 07:32:49 2015 -0400
@@ -31,11 +31,9 @@
 import sun.jvm.hotspot.compiler.*;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.interpreter.*;
-import sun.jvm.hotspot.memory.*;
 import sun.jvm.hotspot.oops.*;
 import sun.jvm.hotspot.runtime.*;
 import sun.jvm.hotspot.tools.jcore.*;
-import sun.jvm.hotspot.types.*;
 import sun.jvm.hotspot.utilities.*;
 
 public class HTMLGenerator implements /* imports */ ClassConstants {
@@ -887,7 +885,7 @@
       private Formatter buf;
       private SymbolFinder symFinder = createSymbolFinder();
       private long pc;
-      private OopMapSet oms;
+      private ImmutableOopMapSet oms;
       private CodeBlob blob;
       private NMethod nmethod;
 
@@ -954,13 +952,13 @@
 
          if (oms != null) {
             long base = addressToLong(blob.codeBegin());
-            for (int i = 0, imax = (int)oms.getSize(); i < imax; i++) {
-               OopMap om = oms.getMapAt(i);
-               long omspc = base + om.getOffset();
+            for (int i = 0, imax = oms.getCount(); i < imax; i++) {
+               ImmutableOopMapPair pair = oms.getPairAt(i);
+               long omspc = base + pair.getPC();
                if (omspc > pc) {
                   if (omspc <= endPc) {
                      buf.br();
-                     buf.append(genOopMapInfo(om));
+                     buf.append(genOopMapInfo(oms.getMap(pair)));
                      // st.move_to(column);
                      // visitor.print("; ");
                         // om.print_on(st);
@@ -1167,7 +1165,7 @@
         }
     }
 
-   protected String genHTMLForOopMap(OopMap map) {
+   protected String genHTMLForOopMap(ImmutableOopMap map) {
       final int stack0 = VMRegImpl.getStack0().getValue();
       Formatter buf = new Formatter(genHTML);
 
@@ -1237,11 +1235,11 @@
 
 
    protected String genOopMapInfo(NMethod nmethod, PCDesc pcDesc) {
-      OopMapSet mapSet = nmethod.getOopMaps();
+      ImmutableOopMapSet mapSet = nmethod.getOopMaps();
       if (mapSet == null || (mapSet.getSize() <= 0))
         return "";
       int pcOffset = pcDesc.getPCOffset();
-      OopMap map = mapSet.findMapAtOffset(pcOffset, VM.getVM().isDebugging());
+      ImmutableOopMap map = mapSet.findMapAtOffset(pcOffset, VM.getVM().isDebugging());
       if (map == null) {
          throw new IllegalArgumentException("no oopmap at safepoint!");
       }
@@ -1249,7 +1247,7 @@
       return genOopMapInfo(map);
    }
 
-   protected String genOopMapInfo(OopMap map) {
+   protected String genOopMapInfo(ImmutableOopMap map) {
      Formatter buf = new Formatter(genHTML);
      buf.beginTag("pre");
      buf.append("OopMap: ");
--- a/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Fri May 08 23:51:37 2015 +0200
+++ b/src/cpu/aarch64/vm/templateTable_aarch64.cpp	Sat May 09 07:32:49 2015 -0400
@@ -502,10 +502,17 @@
   __ neg(reg, reg);
 }
 
-void TemplateTable::iload()
-{
+void TemplateTable::iload() {
+  iload_internal();
+}
+
+void TemplateTable::nofast_iload() {
+  iload_internal(may_not_rewrite);
+}
+
+void TemplateTable::iload_internal(RewriteControl rc) {
   transition(vtos, itos);
-  if (RewriteFrequentPairs) {
+  if (RewriteFrequentPairs && rc == may_rewrite) {
     // TODO : check x86 code for what to do here
     __ call_Unimplemented();
   } else {
@@ -759,8 +766,15 @@
   __ ldr(r0, iaddress(n));
 }
 
-void TemplateTable::aload_0()
-{
+void TemplateTable::aload_0() {
+  aload_0_internal();
+}
+
+void TemplateTable::nofast_aload_0() {
+  aload_0_internal(may_not_rewrite);
+}
+
+void TemplateTable::aload_0_internal(RewriteControl rc) {
   // According to bytecode histograms, the pairs:
   //
   // _aload_0, _fast_igetfield
@@ -782,7 +796,7 @@
   //   aload_0, iload_1
   // These bytecodes with a small amount of code are most profitable
   // to rewrite
-  if (RewriteFrequentPairs) {
+  if (RewriteFrequentPairs && rc == may_rewrite) {
     __ call_Unimplemented();
   } else {
     aload(0);
@@ -2132,14 +2146,21 @@
   assert_different_registers(Rcache, index, temp);
 
   Label resolved;
+
+  Bytecodes::Code code = bytecode();
+  switch (code) {
+  case Bytecodes::_nofast_getfield: code = Bytecodes::_getfield; break;
+  case Bytecodes::_nofast_putfield: code = Bytecodes::_putfield; break;
+  }
+
   assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
   __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
-  __ cmp(temp, (int) bytecode());  // have we resolved this bytecode?
+  __ cmp(temp, (int) code);  // have we resolved this bytecode?
   __ br(Assembler::EQ, resolved);
 
   // resolve first time through
   address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_from_cache);
-  __ mov(temp, (int) bytecode());
+  __ mov(temp, (int) code);
   __ call_VM(noreg, entry, temp);
 
   // Update registers with resolved info
@@ -2257,7 +2278,7 @@
   __ verify_oop(r);
 }
 
-void TemplateTable::getfield_or_static(int byte_no, bool is_static)
+void TemplateTable::getfield_or_static(int byte_no, bool is_static, RewriteControl rc)
 {
   const Register cache = r2;
   const Register index = r3;
@@ -2287,11 +2308,14 @@
   assert(btos == 0, "change code, btos != 0");
   __ cbnz(flags, notByte);
 
+  // Don't rewrite getstatic, only getfield
+  if (is_static) rc = may_not_rewrite;
+
   // btos
   __ load_signed_byte(r0, field);
   __ push(btos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_bgetfield, bc, r1);
   }
   __ b(Done);
@@ -2302,7 +2326,7 @@
   // atos
   __ load_heap_oop(r0, field);
   __ push(atos);
-  if (!is_static) {
+  if (rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_agetfield, bc, r1);
   }
   __ b(Done);
@@ -2314,7 +2338,7 @@
   __ ldrw(r0, field);
   __ push(itos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_igetfield, bc, r1);
   }
   __ b(Done);
@@ -2326,7 +2350,7 @@
   __ load_unsigned_short(r0, field);
   __ push(ctos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_cgetfield, bc, r1);
   }
   __ b(Done);
@@ -2338,7 +2362,7 @@
   __ load_signed_short(r0, field);
   __ push(stos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_sgetfield, bc, r1);
   }
   __ b(Done);
@@ -2350,7 +2374,7 @@
   __ ldr(r0, field);
   __ push(ltos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_lgetfield, bc, r1);
   }
   __ b(Done);
@@ -2362,7 +2386,7 @@
   __ ldrs(v0, field);
   __ push(ftos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_fgetfield, bc, r1);
   }
   __ b(Done);
@@ -2376,7 +2400,7 @@
   __ ldrd(v0, field);
   __ push(dtos);
   // Rewrite bytecode to be faster
-  if (!is_static) {
+  if (rc == may_rewrite) {
     patch_bytecode(Bytecodes::_fast_dgetfield, bc, r1);
   }
 #ifdef ASSERT
@@ -2398,6 +2422,10 @@
   getfield_or_static(byte_no, false);
 }
 
+void TemplateTable::nofast_getfield(int byte_no) {
+  getfield_or_static(byte_no, false, may_not_rewrite);
+}
+
 void TemplateTable::getstatic(int byte_no)
 {
   getfield_or_static(byte_no, true);
@@ -2461,7 +2489,7 @@
   }
 }
 
-void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
+void TemplateTable::putfield_or_static(int byte_no, bool is_static, RewriteControl rc) {
   transition(vtos, vtos);
 
   const Register cache = r2;
@@ -2498,12 +2526,15 @@
   assert(btos == 0, "change code, btos != 0");
   __ cbnz(flags, notByte);
 
+  // Don't rewrite putstatic, only putfield
+  if (is_static) rc = may_not_rewrite;
+
   // btos
   {
     __ pop(btos);
     if (!is_static) pop_and_check_object(obj);
     __ strb(r0, field);
-    if (!is_static) {
+    if (rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_bputfield, bc, r1, true, byte_no);
     }
     __ b(Done);
@@ -2519,7 +2550,7 @@
     if (!is_static) pop_and_check_object(obj);
     // Store into the field
     do_oop_store(_masm, field, r0, _bs->kind(), false);
-    if (!is_static) {
+    if (rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_aputfield, bc, r1, true, byte_no);
     }
     __ b(Done);
@@ -2534,7 +2565,7 @@
     __ pop(itos);
     if (!is_static) pop_and_check_object(obj);
     __ strw(r0, field);
-    if (!is_static) {
+    if (rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_iputfield, bc, r1, true, byte_no);
     }
     __ b(Done);
@@ -2549,7 +2580,7 @@
     __ pop(ctos);
     if (!is_static) pop_and_check_object(obj);
     __ strh(r0, field);
-    if (!is_static) {
+    if (rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_cputfield, bc, r1, true, byte_no);
     }
     __ b(Done);
@@ -2564,7 +2595,7 @@
     __ pop(stos);
     if (!is_static) pop_and_check_object(obj);
     __ strh(r0, field);
-    if (!is_static) {
+    if (rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_sputfield, bc, r1, true, byte_no);
     }
     __ b(Done);
@@ -2579,7 +2610,7 @@
     __ pop(ltos);
     if (!is_static) pop_and_check_object(obj);
     __ str(r0, field);
-    if (!is_static) {
+    if (rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_lputfield, bc, r1, true, byte_no);
     }
     __ b(Done);
@@ -2594,7 +2625,7 @@
     __ pop(ftos);
     if (!is_static) pop_and_check_object(obj);
     __ strs(v0, field);
-    if (!is_static) {
+    if (rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_fputfield, bc, r1, true, byte_no);
     }
     __ b(Done);
@@ -2611,7 +2642,7 @@
     __ pop(dtos);
     if (!is_static) pop_and_check_object(obj);
     __ strd(v0, field);
-    if (!is_static) {
+    if (rc == may_rewrite) {
       patch_bytecode(Bytecodes::_fast_dputfield, bc, r1, true, byte_no);
     }
   }
@@ -2638,6 +2669,10 @@
   putfield_or_static(byte_no, false);
 }
 
+void TemplateTable::nofast_putfield(int byte_no) {
+  putfield_or_static(byte_no, false, may_not_rewrite);
+}
+
 void TemplateTable::putstatic(int byte_no) {
   putfield_or_static(byte_no, true);
 }
--- a/src/cpu/ppc/vm/vm_version_ppc.cpp	Fri May 08 23:51:37 2015 +0200
+++ b/src/cpu/ppc/vm/vm_version_ppc.cpp	Sat May 09 07:32:49 2015 -0400
@@ -629,7 +629,7 @@
   // Print the detection code.
   if (PrintAssembly) {
     ttyLocker ttyl;
-    tty->print_cr("Decoding dscr configuration stub at " INTPTR_FORMAT " before execution:", code);
+    tty->print_cr("Decoding dscr configuration stub at " INTPTR_FORMAT " before execution:", p2i(code));
     Disassembler::decode((u_char*)code, (u_char*)code_end, tty);
   }
 
--- a/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Fri May 08 23:51:37 2015 +0200
+++ b/src/cpu/x86/vm/c1_Runtime1_x86.cpp	Sat May 09 07:32:49 2015 -0400
@@ -1631,36 +1631,22 @@
 
         NOT_LP64(__ get_thread(thread);)
 
-        Address in_progress(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
-                                             PtrQueue::byte_offset_of_active()));
-
         Address queue_index(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
                                              PtrQueue::byte_offset_of_index()));
         Address buffer(thread, in_bytes(JavaThread::satb_mark_queue_offset() +
                                         PtrQueue::byte_offset_of_buf()));
 
-
         Label done;
         Label runtime;
 
         // Can we store original value in the thread's buffer?
 
-#ifdef _LP64
-        __ movslq(tmp, queue_index);
-        __ cmpq(tmp, 0);
-#else
-        __ cmpl(queue_index, 0);
-#endif
-        __ jcc(Assembler::equal, runtime);
-#ifdef _LP64
-        __ subq(tmp, wordSize);
-        __ movl(queue_index, tmp);
-        __ addq(tmp, buffer);
-#else
-        __ subl(queue_index, wordSize);
-        __ movl(tmp, buffer);
-        __ addl(tmp, queue_index);
-#endif
+        __ movptr(tmp, queue_index);
+        __ testptr(tmp, tmp);
+        __ jcc(Assembler::zero, runtime);
+        __ subptr(tmp, wordSize);
+        __ movptr(queue_index, tmp);
+        __ addptr(tmp, buffer);
 
         // prev_val (rax)
         f.load_argument(0, pre_val);
@@ -1713,6 +1699,7 @@
         assert(sizeof(*ct->byte_map_base) == sizeof(jbyte), "adjust this code");
 
         Label done;
+        Label enqueued;
         Label runtime;
 
         // At this point we know new_value is non-NULL and the new_value crosses regions.
@@ -1752,28 +1739,19 @@
 
         __ movb(Address(card_addr, 0), (int)CardTableModRefBS::dirty_card_val());
 
-        __ cmpl(queue_index, 0);
-        __ jcc(Assembler::equal, runtime);
-        __ subl(queue_index, wordSize);
+        const Register tmp = rdx;
+        __ push(rdx);
 
-        const Register buffer_addr = rbx;
-        __ push(rbx);
-
-        __ movptr(buffer_addr, buffer);
-
-#ifdef _LP64
-        __ movslq(rscratch1, queue_index);
-        __ addptr(buffer_addr, rscratch1);
-#else
-        __ addptr(buffer_addr, queue_index);
-#endif
-        __ movptr(Address(buffer_addr, 0), card_addr);
-
-        __ pop(rbx);
-        __ jmp(done);
+        __ movptr(tmp, queue_index);
+        __ testptr(tmp, tmp);
+        __ jcc(Assembler::zero, runtime);
+        __ subptr(tmp, wordSize);
+        __ movptr(queue_index, tmp);
+        __ addptr(tmp, buffer);
+        __ movptr(Address(tmp, 0), card_addr);
+        __ jmp(enqueued);
 
         __ bind(runtime);
-        __ push(rdx);
 #ifdef _LP64
         __ push(r8);
         __ push(r9);
@@ -1795,12 +1773,12 @@
         __ pop(r9);
         __ pop(r8);
 #endif
+        __ bind(enqueued);
         __ pop(rdx);
+
         __ bind(done);
-
         __ pop(rcx);
         __ pop(rax);
-
       }
       break;
 #endif // INCLUDE_ALL_GCS
--- a/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/build-impl.xml	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/build-impl.xml	Sat May 09 07:32:49 2015 -0400
@@ -4,6 +4,13 @@
 ***         EDIT ../build.xml INSTEAD         ***
 -->
 <project name="com.sun.hotspot.igv.svg-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/BatikSVGProxy/nbproject/genfiles.properties	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/genfiles.properties	Sat May 09 07:32:49 2015 -0400
@@ -1,8 +1,5 @@
-build.xml.data.CRC32=ebcf0422
-build.xml.script.CRC32=d7a2678d
-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=ebcf0422
-nbproject/build-impl.xml.script.CRC32=57997f94
-nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
+nbproject/build-impl.xml.script.CRC32=42ef3ff6
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
--- a/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/project.properties	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/project.properties	Sat May 09 07:32:49 2015 -0400
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/BatikSVG.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/BatikSVG.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -25,40 +25,58 @@
 
 import java.awt.Graphics2D;
 import java.io.Writer;
+import java.io.File;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
 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);
+                String batikJar = System.getenv().get("IGV_BATIK_JAR");
+                if (batikJar == null) {
+                    return null;
+                }
+                // Load batik in it's own class loader since some it's support jars interfere with the JDK
+                URL url = new File(batikJar).toURI().toURL();
+                ClassLoader cl = new URLClassLoader(new URL[] { url });
+                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) {
@@ -71,12 +89,22 @@
             return null;
         } catch (InstantiationException e) {
             return null;
+        } catch (MalformedURLException e) {
+            return null;
         }
     }
 
+    /**
+     * 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	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2008, 2015, 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/manifest.mf	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/manifest.mf	Sat May 09 07:32:49 2015 -0400
@@ -1,6 +1,6 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.bytecodes
-OpenIDE-Module-Layer: com/sun/hotspot/igv/bytecodes/layer.xml
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/bytecodes/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.bytecodes
+OpenIDE-Module-Layer: com/sun/hotspot/igv/bytecodes/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/bytecodes/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.properties	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.properties	Sat May 09 07:32:49 2015 -0400
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.xml	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.xml	Sat May 09 07:32:49 2015 -0400
@@ -15,12 +15,36 @@
                     </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/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.4</specification-version>
+                        <specification-version>1.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.39.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -28,7 +52,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.11</specification-version>
+                        <specification-version>6.34.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -36,7 +60,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.2.0.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -44,7 +68,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
+                        <specification-version>8.14.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>
@@ -52,7 +84,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.16</specification-version>
+                        <specification-version>6.39.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/Bundle.properties	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/Bundle.properties	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
-CTL_BytecodeViewAction=Open BytecodeView Window
-CTL_BytecodeViewTopComponent=BytecodeView Window
+CTL_BytecodeViewAction=Bytecode
+CTL_BytecodeViewTopComponent=Bytecode
 CTL_SelectBytecodesAction=Select nodes
-HINT_BytecodeViewTopComponent=This is a BytecodeView window
+HINT_BytecodeViewTopComponent=Shows the bytecode associated with the displayed graph.
 OpenIDE-Module-Name=Bytecodes
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -29,14 +29,14 @@
 import com.sun.hotspot.igv.data.Properties;
 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;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
-import org.openide.util.Utilities;
+import org.openide.util.ImageUtilities;
 
 /**
  *
@@ -49,29 +49,35 @@
     public BytecodeNode(InputBytecode bytecode, InputGraph graph, String bciValue) {
 
         super(Children.LEAF);
-        this.setDisplayName(bytecode.getBci() + " " + bytecode.getName());
+        String displayName = bytecode.getBci() + " " + bytecode.getName() + " " + bytecode.getOperands();
 
         bciValue = bytecode.getBci() + " " + bciValue;
         bciValue = bciValue.trim();
 
-        Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<InputNode>(graph.getNodes());
+        Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(graph.getNodes());
         StringPropertyMatcher matcher = new StringPropertyMatcher("bci", bciValue);
         List<InputNode> nodeList = selector.selectMultiple(matcher);
         if (nodeList.size() > 0) {
-            nodes = new HashSet<InputNode>();
+            nodes = new LinkedHashSet<>();
             for (InputNode n : nodeList) {
                 nodes.add(n);
             }
-            this.setDisplayName(this.getDisplayName() + " (" + nodes.size() + " nodes)");
+            displayName += " (" + nodes.size() + " nodes)";
         }
+
+        if (bytecode.getComment() != null) {
+            displayName += " // " + bytecode.getComment();
+        }
+
+        this.setDisplayName(displayName);
     }
 
     @Override
     public Image getIcon(int i) {
         if (nodes != null) {
-            return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/link.gif");
+            return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/link.png");
         } else {
-            return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/bytecode.gif");
+            return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/bytecode.png");
         }
     }
 
@@ -91,6 +97,7 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public <T extends Node.Cookie> T getCookie(Class<T> aClass) {
         if (aClass == SelectBytecodesCookie.class && nodes != null) {
             return (T) (new SelectBytecodesCookie(nodes));
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewAction.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewAction.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -37,6 +37,7 @@
         super(NbBundle.getMessage(BytecodeViewAction.class, "CTL_BytecodeViewAction"));
     }
 
+    @Override
     public void actionPerformed(ActionEvent evt) {
         TopComponent win = BytecodeViewTopComponent.findInstance();
         win.open();
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.form	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.form	Sat May 09 07:32:49 2015 -0400
@@ -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	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -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;
@@ -33,11 +34,7 @@
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
 import org.openide.explorer.view.BeanTreeView;
-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.util.*;
 import org.openide.windows.TopComponent;
 import org.openide.windows.WindowManager;
 
@@ -91,6 +88,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 +124,7 @@
 
     @Override
     public void componentOpened() {
-        Lookup.Template tpl = new Lookup.Template(Object.class);
+        Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<>(InputGraphProvider.class);
         result = Utilities.actionsGlobalContext().lookup(tpl);
         result.addLookupListener(this);
     }
@@ -147,23 +145,47 @@
         return PREFERRED_ID;
     }
 
+    @Override
     public ExplorerManager getExplorerManager() {
         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);
+    }
+
+    @Override
     public void resultChanged(LookupEvent lookupEvent) {
-        final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
-        if (p != null) {
+        final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
             SwingUtilities.invokeLater(new Runnable() {
+                @Override
                 public void run() {
-            InputGraph graph = p.getGraph();
-            if (graph != null) {
-                Group g = graph.getGroup();
-                rootNode.update(graph, g.getMethod());
-            }
-        }
+                if (p != null) {
+                    InputGraph graph = p.getGraph();
+                    if (graph != null) {
+                        Group g = graph.getGroup();
+                        rootNode.update(graph, g.getMethod());
+                        return;
+                    }
+                }
+                        rootNode.update(null, null);
+                    }
             });
-        }
+
     }
 
     final static class ResolvableHelper implements Serializable {
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/MethodNode.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/MethodNode.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -30,7 +30,7 @@
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
-import org.openide.util.Utilities;
+import org.openide.util.ImageUtilities;
 
 /**
  *
@@ -38,7 +38,7 @@
  */
 public class MethodNode extends AbstractNode {
 
-    private static class MethodNodeChildren extends Children.Keys {
+    private static class MethodNodeChildren extends Children.Keys<InputBytecode> {
 
         private InputMethod method;
         private InputGraph graph;
@@ -50,9 +50,8 @@
             this.graph = graph;
         }
 
-        protected Node[] createNodes(Object object) {
-            assert object instanceof InputBytecode;
-            InputBytecode bc = (InputBytecode) object;
+        @Override
+        protected Node[] createNodes(InputBytecode bc) {
             if (bc.getInlined() == null) {
                 return new Node[]{new BytecodeNode(bc, graph, bciString)};
             } else {
@@ -84,7 +83,7 @@
 
     @Override
     public Image getIcon(int i) {
-        return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/method.gif");
+        return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/method.png");
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -24,9 +24,9 @@
 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.actions.CookieAction;
 
@@ -36,22 +36,26 @@
  */
 public final class SelectBytecodesAction extends CookieAction {
 
+    @Override
     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());
         }
     }
 
+    @Override
     protected int mode() {
         return CookieAction.MODE_EXACTLY_ONE;
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SelectBytecodesAction.class, "CTL_SelectBytecodesAction");
     }
 
+    @Override
     protected Class[] cookieClasses() {
         return new Class[]{
             SelectBytecodesCookie.class
@@ -64,6 +68,7 @@
         putValue("noIconInMenu", Boolean.TRUE);
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -73,3 +78,4 @@
         return false;
     }
 }
+
--- a/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesCookie.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesCookie.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/bytecode.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/bytecode.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/link.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/link.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/method.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/method.png has changed
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/manifest.mf	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/manifest.mf	Sat May 09 07:32:49 2015 -0400
@@ -1,6 +1,6 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.controlflow
-OpenIDE-Module-Layer: com/sun/hotspot/igv/controlflow/layer.xml
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/controlflow/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.controlflow
+OpenIDE-Module-Layer: com/sun/hotspot/igv/controlflow/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/controlflow/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.xml	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.xml	Sat May 09 07:32:49 2015 -0400
@@ -31,12 +31,20 @@
                     </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/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.4</specification-version>
+                        <specification-version>1.16.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -52,7 +60,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
+                        <specification-version>8.14.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>
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockConnectionWidget.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockConnectionWidget.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -26,7 +26,9 @@
 import com.sun.hotspot.igv.data.InputBlockEdge;
 import com.sun.hotspot.igv.layout.Link;
 import com.sun.hotspot.igv.layout.Port;
+import java.awt.BasicStroke;
 import java.awt.Point;
+import java.awt.Stroke;
 import java.util.ArrayList;
 import java.util.List;
 import org.netbeans.api.visual.widget.ConnectionWidget;
@@ -37,12 +39,19 @@
  */
 public class BlockConnectionWidget extends ConnectionWidget implements Link {
 
+    private static final Stroke NORMAL_STROKE = new BasicStroke(1.0f);
+    private static final Stroke BOLD_STROKE = new BasicStroke(2.5f);
+    private static final Stroke DASHED_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, new float[]{5, 5}, 0);
+    private static final Stroke BOLD_DASHED_STROKE = new BasicStroke(2.5f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, new float[]{5, 5}, 0);
+
     private BlockWidget from;
     private BlockWidget to;
     private Port inputSlot;
     private Port outputSlot;
     private List<Point> points;
     private InputBlockEdge edge;
+    private boolean isDashed = false;
+    private boolean isBold = false;
 
     public BlockConnectionWidget(ControlFlowScene scene, InputBlockEdge edge) {
         super(scene);
@@ -67,6 +76,30 @@
         return outputSlot;
     }
 
+    public void setBold(boolean bold) {
+        this.isBold = bold;
+        updateStroke();
+    }
+
+    public void setDashed(boolean dashed) {
+        this.isDashed = dashed;
+        updateStroke();
+    }
+
+    private void updateStroke() {
+        Stroke stroke = NORMAL_STROKE;
+        if (isBold) {
+            if (isDashed) {
+                stroke = BOLD_DASHED_STROKE;
+            } else {
+                stroke = BOLD_STROKE;
+            }
+        } else if (isDashed) {
+            stroke = DASHED_STROKE;
+        }
+        setStroke(stroke);
+    }
+
     public void setControlPoints(List<Point> p) {
         this.points = p;
     }
@@ -80,4 +113,9 @@
     public String toString() {
         return "Connection[ " + from.toString() + " - " + to.toString() + "]";
     }
+
+    @Override
+    public boolean isVIP() {
+        return isBold;
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockWidget.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockWidget.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -31,6 +31,7 @@
 import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.Point;
+import java.awt.Rectangle;
 import org.netbeans.api.visual.border.BorderFactory;
 import org.netbeans.api.visual.model.ObjectState;
 import org.netbeans.api.visual.widget.LabelWidget;
@@ -41,13 +42,13 @@
  */
 public class BlockWidget extends LabelWidget implements Vertex {
 
-    public static final Dimension SIZE = new Dimension(20, 20);
+    public static final Dimension MIN_SIZE = new Dimension(20, 20);
     private InputBlock block;
     private Port inputSlot;
     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(Font.SANS_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;
@@ -59,29 +60,24 @@
         this.setLabel(block.getName());
         this.setForeground(NORMAL_FOREGROUND_COLOR);
         this.setBorder(BorderFactory.createLineBorder(1, NORMAL_FOREGROUND_COLOR));
-        this.setMinimumSize(SIZE);
-        this.setMaximumSize(SIZE);
+        this.setMinimumSize(MIN_SIZE);
 
         this.setFont(font);
+        this.setAlignment(Alignment.CENTER);
 
         final BlockWidget widget = this;
         inputSlot = new Port() {
-
             public Point getRelativePosition() {
-                return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
+                return new Point((int) (getSize().getWidth() / 2), (int) (getSize().getHeight() / 2));
             }
-
             public Vertex getVertex() {
                 return widget;
             }
         };
-
         outputSlot = new Port() {
-
             public Point getRelativePosition() {
-                return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
+                return new Point((int) (getSize().getWidth() / 2), (int) (getSize().getHeight() / 2));
             }
-
             public Vertex getVertex() {
                 return widget;
             }
@@ -101,7 +97,12 @@
     }
 
     public Dimension getSize() {
-        return SIZE;
+        Rectangle bounds = getBounds();
+        if (bounds != null) {
+            return bounds.getSize();
+        } else {
+            return MIN_SIZE;
+        }
     }
 
     public void setPosition(Point p) {
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/Bundle.properties	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/Bundle.properties	Sat May 09 07:32:49 2015 -0400
@@ -1,4 +1,4 @@
-CTL_ControlFlowAction=Open ControlFlow Window
-CTL_ControlFlowTopComponent=ControlFlow Window
-HINT_ControlFlowTopComponent=This is a ControlFlow window
+CTL_ControlFlowAction=Control Flow
+CTL_ControlFlowTopComponent=Control Flow
+HINT_ControlFlowTopComponent=Shows the blocks of the current graph.
 OpenIDE-Module-Name=ControlFlow
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowAction.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowAction.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -23,17 +23,17 @@
  */
 package com.sun.hotspot.igv.controlflow;
 
+import com.sun.hotspot.igv.data.InputBlockEdge;
 import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.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;
@@ -44,15 +44,14 @@
 import org.netbeans.api.visual.action.WidgetAction;
 import org.netbeans.api.visual.anchor.AnchorFactory;
 import org.netbeans.api.visual.anchor.AnchorShape;
-import org.netbeans.api.visual.layout.LayoutFactory;
 import org.netbeans.api.visual.router.RouterFactory;
 import org.netbeans.api.visual.widget.LayerWidget;
 import org.netbeans.api.visual.widget.Widget;
 import org.netbeans.api.visual.graph.GraphScene;
 import org.netbeans.api.visual.graph.layout.GraphLayout;
+import org.netbeans.api.visual.layout.LayoutFactory;
 import org.netbeans.api.visual.layout.SceneLayout;
 import org.netbeans.api.visual.widget.ConnectionWidget;
-import org.openide.util.Lookup;
 
 /**
  *
@@ -61,13 +60,12 @@
 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;
     private LayerWidget selectLayer;
     private WidgetAction hoverAction = this.createWidgetHoverAction();
-    private WidgetAction selectAction = ActionFactory.createSelectAction(this);
+    private WidgetAction selectAction = new DoubleClickSelectAction(this);
     private WidgetAction moveAction = ActionFactory.createMoveAction(null, this);
 
     public ControlFlowScene() {
@@ -111,27 +109,21 @@
             addNode(b);
         }
 
-        for (InputBlock b : g.getBlocks()) {
-            for (InputBlockEdge e : b.getOutputs()) {
-                addEdge(e);
-                assert g.getBlocks().contains(e.getFrom());
-                assert g.getBlocks().contains(e.getTo());
-                this.setEdgeSource(e, e.getFrom());
-                this.setEdgeTarget(e, e.getTo());
-            }
+        for (InputBlockEdge e : g.getBlockEdges()) {
+            addEdge(e);
+            assert g.getBlocks().contains(e.getFrom());
+            assert g.getBlocks().contains(e.getTo());
+            this.setEdgeSource(e, e.getFrom());
+            this.setEdgeTarget(e, e.getTo());
         }
 
-        GraphLayout layout = new HierarchicalGraphLayout();//GridGraphLayout();
+        GraphLayout<InputBlock, InputBlockEdge> layout = new HierarchicalGraphLayout<InputBlock, InputBlockEdge>();//GridGraphLayout();
         SceneLayout sceneLayout = LayoutFactory.createSceneGraphLayout(this, layout);
         sceneLayout.invokeLayout();
 
         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 +133,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) {
@@ -204,15 +196,19 @@
     }
 
     public void setNewLocation(Widget widget, Point location) {
-        Point originalLocation = getOriginalLocation(widget);
-        int xOffset = location.x - originalLocation.x;
-        int yOffset = location.y - originalLocation.y;
-        for (Widget w : this.selection) {
-            Point p = new Point(w.getPreferredLocation());
-            p.translate(xOffset, yOffset);
-            w.setPreferredLocation(p);
+        if (selection.contains(widget)) {
+            // move entire selection
+            Point originalLocation = getOriginalLocation(widget);
+            int xOffset = location.x - originalLocation.x;
+            int yOffset = location.y - originalLocation.y;
+            for (Widget w : selection) {
+                Point p = new Point(w.getPreferredLocation());
+                p.translate(xOffset, yOffset);
+                w.setPreferredLocation(p);
+            }
+        } else {
+            widget.setPreferredLocation(location);
         }
-
     }
 
     public Widget createSelectionWidget() {
@@ -271,7 +267,15 @@
     }
 
     protected Widget attachEdgeWidget(InputBlockEdge edge) {
-        ConnectionWidget w = new BlockConnectionWidget(this, edge);
+        BlockConnectionWidget w = new BlockConnectionWidget(this, edge);
+        switch (edge.getState()) {
+            case NEW:
+                w.setBold(true);
+                break;
+            case DELETED:
+                w.setDashed(true);
+                break;
+        }
         w.setRouter(RouterFactory.createDirectRouter());
         w.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
         edgeLayer.addChild(w);
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.form	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.form	Sat May 09 07:32:49 2015 -0400
@@ -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	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -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;
@@ -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<InputGraphProvider> tpl = new Lookup.Template<InputGraphProvider>(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 {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/DoubleClickSelectAction.java	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, 2015, 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 java.awt.Point;
+import java.awt.event.MouseEvent;
+import org.netbeans.api.visual.action.SelectProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ * Selection action that acts on double-click only. Does not support aiming.
+ *
+ * @author Peter Hofer
+ */
+public class DoubleClickSelectAction extends WidgetAction.LockedAdapter {
+
+    private final SelectProvider provider;
+
+    public DoubleClickSelectAction(SelectProvider provider) {
+        this.provider = provider;
+    }
+
+    protected boolean isLocked() {
+        return false;
+    }
+
+    @Override
+    public State mousePressed(Widget widget, WidgetMouseEvent event) {
+        if (event.getClickCount() >= 2 && (event.getButton() == MouseEvent.BUTTON1 || event.getButton() == MouseEvent.BUTTON2)) {
+            boolean invert = (event.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0;
+            Point point = event.getPoint();
+            if (provider.isSelectionAllowed(widget, point, invert)) {
+                provider.select(widget, point, invert);
+                return State.CHAIN_ONLY;
+            }
+        }
+        return State.REJECTED;
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/HierarchicalGraphLayout.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/HierarchicalGraphLayout.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -34,7 +34,7 @@
 import java.util.ArrayList;
 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;
@@ -76,6 +76,10 @@
         public void setControlPoints(List<Point> list) {
         // Do nothing for now
         }
+
+        public boolean isVIP() {
+            return false;
+        }
     }
 
     private class VertexWrapper implements Vertex {
@@ -127,6 +131,7 @@
         }
 
         public int compareTo(Vertex o) {
+            @SuppressWarnings("unchecked")
             VertexWrapper vw = (VertexWrapper) o;
             return node.toString().compareTo(vw.node.toString());
         }
@@ -138,8 +143,8 @@
 
     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()) {
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.properties	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.properties	Sat May 09 07:32:49 2015 -0400
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.xml	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.xml	Sat May 09 07:32:49 2015 -0400
@@ -1,126 +1,142 @@
-<?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.coordinator</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.difference</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/>
-                    <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.netbeans.api.progress</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <release-version>1</release-version>
-                        <specification-version>1.10.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.actions</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.6.1.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.awt</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.11.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.dialogs</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.5.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.explorer</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.11</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.filesystems</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.3</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.loaders</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.7</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.nodes</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.2.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.util</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.9.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.16</specification-version>
-                    </run-dependency>
-                </dependency>
-            </module-dependencies>
-            <public-packages/>
-        </data>
-    </configuration>
-</project>
+<?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.coordinator</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.connection</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.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.difference</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/>
+                    <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.netbeans.api.progress</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.actions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.21.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.30.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.18.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.explorer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.34.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.filesystems</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.46.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.loaders</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.14.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.39.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer	Fri May 08 23:51:37 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-com.sun.hotspot.igv.coordinator.StandardGroupOrganizer
-com.sun.hotspot.igv.coordinator.GraphCountGroupOrganizer
\ No newline at end of file
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/Bundle.properties	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/Bundle.properties	Sat May 09 07:32:49 2015 -0400
@@ -1,7 +1,6 @@
-
-AdvancedOption_DisplayName_Coordinator=Settings
-AdvancedOption_Tooltip_Coordinator=Visualization Tool Settings
-CTL_OutlineTopComponent=Outline Window
-CTL_SomeAction=test
-HINT_OutlineTopComponent=This is a Outline window
-OpenIDE-Module-Name=Coordinator
+AdvancedOption_DisplayName_Coordinator=Settings
+AdvancedOption_Tooltip_Coordinator=Visualization Tool Settings
+CTL_OutlineTopComponent=Outline
+CTL_SomeAction=test
+HINT_OutlineTopComponent=Displays loaded groups of graphs.
+OpenIDE-Module-Name=Coordinator
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -24,18 +24,13 @@
 package com.sun.hotspot.igv.coordinator;
 
 import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.data.*;
 import java.awt.Image;
-import java.util.ArrayList;
 import java.util.List;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
-import org.openide.util.Utilities;
+import org.openide.util.ImageUtilities;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
 
@@ -45,107 +40,72 @@
  */
 public class FolderNode extends AbstractNode {
 
-    private GroupOrganizer organizer;
     private InstanceContent content;
-    private List<Pair<String, List<Group>>> structure;
-    private List<String> subFolders;
     private FolderChildren children;
 
-    private static class FolderChildren extends Children.Keys implements ChangedListener<Group> {
+    private static class FolderChildren extends Children.Keys<FolderElement> implements ChangedListener {
 
-        private FolderNode parent;
-        private List<Group> registeredGroups;
+        private final Folder folder;
 
-        public void setParent(FolderNode parent) {
-            this.parent = parent;
-            this.registeredGroups = new ArrayList<Group>();
+        public FolderChildren(Folder folder) {
+            this.folder = folder;
+            folder.getChangedEvent().addListener(this);
         }
 
         @Override
-        protected Node[] createNodes(Object arg0) {
-
-            for(Group g : registeredGroups) {
-                g.getChangedEvent().removeListener(this);
-            }
-            registeredGroups.clear();
-
-            Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0;
-            if (p.getLeft().length() == 0) {
-
-                List<Node> curNodes = new ArrayList<Node>();
-                for (Group g : p.getRight()) {
-                    for (InputGraph graph : g.getGraphs()) {
-                        curNodes.add(new GraphNode(graph));
-                    }
-                    g.getChangedEvent().addListener(this);
-                    registeredGroups.add(g);
-                }
-
-                Node[] result = new Node[curNodes.size()];
-                for (int i = 0; i < curNodes.size(); i++) {
-                    result[i] = curNodes.get(i);
-                }
-                return result;
-
-            } else {
-                return new Node[]{new FolderNode(p.getLeft(), parent.organizer, parent.subFolders, p.getRight())};
+        protected Node[] createNodes(FolderElement e) {
+             if (e instanceof InputGraph) {
+                return new Node[]{new GraphNode((InputGraph) e)};
+            } else if (e instanceof Folder) {
+                 return new Node[]{new FolderNode((Folder) e)};
+             } else {
+                return null;
             }
         }
 
         @Override
         public void addNotify() {
-            this.setKeys(parent.structure);
+            this.setKeys(folder.getElements());
         }
 
-        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() {
-        return content;
+        @Override
+        public void changed(Object source) {
+            addNotify();
+         }
     }
 
     @Override
     public Image getIcon(int i) {
-        return Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.gif");
+        return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.png");
     }
 
-    protected FolderNode(String name, GroupOrganizer organizer, List<String> subFolders, List<Group> groups) {
-        this(name, organizer, subFolders, groups, new FolderChildren(), new InstanceContent());
+    protected FolderNode(Folder folder) {
+        this(folder, new FolderChildren(folder), new InstanceContent());
     }
 
-    private FolderNode(String name, GroupOrganizer organizer, List<String> oldSubFolders, final List<Group> groups, FolderChildren children, InstanceContent content) {
+    private FolderNode(final Folder folder, FolderChildren children, InstanceContent content) {
         super(children, new AbstractLookup(content));
-        children.setParent(this);
         this.content = content;
         this.children = children;
-        content.add(new RemoveCookie() {
-
-            public void remove() {
-                for (Group g : groups) {
-                    if (g.getDocument() != null) {
-                        g.getDocument().removeGroup(g);
-                    }
+        if (folder instanceof FolderElement) {
+            final FolderElement folderElement = (FolderElement) folder;
+            this.setDisplayName(folderElement.getName());
+            content.add(new RemoveCookie() {
+                @Override
+                public void remove() {
+                    folderElement.getParent().removeElement(folderElement);
                 }
-            }
-        });
-        init(name, organizer, oldSubFolders, groups);
+            });
+        }
     }
 
-    public void init(String name, GroupOrganizer organizer, List<String> oldSubFolders, List<Group> groups) {
+    public void init(String name, List<Group> groups) {
         this.setDisplayName(name);
-        this.organizer = organizer;
-        this.subFolders = new ArrayList<String>(oldSubFolders);
-        if (name.length() > 0) {
-            this.subFolders.add(name);
+        children.addNotify();
+
+        for (Group g : groups) {
+            content.add(g);
         }
-        structure = organizer.organize(subFolders, groups);
-        assert structure != null;
-        children.addNotify();
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphCountGroupOrganizer.java	Fri May 08 23:51:37 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +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.coordinator;
-
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.Pair;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class GraphCountGroupOrganizer implements GroupOrganizer {
-
-    public String getName() {
-        return "Graph count structure";
-    }
-
-    public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups) {
-
-        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>>();
-            for (Group g : groups) {
-                Integer cur = g.getGraphs().size();
-                if (!map.containsKey(cur)) {
-                    map.put(cur, new ArrayList<Group>());
-                }
-                map.get(cur).add(g);
-            }
-
-            SortedSet<Integer> keys = new TreeSet<Integer>(map.keySet());
-            for (Integer i : keys) {
-                result.add(new Pair<String, List<Group>>("Graph count " + i, map.get(i)));
-            }
-
-        } else if (subFolders.size() == 1) {
-            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);
-            }
-        } else if (subFolders.size() == 2) {
-            result.add(new Pair<String, List<Group>>("", groups));
-        }
-
-        return result;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphNode.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphNode.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -23,23 +23,27 @@
  */
 package com.sun.hotspot.igv.coordinator;
 
+import com.sun.hotspot.igv.coordinator.actions.CloneGraphAction;
 import com.sun.hotspot.igv.coordinator.actions.DiffGraphAction;
 import com.sun.hotspot.igv.coordinator.actions.DiffGraphCookie;
-import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
+import com.sun.hotspot.igv.coordinator.actions.GraphCloneCookie;
+import com.sun.hotspot.igv.coordinator.actions.GraphOpenCookie;
+import com.sun.hotspot.igv.coordinator.actions.GraphRemoveCookie;
 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;
 import org.openide.actions.OpenAction;
-import org.openide.cookies.OpenCookie;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
-import org.openide.nodes.Node;
+import org.openide.nodes.NodeAdapter;
+import org.openide.nodes.NodeEvent;
+import org.openide.nodes.NodeMemberEvent;
 import org.openide.nodes.Sheet;
+import org.openide.util.ImageUtilities;
 import org.openide.util.Lookup;
-import org.openide.util.Utilities;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
 
@@ -48,7 +52,6 @@
  * @author Thomas Wuerthinger
  */
 public class GraphNode extends AbstractNode {
-
     private InputGraph graph;
 
     /** Creates a new instance of GraphNode */
@@ -56,7 +59,7 @@
         this(graph, new InstanceContent());
     }
 
-    private GraphNode(final InputGraph graph, InstanceContent content) {
+    private GraphNode(InputGraph graph, InstanceContent content) {
         super(Children.LEAF, new AbstractLookup(content));
         this.graph = graph;
         this.setDisplayName(graph.getName());
@@ -66,19 +69,22 @@
 
         if (viewer != null) {
             // Action for opening the graph
-            content.add(new OpenCookie() {
-
-                public void open() {
-                    viewer.view(graph);
-                }
-            });
+            content.add(new GraphOpenCookie(viewer, graph));
         }
 
         // Action for removing a graph
-        content.add(new RemoveCookie() {
+        content.add(new GraphRemoveCookie(graph));
 
-            public void remove() {
-                graph.getGroup().removeGraph(graph);
+        // Action for diffing to the current graph
+        content.add(new DiffGraphCookie(graph));
+
+        // Action for cloning to the current graph
+        content.add(new GraphCloneCookie(viewer, graph));
+
+        this.addNodeListener(new NodeAdapter() {
+            @Override
+            public void childrenRemoved(NodeMemberEvent ev) {
+                GraphNode.this.graph = null;
             }
         });
     }
@@ -86,13 +92,17 @@
     @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;
     }
 
     @Override
     public Image getIcon(int i) {
-        return Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/graph.gif");
+        return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/graph.png");
     }
 
     @Override
@@ -101,30 +111,28 @@
     }
 
     @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)};
+        return new Action[]{(Action) DiffGraphAction.findObject(DiffGraphAction.class, true), (Action) CloneGraphAction.findObject(CloneGraphAction.class, true), (Action) OpenAction.findObject(OpenAction.class, true)};
     }
 
     @Override
     public Action getPreferredAction() {
         return (Action) OpenAction.findObject(OpenAction.class, true);
     }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof GraphNode) {
+            return (graph == ((GraphNode) obj).graph);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return graph.hashCode();
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.form	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.form	Sat May 09 07:32:49 2015 -0400
@@ -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"/>
@@ -14,28 +16,17 @@
 
   <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
   <SubComponents>
-    <Container class="javax.swing.JPanel" name="jPanel2">
+    <Container class="javax.swing.JScrollPane" name="treeView">
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BeanTreeView();"/>
+      </AuxValues>
       <Constraints>
         <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
           <BorderConstraints direction="Center"/>
         </Constraint>
       </Constraints>
 
-      <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
-      <SubComponents>
-        <Container class="javax.swing.JScrollPane" name="jScrollPane1">
-          <AuxValues>
-            <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BeanTreeView();"/>
-          </AuxValues>
-          <Constraints>
-            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
-              <BorderConstraints direction="Center"/>
-            </Constraint>
-          </Constraints>
-
-          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
-        </Container>
-      </SubComponents>
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
     </Container>
   </SubComponents>
 </Form>
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -23,37 +23,25 @@
  */
 package com.sun.hotspot.igv.coordinator;
 
-import com.sun.hotspot.igv.coordinator.actions.ImportAction;
-import com.sun.hotspot.igv.coordinator.actions.RemoveAction;
-import com.sun.hotspot.igv.coordinator.actions.RemoveAllAction;
-import com.sun.hotspot.igv.coordinator.actions.SaveAllAction;
-import com.sun.hotspot.igv.coordinator.actions.SaveAsAction;
-import com.sun.hotspot.igv.coordinator.actions.StructuredViewAction;
+import com.sun.hotspot.igv.connection.Server;
+import com.sun.hotspot.igv.coordinator.actions.*;
 import com.sun.hotspot.igv.data.GraphDocument;
-import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.services.GroupCallback;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import com.sun.hotspot.igv.data.services.GroupReceiver;
 import java.awt.BorderLayout;
-import java.awt.Component;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import javax.swing.BoxLayout;
-import javax.swing.JPanel;
 import javax.swing.UIManager;
 import javax.swing.border.Border;
 import org.openide.ErrorManager;
+import org.openide.actions.GarbageCollectAction;
 import org.openide.awt.Toolbar;
 import org.openide.awt.ToolbarPool;
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
 import org.openide.explorer.view.BeanTreeView;
-import org.openide.util.Lookup;
 import org.openide.util.LookupEvent;
 import org.openide.util.LookupListener;
 import org.openide.util.NbBundle;
@@ -72,7 +60,8 @@
     private ExplorerManager manager;
     private GraphDocument document;
     private FolderNode root;
-    private GroupOrganizer organizer;
+    private Server server;
+    private Server binaryServer;
 
     private OutlineTopComponent() {
         initComponents();
@@ -88,17 +77,9 @@
 
     private void initListView() {
         manager = new ExplorerManager();
-        organizer = new StandardGroupOrganizer();
-        root = new FolderNode("", organizer, new ArrayList<String>(), document.getGroups());
+        root = new FolderNode(document);
         manager.setRootContext(root);
-        ((BeanTreeView) this.jScrollPane1).setRootVisible(false);
-
-        document.getChangedEvent().addListener(new ChangedListener<GraphDocument>() {
-
-            public void changed(GraphDocument document) {
-                updateStructure();
-            }
-        });
+        ((BeanTreeView) this.treeView).setRootVisible(false);
 
         associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
     }
@@ -111,61 +92,41 @@
         this.add(toolbar, BorderLayout.NORTH);
 
         toolbar.add(ImportAction.get(ImportAction.class));
-        toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup()));
-        toolbar.add(RemoveAllAction.get(RemoveAllAction.class));
 
         toolbar.add(((NodeAction) SaveAsAction.get(SaveAsAction.class)).createContextAwareInstance(this.getLookup()));
         toolbar.add(SaveAllAction.get(SaveAllAction.class));
 
-        toolbar.add(StructuredViewAction.get(StructuredViewAction.class).getToolbarPresenter());
+        toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup()));
+        toolbar.add(RemoveAllAction.get(RemoveAllAction.class));
+
+        toolbar.add(GarbageCollectAction.get(GarbageCollectAction.class).getToolbarPresenter());
 
         for (Toolbar tb : ToolbarPool.getDefault().getToolbars()) {
             tb.setVisible(false);
         }
-
-        initOrganizers();
-    }
-
-    public void setOrganizer(GroupOrganizer organizer) {
-        this.organizer = organizer;
-        updateStructure();
-    }
-
-    private void initOrganizers() {
-
     }
 
     private void initReceivers() {
 
         final GroupCallback callback = new GroupCallback() {
 
+            @Override
             public void started(Group g) {
-                getDocument().addGroup(g);
+                synchronized(OutlineTopComponent.this) {
+                    getDocument().addElement(g);
+                }
             }
         };
 
-        Collection<? extends GroupReceiver> receivers = Lookup.getDefault().lookupAll(GroupReceiver.class);
-        if (receivers.size() > 0) {
-            JPanel panel = new JPanel();
-            panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
-
-            for (GroupReceiver r : receivers) {
-                Component c = r.init(callback);
-                panel.add(c);
-            }
-
-            jPanel2.add(panel, BorderLayout.PAGE_START);
-        }
-    }
-
-    private void updateStructure() {
-        root.init("", organizer, new ArrayList<String>(), document.getGroups());
+        server = new Server(getDocument(), callback, false);
+        binaryServer = new Server(getDocument(), callback, true);
     }
 
     public void clear() {
         document.clear();
     }
 
+    @Override
     public ExplorerManager getExplorerManager() {
         return manager;
     }
@@ -221,6 +182,25 @@
         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);
+    }
+
+    @Override
     public void resultChanged(LookupEvent lookupEvent) {
     }
 
@@ -228,7 +208,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
@@ -253,19 +233,13 @@
     // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
     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);
-
-        add(jPanel2, java.awt.BorderLayout.CENTER);
+        add(treeView, 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	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml	Sat May 09 07:32:49 2015 -0400
@@ -4,7 +4,7 @@
     <Row>
         <Toolbar name="Edit" position="1" visible="false"/>
         <Toolbar name="File" position="1" visible="false" />
-        <Toolbar name="Memory" position="1" visible="false" />
+        <Toolbar name="Memory" position="1" visible="true" />
     </Row>
     <Row>
         <Toolbar name="WorkspaceSwitcher" />
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardGroupOrganizer.java	Fri May 08 23:51:37 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +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.coordinator;
-
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import com.sun.hotspot.igv.data.Pair;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class StandardGroupOrganizer implements GroupOrganizer {
-
-    public String getName() {
-        return "-- None --";
-    }
-
-    public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups) {
-
-        List<Pair<String, List<Group>>> result = new ArrayList<Pair<String, List<Group>>>();
-
-        if (groups.size() == 1 && subFolders.size() > 0) {
-            result.add(new Pair<String, List<Group>>("", groups));
-        } else {
-            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);
-            }
-        }
-
-        return result;
-    }
-}
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/Bundle.properties	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/Bundle.properties	Sat May 09 07:32:49 2015 -0400
@@ -1,18 +1,10 @@
-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_SaveAsAction=Save selected methods...
-CTL_SaveAllAction=Save all...
-CTL_SaveFilterSettingsAction=Save filter settings...
-CTL_PropertiesAction=Open Properties Window
+CTL_RemoveAction=Remove selected graphs and groups
+CTL_RemoveAllAction=Remove all graphs and groups
+CTL_OutlineAction=Outline
+CTL_SaveAsAction=Save selected groups...
+CTL_SaveAllAction=Save all groups...
+CTL_PropertiesAction=Open Properties Window 
 CTL_NewFilterAction=New filter...
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/CloneGraphAction.java	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013, 2015, 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.coordinator.actions;
+
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CookieAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class CloneGraphAction extends CookieAction {
+
+    @Override
+    protected void performAction(Node[] activatedNodes) {
+        GraphCloneCookie c = activatedNodes[0].getCookie(GraphCloneCookie.class);
+        assert c != null;
+        c.openClone();
+    }
+
+    @Override
+    protected int mode() {
+        return CookieAction.MODE_EXACTLY_ONE;
+    }
+
+    @Override
+    protected boolean enable(Node[] activatedNodes) {
+        boolean b = super.enable(activatedNodes);
+        if (b) {
+            assert activatedNodes.length == 1;
+            GraphCloneCookie c = activatedNodes[0].getCookie(GraphCloneCookie.class);
+            assert c != null;
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public String getName() {
+        return "Open clone";
+    }
+
+    @Override
+    protected Class<?>[] cookieClasses() {
+        return new Class<?>[]{
+            GraphCloneCookie.class
+        };
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/coordinator/images/graph.png";
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
+
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphAction.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphAction.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -35,30 +35,49 @@
  */
 public final class DiffGraphAction extends CookieAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         DiffGraphCookie c = activatedNodes[0].getCookie(DiffGraphCookie.class);
+        assert c != null;
         c.openDiff();
     }
 
+    @Override
     protected int mode() {
         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;
+    }
+
+    @Override
     public String getName() {
         return NbBundle.getMessage(DiffGraphAction.class, "CTL_DiffGraphAction");
     }
 
-    protected Class[] cookieClasses() {
-        return new Class[]{
+    @Override
+    protected Class<?>[] cookieClasses() {
+        return new Class<?>[]{
             DiffGraphCookie.class
         };
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/diff.gif";
+        return "com/sun/hotspot/igv/coordinator/images/diff.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -68,3 +87,4 @@
         return false;
     }
 }
+
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphCookie.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphCookie.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -21,12 +21,13 @@
  * questions.
  *
  */
-
 package com.sun.hotspot.igv.coordinator.actions;
 
 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;
 
@@ -36,21 +37,30 @@
  */
 public class DiffGraphCookie implements Node.Cookie {
 
-    private InputGraph a;
-    private InputGraph b;
+    private InputGraph graph;
 
-    public DiffGraphCookie(InputGraph a, InputGraph b) {
-        this.a = a;
-        this.b = b;
+    public DiffGraphCookie(InputGraph graph) {
+        this.graph = graph;
+    }
+
+    private InputGraph getCurrentGraph() {
+        InputGraphProvider graphProvider = LookupHistory.getLast(InputGraphProvider.class);
+        if (graphProvider != null) {
+            return graphProvider.getGraph();
+        }
+        return null;
+    }
+
+    public boolean isPossible() {
+        return getCurrentGraph() != null;
     }
 
     public void openDiff() {
-
+        InputGraph other = getCurrentGraph();
         final GraphViewer viewer = Lookup.getDefault().lookup(GraphViewer.class);
-
-        if(viewer != null) {
-            InputGraph diffGraph = Difference.createDiffGraph(a, b);
-            viewer.view(diffGraph);
+        if (viewer != null) {
+            InputGraph diffGraph = Difference.createDiffGraph(other, graph);
+            viewer.view(diffGraph, true);
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/GraphCloneCookie.java	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013, 2015, 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.coordinator.actions;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.GraphViewer;
+import org.openide.nodes.Node;
+
+public class GraphCloneCookie implements Node.Cookie {
+
+    private final GraphViewer viewer;
+    private final InputGraph graph;
+
+    public GraphCloneCookie(GraphViewer viewer, InputGraph graph) {
+        this.viewer = viewer;
+        this.graph = graph;
+    }
+
+    public void openClone() {
+        viewer.view(graph, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/GraphOpenCookie.java	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011, 2015, 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.coordinator.actions;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.GraphViewer;
+import org.openide.cookies.OpenCookie;
+
+public class GraphOpenCookie implements OpenCookie {
+
+    private final GraphViewer viewer;
+    private final InputGraph graph;
+
+    public GraphOpenCookie(GraphViewer viewer, InputGraph graph) {
+        this.viewer = viewer;
+        this.graph = graph;
+    }
+
+    @Override
+    public void open() {
+        viewer.view(graph, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/GraphRemoveCookie.java	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011, 2015, 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.coordinator.actions;
+
+import com.sun.hotspot.igv.data.InputGraph;
+
+public class GraphRemoveCookie implements RemoveCookie {
+    private final InputGraph graph;
+
+    public GraphRemoveCookie(InputGraph graph) {
+        this.graph = graph;
+    }
+
+    @Override
+    public void remove() {
+        graph.getGroup().removeElement(graph);
+    }
+}
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -26,51 +26,54 @@
 
 import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
 import com.sun.hotspot.igv.data.GraphDocument;
+import com.sun.hotspot.igv.data.serialization.BinaryParser;
+import com.sun.hotspot.igv.data.serialization.GraphParser;
+import com.sun.hotspot.igv.data.serialization.ParseMonitor;
 import com.sun.hotspot.igv.data.serialization.Parser;
 import com.sun.hotspot.igv.settings.Settings;
-import com.sun.hotspot.igv.data.serialization.XMLParser;
 import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
 import javax.swing.Action;
 import javax.swing.JFileChooser;
 import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
 import javax.swing.filechooser.FileFilter;
 import org.netbeans.api.progress.ProgressHandle;
 import org.netbeans.api.progress.ProgressHandleFactory;
-import org.openide.DialogDisplayer;
-import org.openide.NotifyDescriptor;
+import org.openide.util.Exceptions;
 import org.openide.util.HelpCtx;
 import org.openide.util.NbBundle;
 import org.openide.util.RequestProcessor;
 import org.openide.util.actions.CallableSystemAction;
-import org.openide.xml.XMLUtil;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
 public final class ImportAction extends CallableSystemAction {
+    private static final int WORKUNITS = 10000;
 
     public static FileFilter getFileFilter() {
         return new FileFilter() {
 
+            @Override
             public boolean accept(File f) {
-                return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
+                return f.getName().toLowerCase().endsWith(".xml") || f.getName().toLowerCase().endsWith(".bgv") || f.isDirectory();
             }
 
+            @Override
             public String getDescription() {
-                return "XML files (*.xml)";
+                return "Graph files (*.xml, *.bgv)";
             }
         };
     }
 
+    @Override
     public void performAction() {
 
         JFileChooser fc = new JFileChooser();
@@ -86,84 +89,79 @@
             }
 
             Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
-
             try {
-                final XMLReader reader = XMLUtil.createXMLReader();
-                final FileInputStream inputStream = new FileInputStream(file);
-                final InputSource is = new InputSource(inputStream);
-
+                final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
                 final ProgressHandle handle = ProgressHandleFactory.createHandle("Opening file " + file.getName());
-                final int basis = 1000;
-                handle.start(basis);
-                final int start = inputStream.available();
-
-                final XMLParser.ParseMonitor parseMonitor = new XMLParser.ParseMonitor() {
-
-                    public void setProgress(double d) {
+                handle.start(WORKUNITS);
+                final long start = channel.size();
+                ParseMonitor monitor = new ParseMonitor() {
+                    @Override
+                    public void updateProgress() {
                         try {
-                            int curAvailable = inputStream.available();
-                            int prog = (int) (basis * (double) (start - curAvailable) / (double) start);
+                            int prog = (int) (WORKUNITS * (double) channel.position() / (double) start);
                             handle.progress(prog);
                         } catch (IOException ex) {
                         }
                     }
-
+                    @Override
                     public void setState(String state) {
-                        setProgress(0.0);
+                        updateProgress();
                         handle.progress(state);
                     }
                 };
-                final Parser parser = new Parser();
+                final GraphParser parser;
                 final OutlineTopComponent component = OutlineTopComponent.findInstance();
-
-                component.requestActive();
-
+                if (file.getName().endsWith(".xml")) {
+                    parser = new Parser(channel, monitor, null);
+                } else if (file.getName().endsWith(".bgv")) {
+                    parser = new BinaryParser(channel, monitor, component.getDocument(), null);
+                } else {
+                    parser = null;
+                }
                 RequestProcessor.getDefault().post(new Runnable() {
-
+                    @Override
                     public void run() {
-                        GraphDocument document = null;
                         try {
-                            document = parser.parse(reader, is, parseMonitor);
-                            parseMonitor.setState("Finishing");
-                            component.getDocument().addGraphDocument(document);
-                        } catch (SAXException ex) {
-                            String s = "Exception during parsing the XML file, could not load document!";
-                            if (ex instanceof XMLParser.MissingAttributeException) {
-                                XMLParser.MissingAttributeException e = (XMLParser.MissingAttributeException) ex;
-                                s += "\nMissing attribute \"" + e.getAttributeName() + "\"";
+                            final GraphDocument document = parser.parse();
+                            if (document != null) {
+                                SwingUtilities.invokeLater(new Runnable(){
+                                    @Override
+                                    public void run() {
+                                        component.requestActive();
+                                        component.getDocument().addGraphDocument(document);
+                                    }
+                                });
                             }
-                            ex.printStackTrace();
-                            NotifyDescriptor d = new NotifyDescriptor.Message(s, NotifyDescriptor.ERROR_MESSAGE);
-                            DialogDisplayer.getDefault().notify(d);
+                        } catch (IOException ex) {
+                            Exceptions.printStackTrace(ex);
                         }
                         handle.finish();
                     }
                 });
-
-            } catch (SAXException ex) {
-                ex.printStackTrace();
             } catch (FileNotFoundException ex) {
-                ex.printStackTrace();
+                Exceptions.printStackTrace(ex);
             } catch (IOException ex) {
-                ex.printStackTrace();
+                Exceptions.printStackTrace(ex);
             }
         }
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(ImportAction.class, "CTL_ImportAction");
     }
 
     public ImportAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Open an XML graph document");
+        putValue(Action.SHORT_DESCRIPTION, "Open XML graph document...");
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/import.gif";
+        return "com/sun/hotspot/igv/coordinator/images/import.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/OutlineAction.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/OutlineAction.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -24,7 +24,7 @@
 
 package com.sun.hotspot.igv.coordinator.actions;
 
-import com.sun.hotspot.igv.coordinator.*;
+import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
 import java.awt.event.ActionEvent;
 import javax.swing.AbstractAction;
 import org.openide.util.NbBundle;
@@ -40,6 +40,7 @@
         super(NbBundle.getMessage(OutlineAction.class, "CTL_OutlineAction"));
     }
 
+    @Override
     public void actionPerformed(ActionEvent evt) {
         TopComponent win = OutlineTopComponent.findInstance();
         win.open();
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -36,6 +36,7 @@
  */
 public final class RemoveAction extends NodeAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         for (Node n : activatedNodes) {
             RemoveCookie removeCookie = n.getCookie(RemoveCookie.class);
@@ -46,18 +47,20 @@
     }
 
     public RemoveAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Remove");
+        putValue(Action.SHORT_DESCRIPTION, "Remove selected graphs and groups");
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(RemoveAction.class, "CTL_RemoveAction");
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/remove.gif";
+        return "com/sun/hotspot/igv/coordinator/images/remove.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -67,6 +70,7 @@
         return false;
     }
 
+    @Override
     protected boolean enable(Node[] nodes) {
         return nodes.length > 0;
     }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAllAction.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAllAction.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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
@@ -40,20 +40,22 @@
 public final class RemoveAllAction extends CallableSystemAction {
 
 
+    @Override
     public String getName() {
-        return NbBundle.getMessage(RemoveAllAction.class, "CTL_ImportAction");
+        return NbBundle.getMessage(RemoveAllAction.class, "CTL_RemoveAllAction");
     }
 
     public RemoveAllAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Remove all methods");
+        putValue(Action.SHORT_DESCRIPTION, "Remove all graphs and groups");
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_SHIFT, InputEvent.CTRL_MASK));
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/removeall.gif";
+        return "com/sun/hotspot/igv/coordinator/images/removeall.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveCookie.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveCookie.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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
@@ -39,17 +39,19 @@
  */
 public final class SaveAllAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         final OutlineTopComponent component = OutlineTopComponent.findInstance();
         SaveAsAction.save(component.getDocument());
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SaveAllAction.class, "CTL_SaveAllAction");
     }
 
     public SaveAllAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Save all methods to XML file");
+        putValue(Action.SHORT_DESCRIPTION, "Save all groups to XML file...");
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
     }
 
@@ -58,6 +60,7 @@
         return "com/sun/hotspot/igv/coordinator/images/saveall.gif";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -28,12 +28,8 @@
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.serialization.Printer;
 import com.sun.hotspot.igv.settings.Settings;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
+import java.io.*;
+import javax.swing.Action;
 import javax.swing.JFileChooser;
 import org.openide.nodes.Node;
 import org.openide.util.HelpCtx;
@@ -47,12 +43,17 @@
  */
 public final class SaveAsAction extends NodeAction {
 
+    public SaveAsAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Save selected groups to XML file...");
+    }
+
+    @Override
     protected void performAction(Node[] activatedNodes) {
 
         GraphDocument doc = new GraphDocument();
         for (Node n : activatedNodes) {
             Group group = n.getLookup().lookup(Group.class);
-            doc.addGroup(group);
+            doc.addElement(group);
         }
 
         save(doc);
@@ -75,10 +76,10 @@
             }
             Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
             try {
-                Writer writer = new OutputStreamWriter(new FileOutputStream(file));
-                Printer p = new Printer();
-                p.export(writer, doc);
-                writer.close();
+                try (Writer writer = new OutputStreamWriter(new FileOutputStream(file))) {
+                    Printer p = new Printer();
+                    p.export(writer, doc);
+                }
             } catch (FileNotFoundException e) {
                 e.printStackTrace();
             } catch (IOException e) {
@@ -92,15 +93,17 @@
         return CookieAction.MODE_SOME;
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SaveAsAction.class, "CTL_SaveAsAction");
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/save.gif";
+        return "com/sun/hotspot/igv/coordinator/images/save.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -110,6 +113,7 @@
         return false;
     }
 
+    @Override
     protected boolean enable(Node[] nodes) {
 
         int cnt = 0;
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/StructuredViewAction.java	Fri May 08 23:51:37 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +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.coordinator.actions;
-
-import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import java.awt.Component;
-import java.awt.Image;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.swing.Action;
-import javax.swing.ButtonGroup;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JMenuItem;
-import javax.swing.JPopupMenu;
-import javax.swing.event.PopupMenuEvent;
-import javax.swing.event.PopupMenuListener;
-import org.openide.awt.DropDownButtonFactory;
-import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
-import org.openide.util.Utilities;
-import org.openide.util.actions.CallableSystemAction;
-
-public class StructuredViewAction extends CallableSystemAction {
-
-    private static JButton dropDownButton;
-    private static ButtonGroup buttonGroup;
-    private static JPopupMenu popup;
-    private MyMenuItemListener menuItemListener;
-    private Map<JMenuItem, GroupOrganizer> map;
-
-    public StructuredViewAction() {
-
-        putValue(Action.SHORT_DESCRIPTION, "Cluster nodes into blocks");
-    }
-
-    @Override
-    public Component getToolbarPresenter() {
-
-        Image iconImage = Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/structure.gif");
-        ImageIcon icon = new ImageIcon(iconImage);
-
-        popup = new JPopupMenu();
-
-        menuItemListener = new MyMenuItemListener();
-
-        buttonGroup = new ButtonGroup();
-
-        Collection<? extends GroupOrganizer> organizersCollection = Lookup.getDefault().lookupAll(GroupOrganizer.class);
-
-        List<GroupOrganizer> organizers = new ArrayList<GroupOrganizer>(organizersCollection);
-        Collections.sort(organizers, new Comparator<GroupOrganizer>() {
-            public int compare(GroupOrganizer a, GroupOrganizer b) {
-                return a.getName().compareTo(b.getName());
-            }
-        });
-
-        map = new HashMap<JMenuItem, GroupOrganizer>();
-
-        boolean first = true;
-        for(GroupOrganizer organizer : organizers) {
-            JCheckBoxMenuItem item = new JCheckBoxMenuItem(organizer.getName());
-            map.put(item, organizer);
-            item.addActionListener(menuItemListener);
-            buttonGroup.add(item);
-            popup.add(item);
-            if(first) {
-                item.setSelected(true);
-                first = false;
-            }
-        }
-
-        dropDownButton = DropDownButtonFactory.createDropDownButton(
-                new ImageIcon(
-                new BufferedImage(32, 32, BufferedImage.TYPE_BYTE_GRAY)),
-                popup);
-
-        dropDownButton.setIcon(icon);
-
-        dropDownButton.setToolTipText("Insert Layer Registration");
-
-        dropDownButton.addItemListener(new ItemListener() {
-
-            public void itemStateChanged(ItemEvent e) {
-                int state = e.getStateChange();
-                if (state == ItemEvent.SELECTED) {
-                    performAction();
-                }
-            }
-        });
-
-        dropDownButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                performAction();
-            }
-        });
-
-        popup.addPopupMenuListener(new PopupMenuListener() {
-
-            public void popupMenuCanceled(PopupMenuEvent e) {
-                dropDownButton.setSelected(false);
-            }
-
-            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
-                dropDownButton.setSelected(false);
-            }
-
-            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
-                dropDownButton.setSelected(true);
-            }
-        });
-
-        return dropDownButton;
-
-    }
-
-    private class MyMenuItemListener implements ActionListener {
-
-        public void actionPerformed(ActionEvent ev) {
-            JMenuItem item = (JMenuItem) ev.getSource();
-            GroupOrganizer organizer = map.get(item);
-            assert organizer != null : "Organizer must exist!";
-            OutlineTopComponent.findInstance().setOrganizer(organizer);
-        }
-    }
-
-
-    @Override
-    public void performAction() {
-        popup.show(dropDownButton, 0, dropDownButton.getHeight());
-    }
-
-    public String getName() {
-        return "Structured View";
-    }
-
-    public HelpCtx getHelpCtx() {
-        return HelpCtx.DEFAULT_HELP;
-    }
-
-    @Override
-    protected boolean asynchronous() {
-        return false;
-    }
-
-}
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/customLeftWsmode.xml	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/customLeftWsmode.xml	Sat May 09 07:32:49 2015 -0400
@@ -4,12 +4,8 @@
     <kind type="view" />
     <state type="joined" />
     <constraints>
-        <path orientation="horizontal" number="0" weight="0.779245283018868"/>
-        <path orientation="vertical" number="0" weight="0.7511825922421949"/>
-        <path orientation="horizontal" number="0" weight="0.5"/>
-        <path orientation="vertical" number="20" weight="0.7"/>
-        <path orientation="horizontal" number="40" weight="0.55"/>
-        <path orientation="horizontal" number="0" weight="0.2711864406779661"/>
+        <path orientation="horizontal" number="0" weight="0.2"/>
+        <path orientation="vertical" number="0" weight="0.75"/>
     </constraints>
     <bounds x="0" y="0" width="0" height="0" />
     <frame state="0"/>
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/diff.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/diff.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/folder.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/folder.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/graph.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/graph.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/import.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/import.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/remove.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/remove.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/removeall.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/removeall.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/save.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/save.png has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/saveall.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/structure.gif has changed
Binary file src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/structure.png has changed
--- a/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml	Sat May 09 07:32:49 2015 -0400
@@ -1,110 +1,194 @@
 <?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">
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
 <filesystem>
-    <attr name="Actions\Edit\com-sun-hotspot-igv-bytecodes-SelectBytecodesAction.instance\position" intvalue="200"/>
-    <attr name="Actions\Edit\org-netbeans-core-ui-sysopen-SystemOpenAction.instance\position" intvalue="100"/>
-    <attr name="Actions\Edit\org-openide-actions-CopyAction.instance\position" intvalue="1300"/>
-    <attr name="Actions\Edit\org-openide-actions-CutAction.instance\position" intvalue="1400"/>
-    <attr name="Actions\Edit\org-openide-actions-DeleteAction.instance\position" intvalue="1500"/>
-    <attr name="Actions\Edit\org-openide-actions-FindAction.instance\position" intvalue="1600"/>
-    <attr name="Actions\Edit\org-openide-actions-GotoAction.instance\position" intvalue="1700"/>
-    <attr name="Actions\Edit\org-openide-actions-PasteAction.instance\position" intvalue="1800"/>
-    <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">
-                <attr name="position" intvalue="700"/>
-            </file>
-            <file name="com-sun-hotspot-igv-coordinator-actions-SaveAllAction.instance">
-                <attr name="position" intvalue="800"/>
-            </file>
-            <file name="com-sun-hotspot-igv-coordinator-actions-ImportAction.instance">
-                <attr name="position" intvalue="1000"/>
-            </file>
+            <file name="com-sun-hotspot-igv-coordinator-actions-SaveAsAction.instance"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-SaveAllAction.instance"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-ImportAction.instance"/>
         </folder>
         <folder name="Edit">
-
-            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance">
-                <attr name="position" intvalue="1200"/>
-            </file>
+            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.instance"/>
         </folder>
         <folder name="Window">
             <file name="com-sun-hotspot-igv-coordinator-actions-OutlineAction.instance"/>
         </folder>
     </folder>
+    
     <folder name="Menu">
         <folder name="File">
+            <file name="Separator2.instance_hidden"/>
+            <file name="Separator3.instance_hidden"/>
+            <file name="SeparatorOpen.instance_hidden"/>
             <file name="com-sun-hotspot-igv-coordinator-actions-ImportAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/File/com-sun-hotspot-igv-coordinator-actions-ImportAction.instance"/>
                 <attr name="position" intvalue="100"/>
             </file>
-            <file name="MySeparator2.instance">
+            <file name="SeparatorSave.instance">
                 <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
-                <attr name="position" intvalue="300"/>
+                <attr name="position" intvalue="150"/>
             </file>
             <file name="com-sun-hotspot-igv-coordinator-actions-SaveAsAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/File/com-sun-hotspot-igv-coordinator-actions-SaveAsAction.instance"/>
-                <attr name="position" intvalue="300"/>
+                <attr name="position" intvalue="200"/>
             </file>
             <file name="com-sun-hotspot-igv-coordinator-actions-SaveAllAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/File/com-sun-hotspot-igv-coordinator-actions-SaveAllAction.instance"/>
-                <attr name="position" intvalue="400"/>
+                <attr name="position" intvalue="300"/>
             </file>
-            <file name="MySeparator3.instance">
+            <file name="SeparatorRemove.instance">
                 <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"/>
-            <file name="org-openide-actions-SaveAction.instance_hidden"/>
-            <file name="org-openide-actions-SaveAllAction.instance_hidden"/>
-            <file name="org-openide-actions-SaveAsAction.shadow_hidden"/>
-        </folder>
-        <folder name="Edit">
-            <file name="com-sun-hotspot-igv-coordinator-actions-SaveFilterSettingsAction.shadow">
-                <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-SaveFilterSettingsAction.instance"/>
+                <attr name="position" intvalue="350"/>
             </file>
             <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance"/>
+                <attr name="position" intvalue="400" />
             </file>
-            <file name="org-netbeans-core-actions-JumpNextAction.shadow_hidden"/>
-            <file name="org-netbeans-core-actions-JumpPrevAction.shadow_hidden"/>
-            <file name="org-openide-actions-CutAction.instance_hidden"/>
-            <file name="org-openide-actions-CopyAction.instance_hidden"/>
-            <file name="org-openide-actions-PasteAction.instance_hidden"/>
-            <file name="org-openide-actions-DeleteAction.instance_hidden"/>
-            <file name="org-openide-actions-FindAction.instance_hidden"/>
-            <file name="org-openide-actions-ReplaceAction.instance_hidden"/>
-            <file name="org-openide-actions-JumpNextAction.shadow_hidden"/>
-            <file name="org-openide-actions-JumpPrevAction.shadow_hidden"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.instance"/>
+                <attr name="position" intvalue="500" />
+            </file>
+            
+            <!-- Hidden menu entries from other modules -->
+            <file name="org-netbeans-modules-editor-ExportHtmlAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-openfile-OpenFileAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-openfile-RecentFileAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-print-action-PageSetupAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-print-action-PrintAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-CloseProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-CustomizeProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-NewFile.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-NewProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-OpenProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-RecentProjects.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-groups-GroupsMenu.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAction.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAllAction.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAsAction.shadow_hidden"/>
         </folder>
-        <file name="GoTo_hidden"/>
-        <folder name="View">
+        
+        <folder name="Edit">
+            <!-- Hidden menu entries from other modules -->
             <file name="Separator1.instance_hidden"/>
             <file name="Separator2.instance_hidden"/>
-            <file name="org-netbeans-core-actions-HTMLViewAction.instance_hidden"/>
-            <file name="org-netbeans-core-actions-LogAction.instance_hidden"/>
+            <file name="SeparatorAfterFindPrevious.instance_hidden"/>
+            <file name="SeparatorAfterProjectsSearch.instance_hidden"/>
+            <file name="WhereUsedAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindNextAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindPreviousAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindSelectionAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$PasteFormattedAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$SelectAllAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$SelectIdentifierAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$StartMacroRecordingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$StopMacroRecordingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-search-FindInFilesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-search-ReplaceInFilesAction.shadow_hidden"/>
+            <file name="org-openide-actions-CopyAction.shadow_hidden"/>
+            <file name="org-openide-actions-CutAction.shadow_hidden"/>
+            <file name="org-openide-actions-DeleteAction.shadow_hidden"/>
+            <file name="org-openide-actions-FindAction.shadow_hidden"/>
+            <file name="org-openide-actions-PasteAction.shadow_hidden"/>
+            <file name="org-openide-actions-ReplaceAction.shadow_hidden"/>
+            <file name="sep-before-reposearch.instance_hidden"/>
+        </folder>
+        
+        <folder name="View">
+            <!-- Hidden menu entries from other modules -->
+            <file name="Separator1.instance_hidden"/>
+            <file name="Separator2.instance_hidden"/>
+            <file name="org-netbeans-core-actions-HTMLViewAction.shadow_hidden"/>
+            <file name="org-netbeans-core-actions-LogAction.shadow_hidden"/>
+            <file name="org-netbeans-core-multiview-EditorsAction.instance_hidden"/>
             <file name="org-netbeans-core-windows-actions-ToolbarsListAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-NbCodeFoldingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-project-ui-SyncEditorWithViewsAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-versioning-ShowTextAnnotationsAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-versioning-diff-ShowDiffSidebarAction.shadow_hidden"/>
+            <file name="toggle-line-numbers.shadow_hidden"/>
+            <file name="toggle-non-printable-characters.shadow_hidden"/>
+            <file name="toggle-toolbar.shadow_hidden"/>
         </folder>
+        
+        <!-- Hidden menus -->
+        <folder name="GoTo_hidden"/>
+        <folder name="Source_hidden"/>
+        <folder name="Refactoring_hidden"/>
+        <folder name="BuildProject_hidden"/>
+        <folder name="RunProject_hidden"/>
+        <folder name="Versioning_hidden"/>
+        
+        <folder name="Tools">
+            <!-- Hidden menu entries from other modules -->
+            <file name="LibrariesCustomizerAction.shadow_hidden"/>
+            <file name="PaletteManager_hidden"/>
+            <file name="Separator1.instance_hidden"/>
+            <file name="Separator2.instance_hidden"/>
+            <file name="ServerManagerAction3.shadow_hidden"/>
+            <file name="VariablesCustomizerAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-autoupdate-ui-actions-PluginManagerAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-favorites-templates-TemplatesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-options-OptionsWindowAction-separatorBefore.instance_hidden"/>
+            <file name="org-netbeans-modules-xml-catalog-CatalogAction.shadow_hidden"/>
+            <file name="org-openide-actions-ToolsAction.shadow_hidden"/>
+        </folder>
+        
         <folder name="Window">
             <file name="OutlineAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-coordinator-actions-OutlineAction.instance"/>
             </file>
+            
+            <!-- Hidden menu entries from other modules -->
+            <file name="Debug_hidden"/>
+            <file name="Navigator_hidden"/>
+            <file name="Other_hidden"/>
+            <file name="Output_hidden"/>
+            <file name="ProgressListAction.shadow_hidden"/>
+            <file name="ShowPaletteAction.shadow_hidden"/>
+            <file name="SwitchToRecentDocumentAction.shadow_hidden"/>
+            <file name="Versioning_hidden"/>
+            <file name="org-netbeans-core-ide-ServicesTabAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-favorites-View.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-logical-tab-action.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-physical-tab-action.shadow_hidden"/>
+            <file name="org-netbeans-modules-tasklist-ui-TaskListAction.shadow_hidden"/>
+            <file name="CloneDocumentAction.shadow_hidden"/>
+        </folder>
+
+        <folder name="Help">
+            <!-- Hidden menu entries from other modules -->
+            <file name="Separator1.instance_hidden"/>
+            <file name="netbeans-kb.url_hidden"/>
+            <file name="org-netbeans-modules-autoupdate-ui-actions-CheckForUpdatesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-bugzilla-ReportNBIssueAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-usersguide-master.xml_hidden"/>
+            <file name="shortcuts.xml_hidden"/>
         </folder>
     </folder>
-    <folder name="Toolbars">
-        <file name="Standard.xml" url="StandardConfiguration.xml"/>
+
+    <folder name="OptionsDialog">
+        <!-- Hidden option tabs from other modules -->
+        <file name="Editor.instance_hidden"/>
+        <file name="FontsAndColors.instance_hidden"/>
+        <file name="General.instance_hidden"/>
+        <file name="Keymaps.instance_hidden"/>
+        <folder name="Advanced">
+            <file name="Files.instance_hidden"/>
+            <file name="IssueTracking.instance_hidden"/>
+            <file name="JavaScript.instance_hidden"/>
+            <file name="Spellchecker.instance_hidden"/>
+            <file name="TermAdvancedOption.instance_hidden"/>
+            <file name="ToDo.instance_hidden"/>
+            <file name="Versioning.instance_hidden"/>
+        </folder>
     </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/manifest.mf	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/manifest.mf	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.data
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/data/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.data
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/data/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- a/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.properties	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.properties	Sat May 09 07:32:49 2015 -0400
@@ -1,2 +1,8 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+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	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.xml	Sat May 09 07:32:49 2015 -0400
@@ -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	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -24,20 +24,22 @@
 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;
     }
 
+    @Override
     protected void fire(ChangedListener<T> l) {
         l.changed(object);
     }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEventProvider.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEventProvider.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, 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
@@ -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	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedListener.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -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	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2008, 2015, 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;
+    }
+
+    @Override
+    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	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Event.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -33,23 +33,48 @@
 public abstract class Event<L> {
 
     private List<L> listener;
+    private boolean fireEvents;
+    private boolean eventWasFired;
 
     public Event() {
-        listener = new ArrayList<L>();
+        listener = new ArrayList<>();
+        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<>(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();
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Folder.java	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2015, 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.List;
+
+public interface Folder {
+    List<? extends FolderElement> getElements();
+    void removeElement(FolderElement element);
+    void addElement(FolderElement group);
+    ChangedEvent<? extends Folder> getChangedEvent();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/FolderElement.java	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2015, 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;
+
+public interface FolderElement {
+
+    Folder getParent();
+    String getName();
+    void setParent(Folder parent);
+}
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -24,53 +24,36 @@
 package com.sun.hotspot.igv.data;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument> {
+public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument>, Folder {
 
-    private List<Group> groups;
+    private List<FolderElement> elements;
     private ChangedEvent<GraphDocument> changedEvent;
 
     public GraphDocument() {
-        groups = new ArrayList<Group>();
-        changedEvent = new ChangedEvent<GraphDocument>(this);
+        elements = new ArrayList<>();
+        changedEvent = new ChangedEvent<>(this);
     }
 
     public void clear() {
-        groups.clear();
+        elements.clear();
         getChangedEvent().fire();
     }
 
+    @Override
     public ChangedEvent<GraphDocument> getChangedEvent() {
         return changedEvent;
     }
 
-    public List<Group> getGroups() {
-        return Collections.unmodifiableList(groups);
-    }
-
-    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();
-        }
-    }
-
     public void addGraphDocument(GraphDocument document) {
-        for (Group g : document.groups) {
-            this.addGroup(g);
+        for (FolderElement e : document.elements) {
+            e.setParent(this);
+            this.addElement(e);
         }
         document.clear();
         getChangedEvent().fire();
@@ -80,12 +63,30 @@
     public String toString() {
         StringBuilder sb = new StringBuilder();
 
-        sb.append("GraphDocument: " + getProperties().toString() + " \n\n");
-        for (Group g : getGroups()) {
+        sb.append("GraphDocument: ").append(getProperties().toString()).append(" \n\n");
+        for (FolderElement g : getElements()) {
             sb.append(g.toString());
             sb.append("\n\n");
         }
 
         return sb.toString();
     }
+
+    @Override
+    public List<? extends FolderElement> getElements() {
+        return elements;
+    }
+
+    @Override
+    public void removeElement(FolderElement element) {
+        if (elements.remove(element)) {
+            getChangedEvent().fire();
+        }
+    }
+
+    @Override
+    public void addElement(FolderElement element) {
+        elements.add(element);
+        getChangedEvent().fire();
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -23,49 +23,36 @@
  */
 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;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class Group extends Properties.Entity implements ChangedEventProvider<Group> {
+public class Group extends Properties.Entity implements ChangedEventProvider<Group>, Folder, FolderElement {
 
-    private List<InputGraph> graphs;
+    private final List<FolderElement> elements;
+    private final List<InputGraph> graphs;
+
+    private InputMethod method;
     private transient ChangedEvent<Group> changedEvent;
-    private GraphDocument document;
-    private InputMethod method;
-    private String assembly;
+    private Folder parent;
 
-    public Group() {
-        graphs = new ArrayList<InputGraph>();
-        init();
-    }
+    public Group(Folder parent) {
+        elements = new ArrayList<>();
+        graphs = new ArrayList<>();
+        changedEvent = new ChangedEvent<>(this);
+        this.parent = parent;
 
-    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() {
         changedEvent.fire();
     }
 
-    public void setAssembly(String s) {
-        this.assembly = s;
-    }
-
-    public String getAssembly() {
-        return assembly;
-    }
-
     public void setMethod(InputMethod method) {
         this.method = method;
     }
@@ -74,68 +61,120 @@
         return method;
     }
 
-    void setDocument(GraphDocument document) {
-        this.document = document;
-    }
-
-    public GraphDocument getDocument() {
-        return document;
-    }
-
+    @Override
     public ChangedEvent<Group> getChangedEvent() {
         return changedEvent;
     }
 
-    public List<InputGraph> getGraphs() {
-        return Collections.unmodifiableList(graphs);
+    @Override
+    public List<FolderElement> getElements() {
+        return Collections.unmodifiableList(elements);
     }
 
-    public void addGraph(InputGraph g) {
-        assert g != null;
-        assert !graphs.contains(g);
-        graphs.add(g);
+    public int getGraphsCount() {
+        return elements.size();
+    }
+
+    @Override
+    public void addElement(FolderElement element) {
+        elements.add(element);
+        if (element instanceof InputGraph) {
+            graphs.add((InputGraph) element);
+        } else {
+
+        }
+        element.setParent(this);
         changedEvent.fire();
     }
 
-    public void removeGraph(InputGraph g) {
-        int index = graphs.indexOf(g);
-        if (index != -1) {
-            graphs.remove(g);
-            changedEvent.fire();
-        }
-    }
-
     public Set<Integer> getAllNodes() {
-        Set<Integer> result = new HashSet<Integer>();
-        for (InputGraph g : graphs) {
-            Set<Integer> ids = g.getNodesAsSet();
-            result.addAll(g.getNodesAsSet());
-            for (Integer i : ids) {
-                result.add(-i);
+        Set<Integer> result = new HashSet<>();
+        for (FolderElement e : elements) {
+            if (e instanceof InputGraph) {
+                InputGraph g = (InputGraph) e;
+                result.addAll(g.getNodesAsSet());
             }
         }
         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();
-        sb.append("Group " + getProperties().toString() + "\n");
-        for (InputGraph g : graphs) {
+        sb.append("Group ").append(getProperties()).append("\n");
+        for (FolderElement g : elements) {
             sb.append(g.toString());
-            sb.append("\n");
+            sb.append('\n');
         }
         return sb.toString();
     }
 
+    @Override
     public String getName() {
         return getProperties().get("name");
     }
+
+    public String getType() {
+        return getProperties().get("type");
+
+    }
+
+    InputGraph getPrev(InputGraph graph) {
+        InputGraph lastGraph = null;
+        for (FolderElement e : elements) {
+            if (e == graph) {
+                return lastGraph;
+            }
+            if (e instanceof InputGraph) {
+                lastGraph = (InputGraph) e;
+            }
+        }
+        return null;
+    }
+
+    InputGraph getNext(InputGraph graph) {
+        boolean found = false;
+        for (FolderElement e : elements) {
+            if (e == graph) {
+                found = true;
+            } else if (found && e instanceof InputGraph) {
+                return (InputGraph) e;
+            }
+        }
+        return null;
+    }
+
+    public InputGraph getLastGraph() {
+        InputGraph lastGraph = null;
+        for (FolderElement e : elements) {
+            if (e instanceof InputGraph) {
+                lastGraph = (InputGraph) e;
+            }
+        }
+        return lastGraph;
+    }
+
+    @Override
+    public Folder getParent() {
+         return parent;
+    }
+
+    @Override
+    public void removeElement(FolderElement element) {
+        if (elements.remove(element)) {
+            if (element instanceof InputGraph) {
+                graphs.remove((InputGraph) element);
+            }
+            changedEvent.fire();
+        }
+    }
+
+    public List<InputGraph> getGraphs() {
+        return graphs;
+    }
+
+    @Override
+    public void setParent(Folder parent) {
+        this.parent = parent;
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -23,12 +23,7 @@
  */
 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.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
@@ -37,104 +32,81 @@
 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;
 
-    public InputBlock(InputGraph graph, String name) {
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+
+        if (o == this) {
+            return true;
+        }
+
+        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<>();
+        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);
-        }
+        nodes = new ArrayList<>();
+        successors = new LinkedHashSet<>(2);
     }
 
     public String getName() {
         return name;
     }
 
-    public void setName(String s) {
-        name = s;
-    }
-
     public List<InputNode> getNodes() {
         return Collections.unmodifiableList(nodes);
     }
 
     public void addNode(int id) {
-        InputNode n = graph.getNode(id);
-        assert n != null;
-        graph.setBlock(n, this);
-        addNode(graph.getNode(id));
-    }
-
-    public void addNode(InputNode node) {
-        assert !nodes.contains(node);
+        InputNode node = graph.getNode(id);
+        assert node != null;
+        assert !nodes.contains(node) : "duplicate : " + node;
+        graph.setBlock(node, this);
         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);
+    @Override
+    public String toString() {
+        return "Block " + this.getName();
     }
 
-    public Set<InputBlockEdge> getOutputs() {
-        return Collections.unmodifiableSet(outputs);
-    }
-
-    // resolveBlockLinks must be called afterwards
-    public void addSuccessor(String name) {
-        successorNames.add(name);
-    }
-
-    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	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlockEdge.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -29,8 +29,15 @@
  */
 public class InputBlockEdge {
 
+    public enum State {
+        SAME,
+        NEW,
+        DELETED
+    }
+
     private InputBlock from;
     private InputBlock to;
+    private State state = State.SAME;
 
     public InputBlockEdge(InputBlock from, InputBlock to) {
         assert from != null;
@@ -47,13 +54,21 @@
         return to;
     }
 
+    public State getState() {
+        return state;
+    }
+
+    public void setState(State state) {
+        this.state = state;
+    }
+
     @Override
     public boolean equals(Object obj) {
-        if (obj instanceof InputBlockEdge && obj != null) {
+        if (obj != null && obj instanceof InputBlockEdge) {
             InputBlockEdge e = (InputBlockEdge) obj;
             return e.from.equals(from) && e.to.equals(to);
         }
-        return super.equals(obj);
+        return false;
     }
 
     @Override
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -31,11 +31,15 @@
 
     private int bci;
     private String name;
+    private String operands;
+    private String comment;
     private InputMethod inlined;
 
-    public InputBytecode(int bci, String name) {
+    public InputBytecode(int bci, String name, String operands, String comment) {
         this.bci = bci;
         this.name = name;
+        this.operands = operands;
+        this.comment = comment;
     }
 
     public InputMethod getInlined() {
@@ -53,4 +57,12 @@
     public String getName() {
         return name;
     }
+
+    public String getOperands() {
+        return operands;
+    }
+
+    public String getComment() {
+        return comment;
+    }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -23,6 +23,10 @@
  */
 package com.sun.hotspot.igv.data;
 
+import java.util.Comparator;
+import java.util.WeakHashMap;
+import java.lang.ref.WeakReference;
+
 /**
  *
  * @author Thomas Wuerthinger
@@ -30,21 +34,83 @@
 public class InputEdge {
 
     public enum State {
-
+        IMMUTABLE,
         SAME,
         NEW,
         DELETED
     }
-    private char toIndex;
-    private int from;
-    private int to;
+
+    public static final Comparator<InputEdge> OUTGOING_COMPARATOR = new Comparator<InputEdge>(){
+
+        @Override
+            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>(){
+
+        @Override
+            public int compare(InputEdge o1, InputEdge o2) {
+                if(o1.getToIndex() == o2.getToIndex()) {
+                    return o1.getFrom() - o2.getFrom();
+                }
+                return o1.getToIndex() - o2.getToIndex();
+            }
+    };
+
+    private final char toIndex;
+    private final char fromIndex;
+    private final int from;
+    private final int to;
+    private final String label;
+    private final String type;
     private State state;
 
     public InputEdge(char toIndex, int from, int to) {
+        this((char) 0, toIndex, from, to, null, null);
+    }
+
+    public InputEdge(char fromIndex, char toIndex, int from, int to) {
+        this(fromIndex, toIndex, from, to, null, null);
+    }
+
+    public InputEdge(char fromIndex, char toIndex, int from, int to, String label, String type) {
         this.toIndex = toIndex;
+        this.fromIndex = fromIndex;
         this.from = from;
         this.to = to;
         this.state = State.SAME;
+        this.label = label;
+        this.type = type.intern();
+    }
+
+    static WeakHashMap<InputEdge, WeakReference<InputEdge>> immutableCache = new WeakHashMap<>();
+
+    public static synchronized InputEdge createImmutable(char fromIndex, char toIndex, int from, int to, String label, String type) {
+        InputEdge edge = new InputEdge(fromIndex, toIndex, from, to, label, type, State.IMMUTABLE);
+        WeakReference<InputEdge> result = immutableCache.get(edge);
+        if (result != null) {
+            InputEdge edge2 = result.get();
+            if (edge2 != null) {
+                return edge2;
+            }
+        }
+        immutableCache.put(edge, new WeakReference<>(edge));
+        return edge;
+    }
+
+    public InputEdge(char fromIndex, char toIndex, int from, int to, String label, String type, State state) {
+        this.toIndex = toIndex;
+        this.fromIndex = fromIndex;
+        this.from = from;
+        this.to = to;
+        this.state = state;
+        this.label = label;
+        this.type = type;
     }
 
     public State getState() {
@@ -52,6 +118,9 @@
     }
 
     public void setState(State x) {
+        if (state == State.IMMUTABLE) {
+            throw new InternalError("Can't change immutable instances");
+        }
         this.state = x;
     }
 
@@ -59,6 +128,10 @@
         return toIndex;
     }
 
+    public char getFromIndex() {
+        return fromIndex;
+    }
+
     public String getName() {
         return "in" + toIndex;
     }
@@ -71,22 +144,35 @@
         return to;
     }
 
+    public String getLabel() {
+        return label;
+    }
+
+    public String getType() {
+        return type;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (o == null || !(o instanceof InputEdge)) {
             return false;
         }
         InputEdge conn2 = (InputEdge) o;
-        return conn2.toIndex == toIndex && conn2.from == from && conn2.to == to;
+        boolean result = conn2.fromIndex == fromIndex && conn2.toIndex == toIndex && conn2.from == from && conn2.to == to;
+        if (result && (state == State.IMMUTABLE || conn2.state == State.IMMUTABLE)) {
+            // Immutable instances must be exactly the same
+            return conn2.label == label && conn2.state == state;
+        }
+        return result;
     }
 
     @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	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -23,65 +23,141 @@
  */
 package com.sun.hotspot.igv.data;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class InputGraph extends Properties.Entity {
+public class InputGraph extends Properties.Entity implements FolderElement {
 
-    private HashMap<Integer, InputNode> nodes;
-    private ArrayList<InputEdge> edges;
-    private Group parent;
-    private HashMap<String, InputBlock> blocks;
-    private HashMap<Integer, InputBlock> nodeToBlock;
-    private boolean isDifferenceGraph;
+    private Map<Integer, InputNode> nodes;
+    private List<InputEdge> edges;
+    private Folder parent;
+    private Group parentGroup;
+    private Map<String, InputBlock> blocks;
+    private List<InputBlockEdge> blockEdges;
+    private Map<Integer, InputBlock> nodeToBlock;
 
-    public InputGraph(Group parent) {
-        this(parent, null);
+    public InputGraph(String name) {
+        setName(name);
+        nodes = new LinkedHashMap<>();
+        edges = new ArrayList<>();
+        blocks = new LinkedHashMap<>();
+        blockEdges = new ArrayList<>();
+        nodeToBlock = new LinkedHashMap<>();
     }
 
-    public InputGraph(Group parent, InputGraph last) {
-        this(parent, last, "");
+    @Override
+    public void setParent(Folder parent) {
+        this.parent = parent;
+        if (parent instanceof Group) {
+            assert this.parentGroup == null;
+            this.parentGroup = (Group) parent;
+        }
     }
 
-    private void clearBlocks() {
+    public InputBlockEdge addBlockEdge(InputBlock left, InputBlock right) {
+        InputBlockEdge edge = new InputBlockEdge(left, right);
+        blockEdges.add(edge);
+        left.addSuccessor(right);
+        return edge;
+    }
+
+    public List<InputNode> findRootNodes() {
+        List<InputNode> result = new ArrayList<>();
+        Set<Integer> nonRoot = new HashSet<>();
+        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<>(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<>(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<>();
+
+        for(InputEdge e : this.edges) {
+            if(e.getFrom() == n.getId()) {
+                result.add(e);
+            }
+        }
+
+        Collections.sort(result, InputEdge.OUTGOING_COMPARATOR);
+
+        return result;
+    }
+
+    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) {
+    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";
 
-            for (InputNode n : last.getNodes()) {
-                addNode(n);
-            }
-
-            for (InputEdge c : last.getEdges()) {
-                addEdge(c);
-            }
+        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");
-        Set<InputNode> scheduledNodes = new HashSet<InputNode>();
+    public void ensureNodesInBlocks() {
+        InputBlock noBlock = null;
+        Set<InputNode> scheduledNodes = new HashSet<>();
 
-        for (InputBlock b : newBlocks) {
+        for (InputBlock b : getBlocks()) {
             for (InputNode n : b.getNodes()) {
                 assert !scheduledNodes.contains(n);
                 scheduledNodes.add(n);
@@ -91,18 +167,11 @@
         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 +185,28 @@
     }
 
     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) {
-            return null;
-        } else {
-            return list.get(index + 1);
-        }
+        return parentGroup.getNext(this);
     }
 
     public InputGraph getPrev() {
-        List<InputGraph> list = parent.getGraphs();
-        if (!list.contains(this)) {
-            return null;
-        }
-        int index = list.indexOf(this);
-        if (index == 0) {
-            return null;
-        } else {
-            return list.get(index - 1);
-        }
+        return parentGroup.getPrev(this);
     }
 
+    private void setName(String name) {
+        this.getProperties().setProperty("name", name);
+    }
+
+    @Override
     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());
     }
@@ -186,25 +236,22 @@
     }
 
     public void removeEdge(InputEdge c) {
-        assert edges.contains(c);
-        edges.remove(c);
-        assert !edges.contains(c);
+        boolean removed = edges.remove(c);
+        assert removed;
     }
 
     public void addEdge(InputEdge c) {
-        assert !edges.contains(c);
         edges.add(c);
-        assert edges.contains(c);
     }
 
     public Group getGroup() {
-        return parent;
+        return parentGroup;
     }
 
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("Graph " + getName() + " " + getProperties().toString() + "\n");
+        sb.append("Graph ").append(getName()).append(" ").append(getProperties().toString()).append("\n");
         for (InputNode n : nodes.values()) {
             sb.append(n.toString());
             sb.append("\n");
@@ -214,35 +261,31 @@
             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 Collection<InputBlockEdge> getBlockEdges() {
+        return Collections.unmodifiableList(blockEdges);
     }
 
-    public void setIsDifferenceGraph(boolean b) {
-        isDifferenceGraph = b;
+    @Override
+    public Folder getParent() {
+        return parent;
     }
 }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -23,10 +23,11 @@
  */
 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;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  *
@@ -42,14 +43,37 @@
     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;
         this.name = name;
         this.bci = bci;
         this.shortName = shortName;
-        inlined = new ArrayList<InputMethod>();
-        bytecodes = new ArrayList<InputBytecode>();
+        inlined = new ArrayList<>();
+        bytecodes = new ArrayList<>();
     }
 
     public List<InputBytecode> getBytecodes() {
@@ -87,31 +111,42 @@
     }
 
     public void setBytecodes(String text) {
+        Pattern instruction = Pattern.compile("\\s*(\\d+)\\s*:?\\s*(\\w+)\\s*(.*)(?://(.*))?");
+        String[] strings = text.split("\n");
+        int oldBci = -1;
+        for (String s : strings) {
+            if (s.startsWith(" ")) {
+                // indented lines are extra textual information
+                continue;
+            }
+            s = s.trim();
+            if (s.length() != 0) {
+                final Matcher matcher = instruction.matcher(s);
+                if (matcher.matches()) {
+                    String bciString = matcher.group(1);
+                    String opcode = matcher.group(2);
+                    String operands = matcher.group(3).trim();
+                    String comment = matcher.group(4);
+                    if (comment != null) {
+                        comment = comment.trim();
+                    }
 
-        String[] strings = text.split("\n");
-        int oldNumber = -1;
-        for (String s : strings) {
+                    int bci = Integer.parseInt(bciString);
 
-            if (s.length() > 0 && Character.isDigit(s.charAt(0))) {
-                s = s.trim();
-                int spaceIndex = s.indexOf(' ');
-                String numberString = s.substring(0, spaceIndex);
-                String tmpName = s.substring(spaceIndex + 1, s.length());
+                    // assert correct order of bytecodes
+                    assert bci > oldBci;
 
-                int number = -1;
-                number = Integer.parseInt(numberString);
+                    InputBytecode bc = new InputBytecode(bci, opcode, operands, comment);
+                    bytecodes.add(bc);
 
-                // assert correct order of bytecodes
-                assert number > oldNumber;
-
-                InputBytecode bc = new InputBytecode(number, tmpName);
-                bytecodes.add(bc);
-
-                for (InputMethod m : inlined) {
-                    if (m.getBci() == number) {
-                        bc.setInlined(m);
-                        break;
+                    for (InputMethod m : inlined) {
+                        if (m.getBci() == bci) {
+                            bc.setInlined(m);
+                            break;
+                        }
                     }
+                } else {
+                    System.out.println("no match: " + s);
                 }
             }
         }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -23,6 +23,10 @@
  */
 package com.sun.hotspot.igv.data;
 
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
 /**
  *
  * @author Thomas Wuerthinger
@@ -30,6 +34,37 @@
 public class InputNode extends Properties.Entity {
 
     private int id;
+    private List<InputGraph> subgraphs;
+
+    public static final Comparator<InputNode> COMPARATOR = new Comparator<InputNode>() {
+        @Override
+        public int compare(InputNode o1, InputNode o2) {
+            return o1.getId() - o2.getId();
+        }
+    };
+
+    public static Comparator<InputNode> getPropertyComparator(final String propertyName) {
+        return new Comparator<InputNode>() {
+
+            @Override
+            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);
@@ -49,21 +84,29 @@
         return id;
     }
 
+    public void addSubgraph(InputGraph graph) {
+        if (subgraphs == null) {
+            subgraphs = new ArrayList<>();
+        }
+        subgraphs.add(graph);
+    }
+
+    public List<InputGraph> getSubgraphs() {
+        return subgraphs;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (!(o instanceof InputNode)) {
             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	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Pair.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -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);
+        Pair<?,?> obj = (Pair<?,?>) o;
+        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	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -24,13 +24,10 @@
 package com.sun.hotspot.igv.data;
 
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
+import java.util.regex.PatternSyntaxException;
 
 /**
  *
@@ -58,13 +55,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 +99,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 {
@@ -100,19 +114,12 @@
             properties = new Properties(object.getProperties());
         }
 
+        @Override
         public Properties getProperties() {
             return properties;
         }
     }
 
-    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();
@@ -128,11 +135,16 @@
             this.matcher = matcher;
         }
 
+        @Override
         public String getName() {
             return matcher.getName();
         }
 
+        @Override
         public boolean match(String p) {
+            if (p == null) {
+                return false;
+            }
             return !matcher.match(p);
         }
     }
@@ -143,15 +155,26 @@
         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;
         }
 
+        @Override
         public String getName() {
             return name;
         }
 
+        @Override
         public boolean match(String p) {
+            if (p == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
             return p.equals(value);
         }
     }
@@ -162,30 +185,55 @@
         private Pattern valuePattern;
 
         public RegexpPropertyMatcher(String name, String value) {
-            this.name = name;
-            valuePattern = Pattern.compile(value);
+            this(name, value, 0);
         }
 
+        public RegexpPropertyMatcher(String name, String value, int flags) {
+
+            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;
+
+            try {
+                valuePattern = Pattern.compile(value, flags);
+            } catch (PatternSyntaxException e) {
+                throw new IllegalArgumentException("Bad pattern: " + value);
+            }
+        }
+
+        @Override
         public String getName() {
             return name;
         }
 
+        @Override
         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 +246,32 @@
 
     @Override
     public String toString() {
+        List<String[]> pairs = new ArrayList<>();
+        for (int i = 0; i < map.length; i += 2) {
+            if (map[i + 1] != null) {
+                pairs.add(new String[]{map[i], map[i + 1]});
+            }
+        }
+
+        Collections.sort(pairs, new Comparator<String[]>() {
+            @Override
+            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("[");
-        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] + "; ");
+        boolean first = true;
+        for (String[] p : pairs) {
+            if (first) {
+                first = false;
+            } else {
+                sb.append(", ");
             }
+            sb.append(p[0]).append("=").append(p[1]);
         }
         return sb.append("]").toString();
     }
@@ -217,10 +284,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 +296,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<>();
 
-        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 +320,10 @@
     }
 
     public void setProperty(String name, String value) {
+        setPropertyInternal(name.intern(), value != null ? value.intern() : null);
+    }
+    private void setPropertyInternal(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,34 +354,26 @@
         map = newMap;
     }
 
-    public  Iterator<Property> getProperties() {
-        return iterator();
-    }
-
     public void add(Properties properties) {
         for (Property p : properties) {
-            add(p);
+            // Already interned
+            setPropertyInternal(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;
 
+        @Override
         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;
         }
 
+        @Override
         public Property next() {
             if (index < map.length) {
                 index += 2;
@@ -325,11 +382,13 @@
             return null;
         }
 
+        @Override
         public void remove() {
             throw new UnsupportedOperationException("Not supported yet.");
         }
+    }
 
-    }
+    @Override
     public Iterator<Property> iterator() {
         return new PropertiesIterator();
     }
--- a/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Fri May 08 23:51:37 2015 +0200
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Sat May 09 07:32:49 2015 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, 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
@@ -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	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008, 2015, 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.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Source {
+
+    private List<InputNode> sourceNodes;
+    private Set<Integer> set;
+
+    public Source() {
+        sourceNodes = new ArrayList<>(1);
+        set = new LinkedHashSet<>(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);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java	Sat May 09 07:32:49 2015 -0400
@@ -0,0 +1,900 @@
+/*
+ * Copyright (c) 2012, 2015, 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.*;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.services.GroupCallback;
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ReadableByteChannel;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.swing.SwingUtilities;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class BinaryParser implements GraphParser {
+    private static final int BEGIN_GROUP = 0x00;
+    private static final int BEGIN_GRAPH = 0x01;
+    private static final int CLOSE_GROUP = 0x02;
+
+    private static final int POOL_NEW = 0x00;
+    private static final int POOL_STRING = 0x01;
+    private static final int POOL_ENUM = 0x02;
+    private static final int POOL_CLASS = 0x03;
+    private static final int POOL_METHOD = 0x04;
+    private static final int POOL_NULL = 0x05;
+    private static final int POOL_NODE_CLASS = 0x06;
+    private static final int POOL_FIELD = 0x07;
+    private static final int POOL_SIGNATURE = 0x08;
+
+    private static final int KLASS = 0x00;
+    private static final int ENUM_KLASS = 0x01;
+
+    private static final int PROPERTY_POOL = 0x00;
+    private static final int PROPERTY_INT = 0x01;
+    private static final int PROPERTY_LONG = 0x02;
+    private static final int PROPERTY_DOUBLE = 0x03;
+    private static final int PROPERTY_FLOAT = 0x04;
+    private static final int PROPERTY_TRUE = 0x05;
+    private static final int PROPERTY_FALSE = 0x06;
+    private static final int PROPERTY_ARRAY = 0x07;
+    private static final int PROPERTY_SUBGRAPH = 0x08;
+
+    private static final String NO_BLOCK = "noBlock";
+
+    private final GroupCallback callback;
+    private final List<Object> constantPool;
+    private final ByteBuffer buffer;
+    private final ReadableByteChannel channel;
+    private final GraphDocument rootDocument;
+    private final Deque<Folder> folderStack;
+    private final Deque<byte[]> hashStack;
+    private final ParseMonitor monitor;
+
+    private MessageDigest digest;
+
+    private enum Length {
+        S,
+        M,
+        L
+    }
+
+    private interface LengthToString {
+        String toString(Length l);
+    }
+
+    private static abstract class Member implements LengthToString {
+        public final Klass holder;
+        public final int accessFlags;
+        public final String name;
+        public Member(Klass holder, String name, int accessFlags) {
+            this.holder = holder;
+            this.accessFlags = accessFlags;
+            this.name = name;
+        }
+    }
+
+    private static class Method extends Member {
+        public final Signature signature;
+        public final byte[] code;
+        public Method(String name, Signature signature, byte[] code, Klass holder, int accessFlags) {
+            super(holder, name, accessFlags);
+            this.signature = signature;
+            this.code = code;
+        }
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(holder).append('.').append(name).append('(');
+            for (int i = 0; i < signature.argTypes.length; i++) {
+                if (i > 0) {
+                    sb.append(", ");
+                }
+                sb.append(signature.argTypes[i]);
+            }
+            sb.append(')');
+            return sb.toString();
+        }
+        @Override
+        public String toString(Length l) {
+            switch(l) {
+                case M:
+                    return holder.toString(Length.L) + "." + name;
+                case S:
+                    return holder.toString(Length.S) + "." + name;
+                default:
+                case L:
+                    return toString();
+            }
+        }
+    }
+
+    private static class Signature {
+        public final String returnType;
+        public final String[] argTypes;
+        public Signature(String returnType, String[] argTypes) {
+            this.returnType = returnType;
+            this.argTypes = argTypes;
+        }
+    }
+
+    private static class Field extends Member {
+        public final String type;
+        public Field(String type, Klass holder, String name, int accessFlags) {
+            super(holder, name, accessFlags);
+            this.type = type;
+        }
+        @Override
+        public String toString() {
+            return holder + "." + name;
+        }
+        @Override
+        public String toString(Length l) {
+            switch(l) {
+                case M:
+                    return holder.toString(Length.L) + "." + name;
+                case S:
+                    return holder.toString(Length.S) + "." + name;
+                default:
+                case L:
+                    return toString();
+            }
+        }
+    }
+
+    private static class Klass implements LengthToString {
+        public final String name;
+        public final String simpleName;
+        public Klass(String name) {
+            this.name = name;
+            String simple;
+            try {
+                simple = name.substring(name.lastIndexOf('.') + 1);
+            } catch (IndexOutOfBoundsException ioobe) {
+                simple = name;
+            }
+            this.simpleName = simple;
+        }
+        @Override
+        public String toString() {
+            return name;
+        }
+        @Override
+        public String toString(Length l) {
+            switch(l) {
+                case S:
+                    return simpleName;
+                default:
+                case L:
+                case M:
+                    return toString();
+            }
+        }
+    }
+
+    private static class EnumKlass extends Klass {
+        public final String[] values;
+        public EnumKlass(String name, String[] values) {
+            super(name);
+            this.values = values;
+        }
+    }
+
+    private static class Port {
+        public final boolean isList;
+        public final String name;
+        private Port(boolean isList, String name) {
+            this.isList = isList;
+            this.name = name;
+        }
+    }
+
+    private static class TypedPort extends Port {
+        public final EnumValue type;
+        private TypedPort(boolean isList, String name, EnumValue type) {
+            super(isList, name);
+            this.type = type;
+        }
+    }
+
+    private static class NodeClass {
+        public final String className;
+        public final String nameTemplate;
+        public final List<TypedPort> inputs;
+        public final List<Port> sux;
+        private NodeClass(String className, String nameTemplate, List<TypedPort> inputs, List<Port> sux) {
+            this.className = className;
+            this.nameTemplate = nameTemplate;
+            this.inputs = inputs;
+            this.sux = sux;
+        }
+        @Override
+        public String toString() {
+            return className;
+        }
+    }
+
+    private static class EnumValue implements LengthToString {
+        public EnumKlass enumKlass;
+        public int ordinal;
+        public EnumValue(EnumKlass enumKlass, int ordinal) {
+            this.enumKlass = enumKlass;
+            this.ordinal = ordinal;
+        }
+        @Override
+        public String toString() {
+            return enumKlass.simpleName + "." + enumKlass.values[ordinal];
+        }
+        @Override
+        public String toString(Length l) {
+            switch(l) {
+                case S:
+                    return enumKlass.values[ordinal];
+                default:
+                case M:
+                case L:
+                    return toString();
+            }
+        }
+    }
+
+    public BinaryParser(ReadableByteChannel channel, ParseMonitor monitor, GraphDocument rootDocument, GroupCallback callback) {
+        this.callback = callback;
+        constantPool = new ArrayList<>();
+        buffer = ByteBuffer.allocateDirect(256 * 1024);
+        buffer.flip();
+        this.channel = channel;
+        this.rootDocument = rootDocument;
+        folderStack = new LinkedList<>();
+        hashStack = new LinkedList<>();
+        this.monitor = monitor;
+        try {
+            this.digest = MessageDigest.getInstance("SHA-256");
+        } catch (NoSuchAlgorithmException e) {
+        }
+    }
+
+    private void fill() throws IOException {
+        buffer.compact();
+        if (channel.read(buffer) < 0) {
+            throw new EOFException();
+        }
+        buffer.flip();
+    }
+
+    private void ensureAvailable(int i) throws IOException {
+        while (buffer.remaining() < i) {
+            fill();
+        }
+        buffer.mark();
+        byte[] result = new byte[i];
+        buffer.get(result);
+        digest.update(result);
+        buffer.reset();
+    }
+
+    private int readByte() throws IOException {
+        ensureAvailable(1);
+        return ((int)buffer.get()) & 0xff;
+    }
+
+    private int readInt() throws IOException {
+        ensureAvailable(4);
+        return buffer.getInt();
+    }
+
+    private char readShort() throws IOException {
+        ensureAvailable(2);
+        return buffer.getChar();
+    }
+
+    private long readLong() throws IOException {
+        ensureAvailable(8);
+        return buffer.getLong();
+    }
+
+    private double readDouble() throws IOException {
+        ensureAvailable(8);
+        return buffer.getDouble();
+    }
+
+    private float readFloat() throws IOException {
+        ensureAvailable(4);
+        return buffer.getFloat();
+    }
+
+    private String readString() throws IOException {
+        int len = readInt();
+        ensureAvailable(len * 2);
+        char[] chars = new char[len];
+        buffer.asCharBuffer().get(chars);
+        buffer.position(buffer.position() + len * 2);
+        return new String(chars).intern();
+    }
+
+    private byte[] readBytes() throws IOException {
+        int len = readInt();
+        if (len < 0) {
+            return null;
+        }
+        ensureAvailable(len);
+        byte[] data = new byte[len];
+        buffer.get(data);
+        return data;
+    }
+
+    private String readIntsToString() throws IOException {
+        int len = readInt();
+        if (len < 0) {
+            return "null";
+        }
+        ensureAvailable(len * 4);
+        StringBuilder sb = new StringBuilder().append('[');
+        for (int i = 0; i < len; i++) {
+            sb.append(buffer.getInt());
+            if (i < len - 1) {
+                sb.append(", ");
+            }
+        }
+        sb.append(']');
+        return sb.toString().intern();
+    }
+
+    private String readDoublesToString() throws IOException {
+        int len = readInt();
+        if (len < 0) {
+            return "null";
+        }
+        ensureAvailable(len * 8);
+        StringBuilder sb = new StringBuilder().append('[');
+        for (int i = 0; i < len; i++) {
+            sb.append(buffer.getDouble());
+            if (i < len - 1) {
+                sb.append(", ");
+            }
+        }
+        sb.append(']');
+        return sb.toString().intern();
+    }
+
+    private String readPoolObjectsToString() throws IOException {
+        int len = readInt();
+        if (len < 0) {
+            return "null";
+        }
+        StringBuilder sb = new StringBuilder().append('[');
+        for (int i = 0; i < len; i++) {
+            sb.append(readPoolObject(Object.class));
+            if (i < len - 1) {
+                sb.append(", ");
+            }
+        }
+        sb.append(']');
+        return sb.toString().intern();
+    }
+
+    private <T> T readPoolObject(Class<T> klass) throws IOException {
+        int type = readByte();
+        if (type == POOL_NULL) {
+            return null;
+        }
+        if (type == POOL_NEW) {
+            return (T) addPoolEntry(klass);
+        }
+        assert assertObjectType(klass, type);
+        char index = readShort();
+        if (index < 0 || index >= constantPool.size()) {
+            throw new IOException("Invalid constant pool index : " + index);
+        }
+        Object obj = constantPool.get(index);
+        return (T) obj;
+    }
+
+    private boolean assertObjectType(Class<?> klass, int type) {
+        switch(type) {
+            case POOL_CLASS:
+                return klass.isAssignableFrom(EnumKlass.class);
+            case POOL_ENUM:
+                return klass.isAssignableFrom(EnumValue.class);
+            case POOL_METHOD:
+                return klass.isAssignableFrom(Method.class);
+            case POOL_STRING:
+                return klass.isAssignableFrom(String.class);
+            case POOL_NODE_CLASS:
+                return klass.isAssignableFrom(NodeClass.class);
+            case POOL_FIELD:
+                return klass.isAssignableFrom(Field.class);
+            case POOL_SIGNATURE:
+                return klass.isAssignableFrom(Signature.class);
+            case POOL_NULL:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private Object addPoolEntry(Class<?> klass) throws IOException {
+        char index = readShort();
+        int type = readByte();
+        assert assertObjectType(klass, type) : "Wrong object type : " + klass + " != " + type;
+        Object obj;
+        switch(type) {
+            case POOL_CLASS: {
+                String name = readString();
+                int klasstype = readByte();
+                if (klasstype == ENUM_KLASS) {
+                    int len = readInt();
+                    String[] values = new String[len];
+                    for (int i = 0; i < len; i++) {
+                        values[i] = readPoolObject(String.class);
+                    }
+                    obj = new EnumKlass(name, values);
+                } else if (klasstype == KLASS) {
+                    obj = new Klass(name);
+                } else {
+                    throw new IOException("unknown klass type : " + klasstype);
+                }
+                break;
+            }
+            case POOL_ENUM: {
+                EnumKlass enumClass = readPoolObject(EnumKlass.class);
+                int ordinal = readInt();
+                obj = new EnumValue(enumClass, ordinal);
+                break;
+            }
+            case POOL_NODE_CLASS: {
+                String className = readString();
+                String nameTemplate = readString();
+                int inputCount = readShort();
+                List<TypedPort> inputs = new ArrayList<>(inputCount);
+                for (int i = 0; i < inputCount; i++) {
+                    boolean isList = readByte() != 0;
+                    String name = readPoolObject(String.class);
+                    EnumValue inputType = readPoolObject(EnumValue.class);
+                    inputs.add(new TypedPort(isList, name, inputType));
+                }
+                int suxCount = readShort();
+                List<Port> sux = new ArrayList<>(suxCount);
+                for (int i = 0; i < suxCount; i++) {
+                    boolean isList = readByte() != 0;
+                    String name = readPoolObject(String.class);
+                    sux.add(new Port(isList, name));
+                }
+                obj = new NodeClass(className, nameTemplate, inputs, sux);
+                break;
+            }
+            case POOL_METHOD: {
+                Klass holder = readPoolObject(Klass.class);
+                String name = readPoolObject(String.class);
+                Signature sign = readPoolObject(Signature.class);
+                int flags = readInt();
+                byte[] code = readBytes();
+                obj = new Method(name, sign, code, holder, flags);
+                break;
+            }
+            case POOL_FIELD: {
+                Klass holder = readPoolObject(Klass.class);
+                String name = readPoolObject(String.class);
+                String fType = readPoolObject(String.class);
+                int flags = readInt();
+                obj = new Field(fType, holder, name, flags);
+                break;
+            }
+            case POOL_SIGNATURE: {
+                int argc = readShort();
+                String[] args = new String[argc];
+                for (int i = 0; i < argc; i++) {
+                    args[i] = readPoolObject(String.class);
+                }
+                String returnType = readPoolObject(String.class);
+                obj = new Signature(returnType, args);
+                break;
+            }
+            case POOL_STRING: {
+                obj = readString();
+                break;
+            }
+            default:
+                throw new IOException("unknown pool type");
+        }
+        while (constantPool.size() <= index) {
+            constantPool.add(null);
+        }
+        constantPool.set(index, obj);
+        return obj;
+    }
+
+    private Object readPropertyObject() throws IOException {
+        int type = readByte();
+        switch (type) {
+            case PROPERTY_INT:
+                return readInt();
+            case PROPERTY_LONG:
+                return readLong();
+            case PROPERTY_FLOAT:
+                return readFloat();
+            case PROPERTY_DOUBLE:
+                return readDouble();
+            case PROPERTY_TRUE:
+                return Boolean.TRUE;
+            case PROPERTY_FALSE:
+                return Boolean.FALSE;
+            case PROPERTY_POOL:
+                return readPoolObject(Object.class);
+            case PROPERTY_ARRAY:
+                int subType = readByte();
+                switch(subType) {
+                    case PROPERTY_INT:
+                        return readIntsToString();
+                    case PROPERTY_DOUBLE:
+                        return readDoublesToString();
+                    case PROPERTY_POOL:
+                        return readPoolObjectsToString();
+                    default:
+                        throw new IOException("Unknown type");
+                }
+            case PROPERTY_SUBGRAPH:
+                InputGraph graph = parseGraph("");
+                new Group(null).addElement(graph);
+                return graph;
+            default:
+                throw new IOException("Unknown type");
+        }
+    }
+
+    @Override
+    public GraphDocument parse() throws IOException {
+        folderStack.push(rootDocument);
+        hashStack.push(null);
+        if (monitor != null) {
+            monitor.setState("Starting parsing");
+        }
+        try {
+            while(true) {
+                parseRoot();
+            }
+        } catch (EOFException e) {
+
+        }
+        if (monitor != null) {
+            monitor.setState("Finished parsing");
+        }
+        return rootDocument;
+    }
+
+    private void parseRoot() throws IOException {
+        int type = readByte();
+        switch(type) {
+            case BEGIN_GRAPH: {
+                final Folder parent = folderStack.peek();
+                final InputGraph graph = parseGraph();
+                SwingUtilities.invokeLater(new Runnable(){
+                    @Override
+                    public void run() {
+                        parent.addElement(graph);
+                    }
+                });
+                break;
+            }
+            case BEGIN_GROUP: {
+                final Folder parent = folderStack.peek();
+                final Group group = parseGroup(parent);
+                if (callback == null || parent instanceof Group) {
+                    SwingUtilities.invokeLater(new Runnable(){
+                        @Override
+                        public void run() {
+                            parent.addElement(group);
+                        }
+                    });
+                }
+                folderStack.push(group);
+                hashStack.push(null);
+                if (callback != null && parent instanceof GraphDocument) {
+                    callback.started(group);
+                }
+                break;
+            }
+            case CLOSE_GROUP: {
+                if (folderStack.isEmpty()) {
+                    throw new IOException("Unbalanced groups");
+                }
+                folderStack.pop();
+                hashStack.pop();
+                break;
+            }
+            default:
+                throw new IOException("unknown root : " + type);
+        }
+    }
+
+    private Group parseGroup(Folder parent) throws IOException {
+        String name = readPoolObject(String.class);
+        String shortName = readPoolObject(String.class);
+        if (monitor != null) {
+            monitor.setState(shortName);
+        }
+        Method method = readPoolObject(Method.class);
+        int bci = readInt();
+        Group group = new Group(parent);
+        group.getProperties().setProperty("name", name);
+        if (method != null) {
+            InputMethod inMethod = new InputMethod(group, method.name, shortName, bci);
+            inMethod.setBytecodes("TODO");
+            group.setMethod(inMethod);
+        }
+        return group;
+    }
+
+    private InputGraph parseGraph() throws IOException {
+        if (monitor != null) {
+            monitor.updateProgress();
+        }
+        String title = readPoolObject(String.class);
+        digest.reset();
+        InputGraph graph = parseGraph(title);
+        byte[] d = digest.digest();
+        byte[] hash = hashStack.peek();
+        if (hash != null && Arrays.equals(hash, d)) {
+            graph.getProperties().setProperty("_isDuplicate", "true");
+        } else {
+            hashStack.pop();
+            hashStack.push(d);
+        }
+        return graph;
+    }
+
+    private InputGraph parseGraph(String title) throws IOException {
+        InputGraph graph = new InputGraph(title);
+        parseNodes(graph);
+        parseBlocks(graph);
+        graph.ensureNodesInBlocks();
+        return graph;
+    }
+
+    private void parseBlocks(InputGraph graph) throws IOException {
+        int blockCount = readInt();
+        List<Edge> edges = new LinkedList<>();
+        for (int i = 0; i < blockCount; i++) {
+            int id = readInt();
+            String name = id >= 0 ? Integer.toString(id) : NO_BLOCK;
+            InputBlock block = graph.addBlock(name);
+            int nodeCount = readInt();
+            for (int j = 0; j < nodeCount; j++) {
+                int nodeId = readInt();
+                if (nodeId < 0) {
+                    continue;
+                }
+                final Properties properties = graph.getNode(nodeId).getProperties();
+                final String oldBlock = properties.get("block");
+                if(oldBlock != null) {
+                    properties.setProperty("block", oldBlock + ", " + name);
+                } else {
+                    block.addNode(nodeId);
+                    properties.setProperty("block", name);
+                }
+            }
+            int edgeCount = readInt();
+            for (int j = 0; j < edgeCount; j++) {
+                int to = readInt();
+                edges.add(new Edge(id, to));
+            }
+        }
+        for (Edge e : edges) {
+            String fromName = e.from >= 0 ? Integer.toString(e.from) : NO_BLOCK;
+            String toName = e.to >= 0 ? Integer.toString(e.to) : NO_BLOCK;
+            graph.addBlockEdge(graph.getBlock(fromName), graph.getBlock(toName));
+        }
+    }
+
+    private void parseNodes(InputGraph graph) throws IOException {
+        int count = readInt();
+        Map<String, Object> props = new HashMap<>();
+        List<Edge> inputEdges = new ArrayList<>(count);
+        List<Edge> succEdges = new ArrayList<>(count);
+        for (int i = 0; i < count; i++) {
+            int id = readInt();
+            InputNode node = new InputNode(id);
+            final Properties properties = node.getProperties();
+            NodeClass nodeClass = readPoolObject(NodeClass.class);
+            int preds = readByte();
+            if (preds > 0) {
+                properties.setProperty("hasPredecessor", "true");
+            }
+            properties.setProperty("idx", Integer.toString(id));
+            int propCount = readShort();
+            for (int j = 0; j < propCount; j++) {
+                String key = readPoolObject(String.class);
+                if (key.equals("hasPredecessor") || key.equals("name") || key.equals("class") || key.equals("id") || key.equals("idx")) {
+                    key = "!data." + key;
+                }
+                Object value = readPropertyObject();
+                if (value instanceof InputGraph) {
+                    InputGraph subgraph = (InputGraph) value;
+                    subgraph.getProperties().setProperty("name", node.getId() + ":" + key);
+                    node.addSubgraph((InputGraph) value);
+                } else {
+                    properties.setProperty(key, value != null ? value.toString() : "null");
+                    props.put(key, value);
+                }
+            }
+            ArrayList<Edge> currentEdges = new ArrayList<>();
+            int portNum = 0;
+            for (TypedPort p : nodeClass.inputs) {
+                if (p.isList) {
+                    int size = readShort();
+                    for (int j = 0; j < size; j++) {
+                        int in = readInt();
+                        if (in >= 0) {
+                            Edge e = new Edge(in, id, (char) (preds + portNum), p.name + "[" + j + "]", p.type.toString(Length.S), true);
+                            currentEdges.add(e);
+                            inputEdges.add(e);
+                            portNum++;
+                        }
+                    }
+                } else {
+                    int in = readInt();
+                    if (in >= 0) {
+                        Edge e = new Edge(in, id, (char) (preds + portNum), p.name, p.type.toString(Length.S), true);
+                        currentEdges.add(e);
+                        inputEdges.add(e);
+                        portNum++;
+                    }
+                }
+
+            }
+            portNum = 0;
+            for (Port p : nodeClass.sux) {
+                if (p.isList) {
+                    int size = readShort();
+                    for (int j = 0; j < size; j++) {
+                        int sux = readInt();
+                        if (sux >= 0) {
+                            Edge e = new Edge(id, sux, (char) portNum, p.name + "[" + j + "]", "Successor", false);
+                            currentEdges.add(e);
+                            succEdges.add(e);
+                            portNum++;
+                        }
+                    }
+                } else {
+                    int sux = readInt();
+                    if (sux >= 0) {
+                        Edge e = new Edge(id, sux, (char) portNum, p.name, "Successor", false);
+                        currentEdges.add(e);
+                        succEdges.add(e);
+                        portNum++;
+                    }
+                }
+            }
+            properties.setProperty("name", createName(currentEdges, props, nodeClass.nameTemplate));
+            properties.setProperty("class", nodeClass.className);
+            switch (nodeClass.className) {
+                case "BeginNode":
+                    properties.setProperty("shortName", "B");
+                    break;
+                case "EndNode":
+                    properties.setProperty("shortName", "E");
+                    break;
+            }
+            graph.addNode(node);
+            props.clear();
+        }
+
+        Set<InputNode> nodesWithSuccessor = new HashSet<>();
+
+        for (Edge e : succEdges) {
+            assert !e.input;
+            char fromIndex = e.num;
+            nodesWithSuccessor.add(graph.getNode(e.from));
+            char toIndex = 0;
+            graph.addEdge(InputEdge.createImmutable(fromIndex, toIndex, e.from, e.to, e.label, e.type));
+        }
+        for (Edge e : inputEdges) {
+            assert e.input;
+            char fromIndex = (char) (nodesWithSuccessor.contains(graph.getNode(e.from)) ? 1 : 0);
+            char toIndex = e.num;
+            graph.addEdge(InputEdge.createImmutable(fromIndex, toIndex, e.from, e.to, e.label, e.type));
+        }
+    }
+
+    private String createName(List<Edge> edges, Map<String, Object> properties, String template) {
+        Pattern p = Pattern.compile("\\{(p|i)#([a-zA-Z0-9$_]+)(/(l|m|s))?\\}");
+        Matcher m = p.matcher(template);