Index: trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- trunk/src/org/openstreetmap/josm/Main.java	(revision 14122)
+++ trunk/src/org/openstreetmap/josm/Main.java	(revision 14125)
@@ -36,7 +36,7 @@
 import org.openstreetmap.josm.io.NetworkManager;
 import org.openstreetmap.josm.io.OnlineResource;
+import org.openstreetmap.josm.spi.lifecycle.InitializationTask;
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.spi.preferences.IUrls;
-import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
@@ -87,34 +87,4 @@
      */
     public static volatile PlatformHook platform;
-
-    private static volatile InitStatusListener initListener;
-
-    /**
-     * Initialization task listener.
-     */
-    public interface InitStatusListener {
-
-        /**
-         * Called when an initialization task updates its status.
-         * @param event task name
-         * @return new status
-         */
-        Object updateStatus(String event);
-
-        /**
-         * Called when an initialization task completes.
-         * @param status final status
-         */
-        void finish(Object status);
-    }
-
-    /**
-     * Sets initialization task listener.
-     * @param listener initialization task listener
-     */
-    public static void setInitStatusListener(InitStatusListener listener) {
-        CheckParameterUtil.ensureParameterNotNull(listener);
-        initListener = listener;
-    }
 
     /**
@@ -217,33 +187,4 @@
     }
 
-    protected static final class InitializationTask implements Callable<Void> {
-
-        private final String name;
-        private final Runnable task;
-
-        /**
-         * Constructs a new {@code InitializationTask}.
-         * @param name translated name to be displayed to user
-         * @param task runnable initialization task
-         */
-        public InitializationTask(String name, Runnable task) {
-            this.name = name;
-            this.task = task;
-        }
-
-        @Override
-        public Void call() {
-            Object status = null;
-            if (initListener != null) {
-                status = initListener.updateStatus(name);
-            }
-            task.run();
-            if (initListener != null) {
-                initListener.finish(status);
-            }
-            return null;
-        }
-    }
-
     /**
      * Replies the current selected OSM primitives, from a end-user point of view.
Index: trunk/src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 14122)
+++ trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 14125)
@@ -161,4 +161,7 @@
 import org.openstreetmap.josm.plugins.PluginHandler;
 import org.openstreetmap.josm.plugins.PluginInformation;
+import org.openstreetmap.josm.spi.lifecycle.InitStatusListener;
+import org.openstreetmap.josm.spi.lifecycle.InitializationTask;
+import org.openstreetmap.josm.spi.lifecycle.Lifecycle;
 import org.openstreetmap.josm.spi.preferences.Config;
 import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
@@ -318,4 +321,5 @@
         String location = Config.getUrls().getJOSMWebsite() + "/proj/" + gridFileName;
         // Try to load grid file
+        @SuppressWarnings("resource")
         CachedFile cf = new CachedFile(location);
         try {
@@ -667,4 +671,8 @@
     }
 
+    /**
+     * Redirects the key inputs from {@code source} to main content pane.
+     * @param source source component from which key inputs are redirected
+     */
     public static void redirectToMainContentPane(JComponent source) {
         RedirectInputMap.redirect(source, contentPanePrivate);
@@ -1045,5 +1053,5 @@
             GuiHelper.runInEDT(() -> splash.setVisible(Config.getPref().getBoolean("draw.splashscreen", true)));
         }
-        Main.setInitStatusListener(new InitStatusListener() {
+        Lifecycle.setInitStatusListener(new InitStatusListener() {
 
             @Override
Index: trunk/src/org/openstreetmap/josm/spi/lifecycle/InitStatusListener.java
===================================================================
--- trunk/src/org/openstreetmap/josm/spi/lifecycle/InitStatusListener.java	(revision 14125)
+++ trunk/src/org/openstreetmap/josm/spi/lifecycle/InitStatusListener.java	(revision 14125)
@@ -0,0 +1,22 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.spi.lifecycle;
+
+/**
+ * Initialization task listener.
+ * @since xxx
+ */
+public interface InitStatusListener {
+
+    /**
+     * Called when an initialization task updates its status.
+     * @param event task name
+     * @return new status
+     */
+    Object updateStatus(String event);
+
+    /**
+     * Called when an initialization task completes.
+     * @param status final status
+     */
+    void finish(Object status);
+}
Index: trunk/src/org/openstreetmap/josm/spi/lifecycle/InitializationTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/spi/lifecycle/InitializationTask.java	(revision 14125)
+++ trunk/src/org/openstreetmap/josm/spi/lifecycle/InitializationTask.java	(revision 14125)
@@ -0,0 +1,39 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.spi.lifecycle;
+
+import java.util.Objects;
+import java.util.concurrent.Callable;
+
+/**
+ * Initialization task notifying the current lifecycle {@link InitStatusListener}.
+ * @since xxx
+ */
+public final class InitializationTask implements Callable<Void> {
+
+    private final String name;
+    private final Runnable task;
+
+    /**
+     * Constructs a new {@code InitializationTask}.
+     * @param name translated name to be displayed to user
+     * @param task runnable initialization task
+     */
+    public InitializationTask(String name, Runnable task) {
+        this.name = Objects.requireNonNull(name);
+        this.task = Objects.requireNonNull(task);
+    }
+
+    @Override
+    public Void call() {
+        Object status = null;
+        InitStatusListener initListener = Lifecycle.getInitStatusListener();
+        if (initListener != null) {
+            status = initListener.updateStatus(name);
+        }
+        task.run();
+        if (initListener != null) {
+            initListener.finish(status);
+        }
+        return null;
+    }
+}
Index: trunk/src/org/openstreetmap/josm/spi/lifecycle/Lifecycle.java
===================================================================
--- trunk/src/org/openstreetmap/josm/spi/lifecycle/Lifecycle.java	(revision 14125)
+++ trunk/src/org/openstreetmap/josm/spi/lifecycle/Lifecycle.java	(revision 14125)
@@ -0,0 +1,33 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.spi.lifecycle;
+
+import java.util.Objects;
+
+/**
+ * JOSM lifecycle.
+ * @since xxx
+ */
+public final class Lifecycle {
+
+    private static volatile InitStatusListener initStatusListener;
+
+    private Lifecycle() {
+        // Hide constructor
+    }
+
+    /**
+     * Gets initialization task listener.
+     * @return initialization task listener
+     */
+    public static InitStatusListener getInitStatusListener() {
+        return initStatusListener;
+    }
+
+    /**
+     * Sets initialization task listener.
+     * @param listener initialization task listener. Must not be null
+     */
+    public static void setInitStatusListener(InitStatusListener listener) {
+        initStatusListener = Objects.requireNonNull(listener);
+    }
+}
