diff --git a/apps/desktopgui/src/net/i2p/desktopgui/ExternalTrayManager.java b/apps/desktopgui/src/net/i2p/desktopgui/ExternalTrayManager.java
index cf97d255b79d5b33ee8f79efdc5bef7d3c3a6830..a18d16b22365057cfa4a12d413100f1aa810b940 100644
--- a/apps/desktopgui/src/net/i2p/desktopgui/ExternalTrayManager.java
+++ b/apps/desktopgui/src/net/i2p/desktopgui/ExternalTrayManager.java
@@ -13,7 +13,7 @@ import net.i2p.desktopgui.router.RouterManager;
 
 /**
  *  When started before the router, e.g. with
- *  java -cp i2p.jar:desktopgui.jar net.i2p.desktopgui.Main
+ *  java -cp i2p.jar:router.jar:desktopgui.jar net.i2p.desktopgui.Main
  *
  *  No access to context, very limited abilities.
  *  Not fully supported.
@@ -56,4 +56,10 @@ class ExternalTrayManager extends TrayManager {
         popup.add(startItem);
         return popup;
     }
+
+    /**
+     * Update the menu
+     * @since 0.9.26
+     */
+    protected void updateMenu() {}
 }
diff --git a/apps/desktopgui/src/net/i2p/desktopgui/InternalTrayManager.java b/apps/desktopgui/src/net/i2p/desktopgui/InternalTrayManager.java
index 70fb2c553bd537ee84173fcbd0090783191e4552..8c49559b8d3fcc67db5e6054c3a3fa98522a3111 100644
--- a/apps/desktopgui/src/net/i2p/desktopgui/InternalTrayManager.java
+++ b/apps/desktopgui/src/net/i2p/desktopgui/InternalTrayManager.java
@@ -14,7 +14,7 @@ import net.i2p.router.RouterContext;
 import net.i2p.util.Log;
 
 /**
- *  java -cp i2p.jar:desktopgui.jar net.i2p.desktopgui.Main
+ *  java -cp i2p.jar:router.jar:desktopgui.jar net.i2p.desktopgui.Main
  *
  *  Full access to router context.
  */
@@ -22,6 +22,7 @@ class InternalTrayManager extends TrayManager {
 	
     private final RouterContext _context;
     private final Log log;
+    private MenuItem _restartItem, _stopItem, _cancelItem;
 
     public InternalTrayManager(RouterContext ctx, Main main) {
         super(ctx, main);
@@ -35,11 +36,9 @@ class InternalTrayManager extends TrayManager {
         
         MenuItem browserLauncher = new MenuItem(_t("Launch I2P Browser"));
         browserLauncher.addActionListener(new ActionListener() {
-            
             @Override
             public void actionPerformed(ActionEvent arg0) {
                 new SwingWorker<Object, Object>() {
-
                     @Override
                     protected Object doInBackground() throws Exception {
                         return null;
@@ -53,76 +52,137 @@ class InternalTrayManager extends TrayManager {
                             log.log(Log.WARN, "Failed to open browser!", e1);
                         }    
                     }
-                    
                 }.execute();
             }
         });
+
         PopupMenu desktopguiConfigurationLauncher = new PopupMenu(_t("Configure I2P System Tray"));
         MenuItem configSubmenu = new MenuItem(_t("Disable"));
         configSubmenu.addActionListener(new ActionListener() {
-
             @Override
             public void actionPerformed(ActionEvent arg0) {
                 new SwingWorker<Object, Object>() {
-
                     @Override
                     protected Object doInBackground() throws Exception {
                         configureDesktopgui(false);
                         return null;
                     }
-
                 }.execute();
             }
-
         });
-        MenuItem restartItem = new MenuItem(_t("Restart I2P"));
-        restartItem.addActionListener(new ActionListener() {
 
+        final MenuItem restartItem;
+        if (_context.hasWrapper()) {
+            restartItem = new MenuItem(_t("Restart I2P"));
+            restartItem.addActionListener(new ActionListener() {
+                @Override
+                public void actionPerformed(ActionEvent arg0) {
+                    new SwingWorker<Object, Object>() {
+                        @Override
+                        protected Object doInBackground() throws Exception {
+                            RouterManager.restartGracefully(_context);
+                            return null;
+                        }
+                    }.execute();
+                }
+            });
+        } else {
+            restartItem = null;
+        }
+
+        final MenuItem stopItem = new MenuItem(_t("Stop I2P"));
+        stopItem.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent arg0) {
                 new SwingWorker<Object, Object>() {
-
                     @Override
                     protected Object doInBackground() throws Exception {
-                        RouterManager.restart(_context);
+                        RouterManager.shutDownGracefully(_context);
                         return null;
                     }
-                    
                 }.execute();
-                
             }
-            
         });
-        MenuItem stopItem = new MenuItem(_t("Stop I2P"));
-        stopItem.addActionListener(new ActionListener() {
 
+        final MenuItem restartItem2;
+        if (_context.hasWrapper()) {
+            restartItem2 = new MenuItem(_t("Restart I2P Immediately"));
+            restartItem2.addActionListener(new ActionListener() {
+                @Override
+                public void actionPerformed(ActionEvent arg0) {
+                    new SwingWorker<Object, Object>() {
+                        @Override
+                        protected Object doInBackground() throws Exception {
+                            RouterManager.restart(_context);
+                            return null;
+                        }
+                    }.execute();
+                }
+            });
+        } else {
+            restartItem2 = null;
+        }
+
+        final MenuItem stopItem2 = new MenuItem(_t("Stop I2P Immediately"));
+        stopItem2.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent arg0) {
                 new SwingWorker<Object, Object>() {
-                    
                     @Override
                     protected Object doInBackground() throws Exception {
                         RouterManager.shutDown(_context);
                         return null;
                     }
-                    
                 }.execute();
-                
             }
-            
         });
-        
+
+        final MenuItem cancelItem = new MenuItem(_t("Cancel I2P Shutdown"));
+        cancelItem.addActionListener(new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent arg0) {
+                new SwingWorker<Object, Object>() {
+                    @Override
+                    protected Object doInBackground() throws Exception {
+                        RouterManager.cancelShutdown(_context);
+                        return null;
+                    }
+                }.execute();
+            }
+        });
+
         popup.add(browserLauncher);
         popup.addSeparator();
         desktopguiConfigurationLauncher.add(configSubmenu);
         popup.add(desktopguiConfigurationLauncher);
         popup.addSeparator();
-        popup.add(restartItem);
+        if (_context.hasWrapper())
+            popup.add(restartItem);
         popup.add(stopItem);
+        if (_context.hasWrapper())
+            popup.add(restartItem2);
+        popup.add(stopItem2);
+        popup.add(cancelItem);
         
+        _restartItem = restartItem;
+        _stopItem = stopItem;
+        _cancelItem = cancelItem;
+
         return popup;
     }
 
+    /**
+     * Update the menu
+     * @since 0.9.26
+     */
+    protected void updateMenu() {
+        boolean x = RouterManager.isShutdownInProgress(_context);
+        if (_restartItem != null)
+            _restartItem.setEnabled(!x);
+        _stopItem.setEnabled(!x);
+        _cancelItem.setEnabled(x);
+    }
+
     /**
      *  @since 0.9.26 from removed gui/DesktopguiConfigurationFrame
      */
diff --git a/apps/desktopgui/src/net/i2p/desktopgui/TrayManager.java b/apps/desktopgui/src/net/i2p/desktopgui/TrayManager.java
index 31b7569d3c2afd901cfcad5c0c67ff6145a06e0a..1982dba61beed8ea0c98cb6081c077ea12ae3abc 100644
--- a/apps/desktopgui/src/net/i2p/desktopgui/TrayManager.java
+++ b/apps/desktopgui/src/net/i2p/desktopgui/TrayManager.java
@@ -6,6 +6,8 @@ import java.awt.PopupMenu;
 import java.awt.SystemTray;
 import java.awt.Toolkit;
 import java.awt.TrayIcon;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseListener;
 import java.net.URL;
 
 import net.i2p.I2PAppContext;
@@ -48,6 +50,13 @@ abstract class TrayManager {
             tray.add(trayIcon);
             // 16x16 on Windows, 24x24 on Linux, but that will probably vary
             //System.out.println("Tray icon size is " + trayIcon.getSize());
+            trayIcon.addMouseListener(new MouseListener() {
+                public void mouseClicked(MouseEvent m)  { updateMenu(); }
+                public void mouseEntered(MouseEvent m)  { updateMenu(); }
+                public void mouseExited(MouseEvent m)   { updateMenu(); }
+                public void mousePressed(MouseEvent m)  { updateMenu(); }
+                public void mouseReleased(MouseEvent m) { updateMenu(); }
+            });
         } else {
             throw new AWTException("SystemTray not supported");
         }
@@ -77,6 +86,12 @@ abstract class TrayManager {
      */
     protected abstract PopupMenu getMainMenu();
     
+    /**
+     * Update the menu
+     * @since 0.9.26
+     */
+    protected abstract void updateMenu();
+    
     /**
      * Get tray icon image from the desktopgui resources in the jar file.
      * @return image used for the tray icon
diff --git a/apps/desktopgui/src/net/i2p/desktopgui/router/RouterManager.java b/apps/desktopgui/src/net/i2p/desktopgui/router/RouterManager.java
index 9267bcef082b924e80d9fa4ed274319dd961503d..4d2f8e2143dbd67022c0524127c224d811370dae 100644
--- a/apps/desktopgui/src/net/i2p/desktopgui/router/RouterManager.java
+++ b/apps/desktopgui/src/net/i2p/desktopgui/router/RouterManager.java
@@ -2,15 +2,18 @@ package net.i2p.desktopgui.router;
 
 import java.io.IOException;
 
-import org.tanukisoftware.wrapper.WrapperManager;
-
 import net.i2p.I2PAppContext;
 import net.i2p.router.Router;
 import net.i2p.router.RouterContext;
+//import net.i2p.router.web.ConfigServiceHandler;
 import net.i2p.util.Log;
 
 /**
  * Handle communications with the router instance.
+ *
+ * See ConfigServiceHandler for best practices on stopping the router.
+ * We don't bother notifying any Wrapper instance here.
+ *
  * @author mathias
  *
  */
@@ -45,22 +48,53 @@ public class RouterManager {
      * Restart the running I2P instance.
      */
     public static void restart(RouterContext ctx) {
-        ctx.router().restart();
+        //if (ctx.hasWrapper())
+        //    ConfigServiceHandler.registerWrapperNotifier(ctx, Router.EXIT_HARD_RESTART, false);
+        ctx.router().shutdownGracefully(Router.EXIT_HARD_RESTART);
     }
 
     /**
      * Stop the running I2P instance.
      */
     public static void shutDown(RouterContext ctx) {
-            Thread t = new Thread(new Runnable() {
+        //if (ctx.hasWrapper())
+        //    ConfigServiceHandler.registerWrapperNotifier(ctx, Router.EXIT_HARD, false);
+        ctx.router().shutdownGracefully(Router.EXIT_HARD);
+    }
+    
+    /**
+     * Restart the running I2P instance.
+     * @since 0.9.26
+     */
+    public static void restartGracefully(RouterContext ctx) {
+        //if (ctx.hasWrapper())
+        //    ConfigServiceHandler.registerWrapperNotifier(ctx, Router.EXIT_GRACEFUL_RESTART, false);
+        ctx.router().shutdownGracefully(Router.EXIT_GRACEFUL_RESTART);
+    }
+
+    /**
+     * Stop the running I2P instance.
+     * @since 0.9.26
+     */
+    public static void shutDownGracefully(RouterContext ctx) {
+        //if (ctx.hasWrapper())
+        //    ConfigServiceHandler.registerWrapperNotifier(ctx, Router.EXIT_GRACEFUL, false);
+        ctx.router().shutdownGracefully();
+    }
+
+    /**
+     * Cancel a graceful shutdown or restart
+     * @since 0.9.26
+     */
+    public static void cancelShutdown(RouterContext ctx) {
+        ctx.router().cancelGracefulShutdown();
+    }
 
-                @Override
-                public void run() {
-                    WrapperManager.signalStopped(Router.EXIT_HARD);    
-                }
-                
-            });
-            t.start();
-            ctx.router().shutdown(Router.EXIT_HARD);
+    /**
+     * Is a graceful shutdown or restart in progress?
+     * @since 0.9.26
+     */
+    public static boolean isShutdownInProgress(RouterContext ctx) {
+        return ctx.router().scheduledGracefulExitCode() > 0;
     }
 }