diff --git a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java
index 4f9b33e93ca..9564e53d1ab 100644
--- a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java
+++ b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java
@@ -23,13 +23,13 @@
  */
 package com.sun.hotspot.igv.bytecodes;
 
+import com.sun.hotspot.igv.data.ChangedListener;
 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;
 import org.openide.ErrorManager;
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
@@ -41,13 +41,12 @@ import org.openide.windows.WindowManager;
 /**
  * @author Thomas Wuerthinger
  */
-final class BytecodeViewTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener {
+final class BytecodeViewTopComponent extends TopComponent implements ExplorerManager.Provider, ChangedListener<InputGraphProvider> {
 
     private static BytecodeViewTopComponent instance;
     private static final String PREFERRED_ID = "BytecodeViewTopComponent";
-    private ExplorerManager manager;
-    private BeanTreeView treeView;
-    private Lookup.Result result = null;
+    private final ExplorerManager manager;
+    private final BeanTreeView treeView;
     private MethodNode rootNode;
 
     private BytecodeViewTopComponent() {
@@ -67,32 +66,10 @@ final class BytecodeViewTopComponent extends TopComponent implements ExplorerMan
         associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
     }
 
-    /** This method is called from within the constructor to
-     * initialize the form.
-     * WARNING: Do NOT modify this code. The content of this method is
-     * always regenerated by the Form Editor.
-     */
-    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
-    private void initComponents() {
-
-        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
-        this.setLayout(layout);
-        layout.setHorizontalGroup(
-            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
-            .add(0, 400, Short.MAX_VALUE)
-        );
-        layout.setVerticalGroup(
-            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
-            .add(0, 300, Short.MAX_VALUE)
-        );
-    }// </editor-fold>//GEN-END:initComponents
-    // Variables declaration - do not modify//GEN-BEGIN:variables
-    // End of variables declaration//GEN-END:variables
-
     /**
      * Gets default instance. Do not use directly: reserved for *.settings files only,
      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
-     * To obtain the singleton instance, use {@link findInstance}.
+     * To obtain the singleton instance, use {@link #findInstance()}.
      */
     public static synchronized BytecodeViewTopComponent getDefault() {
         if (instance == null) {
@@ -124,15 +101,12 @@ final class BytecodeViewTopComponent extends TopComponent implements ExplorerMan
 
     @Override
     public void componentOpened() {
-        Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<>(InputGraphProvider.class);
-        result = Utilities.actionsGlobalContext().lookup(tpl);
-        result.addLookupListener(this);
+        LookupHistory.addListener(InputGraphProvider.class, this);
     }
 
     @Override
     public void componentClosed() {
-        result.removeLookupListener(this);
-        result = null;
+        LookupHistory.removeListener(InputGraphProvider.class, this);
     }
 
     @Override
@@ -169,23 +143,17 @@ final class BytecodeViewTopComponent extends TopComponent implements ExplorerMan
     }
 
     @Override
-    public void resultChanged(LookupEvent lookupEvent) {
-        final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
-            SwingUtilities.invokeLater(new Runnable() {
-                @Override
-                public void run() {
-                if (p != null) {
-                    InputGraph graph = p.getGraph();
-                    if (graph != null) {
-                        Group g = graph.getGroup();
-                        rootNode.update(graph, g.getMethod());
-                        return;
-                    }
-                }
-                        rootNode.update(null, null);
-                    }
-            });
-
+    public void changed(InputGraphProvider lastProvider) {
+        if (lastProvider != null) {
+            InputGraph graph = lastProvider.getGraph();
+            if (graph != null) {
+                Group g = graph.getGroup();
+                rootNode.update(graph, g.getMethod());
+                return;
+            }
+        }
+        rootNode = new MethodNode(null, null, "");
+        manager.setRootContext(rootNode);
     }
 
     static final class ResolvableHelper implements Serializable {
@@ -196,4 +164,26 @@ final class BytecodeViewTopComponent extends TopComponent implements ExplorerMan
             return BytecodeViewTopComponent.getDefault();
         }
     }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+                layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                        .add(0, 400, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+                layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                        .add(0, 300, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    // End of variables declaration//GEN-END:variables
 }
diff --git a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java
index e1460753a5b..dd892e3700c 100644
--- a/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java
+++ b/src/utils/IdealGraphVisualizer/Bytecodes/src/main/java/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java
@@ -39,7 +39,7 @@ public final class SelectBytecodesAction extends CookieAction {
     @Override
     protected void performAction(Node[] activatedNodes) {
         SelectBytecodesCookie c = activatedNodes[0].getCookie(SelectBytecodesCookie.class);
-        InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
+        InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
         if (p != null) {
             p.setSelectedNodes(c.getNodes());
         }
diff --git a/src/utils/IdealGraphVisualizer/ControlFlow/src/main/java/com/sun/hotspot/igv/controlflow/ControlFlowScene.java b/src/utils/IdealGraphVisualizer/ControlFlow/src/main/java/com/sun/hotspot/igv/controlflow/ControlFlowScene.java
index b858ef0aa27..c6cb8c4290a 100644
--- a/src/utils/IdealGraphVisualizer/ControlFlow/src/main/java/com/sun/hotspot/igv/controlflow/ControlFlowScene.java
+++ b/src/utils/IdealGraphVisualizer/ControlFlow/src/main/java/com/sun/hotspot/igv/controlflow/ControlFlowScene.java
@@ -133,7 +133,7 @@ public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> imp
     }
 
     public void selectionChanged() {
-        InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
+        InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
         if (p != null) {
             Set<InputNode> inputNodes = new HashSet<InputNode>();
             for (BlockWidget w : selection) {
diff --git a/src/utils/IdealGraphVisualizer/ControlFlow/src/main/java/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java b/src/utils/IdealGraphVisualizer/ControlFlow/src/main/java/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java
index b774dac1d49..80597a9eee2 100644
--- a/src/utils/IdealGraphVisualizer/ControlFlow/src/main/java/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java
+++ b/src/utils/IdealGraphVisualizer/ControlFlow/src/main/java/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2022, 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,19 +23,15 @@
  */
 package com.sun.hotspot.igv.controlflow;
 
+import com.sun.hotspot.igv.data.ChangedListener;
 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;
-import javax.swing.SwingUtilities;
 import org.openide.ErrorManager;
-import org.openide.util.Lookup;
-import org.openide.util.LookupEvent;
-import org.openide.util.LookupListener;
 import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
 import org.openide.windows.TopComponent;
 import org.openide.windows.WindowManager;
 
@@ -43,12 +39,11 @@ import org.openide.windows.WindowManager;
  *
  * @author Thomas Wuerthinger
  */
-final class ControlFlowTopComponent extends TopComponent implements LookupListener {
+final class ControlFlowTopComponent extends TopComponent implements ChangedListener<InputGraphProvider> {
 
     private static ControlFlowTopComponent instance;
-    private Lookup.Result result = null;
     private static final String PREFERRED_ID = "ControlFlowTopComponent";
-    private ControlFlowScene scene;
+    private final ControlFlowScene scene;
 
     private ControlFlowTopComponent() {
         initComponents();
@@ -64,34 +59,10 @@ final class ControlFlowTopComponent extends TopComponent implements LookupListen
         this.add(panel, BorderLayout.CENTER);
     }
 
-
-
-    /** This method is called from within the constructor to
-     * initialize the form.
-     * WARNING: Do NOT modify this code. The content of this method is
-     * always regenerated by the Form Editor.
-     */
-    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
-    private void initComponents() {
-
-        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
-        this.setLayout(layout);
-        layout.setHorizontalGroup(
-            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
-            .add(0, 400, Short.MAX_VALUE)
-        );
-        layout.setVerticalGroup(
-            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
-            .add(0, 300, Short.MAX_VALUE)
-        );
-    }// </editor-fold>//GEN-END:initComponents
-    // Variables declaration - do not modify//GEN-BEGIN:variables
-    // End of variables declaration//GEN-END:variables
-
     /**
      * Gets default instance. Do not use directly: reserved for *.settings files only,
      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
-     * To obtain the singleton instance, use {@link findInstance}.
+     * To obtain the singleton instance, use {@link #findInstance()}.
      */
     public static synchronized ControlFlowTopComponent getDefault() {
         if (instance == null) {
@@ -123,30 +94,24 @@ final class ControlFlowTopComponent extends TopComponent implements LookupListen
 
     @Override
     public void componentOpened() {
-        Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<InputGraphProvider>(InputGraphProvider.class);
-        result = Utilities.actionsGlobalContext().lookup(tpl);
-        result.addLookupListener(this);
+        LookupHistory.addListener(InputGraphProvider.class, this);
     }
 
     @Override
     public void componentClosed() {
-        result.removeLookupListener(this);
-        result = null;
+        LookupHistory.removeListener(InputGraphProvider.class, this);
     }
 
-    public void resultChanged(LookupEvent lookupEvent) {
-        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);
-                    }
-                }
-            });
+    @Override
+    public void changed(InputGraphProvider lastProvider) {
+        if (lastProvider != null) {
+            InputGraph graph = lastProvider.getGraph();
+            if (graph != null) {
+                scene.setGraph(graph);
+                return;
+            }
         }
+        scene.setGraph(new InputGraph(""));
     }
 
     @Override
@@ -173,4 +138,26 @@ final class ControlFlowTopComponent extends TopComponent implements LookupListen
             return ControlFlowTopComponent.getDefault();
         }
     }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+                layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                        .add(0, 400, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+                layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                        .add(0, 300, Short.MAX_VALUE)
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    // End of variables declaration//GEN-END:variables
 }
diff --git a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java
index 9962d0ef713..bb630b58d12 100644
--- a/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java
+++ b/src/utils/IdealGraphVisualizer/Coordinator/src/main/java/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java
@@ -25,8 +25,8 @@ package com.sun.hotspot.igv.coordinator;
 
 import com.sun.hotspot.igv.connection.Server;
 import com.sun.hotspot.igv.coordinator.actions.*;
+import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.data.GraphDocument;
-import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.services.GroupCallback;
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
@@ -48,8 +48,8 @@ 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.*;
-import org.openide.util.actions.NodeAction;
+import org.openide.util.Exceptions;
+import org.openide.util.NbBundle;
 import org.openide.windows.TopComponent;
 import org.openide.windows.WindowManager;
 
@@ -57,13 +57,12 @@ import org.openide.windows.WindowManager;
  *
  * @author Thomas Wuerthinger
  */
-public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener {
+public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider, ChangedListener<InputGraphProvider> {
 
     public static OutlineTopComponent instance;
     public static final String PREFERRED_ID = "OutlineTopComponent";
-    private Lookup.Result result = null;
     private ExplorerManager manager;
-    private GraphDocument document;
+    private final GraphDocument document;
     private FolderNode root;
     private Server server;
     private Server binaryServer;
@@ -100,13 +99,13 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
         this.add(toolbar, BorderLayout.NORTH);
 
         toolbar.add(ImportAction.get(ImportAction.class));
-        toolbar.add(((NodeAction) SaveAsAction.get(SaveAsAction.class)).createContextAwareInstance(this.getLookup()));
+        toolbar.add(SaveAsAction.get(SaveAsAction.class).createContextAwareInstance(this.getLookup()));
 
         saveAllAction = SaveAllAction.get(SaveAllAction.class);
         saveAllAction.setEnabled(false);
         toolbar.add(saveAllAction);
 
-        toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup()));
+        toolbar.add(RemoveAction.get(RemoveAction.class).createContextAwareInstance(this.getLookup()));
 
         removeAllAction = RemoveAllAction.get(RemoveAllAction.class);
         removeAllAction.setEnabled(false);
@@ -129,14 +128,10 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
 
     private void initReceivers() {
 
-        final GroupCallback callback = new GroupCallback() {
-
-            @Override
-            public void started(Group g) {
-                synchronized(OutlineTopComponent.this) {
-                    getDocument().addElement(g);
-                    g.setParent(getDocument());
-                }
+        final GroupCallback callback = g -> {
+            synchronized(OutlineTopComponent.this) {
+                g.setParent(getDocument());
+                getDocument().addElement(g);
             }
         };
 
@@ -144,28 +139,6 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
         binaryServer = new Server(getDocument(), callback, true);
     }
 
-    // Fetch and select the latest active graph.
-    private void updateGraphSelection() {
-        final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
-        if (p != null) {
-            try {
-                InputGraph graph = p.getGraph();
-                if (graph.isDiffGraph()) {
-                    EditorTopComponent editor = EditorTopComponent.getActive();
-                    if (editor != null) {
-                        InputGraph firstGraph = editor.getModel().getFirstGraph();
-                        InputGraph secondGraph = editor.getModel().getSecondGraph();
-                        manager.setSelectedNodes(new GraphNode[]{FolderNode.getGraphNode(firstGraph), FolderNode.getGraphNode(secondGraph)});
-                    }
-                } else {
-                    manager.setSelectedNodes(new GraphNode[]{FolderNode.getGraphNode(graph)});
-                }
-            } catch (Exception e) {
-                Exceptions.printStackTrace(e);
-            }
-        }
-    }
-
     public void clear() {
         document.clear();
         FolderNode.clearGraphNodeMap();
@@ -185,7 +158,7 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
     /**
      * Gets default instance. Do not use directly: reserved for *.settings files only,
      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
-     * To obtain the singleton instance, use {@link findInstance}.
+     * To obtain the singleton instance, use {@link #findInstance()}.
      */
     public static synchronized OutlineTopComponent getDefault() {
         if (instance == null) {
@@ -217,16 +190,13 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
 
     @Override
     public void componentOpened() {
-        Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<InputGraphProvider>(InputGraphProvider.class);
-        result = Utilities.actionsGlobalContext().lookup(tpl);
-        result.addLookupListener(this);
-        updateGraphSelection();
+        LookupHistory.addListener(InputGraphProvider.class, this);
         this.requestActive();
     }
 
     @Override
     public void componentClosed() {
-        result.removeLookupListener(this);
+        LookupHistory.removeListener(InputGraphProvider.class, this);
     }
 
     @Override
@@ -253,14 +223,33 @@ public final class OutlineTopComponent extends TopComponent implements ExplorerM
     }
 
     @Override
-    public void resultChanged(LookupEvent lookupEvent) {
-        // Highlight the focused graph, if available, in the outline.
-        if (result.allItems().isEmpty()) {
-            return;
-        }
+    public void changed(InputGraphProvider lastProvider) {
         // Wait for LookupHistory to be updated with the last active graph
         // before selecting it.
-        SwingUtilities.invokeLater(() -> updateGraphSelection());
+        SwingUtilities.invokeLater(() -> {
+            GraphNode[] selection = new GraphNode[0];
+            if (lastProvider != null) {
+                // Try to fetch and select the latest active graph.
+                InputGraph graph = lastProvider.getGraph();
+                if (graph != null) {
+                    if (graph.isDiffGraph()) {
+                        EditorTopComponent editor = EditorTopComponent.getActive();
+                        if (editor != null) {
+                            InputGraph firstGraph = editor.getModel().getFirstGraph();
+                            InputGraph secondGraph = editor.getModel().getSecondGraph();
+                            selection = new GraphNode[]{FolderNode.getGraphNode(firstGraph), FolderNode.getGraphNode(secondGraph)};
+                        }
+                    } else {
+                        selection = new GraphNode[]{FolderNode.getGraphNode(graph)};
+                    }
+                }
+            }
+            try {
+                manager.setSelectedNodes(selection);
+            } catch (Exception e) {
+                Exceptions.printStackTrace(e);
+            }
+        });
     }
 
     @Override
diff --git a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java
index ea484efcd63..174efb5b84b 100644
--- a/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java
+++ b/src/utils/IdealGraphVisualizer/FilterWindow/src/main/java/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java
@@ -546,7 +546,7 @@ public final class FilterTopComponent extends TopComponent implements LookupList
     /**
      * Gets default instance. Do not use directly: reserved for *.settings files only,
      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
-     * To obtain the singleton instance, use {@link findInstance}.
+     * To obtain the singleton instance, use {@link #findInstance()}.
      */
     public static synchronized FilterTopComponent getDefault() {
         if (instance == null) {
diff --git a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/services/DiagramProvider.java b/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/services/DiagramProvider.java
deleted file mode 100644
index 319825f2a65..00000000000
--- a/src/utils/IdealGraphVisualizer/Graph/src/main/java/com/sun/hotspot/igv/graph/services/DiagramProvider.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * 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.graph.services;
-
-import com.sun.hotspot.igv.data.ChangedEvent;
-import com.sun.hotspot.igv.graph.Diagram;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public interface DiagramProvider {
-    Diagram getDiagram();
-    ChangedEvent<DiagramProvider> getChangedEvent();
-
-}
diff --git a/src/utils/IdealGraphVisualizer/Util/src/main/java/com/sun/hotspot/igv/util/LookupHistory.java b/src/utils/IdealGraphVisualizer/Util/src/main/java/com/sun/hotspot/igv/util/LookupHistory.java
index 4bf7781b2d8..0b6f27cf8d4 100644
--- a/src/utils/IdealGraphVisualizer/Util/src/main/java/com/sun/hotspot/igv/util/LookupHistory.java
+++ b/src/utils/IdealGraphVisualizer/Util/src/main/java/com/sun/hotspot/igv/util/LookupHistory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2022, 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,8 @@
  */
 package com.sun.hotspot.igv.util;
 
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.data.Event;
 import java.util.HashMap;
 import java.util.Map;
 import org.openide.util.Lookup.Result;
@@ -38,7 +40,7 @@ public class LookupHistory {
 
     private static Map<Class, LookupHistoryImpl> cache = new HashMap<>();
 
-    private static class LookupHistoryImpl<T> implements LookupListener {
+    private static class LookupHistoryImpl<T> extends Event<ChangedListener<T>> implements LookupListener {
 
         private Class<T> klass;
         private Result<T> result;
@@ -49,17 +51,25 @@ public class LookupHistory {
             result = Utilities.actionsGlobalContext().lookupResult(klass);
             result.addLookupListener(this);
             last = Utilities.actionsGlobalContext().lookup(klass);
+            fire();
         }
 
         public T getLast() {
             return last;
         }
 
+        @Override
+        protected void fire(ChangedListener<T> l) {
+            l.changed(last);
+        }
+
+
         @Override
         public void resultChanged(LookupEvent ev) {
             T current = Utilities.actionsGlobalContext().lookup(klass);
             if (current != null) {
                 last = current;
+                this.fire();
             }
         }
     }
@@ -70,10 +80,31 @@ public class LookupHistory {
         }
     }
 
+    public static <T> void terminate(Class<T> klass) {
+        if (cache.containsKey(klass)) {
+            cache.get(klass).fire();
+        }
+    }
+
     @SuppressWarnings("unchecked")
     public static <T> T getLast(Class<T> klass) {
         init(klass);
         assert cache.containsKey(klass);
         return (T) cache.get(klass).getLast();
     }
+
+    @SuppressWarnings("unchecked")
+    public static <T> void addListener(Class<T> klass, ChangedListener<T> listener) {
+        init(klass);
+        assert cache.containsKey(klass);
+        cache.get(klass).addListener(listener);
+        cache.get(klass).fire();
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> void removeListener(Class<T> klass, ChangedListener<T> listener) {
+        if (cache.containsKey(klass)) {
+            cache.get(klass).removeListener(listener);
+        }
+    }
 }
diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java
index 30a494abe39..f42f20eb502 100644
--- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java
+++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java
@@ -60,7 +60,6 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
     private FilterChain sequenceFilterChain;
     private Diagram diagram;
     private InputGraph inputGraph;
-    private ChangedEvent<DiagramViewModel> groupChangedEvent;
     private ChangedEvent<DiagramViewModel> diagramChangedEvent;
     private ChangedEvent<DiagramViewModel> viewChangedEvent;
     private ChangedEvent<DiagramViewModel> hiddenNodesChangedEvent;
@@ -96,9 +95,14 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
         boolean viewChanged = false;
         boolean viewPropertiesChanged = false;
 
-        boolean groupChanged = (group == newModel.group);
-        this.group = newModel.group;
-        if (groupChanged) {
+        if (group != newModel.group) {
+            if (group != null) {
+                group.getChangedEvent().removeListener(groupContentChangedListener);
+            }
+            group = newModel.group;
+            if (group != null) {
+                group.getChangedEvent().addListener(groupContentChangedListener);
+            }
             filterGraphs();
         }
 
@@ -123,10 +127,6 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
         viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
         this.showNodeHull = newModel.showNodeHull;
 
-        if (groupChanged) {
-            groupChangedEvent.fire();
-        }
-
         if (diagramChanged) {
             diagramChangedEvent.fire();
         }
@@ -213,6 +213,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
         this.showNodeHull = true;
         this.showEmptyBlocks = true;
         this.group = g;
+        group.getChangedEvent().addListener(groupContentChangedListener);
         filterGraphs();
         assert filterChain != null;
         this.filterChain = filterChain;
@@ -227,26 +228,11 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
         hiddenNodesChangedEvent = new ChangedEvent<>(this);
         viewPropertiesChangedEvent = new ChangedEvent<>(this);
 
-        groupChangedEvent = new ChangedEvent<>(this);
-        groupChangedEvent.addListener(groupChangedListener);
-        groupChangedEvent.fire();
 
         filterChain.getChangedEvent().addListener(filterChainChangedListener);
         sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
     }
-    private final ChangedListener<DiagramViewModel> groupChangedListener = new ChangedListener<DiagramViewModel>() {
 
-        private Group oldGroup;
-
-        @Override
-        public void changed(DiagramViewModel source) {
-            if (oldGroup != null) {
-                oldGroup.getChangedEvent().removeListener(groupContentChangedListener);
-            }
-            group.getChangedEvent().addListener(groupContentChangedListener);
-            oldGroup = group;
-        }
-    };
     private final ChangedListener<Group> groupContentChangedListener = new ChangedListener<Group>() {
 
         @Override
@@ -511,6 +497,7 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene
     void close() {
         filterChain.getChangedEvent().removeListener(filterChainChangedListener);
         sequenceFilterChain.getChangedEvent().removeListener(filterChainChangedListener);
+        getChangedEvent().fire();
     }
 
     Iterable<InputGraph> getGraphsForward() {
diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java
index 70da147e534..903dc5afa43 100644
--- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java
+++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorInputGraphProvider.java
@@ -37,9 +37,11 @@ import org.openide.util.lookup.ServiceProvider;
 @ServiceProvider(service=InputGraphProvider.class)
 public class EditorInputGraphProvider implements InputGraphProvider {
 
-    private EditorTopComponent editor;
+    private final EditorTopComponent editor;
 
-    public EditorInputGraphProvider() {}
+    public EditorInputGraphProvider() {
+        editor = null;
+    }
 
     public EditorInputGraphProvider(EditorTopComponent editor) {
         this.editor = editor;
@@ -47,21 +49,35 @@ public class EditorInputGraphProvider implements InputGraphProvider {
 
     @Override
     public InputGraph getGraph() {
-        return editor.getDiagramModel().getGraphToView();
+        if (editor != null && editor.isOpened()) {
+            return editor.getDiagramModel().getGraphToView();
+        } else {
+            return null;
+        }
     }
 
     @Override
     public void setSelectedNodes(Set<InputNode> nodes) {
-        editor.setSelectedNodes(nodes);
+        if (editor != null && editor.isOpened()) {
+            editor.setSelectedNodes(nodes);
+        }
     }
 
     @Override
     public Iterable<InputGraph> searchBackward() {
-        return editor.getDiagramModel().getGraphsBackward();
+        if (editor != null && editor.isOpened()) {
+            return editor.getDiagramModel().getGraphsBackward();
+        } else {
+            return null;
+        }
     }
 
     @Override
     public Iterable<InputGraph> searchForward() {
-        return editor.getDiagramModel().getGraphsForward();
+        if (editor != null && editor.isOpened()) {
+            return editor.getDiagramModel().getGraphsForward();
+        } else {
+            return null;
+        }
     }
 }
diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java
index 432d3eebd30..343a0fd28e1 100644
--- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java
+++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java
@@ -37,7 +37,6 @@ import com.sun.hotspot.igv.filter.FilterChain;
 import com.sun.hotspot.igv.filter.FilterChainProvider;
 import com.sun.hotspot.igv.graph.Diagram;
 import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.services.DiagramProvider;
 import com.sun.hotspot.igv.settings.Settings;
 import com.sun.hotspot.igv.util.LookupHistory;
 import com.sun.hotspot.igv.util.RangeSlider;
@@ -124,31 +123,8 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh
         }
     };
 
-    private DiagramProvider diagramProvider = new DiagramProvider() {
-
-        @Override
-        public Diagram getDiagram() {
-            return getModel().getDiagramToView();
-        }
-
-        @Override
-        public ChangedEvent<DiagramProvider> getChangedEvent() {
-            return diagramChangedEvent;
-        }
-    };
-
-    private ChangedEvent<DiagramProvider> diagramChangedEvent = new ChangedEvent<>(diagramProvider);
-
-
-    private void updateDisplayName() {
-        setDisplayName(getDiagram().getName());
-        setToolTipText(getDiagram().getGraph().getGroup().getName());
-    }
-
     public EditorTopComponent(Diagram diagram) {
-
         LookupHistory.init(InputGraphProvider.class);
-        LookupHistory.init(DiagramProvider.class);
         this.setFocusable(true);
         FilterChain filterChain = null;
         FilterChain sequence = null;
@@ -208,13 +184,16 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh
 
         scene = new DiagramScene(actions, actionsWithSelection, rangeSliderModel);
         content = new InstanceContent();
-        graphContent = new InstanceContent();
-        this.associateLookup(new ProxyLookup(new Lookup[]{scene.getLookup(), new AbstractLookup(graphContent), new AbstractLookup(content)}));
         content.add(exportCookie);
         content.add(rangeSliderModel);
-        content.add(diagramProvider);
+        graphContent = new InstanceContent();
+        associateLookup(new ProxyLookup(scene.getLookup(), new AbstractLookup(graphContent), new AbstractLookup(content)));
 
-        rangeSliderModel.getDiagramChangedEvent().addListener(diagramChangedListener);
+        rangeSliderModel.getDiagramChangedEvent().addListener(source -> {
+            setDisplayName(getDiagram().getName());
+            setToolTipText(getDiagram().getGraph().getGroup().getName());
+            graphContent.set(Collections.singletonList(new EditorInputGraphProvider(this)), null);
+        });
         rangeSliderModel.selectGraph(diagram.getGraph());
         rangeSliderModel.getViewPropertiesChangedEvent().addListener(new ChangedListener<DiagramViewModel>() {
                 @Override
@@ -383,7 +362,7 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh
             rangeSlider.setVisible(false);
         }
 
-        updateDisplayName();
+        getModel().getDiagramChangedEvent().fire();
     }
 
     public DiagramViewModel getDiagramModel() {
@@ -428,7 +407,11 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh
     }
 
     public static EditorTopComponent getActive() {
-        return (EditorTopComponent) EditorTopComponent.getRegistry().getActivated();
+        try {
+            return (EditorTopComponent) EditorTopComponent.getRegistry().getActivated();
+        } catch (Exception e) {
+            return null;
+        }
     }
 
     /** This method is called from within the constructor to
@@ -460,6 +443,7 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh
     public void componentClosed() {
         super.componentClosed();
         rangeSliderModel.close();
+        LookupHistory.terminate(InputGraphProvider.class);
     }
 
     @Override
@@ -468,26 +452,13 @@ public final class EditorTopComponent extends TopComponent implements PropertyCh
     }
 
     private void closeOnRemovedOrEmptyGroup() {
-        Group group = getDiagram().getGraph().getGroup();
+        Group group = getDiagramModel().getGroup();
         if (!group.getParent().getElements().contains(group) ||
             group.getGraphs().isEmpty()) {
             close();
         }
     }
 
-    private ChangedListener<DiagramViewModel> diagramChangedListener = new ChangedListener<DiagramViewModel>() {
-
-        @Override
-        public void changed(DiagramViewModel source) {
-            updateDisplayName();
-            Collection<Object> list = new ArrayList<>();
-            list.add(new EditorInputGraphProvider(EditorTopComponent.this));
-            graphContent.set(list, null);
-            diagramProvider.getChangedEvent().fire();
-        }
-
-    };
-
     public boolean showPredSucc() {
         return (Boolean) predSuccAction.getValue(PredSuccAction.STATE);
     }