Index: trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- trunk/src/org/openstreetmap/josm/Main.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/Main.java	(revision 12620)
@@ -232,5 +232,7 @@
      * @return the first lines of last 5 error and warning messages
      * @since 7420
-     */
+     * @deprecated Use {@link Logging#getLastErrorAndWarnings}.
+     */
+    @Deprecated
     public static final Collection<String> getLastErrorAndWarnings() {
         return Logging.getLastErrorAndWarnings();
@@ -240,5 +242,7 @@
      * Clears the list of last error and warning messages.
      * @since 8959
-     */
+     * @deprecated Use {@link Logging#clearLastErrorAndWarnings}.
+     */
+    @Deprecated
     public static void clearLastErrorAndWarnings() {
         Logging.clearLastErrorAndWarnings();
@@ -249,5 +253,7 @@
      * @param msg The message to print.
      * @since 6248
-     */
+     * @deprecated Use {@link Logging#error(String)}.
+     */
+    @Deprecated
     public static void error(String msg) {
         Logging.error(msg);
@@ -257,5 +263,7 @@
      * Prints a warning message if logging is on.
      * @param msg The message to print.
-     */
+     * @deprecated Use {@link Logging#warn(String)}.
+     */
+    @Deprecated
     public static void warn(String msg) {
         Logging.warn(msg);
@@ -265,5 +273,7 @@
      * Prints an informational message if logging is on.
      * @param msg The message to print.
-     */
+     * @deprecated Use {@link Logging#info(String)}.
+     */
+    @Deprecated
     public static void info(String msg) {
         Logging.info(msg);
@@ -273,5 +283,7 @@
      * Prints a debug message if logging is on.
      * @param msg The message to print.
-     */
+     * @deprecated Use {@link Logging#debug(String)}.
+     */
+    @Deprecated
     public static void debug(String msg) {
         Logging.debug(msg);
@@ -281,5 +293,7 @@
      * Prints a trace message if logging is on.
      * @param msg The message to print.
-     */
+     * @deprecated Use {@link Logging#trace(String)}.
+     */
+    @Deprecated
     public static void trace(String msg) {
         Logging.trace(msg);
@@ -291,7 +305,9 @@
      * @return {@code true} if log level is at least debug, {@code false} otherwise
      * @since 6852
-     */
+     * @deprecated Use {@link Logging#isDebugEnabled}.
+     */
+    @Deprecated
     public static boolean isDebugEnabled() {
-        return Logging.isLoggingEnabled(Logging.LEVEL_DEBUG);
+        return Logging.isDebugEnabled();
     }
 
@@ -301,7 +317,9 @@
      * @return {@code true} if log level is at least trace, {@code false} otherwise
      * @since 6852
-     */
+     * @deprecated Use {@link Logging#isTraceEnabled}.
+     */
+    @Deprecated
     public static boolean isTraceEnabled() {
-        return Logging.isLoggingEnabled(Logging.LEVEL_TRACE);
+        return Logging.isTraceEnabled();
     }
 
@@ -312,5 +330,7 @@
      * @param objects The objects to insert into format string.
      * @since 6248
-     */
+     * @deprecated Use {@link Logging#error(String, Object...)}.
+     */
+    @Deprecated
     public static void error(String msg, Object... objects) {
         Logging.error(msg, objects);
@@ -322,5 +342,7 @@
      * @param msg The formatted message to print.
      * @param objects The objects to insert into format string.
-     */
+     * @deprecated Use {@link Logging#warn(String, Object...)}.
+     */
+    @Deprecated
     public static void warn(String msg, Object... objects) {
         Logging.warn(msg, objects);
@@ -332,5 +354,7 @@
      * @param msg The formatted message to print.
      * @param objects The objects to insert into format string.
-     */
+     * @deprecated Use {@link Logging#info(String, Object...)}.
+     */
+    @Deprecated
     public static void info(String msg, Object... objects) {
         Logging.info(msg, objects);
@@ -342,5 +366,7 @@
      * @param msg The formatted message to print.
      * @param objects The objects to insert into format string.
-     */
+     * @deprecated Use {@link Logging#debug(String, Object...)}.
+     */
+    @Deprecated
     public static void debug(String msg, Object... objects) {
         Logging.debug(msg, objects);
@@ -352,5 +378,7 @@
      * @param msg The formatted message to print.
      * @param objects The objects to insert into format string.
-     */
+     * @deprecated Use {@link Logging#trace(String, Object...)}.
+     */
+    @Deprecated
     public static void trace(String msg, Object... objects) {
         Logging.trace(msg, objects);
@@ -361,7 +389,9 @@
      * @param t The throwable object causing the error
      * @since 6248
-     */
+     * @deprecated Use {@link Logging#error(Throwable)}.
+     */
+    @Deprecated
     public static void error(Throwable t) {
-        Logging.logWithStackTrace(Logging.LEVEL_ERROR, t);
+        Logging.error(t);
     }
 
@@ -370,7 +400,9 @@
      * @param t The throwable object causing the error
      * @since 6248
-     */
+     * @deprecated Use {@link Logging#warn(Throwable)}.
+     */
+    @Deprecated
     public static void warn(Throwable t) {
-        Logging.logWithStackTrace(Logging.LEVEL_WARN, t);
+        Logging.warn(t);
     }
 
@@ -379,7 +411,9 @@
      * @param t The throwable object causing the error
      * @since 10420
-     */
+     * @deprecated Use {@link Logging#debug(Throwable)}.
+     */
+    @Deprecated
     public static void debug(Throwable t) {
-        Logging.log(Logging.LEVEL_DEBUG, t);
+        Logging.debug(t);
     }
 
@@ -388,7 +422,9 @@
      * @param t The throwable object causing the error
      * @since 10420
-     */
+     * @deprecated Use {@link Logging#trace(Throwable)}.
+     */
+    @Deprecated
     public static void trace(Throwable t) {
-        Logging.log(Logging.LEVEL_TRACE, t);
+        Logging.trace(t);
     }
 
@@ -398,5 +434,8 @@
      * @param stackTrace {@code true}, if the stacktrace should be displayed
      * @since 6642
-     */
+     * @deprecated Use {@link Logging#log(java.util.logging.Level, Throwable)}
+     *              or {@link Logging#logWithStackTrace(java.util.logging.Level, Throwable)}.
+     */
+    @Deprecated
     public static void error(Throwable t, boolean stackTrace) {
         if (stackTrace) {
@@ -412,5 +451,7 @@
      * @param message additional error message
      * @since 10420
-     */
+     * @deprecated Use {@link Logging#log(java.util.logging.Level, String, Throwable)}.
+     */
+    @Deprecated
     public static void error(Throwable t, String message) {
         Logging.log(Logging.LEVEL_ERROR, message, t);
@@ -422,5 +463,8 @@
      * @param stackTrace {@code true}, if the stacktrace should be displayed
      * @since 6642
-     */
+     * @deprecated Use {@link Logging#log(java.util.logging.Level, Throwable)}
+     *              or {@link Logging#logWithStackTrace(java.util.logging.Level, Throwable)}.
+     */
+    @Deprecated
     public static void warn(Throwable t, boolean stackTrace) {
         if (stackTrace) {
@@ -436,5 +480,7 @@
      * @param message additional error message
      * @since 10420
-     */
+     * @deprecated Use {@link Logging#log(java.util.logging.Level, String, Throwable)}.
+     */
+    @Deprecated
     public static void warn(Throwable t, String message) {
         Logging.log(Logging.LEVEL_WARN, message, t);
@@ -446,5 +492,7 @@
      * @return The human-readable error message
      * @since 6642
-     */
+     * @deprecated Use {@link Logging#getErrorMessage}.
+     */
+    @Deprecated
     public static String getErrorMessage(Throwable t) {
         if (t == null) {
@@ -543,5 +591,5 @@
                     OsmApi.getOsmApi().initialize(null, true);
                 } catch (OsmTransferCanceledException | OsmApiInitializationException e) {
-                    Main.warn(getErrorMessage(Utils.getRootCause(e)));
+                    Logging.warn(getErrorMessage(Utils.getRootCause(e)));
                 }
             }));
@@ -667,5 +715,5 @@
         Object existing = inputMap.get(keyStroke);
         if (existing != null && !existing.equals(action)) {
-            info(String.format("Keystroke %s is already assigned to %s, will be overridden by %s", keyStroke, existing, action));
+            Logging.info(String.format("Keystroke %s is already assigned to %s, will be overridden by %s", keyStroke, existing, action));
         }
         inputMap.put(keyStroke, action);
@@ -740,5 +788,5 @@
         } catch (final NoClassDefFoundError | ClassNotFoundException e) {
             // Try to find look and feel in plugin classloaders
-            Main.trace(e);
+            Logging.trace(e);
             Class<?> klass = null;
             for (ClassLoader cl : PluginHandler.getResourceClassLoaders()) {
@@ -747,5 +795,5 @@
                     break;
                 } catch (ClassNotFoundException ex) {
-                    Main.trace(ex);
+                    Logging.trace(ex);
                 }
             }
@@ -754,20 +802,20 @@
                     UIManager.setLookAndFeel((LookAndFeel) klass.getConstructor().newInstance());
                 } catch (ReflectiveOperationException ex) {
-                    warn(ex, "Cannot set Look and Feel: " + laf + ": "+ex.getMessage());
+                    Logging.log(Logging.LEVEL_WARN, "Cannot set Look and Feel: " + laf + ": "+ex.getMessage(), ex);
                 } catch (UnsupportedLookAndFeelException ex) {
-                    info("Look and Feel not supported: " + laf);
+                    Logging.info("Look and Feel not supported: " + laf);
                     LafPreference.LAF.put(defaultlaf);
-                    trace(ex);
+                    Logging.trace(ex);
                 }
             } else {
-                info("Look and Feel not found: " + laf);
+                Logging.info("Look and Feel not found: " + laf);
                 LafPreference.LAF.put(defaultlaf);
             }
         } catch (UnsupportedLookAndFeelException e) {
-            info("Look and Feel not supported: " + laf);
+            Logging.info("Look and Feel not supported: " + laf);
             LafPreference.LAF.put(defaultlaf);
-            trace(e);
+            Logging.trace(e);
         } catch (InstantiationException | IllegalAccessException e) {
-            error(e);
+            Logging.error(e);
         }
         toolbar = new ToolbarPreferences();
@@ -791,5 +839,5 @@
             CoordinateFormat.setCoordinateFormat(CoordinateFormat.valueOf(Main.pref.get("coordinates")));
         } catch (IllegalArgumentException iae) {
-            Main.trace(iae);
+            Logging.trace(iae);
             CoordinateFormat.setCoordinateFormat(CoordinateFormat.DECIMAL_DEGREES);
         }
@@ -867,5 +915,5 @@
             pref.saveDefaults();
         } catch (IOException ex) {
-            Main.warn(ex, tr("Failed to save default preferences."));
+            Logging.log(Logging.LEVEL_WARN, tr("Failed to save default preferences."), ex);
         }
         if (!GraphicsEnvironment.isHeadless()) {
@@ -907,5 +955,5 @@
                     f = new File(new URI(s));
                 } catch (URISyntaxException e) {
-                    Main.warn(e);
+                    Logging.warn(e);
                     JOptionPane.showMessageDialog(
                             Main.parent,
@@ -1018,5 +1066,5 @@
         String os = System.getProperty("os.name");
         if (os == null) {
-            warn("Your operating system has no name, so I'm guessing its some kind of *nix.");
+            Logging.warn("Your operating system has no name, so I'm guessing its some kind of *nix.");
             platform = new PlatformHookUnixoid();
         } else if (os.toLowerCase(Locale.ENGLISH).startsWith("windows")) {
@@ -1029,5 +1077,5 @@
             platform = new PlatformHookOsx();
         } else {
-            warn("I don't know your operating system '"+os+"', so I'm guessing its some kind of *nix.");
+            Logging.warn("I don't know your operating system '"+os+"', so I'm guessing its some kind of *nix.");
             platform = new PlatformHookUnixoid();
         }
@@ -1196,5 +1244,5 @@
             Throwable old = addNetworkError(url.toExternalForm(), t);
             if (old != null) {
-                Main.warn("Already here "+old);
+                Logging.warn("Already here "+old);
             }
             return old;
Index: trunk/src/org/openstreetmap/josm/actions/AboutAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AboutAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/AboutAction.java	(revision 12620)
@@ -31,4 +31,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -137,5 +138,5 @@
                 }
             } catch (IOException e) {
-                Main.warn(e);
+                Logging.warn(e);
                 displayErrorMessage(ta, tr("Failed to load resource ''{0}'', error is {1}.", filePath, e.toString()));
             }
@@ -144,5 +145,5 @@
 
     private static void displayErrorMessage(JTextArea ta, String msg) {
-        Main.warn(msg);
+        Logging.warn(msg);
         ta.setForeground(new Color(200, 0, 0));
         ta.setText(msg);
Index: trunk/src/org/openstreetmap/josm/actions/AbstractInfoAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AbstractInfoAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/AbstractInfoAction.java	(revision 12620)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.gui.help.HelpUtil;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OpenBrowser;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -139,5 +140,5 @@
             String result = OpenBrowser.displayUrl(url);
             if (result != null) {
-                Main.warn(result);
+                Logging.warn(result);
             }
         }
Index: trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/AddImageryLayerAction.java	(revision 12620)
@@ -39,4 +39,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -115,5 +116,5 @@
                         tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
             }
-            Main.error(ex, false);
+            Logging.log(Logging.LEVEL_ERROR, ex);
         } catch (IOException ex) {
             if (!GraphicsEnvironment.isHeadless()) {
@@ -121,5 +122,5 @@
                         tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
             }
-            Main.error(ex, false);
+            Logging.log(Logging.LEVEL_ERROR, ex);
         } catch (WMSGetCapabilitiesException ex) {
             if (!GraphicsEnvironment.isHeadless()) {
@@ -127,5 +128,5 @@
                         tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
             }
-            Main.error(ex, "Could not parse WMS layer list. Incoming data:\n"+ex.getIncomingData());
+            Logging.log(Logging.LEVEL_ERROR, "Could not parse WMS layer list. Incoming data:\n"+ex.getIncomingData(), ex);
         }
         return null;
Index: trunk/src/org/openstreetmap/josm/actions/AlignInLineAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AlignInLineAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/AlignInLineAction.java	(revision 12620)
@@ -27,4 +27,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.Notification;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -173,5 +174,5 @@
             Main.main.undoRedo.add(buildCommand());
         } catch (InvalidSelection except) {
-            Main.debug(except);
+            Logging.debug(except);
             new Notification(except.getMessage())
                 .setIcon(JOptionPane.INFORMATION_MESSAGE)
Index: trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java	(revision 12620)
@@ -35,4 +35,5 @@
 import org.openstreetmap.josm.gui.dialogs.ValidatorDialog.ValidatorBoundingXYVisitor;
 import org.openstreetmap.josm.gui.layer.Layer;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -229,5 +230,5 @@
                 return layers.get(0);
         } catch (IllegalStateException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         return null;
Index: trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/CombineWayAction.java	(revision 12620)
@@ -35,4 +35,5 @@
 import org.openstreetmap.josm.gui.conflict.tags.CombinePrimitiveResolverDialog;
 import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -228,5 +229,5 @@
             combineResult = combineWaysWorker(selectedWays);
         } catch (UserCancelException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
             return;
         }
Index: trunk/src/org/openstreetmap/josm/actions/DistributeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/DistributeAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/DistributeAction.java	(revision 12620)
@@ -24,4 +24,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.Notification;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -71,5 +72,5 @@
         Set<Node> ignoredNodes = removeNodesWithoutCoordinates(nodes);
         if (!ignoredNodes.isEmpty()) {
-            Main.warn(tr("Ignoring {0} nodes with null coordinates", ignoredNodes.size()));
+            Logging.warn(tr("Ignoring {0} nodes with null coordinates", ignoredNodes.size()));
             ignoredNodes.clear();
         }
Index: trunk/src/org/openstreetmap/josm/actions/DownloadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/DownloadAction.java	(revision 12620)
@@ -26,4 +26,5 @@
 import org.openstreetmap.josm.gui.download.DownloadDialog;
 import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -120,5 +121,5 @@
                         }
                     } catch (InterruptedException | ExecutionException ex) {
-                        Main.warn(ex);
+                        Logging.warn(ex);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java	(revision 12620)
@@ -29,4 +29,5 @@
 import org.openstreetmap.josm.io.WMSLayerImporter;
 import org.openstreetmap.josm.io.session.SessionImporter;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -75,5 +76,5 @@
                 importers.add(importer);
             } catch (ReflectiveOperationException e) {
-                Main.debug(e);
+                Logging.debug(e);
             } catch (ServiceConfigurationError e) {
                 // error seen while initializing WMSLayerImporter in plugin unit tests:
@@ -91,5 +92,5 @@
                 // -
                 // that can lead to various problems, see #8583 comments
-                Main.error(e);
+                Logging.error(e);
             }
         }
@@ -113,8 +114,8 @@
                 Main.getLayerManager().addAndFireActiveLayerChangeListener(exporter);
             } catch (ReflectiveOperationException e) {
-                Main.debug(e);
+                Logging.debug(e);
             } catch (ServiceConfigurationError e) {
                 // see above in importers initialization
-                Main.error(e);
+                Logging.error(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/actions/GpxExportAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/GpxExportAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/GpxExportAction.java	(revision 12620)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.io.GpxImporter;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -90,5 +91,5 @@
                     exporter.exportData(file, layer);
                 } catch (IOException e) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/actions/ImageryAdjustAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ImageryAdjustAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/ImageryAdjustAction.java	(revision 12620)
@@ -35,4 +35,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -102,5 +103,5 @@
             Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
         } catch (SecurityException ex) {
-            Main.error(ex);
+            Logging.error(ex);
         }
     }
@@ -123,5 +124,5 @@
             Toolkit.getDefaultToolkit().removeAWTEventListener(this);
         } catch (SecurityException ex) {
-            Main.error(ex);
+            Logging.error(ex);
         }
         if (Main.isDisplayingMapView()) {
@@ -157,6 +158,6 @@
                 offsetDialog.updateOffset();
             }
-            if (Main.isDebugEnabled()) {
-                Main.debug(getClass().getName()+" consuming event "+kev);
+            if (Logging.isDebugEnabled()) {
+                Logging.debug("{0} consuming event {1}", getClass().getName(), kev);
             }
             kev.consume();
@@ -261,5 +262,5 @@
                 } catch (NumberFormatException nfe) {
                     // we repaint offset numbers in any case
-                    Main.trace(nfe);
+                    Logging.trace(nfe);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/JoinAreasAction.java	(revision 12620)
@@ -46,4 +46,5 @@
 import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -564,5 +565,5 @@
             }
         } catch (UserCancelException exception) {
-            Main.trace(exception);
+            Logging.trace(exception);
             //revert changes
             //FIXME: this is dirty hack
@@ -735,5 +736,5 @@
             return true;
         } catch (UserCancelException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
             return false;
         }
Index: trunk/src/org/openstreetmap/josm/actions/JosmAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/JosmAction.java	(revision 12620)
@@ -28,4 +28,5 @@
 import org.openstreetmap.josm.tools.Destroyable;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -276,5 +277,5 @@
                             future.get();
                         } catch (InterruptedException | ExecutionException | CancellationException e) {
-                            Main.error(e);
+                            Logging.error(e);
                             return;
                         }
Index: trunk/src/org/openstreetmap/josm/actions/JumpToAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/JumpToAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/JumpToAction.java	(revision 12620)
@@ -27,4 +27,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OsmUrlToBounds;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -196,5 +197,5 @@
             url.setText(OsmUrlToBounds.getURL(dlat, dlon, (int) zoomLvl));
         } catch (NumberFormatException e) {
-            Main.debug(e.getMessage());
+            Logging.debug(e.getMessage());
         }
     }
Index: trunk/src/org/openstreetmap/josm/actions/MapRectifierWMSmenuAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MapRectifierWMSmenuAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/MapRectifierWMSmenuAction.java	(revision 12620)
@@ -31,4 +31,5 @@
 import org.openstreetmap.josm.io.imagery.WMSImagery.WMSGetCapabilitiesException;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -193,5 +194,5 @@
                         break outer;
                     } catch (IllegalStateException ex) {
-                        Main.error(ex, false);
+                        Logging.log(Logging.LEVEL_ERROR, ex);
                     }
                 }
@@ -240,5 +241,5 @@
                 info = AddImageryLayerAction.getWMSLayerInfo(info);
             } catch (IOException | WMSGetCapabilitiesException e) {
-                Main.error(e);
+                Logging.error(e);
                 JOptionPane.showMessageDialog(Main.parent, e.getMessage(), tr("No valid WMS URL or id"), JOptionPane.ERROR_MESSAGE);
                 return;
Index: trunk/src/org/openstreetmap/josm/actions/MergeLayerAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MergeLayerAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/MergeLayerAction.java	(revision 12620)
@@ -18,4 +18,5 @@
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.Utils;
@@ -69,5 +70,5 @@
                 if (layerMerged) {
                     Main.getLayerManager().setActiveLayer(targetLayer);
-                    Main.info(tr("{0} completed in {1}", actionName, Utils.getDurationString(System.currentTimeMillis() - start)));
+                    Logging.info(tr("{0} completed in {1}", actionName, Utils.getDurationString(System.currentTimeMillis() - start)));
                 }
         });
@@ -118,5 +119,5 @@
                         // May occur when destroying last layer / exiting JOSM, see #14476
                         setEnabled(false);
-                        Main.error(e);
+                        Logging.error(e);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/MergeNodesAction.java	(revision 12620)
@@ -40,4 +40,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.UserCancelException;
@@ -346,5 +347,5 @@
                     trn("Merge {0} node", "Merge {0} nodes", nodes.size(), nodes.size()), cmds);
         } catch (UserCancelException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
             return null;
         }
Index: trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java	(revision 12620)
@@ -38,4 +38,5 @@
 import org.openstreetmap.josm.io.FileImporter;
 import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -320,5 +321,5 @@
                         }
                     } catch (IOException | PatternSyntaxException | IllegalStateException | IndexOutOfBoundsException e) {
-                        Main.error(e);
+                        Logging.error(e);
                     }
                 }
@@ -367,5 +368,5 @@
                         }
                     } catch (IOException e) {
-                        Main.warn(e);
+                        Logging.warn(e);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/OpenLocationAction.java	(revision 12620)
@@ -44,4 +44,5 @@
 import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.Utils;
@@ -166,5 +167,5 @@
                         return taskClass.getConstructor().newInstance();
                     } catch (ReflectiveOperationException e) {
-                        Main.error(e);
+                        Logging.error(e);
                         return null;
                     }
@@ -188,5 +189,5 @@
                     result.append(task.acceptsDocumentationSummary());
                 } catch (ReflectiveOperationException e) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
             }
@@ -234,5 +235,5 @@
                 result.add(Main.worker.submit(new PostDownloadHandler(task, task.loadUrl(newLayer, url, monitor))));
             } catch (IllegalArgumentException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/OrthogonalizeAction.java	(revision 12620)
@@ -32,4 +32,5 @@
 import org.openstreetmap.josm.gui.Notification;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.Utils;
@@ -120,5 +121,5 @@
                 }
             } catch (InvalidUserInputException ex) {
-                Main.debug(ex);
+                Logging.debug(ex);
                 new Notification(
                         tr("Orthogonalize Shape / Undo<br>"+
@@ -166,5 +167,5 @@
             Main.main.undoRedo.add(new SequenceCommand(tr("Orthogonalize"), command));
         } catch (InvalidUserInputException ex) {
-            Main.debug(ex);
+            Logging.debug(ex);
             String msg;
             if ("usage".equals(ex.getMessage())) {
Index: trunk/src/org/openstreetmap/josm/actions/RestartAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/RestartAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/RestartAction.java	(revision 12620)
@@ -20,4 +20,5 @@
 import org.openstreetmap.josm.gui.io.SaveLayersDialog;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -59,5 +60,5 @@
             restartJOSM();
         } catch (IOException ex) {
-            Main.error(ex);
+            Logging.error(ex);
         }
     }
@@ -93,7 +94,7 @@
             cmd = getCommands();
         }
-        Main.info("Restart "+cmd);
-        if (Main.isDebugEnabled() && Main.pref.getBoolean("restart.debug.simulation")) {
-            Main.debug("Restart cancelled to get debug info");
+        Logging.info("Restart "+cmd);
+        if (Logging.isDebugEnabled() && Main.pref.getBoolean("restart.debug.simulation")) {
+            Logging.debug("Restart cancelled to get debug info");
             return;
         }
@@ -106,5 +107,5 @@
                     Runtime.getRuntime().exec(cmd.toArray(new String[cmd.size()]));
                 } catch (IOException e) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
             }
@@ -138,7 +139,5 @@
         if (javaCommand.endsWith(".jnlp") && jnlp == null) {
             // see #11751 - jnlp on Linux
-            if (Main.isDebugEnabled()) {
-                Main.debug("Detected jnlp without jnlpx.origFilenameArg property set");
-            }
+            Logging.debug("Detected jnlp without jnlpx.origFilenameArg property set");
             cmd.addAll(Arrays.asList(mainCommand));
         } else {
@@ -181,7 +180,5 @@
     private static void addVMArguments(Collection<String> cmd) {
         List<String> arguments = ManagementFactory.getRuntimeMXBean().getInputArguments();
-        if (Main.isDebugEnabled()) {
-            Main.debug("VM arguments: "+arguments);
-        }
+        Logging.debug("VM arguments: {0}", arguments);
         for (String arg : arguments) {
             // When run from jp2launcher.exe, jnlpx.remove is true, while it is not when run from javaws
Index: trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/ReverseWayAction.java	(revision 12620)
@@ -27,4 +27,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.Notification;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.UserCancelException;
@@ -131,5 +132,5 @@
                 revResult = reverseWay(w);
             } catch (UserCancelException ex) {
-                Main.trace(ex);
+                Logging.trace(ex);
                 return;
             }
Index: trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java	(revision 12620)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.gui.widgets.AbstractFileChooser;
 import org.openstreetmap.josm.io.FileExporter;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -117,5 +118,5 @@
             Main.parent.repaint();
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
             return false;
         }
@@ -224,5 +225,5 @@
             filepath = file.getCanonicalPath();
         } catch (IOException ign) {
-            Main.warn(ign);
+            Logging.warn(ign);
             return;
         }
Index: trunk/src/org/openstreetmap/josm/actions/SearchNotesDownloadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SearchNotesDownloadAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/SearchNotesDownloadAction.java	(revision 12620)
@@ -22,4 +22,5 @@
 import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
 import org.openstreetmap.josm.io.OsmApi;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -87,5 +88,5 @@
             return;
         } catch (NumberFormatException ignore) {
-            Main.trace(ignore);
+            Logging.trace(ignore);
         }
 
Index: trunk/src/org/openstreetmap/josm/actions/SessionLoadAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SessionLoadAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/SessionLoadAction.java	(revision 12620)
@@ -34,4 +34,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -196,5 +197,5 @@
 
         private void handleException(String dialogTitle, Exception e) {
-            Main.error(e);
+            Logging.error(e);
             HelpAwareOptionPane.showMessageDialogInEDT(
                     Main.parent,
Index: trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/SessionSaveAsAction.java	(revision 12620)
@@ -42,4 +42,5 @@
 import org.openstreetmap.josm.io.session.SessionWriter;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.UserCancelException;
@@ -81,5 +82,5 @@
             saveSession();
         } catch (UserCancelException ignore) {
-            Main.trace(ignore);
+            Logging.trace(ignore);
         }
     }
@@ -167,5 +168,5 @@
             SaveActionBase.addToFileOpenHistory(file);
         } catch (IOException ex) {
-            Main.error(ex);
+            Logging.error(ex);
             HelpAwareOptionPane.showMessageDialogInEDT(
                     Main.parent,
Index: trunk/src/org/openstreetmap/josm/actions/ShowStatusReportAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ShowStatusReportAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/ShowStatusReportAction.java	(revision 12620)
@@ -37,4 +37,5 @@
 import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.plugins.PluginHandler;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.PlatformHookUnixoid;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -169,5 +170,5 @@
             }
         } catch (SecurityException e) {
-            Main.trace(e);
+            Logging.trace(e);
         }
         List<String> commandLineArgs = MainApplication.getCommandLineArgs();
@@ -191,5 +192,5 @@
         appendCollection(text, "Map paint styles", getCustomUrls(MapPaintPreference.MapPaintPrefHelper.INSTANCE));
         appendCollection(text, "Validator rules", getCustomUrls(ValidatorTagCheckerRulesPreference.RulePrefHelper.INSTANCE));
-        appendCollection(text, "Last errors/warnings", Utils.transform(Main.getLastErrorAndWarnings(), i -> "- " + i));
+        appendCollection(text, "Last errors/warnings", Utils.transform(Logging.getLastErrorAndWarnings(), i -> "- " + i));
 
         String osmApi = OsmApi.getOsmApi().getServerUrl();
Index: trunk/src/org/openstreetmap/josm/actions/ToggleAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/ToggleAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/ToggleAction.java	(revision 12620)
@@ -13,6 +13,6 @@
 import javax.swing.JToggleButton;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -79,5 +79,5 @@
             return (Boolean) selected;
         } else {
-            Main.warn(getClass().getName() + " does not define a boolean for SELECTED_KEY but " + selected +
+            Logging.warn(getClass().getName() + " does not define a boolean for SELECTED_KEY but " + selected +
                     ". You should report it to JOSM developers.");
             return false;
Index: trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/UnGlueAction.java	(revision 12620)
@@ -43,4 +43,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.UserCancelException;
@@ -81,5 +82,5 @@
             unglue(e);
         } catch (UserCancelException ignore) {
-            Main.trace(ignore);
+            Logging.trace(ignore);
         } finally {
             cleanup();
@@ -294,5 +295,5 @@
             dialog = PropertiesMembershipDialog.showIfNecessary(Collections.singleton(selectedNode), true);
         } catch (UserCancelException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
             return;
         }
@@ -507,5 +508,5 @@
             dialog = PropertiesMembershipDialog.showIfNecessary(Collections.singleton(selectedNode), false);
         } catch (UserCancelException e) {
-            Main.trace(e);
+            Logging.trace(e);
             return;
         }
@@ -606,5 +607,5 @@
             return true;
         } catch (UserCancelException ignore) {
-            Main.trace(ignore);
+            Logging.trace(ignore);
         }
         return false;
@@ -622,5 +623,5 @@
             dialog = PropertiesMembershipDialog.showIfNecessary(selectedNodes, false);
         } catch (UserCancelException e) {
-            Main.trace(e);
+            Logging.trace(e);
             return;
         }
Index: trunk/src/org/openstreetmap/josm/actions/UploadNotesAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/UploadNotesAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/UploadNotesAction.java	(revision 12620)
@@ -13,4 +13,5 @@
 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -36,12 +37,12 @@
             layer = noteLayers.get(0);
         } else {
-            Main.error("No note layer found");
+            Logging.error("No note layer found");
             return;
         }
-        Main.debug("uploading note changes");
+        Logging.debug("uploading note changes");
         NoteData noteData = layer.getNoteData();
 
         if (noteData == null || !noteData.isModified()) {
-            Main.debug("No changed notes to upload");
+            Logging.debug("No changed notes to upload");
             return;
         }
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractChangesetDownloadTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractChangesetDownloadTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/AbstractChangesetDownloadTask.java	(revision 12620)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.io.OsmServerChangesetReader;
 import org.openstreetmap.josm.tools.ExceptionUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;
 
@@ -68,5 +69,5 @@
                     SwingUtilities.invokeAndWait(r);
                 } catch (InterruptedException e) {
-                    Main.warn("InterruptedException in "+getClass().getSimpleName()+" while updating changeset cache");
+                    Logging.warn("InterruptedException in "+getClass().getSimpleName()+" while updating changeset cache");
                     Thread.currentThread().interrupt();
                 } catch (InvocationTargetException e) {
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/ChangesetContentDownloadTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/ChangesetContentDownloadTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/ChangesetContentDownloadTask.java	(revision 12620)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.io.OsmTransferCanceledException;
 import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -76,5 +77,5 @@
                 // the download was canceled by the user. This exception is caught if the user canceled the authentication dialog.
                 setCanceled(true);
-                Main.trace(e);
+                Logging.trace(e);
                 return;
             } catch (OsmTransferException e) {
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/ChangesetQueryTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/ChangesetQueryTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/ChangesetQueryTask.java	(revision 12620)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.ExceptionUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -71,5 +72,5 @@
                 // thrown if user cancel the authentication dialog
                 setCanceled(true);
-                Main.trace(e);
+                Logging.trace(e);
             } catch (OsmTransferException e) {
                 if (isCanceled())
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadNotesTask.java	(revision 12620)
@@ -28,4 +28,5 @@
 import org.openstreetmap.josm.io.OsmServerReader;
 import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -123,6 +124,6 @@
                 return;
             }
-            if (Main.isDebugEnabled()) {
-                Main.debug("Notes downloaded: " + notesData.size());
+            if (Logging.isDebugEnabled()) {
+                Logging.debug("Notes downloaded: {0}", notesData.size());
             }
 
@@ -166,5 +167,5 @@
                 notesData = reader.parseNotes(DOWNLOAD_LIMIT.get(), DAYS_CLOSED.get(), subMonitor);
             } catch (MoreNotesException e) {
-                Main.debug(e);
+                Logging.debug(e);
                 notesData = e.notes;
                 JOptionPane.showMessageDialog(Main.parent, "<html>"
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmChangeTask.java	(revision 12620)
@@ -38,4 +38,5 @@
 import org.openstreetmap.josm.io.OsmServerReader;
 import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -185,5 +186,5 @@
                             it.remove();
                         } catch (AssertionError e) {
-                            Main.error(e, "Cannot load "+p+':');
+                            Logging.log(Logging.LEVEL_ERROR, "Cannot load "+p+':', e);
                         }
                     }
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java	(revision 12620)
@@ -37,4 +37,5 @@
 import org.openstreetmap.josm.io.OsmTransferCanceledException;
 import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
@@ -360,5 +361,5 @@
             } catch (OsmTransferException e) {
                 if (isCanceled()) {
-                    Main.info(tr("Ignoring exception because download has been canceled. Exception was: {0}", e.toString()));
+                    Logging.info(tr("Ignoring exception because download has been canceled. Exception was: {0}", e.toString()));
                     return;
                 }
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadSessionTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadSessionTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadSessionTask.java	(revision 12620)
@@ -14,4 +14,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -48,5 +49,5 @@
                 return Main.worker.submit(loader);
             } catch (URISyntaxException | IOException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTaskList.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTaskList.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadTaskList.java	(revision 12620)
@@ -36,4 +36,5 @@
 import org.openstreetmap.josm.tools.ExceptionUtil;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -244,5 +245,5 @@
                     future.get();
                 } catch (InterruptedException | ExecutionException | CancellationException e) {
-                    Main.error(e);
+                    Logging.error(e);
                     return;
                 }
Index: trunk/src/org/openstreetmap/josm/actions/downloadtasks/PostDownloadHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/downloadtasks/PostDownloadHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/downloadtasks/PostDownloadHandler.java	(revision 12620)
@@ -22,4 +22,5 @@
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.tools.ExceptionUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -62,5 +63,5 @@
             future.get();
         } catch (InterruptedException | ExecutionException | CancellationException e) {
-            Main.error(e);
+            Logging.error(e);
             return;
         }
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/AddNoteAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/AddNoteAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/AddNoteAction.java	(revision 12620)
@@ -18,4 +18,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -70,5 +71,5 @@
 
         if (dialog.getValue() != 1) {
-            Main.debug("User aborted note creation");
+            Logging.debug("User aborted note creation");
             return;
         }
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/DrawSnapHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/DrawSnapHelper.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/DrawSnapHelper.java	(revision 12620)
@@ -30,4 +30,5 @@
 import org.openstreetmap.josm.gui.draw.SymbolShape;
 import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -246,5 +247,5 @@
             return Double.parseDouble(string);
         } catch (NumberFormatException e) {
-            Main.warn("Incorrect number in draw.anglesnap.angles preferences: {0}", string);
+            Logging.warn("Incorrect number in draw.anglesnap.angles preferences: {0}", string);
             return 0;
         }
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/ExtrudeAction.java	(revision 12620)
@@ -57,4 +57,5 @@
 import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -271,5 +272,5 @@
                 rv = new StringBuilder(tr("Draw a rectangle of the desired size, then release the mouse button."));
             else {
-                Main.warn("Extrude: unknown mode " + mode);
+                Logging.warn("Extrude: unknown mode " + mode);
                 rv = new StringBuilder();
             }
@@ -541,5 +542,5 @@
                     } catch (DataIntegrityProblemException ex) {
                         // Can occur if calling undo while extruding, see #12870
-                        Main.error(ex);
+                        Logging.error(ex);
                     }
                 }
@@ -1191,5 +1192,5 @@
                     + (unitvector.getY() * linelength)));
         } catch (NoninvertibleTransformException e) {
-            Main.debug(e);
+            Logging.debug(e);
             return new Line2D.Double(start, new Point2D.Double(start.getX() + (unitvector.getX() * 10), start.getY()
                     + (unitvector.getY() * 10)));
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/ParallelWayAction.java	(revision 12620)
@@ -51,4 +51,5 @@
 import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -522,5 +523,5 @@
             return true;
         } catch (IllegalArgumentException e) {
-            Main.debug(e);
+            Logging.debug(e);
             new Notification(tr("ParallelWayAction\n" +
                     "The ways selected must form a simple branchless path"))
@@ -584,5 +585,5 @@
                     ret.put(mod.get(), Character.isUpperCase(c));
                 } else {
-                    Main.debug("Ignoring unknown modifier {0}", c);
+                    Logging.debug("Ignoring unknown modifier {0}", c);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/mapmode/SelectAction.java	(revision 12620)
@@ -51,4 +51,5 @@
 import org.openstreetmap.josm.gui.util.ModifierExListener;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -631,6 +632,6 @@
         if (!repeatedKeySwitchLassoOption || !Main.isDisplayingMapView() || !getShortcut().isEvent(e))
             return;
-        if (Main.isDebugEnabled()) {
-            Main.debug(getClass().getName()+" consuming event "+e);
+        if (Logging.isDebugEnabled()) {
+            Logging.debug("{0} consuming event {1}", getClass().getName(), e);
         }
         e.consume();
Index: trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 12620)
@@ -62,4 +62,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.Utils;
@@ -416,5 +417,5 @@
                         super.buttonAction(buttonIndex, evt);
                     } catch (ParseError e) {
-                        Main.debug(e);
+                        Logging.debug(e);
                         JOptionPane.showMessageDialog(
                                 Main.parent,
@@ -825,5 +826,5 @@
                 subMonitor.finishTask();
             } catch (ParseError e) {
-                Main.debug(e);
+                Logging.debug(e);
                 JOptionPane.showMessageDialog(
                         Main.parent,
@@ -953,5 +954,5 @@
                     break;
                 } else {
-                    Main.warn("Unknown char in SearchSettings: " + s);
+                    Logging.warn("Unknown char in SearchSettings: " + s);
                     break;
                 }
Index: trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 12620)
@@ -46,4 +46,5 @@
 import org.openstreetmap.josm.tools.AlphanumComparator;
 import org.openstreetmap.josm.tools.Geometry;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.UncheckedParseException;
 import org.openstreetmap.josm.tools.Utils;
@@ -112,5 +113,5 @@
                 throw new AssertionError("Unknown match factory");
             if (existing != null) {
-                Main.warn("SearchCompiler: for key ''{0}'', overriding match factory ''{1}'' with ''{2}''", keyword, existing, factory);
+                Logging.warn("SearchCompiler: for key ''{0}'', overriding match factory ''{1}'' with ''{2}''", keyword, existing, factory);
             }
         }
@@ -716,5 +717,5 @@
                 }
             } catch (NumberFormatException ignore) {
-                Main.trace(ignore);
+                Logging.trace(ignore);
             }
             this.referenceNumber = v;
@@ -1696,5 +1697,5 @@
         if (!tokenizer.readIfEqual(Token.EOF))
             throw new ParseError(tr("Unexpected token: {0}", tokenizer.nextToken()));
-        Main.debug("Parsed search expression is {0}", m);
+        Logging.debug("Parsed search expression is {0}", m);
         return m;
     }
Index: trunk/src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/upload/ApiPreconditionCheckerHook.java	(revision 12620)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.io.OsmApiInitializationException;
 import org.openstreetmap.josm.io.OsmTransferCanceledException;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -46,5 +47,5 @@
             }
         } catch (OsmTransferCanceledException e) {
-            Main.trace(e);
+            Logging.trace(e);
             return false;
         } catch (OsmApiInitializationException e) {
@@ -62,5 +63,5 @@
                     if (osmPrimitive.isDeleted()) {
                         // if OsmPrimitive is going to be deleted we automatically shorten the value
-                        Main.warn(
+                        Logging.warn(
                                 tr("Automatically truncating value of tag ''{0}'' on deleted object {1}",
                                         key,
Index: trunk/src/org/openstreetmap/josm/actions/upload/UploadNotesTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/upload/UploadNotesTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/actions/upload/UploadNotesTask.java	(revision 12620)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -55,7 +56,5 @@
         @Override
         protected void cancel() {
-            if (Main.isDebugEnabled()) {
-                Main.debug("note upload canceled");
-            }
+            Logging.debug("note upload canceled");
             isCanceled = true;
         }
@@ -67,12 +66,10 @@
             for (Note note : noteData.getNotes()) {
                 if (isCanceled) {
-                    Main.info("Note upload interrupted by user");
+                    Logging.info("Note upload interrupted by user");
                     break;
                 }
                 for (NoteComment comment : note.getComments()) {
                     if (comment.isNew()) {
-                        if (Main.isDebugEnabled()) {
-                            Main.debug("found note change to upload");
-                        }
+                        Logging.debug("found note change to upload");
                         processNoteComment(monitor, api, note, comment);
                     }
@@ -90,25 +87,17 @@
                 switch (comment.getNoteAction()) {
                 case OPENED:
-                    if (Main.isDebugEnabled()) {
-                        Main.debug("opening new note");
-                    }
+                    Logging.debug("opening new note");
                     newNote = api.createNote(note.getLatLon(), comment.getText(), monitor);
                     break;
                 case CLOSED:
-                    if (Main.isDebugEnabled()) {
-                        Main.debug("closing note " + note.getId());
-                    }
+                    Logging.debug("closing note {0}", note.getId());
                     newNote = api.closeNote(note, comment.getText(), monitor);
                     break;
                 case COMMENTED:
-                    if (Main.isDebugEnabled()) {
-                        Main.debug("adding comment to note " + note.getId());
-                    }
+                    Logging.debug("adding comment to note {0}", note.getId());
                     newNote = api.addCommentToNote(note, comment.getText(), monitor);
                     break;
                 case REOPENED:
-                    if (Main.isDebugEnabled()) {
-                        Main.debug("reopening note " + note.getId());
-                    }
+                    Logging.debug("reopening note {0}", note.getId());
                     newNote = api.reopenNote(note, comment.getText(), monitor);
                     break;
@@ -118,6 +107,6 @@
                 updatedNotes.put(note, newNote);
             } catch (OsmTransferException e) {
-                Main.error("Failed to upload note to server: " + note.getId());
-                Main.error(e);
+                Logging.error("Failed to upload note to server: {0}", note.getId());
+                Logging.error(e);
                 failedNotes.put(note, e);
             }
@@ -127,6 +116,6 @@
         @Override
         protected void finish() {
-            if (Main.isDebugEnabled()) {
-                Main.debug("finish called in notes upload task. Notes to update: " + updatedNotes.size());
+            if (Logging.isDebugEnabled()) {
+                Logging.debug("finish called in notes upload task. Notes to update: {0}", updatedNotes.size());
             }
             noteData.updateNotes(updatedNotes);
@@ -137,5 +126,5 @@
                     sb.append('\n');
                 }
-                Main.error("Notes failed to upload: " + sb.toString());
+                Logging.error("Notes failed to upload: " + sb.toString());
                 JOptionPane.showMessageDialog(Main.map, sb.toString(), tr("Notes failed to upload"), JOptionPane.ERROR_MESSAGE);
                 ExceptionDialogUtil.explainException(failedNotes.values().iterator().next());
Index: trunk/src/org/openstreetmap/josm/command/conflict/ConflictAddCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/conflict/ConflictAddCommand.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/command/conflict/ConflictAddCommand.java	(revision 12620)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -55,5 +56,5 @@
             getLayer().getConflicts().add(conflict);
         } catch (IllegalStateException e) {
-            Main.error(e);
+            Logging.error(e);
             warnBecauseOfDoubleConflict();
         }
@@ -64,5 +65,5 @@
     public void undoCommand() {
         if (Main.isDisplayingMapView() && !Main.getLayerManager().containsLayer(getLayer())) {
-            Main.warn(tr("Layer ''{0}'' does not exist any more. Cannot remove conflict for object ''{1}''.",
+            Logging.warn(tr("Layer ''{0}'' does not exist any more. Cannot remove conflict for object ''{1}''.",
                     getLayer().getName(),
                     conflict.getMy().getDisplayName(DefaultNameFormatter.getInstance())
Index: trunk/src/org/openstreetmap/josm/command/conflict/ConflictResolveCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/conflict/ConflictResolveCommand.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/command/conflict/ConflictResolveCommand.java	(revision 12620)
@@ -11,4 +11,5 @@
 import org.openstreetmap.josm.data.conflict.ConflictCollection;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -72,5 +73,5 @@
         if (Main.isDisplayingMapView()) {
             if (!Main.getLayerManager().containsLayer(getLayer())) {
-                Main.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more",
+                Logging.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more",
                         this.toString(),
                         getLayer().toString()
Index: trunk/src/org/openstreetmap/josm/command/conflict/RelationMemberConflictResolverCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/conflict/RelationMemberConflictResolverCommand.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/command/conflict/RelationMemberConflictResolverCommand.java	(revision 12620)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -72,5 +73,5 @@
         OsmDataLayer layer = getLayer();
         if (!Main.getLayerManager().containsLayer(layer)) {
-            Main.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more",
+            Logging.warn(tr("Cannot undo command ''{0}'' because layer ''{1}'' is not present any more",
                     this.toString(),
                     layer.toString()
Index: trunk/src/org/openstreetmap/josm/command/conflict/WayNodesConflictResolverCommand.java
===================================================================
--- trunk/src/org/openstreetmap/josm/command/conflict/WayNodesConflictResolverCommand.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/command/conflict/WayNodesConflictResolverCommand.java	(revision 12620)
@@ -10,5 +10,4 @@
 import javax.swing.Icon;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.conflict.Conflict;
 import org.openstreetmap.josm.data.osm.Node;
@@ -16,4 +15,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -60,5 +60,5 @@
         for (Node n:mergedNodeList) {
             if (!getAffectedDataSet().getNodes().contains(n)) {
-                Main.warn(tr("Main dataset does not include node {0}", n.toString()));
+                Logging.warn(tr("Main dataset does not include node {0}", n.toString()));
             }
         }
Index: trunk/src/org/openstreetmap/josm/data/AutosaveTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/AutosaveTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/AutosaveTask.java	(revision 12620)
@@ -46,4 +46,5 @@
 import org.openstreetmap.josm.io.OsmExporter;
 import org.openstreetmap.josm.io.OsmImporter;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -134,9 +135,9 @@
 
             if (!autosaveDir.exists() && !autosaveDir.mkdirs()) {
-                Main.warn(tr("Unable to create directory {0}, autosave will be disabled", autosaveDir.getAbsolutePath()));
+                Logging.warn(tr("Unable to create directory {0}, autosave will be disabled", autosaveDir.getAbsolutePath()));
                 return;
             }
             if (!deletedLayersDir.exists() && !deletedLayersDir.mkdirs()) {
-                Main.warn(tr("Unable to create directory {0}, autosave will be disabled", deletedLayersDir.getAbsolutePath()));
+                Logging.warn(tr("Unable to create directory {0}, autosave will be disabled", deletedLayersDir.getAbsolutePath()));
                 return;
             }
@@ -200,8 +201,8 @@
                     return result;
                 } else {
-                    Main.warn(tr("Unable to create file {0}, other filename will be used", result.getAbsolutePath()));
+                    Logging.warn(tr("Unable to create file {0}, other filename will be used", result.getAbsolutePath()));
                 }
             } catch (IOException e) {
-                Main.error(e, tr("IOError while creating file, autosave will be skipped: {0}", e.getMessage()));
+                Logging.log(Logging.LEVEL_ERROR, tr("IOError while creating file, autosave will be skipped: {0}", e.getMessage()), e);
                 return null;
             }
@@ -215,5 +216,5 @@
             ps.println(ManagementFactory.getRuntimeMXBean().getName());
         } catch (IOException | SecurityException t) {
-            Main.error(t);
+            Logging.error(t);
         }
     }
@@ -252,6 +253,6 @@
             } catch (RuntimeException t) { // NOPMD
                 // Don't let exception stop time thread
-                Main.error("Autosave failed:");
-                Main.error(t);
+                Logging.error("Autosave failed:");
+                Logging.error(t);
             }
         }
@@ -343,5 +344,5 @@
                         }
                     } catch (IOException | SecurityException t) {
-                        Main.error(t);
+                        Logging.error(t);
                     }
                 }
@@ -379,5 +380,5 @@
                 }
             } catch (InterruptedException | ExecutionException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         });
@@ -404,5 +405,5 @@
             Utils.deleteFile(pidFile);
         } else {
-            Main.warn(String.format("Could not move autosaved file %s to %s folder", f.getName(), deletedLayersDir.getName()));
+            Logging.warn(String.format("Could not move autosaved file %s to %s folder", f.getName(), deletedLayersDir.getName()));
             // we cannot move to deleted folder, so just try to delete it directly
             if (Utils.deleteFile(f, marktr("Unable to delete backup file {0}"))) {
Index: trunk/src/org/openstreetmap/josm/data/CustomConfigurator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/CustomConfigurator.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/CustomConfigurator.java	(revision 12620)
@@ -55,4 +55,5 @@
 import org.openstreetmap.josm.plugins.ReadLocalPluginInformationTask;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.w3c.dom.DOMException;
@@ -100,5 +101,5 @@
      */
     public static void log(Exception e, String s) {
-        summary.append(s).append(' ').append(Main.getErrorMessage(e)).append('\n');
+        summary.append(s).append(' ').append(Logging.getErrorMessage(e)).append('\n');
     }
 
@@ -206,5 +207,5 @@
             case 'q': JOptionPane.showMessageDialog(Main.parent, text, tr("Question"), JOptionPane.QUESTION_MESSAGE); break;
             case 'p': JOptionPane.showMessageDialog(Main.parent, text, tr("Message"), JOptionPane.PLAIN_MESSAGE); break;
-            default: Main.warn("Unsupported messageBox type: " + c);
+            default: Logging.warn("Unsupported messageBox type: " + c);
         }
     }
@@ -281,5 +282,5 @@
             root = document.getDocumentElement();
         } catch (SAXException | IOException | ParserConfigurationException ex) {
-            Main.warn(ex, "Error getting preferences to save:");
+            Logging.log(Logging.LEVEL_WARN, "Error getting preferences to save:", ex);
         }
         if (root == null || exportDocument == null)
@@ -310,6 +311,6 @@
             ts.transform(new DOMSource(exportDocument), new StreamResult(f.toURI().getPath()));
         } catch (DOMException | TransformerFactoryConfigurationError | TransformerException ex) {
-            Main.warn("Error saving preferences part:");
-            Main.error(ex);
+            Logging.warn("Error saving preferences part:");
+            Logging.error(ex);
         }
     }
@@ -375,5 +376,5 @@
                     while (busy) CustomConfigurator.class.wait();
                 } catch (InterruptedException ex) {
-                    Main.warn(ex, "InterruptedException while reading local plugin information");
+                    Logging.log(Logging.LEVEL_WARN, "InterruptedException while reading local plugin information", ex);
                     Thread.currentThread().interrupt();
                 }
@@ -495,5 +496,5 @@
             } catch (ScriptException ex) {
                 log("Error: initializing script engine: "+ex.getMessage());
-                Main.error(ex);
+                Logging.error(ex);
             }
         }
@@ -961,5 +962,5 @@
 
     private static void showPrefs(Preferences tmpPref) {
-        Main.info("properties: " + tmpPref.settingsMap);
+        Logging.info("properties: " + tmpPref.settingsMap);
     }
 
Index: trunk/src/org/openstreetmap/josm/data/Preferences.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/Preferences.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/Preferences.java	(revision 12620)
@@ -78,4 +78,5 @@
 import org.openstreetmap.josm.tools.JosmRuntimeException;
 import org.openstreetmap.josm.tools.ListenerList;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.Utils;
@@ -414,5 +415,5 @@
         }
         if (!cacheDir.exists() && !cacheDir.mkdirs()) {
-            Main.warn(tr("Failed to create missing cache directory: {0}", cacheDir.getAbsoluteFile()));
+            Logging.warn(tr("Failed to create missing cache directory: {0}", cacheDir.getAbsoluteFile()));
             JOptionPane.showMessageDialog(
                     Main.parent,
@@ -671,18 +672,18 @@
 
     private static void setCorrectPermissions(File file) {
-        if (!file.setReadable(false, false) && Main.isTraceEnabled()) {
-            Main.trace(tr("Unable to set file non-readable {0}", file.getAbsolutePath()));
-        }
-        if (!file.setWritable(false, false) && Main.isTraceEnabled()) {
-            Main.trace(tr("Unable to set file non-writable {0}", file.getAbsolutePath()));
-        }
-        if (!file.setExecutable(false, false) && Main.isTraceEnabled()) {
-            Main.trace(tr("Unable to set file non-executable {0}", file.getAbsolutePath()));
-        }
-        if (!file.setReadable(true, true) && Main.isTraceEnabled()) {
-            Main.trace(tr("Unable to set file readable {0}", file.getAbsolutePath()));
-        }
-        if (!file.setWritable(true, true) && Main.isTraceEnabled()) {
-            Main.trace(tr("Unable to set file writable {0}", file.getAbsolutePath()));
+        if (!file.setReadable(false, false) && Logging.isTraceEnabled()) {
+            Logging.trace(tr("Unable to set file non-readable {0}", file.getAbsolutePath()));
+        }
+        if (!file.setWritable(false, false) && Logging.isTraceEnabled()) {
+            Logging.trace(tr("Unable to set file non-writable {0}", file.getAbsolutePath()));
+        }
+        if (!file.setExecutable(false, false) && Logging.isTraceEnabled()) {
+            Logging.trace(tr("Unable to set file non-executable {0}", file.getAbsolutePath()));
+        }
+        if (!file.setReadable(true, true) && Logging.isTraceEnabled()) {
+            Logging.trace(tr("Unable to set file readable {0}", file.getAbsolutePath()));
+        }
+        if (!file.setWritable(true, true) && Logging.isTraceEnabled()) {
+            Logging.trace(tr("Unable to set file writable {0}", file.getAbsolutePath()));
         }
     }
@@ -751,5 +752,5 @@
         if (prefDir.exists()) {
             if (!prefDir.isDirectory()) {
-                Main.warn(tr("Failed to initialize preferences. Preference directory ''{0}'' is not a directory.",
+                Logging.warn(tr("Failed to initialize preferences. Preference directory ''{0}'' is not a directory.",
                         prefDir.getAbsoluteFile()));
                 JOptionPane.showMessageDialog(
@@ -764,5 +765,5 @@
         } else {
             if (!prefDir.mkdirs()) {
-                Main.warn(tr("Failed to initialize preferences. Failed to create missing preference directory: {0}",
+                Logging.warn(tr("Failed to initialize preferences. Failed to create missing preference directory: {0}",
                         prefDir.getAbsoluteFile()));
                 JOptionPane.showMessageDialog(
@@ -780,5 +781,5 @@
         try {
             if (!preferenceFile.exists()) {
-                Main.info(tr("Missing preference file ''{0}''. Creating a default preference file.", preferenceFile.getAbsoluteFile()));
+                Logging.info(tr("Missing preference file ''{0}''. Creating a default preference file.", preferenceFile.getAbsoluteFile()));
                 resetToDefault();
                 save();
@@ -786,10 +787,10 @@
                 File backupFile = new File(prefDir, "preferences.xml.bak");
                 Main.platform.rename(preferenceFile, backupFile);
-                Main.warn(tr("Replacing existing preference file ''{0}'' with default preference file.", preferenceFile.getAbsoluteFile()));
+                Logging.warn(tr("Replacing existing preference file ''{0}'' with default preference file.", preferenceFile.getAbsoluteFile()));
                 resetToDefault();
                 save();
             }
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
             JOptionPane.showMessageDialog(
                     Main.parent,
@@ -805,5 +806,5 @@
             initSuccessful = true;
         } catch (IOException | SAXException | XMLStreamException e) {
-            Main.error(e);
+            Logging.error(e);
             File backupFile = new File(prefDir, "preferences.xml.bak");
             JOptionPane.showMessageDialog(
@@ -820,6 +821,6 @@
                 save();
             } catch (IOException e1) {
-                Main.error(e1);
-                Main.warn(tr("Failed to initialize preferences. Failed to reset preference file to default: {0}", getPreferenceFile()));
+                Logging.error(e1);
+                Logging.warn(tr("Failed to initialize preferences. Failed to reset preference file to default: {0}", getPreferenceFile()));
             }
         }
@@ -829,9 +830,9 @@
                 loadDefaults();
             } catch (IOException | XMLStreamException | SAXException e) {
-                Main.error(e);
-                Main.warn(tr("Failed to load defaults cache file: {0}", def));
+                Logging.error(e);
+                Logging.warn(tr("Failed to load defaults cache file: {0}", def));
                 defaultsMap.clear();
                 if (!def.delete()) {
-                    Main.warn(tr("Failed to delete faulty defaults cache file: {0}", def));
+                    Logging.warn(tr("Failed to delete faulty defaults cache file: {0}", def));
                 }
             }
@@ -966,5 +967,5 @@
         } catch (NumberFormatException e) {
             // fall out
-            Main.trace(e);
+            Logging.trace(e);
         }
         return def;
@@ -989,5 +990,5 @@
         } catch (NumberFormatException e) {
             // fall out
-            Main.trace(e);
+            Logging.trace(e);
         }
         return def;
@@ -1010,5 +1011,5 @@
         } catch (NumberFormatException e) {
             // fall out
-            Main.trace(e);
+            Logging.trace(e);
         }
         return def;
@@ -1031,5 +1032,5 @@
         } catch (NumberFormatException e) {
             // fall out
-            Main.trace(e);
+            Logging.trace(e);
         }
         return def;
@@ -1099,5 +1100,5 @@
                     save();
                 } catch (IOException e) {
-                    Main.warn(e, tr("Failed to persist preferences to ''{0}''", getPreferenceFile().getAbsoluteFile()));
+                    Logging.log(Logging.LEVEL_WARN, tr("Failed to persist preferences to ''{0}''", getPreferenceFile().getAbsoluteFile()), e);
                 }
             }
@@ -1133,5 +1134,5 @@
         Setting<?> oldDef = defaultsMap.get(key);
         if (oldDef != null && oldDef.isNew() && oldDef.getValue() != null && def.getValue() != null && !def.equals(oldDef)) {
-            Main.info("Defaults for " + key + " differ: " + def + " != " + defaultsMap.get(key));
+            Logging.info("Defaults for " + key + " differ: " + def + " != " + defaultsMap.get(key));
         }
         if (def.getValue() != null || oldDef == null) {
@@ -1463,5 +1464,5 @@
                 f = klass.getDeclaredField(keyValue.getKey().replace('-', '_'));
             } catch (NoSuchFieldException ex) {
-                Main.trace(ex);
+                Logging.trace(ex);
                 continue;
             }
@@ -1526,5 +1527,5 @@
         if ("true".equals(get("prefer.ipv6", "auto")) && !"true".equals(Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true"))) {
             // never set this to false, only true!
-            Main.info(tr("Try enabling IPv6 network, prefering IPv6 over IPv4 (only works on early startup)."));
+            Logging.info(tr("Try enabling IPv6 network, prefering IPv6 over IPv4 (only works on early startup)."));
         }
         Utils.updateSystemProperty("http.agent", Version.getInstance().getAgentString());
@@ -1540,5 +1541,5 @@
             } catch (ReflectiveOperationException | RuntimeException e) { // NOPMD
                 // Catch RuntimeException in order to catch InaccessibleObjectException, new in Java 9
-                Main.warn(e);
+                Logging.warn(e);
             }
         }
@@ -1571,5 +1572,5 @@
                 OnlineResource.JOSM_WEBSITE.checkOfflineAccess(it.next(), Main.getJOSMWebsite());
             } catch (OfflineAccessException ex) {
-                Main.warn(ex, false);
+                Logging.log(Logging.LEVEL_WARN, ex);
                 it.remove();
             }
@@ -1613,5 +1614,5 @@
             return sw.toString();
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
             return null;
         }
@@ -1643,5 +1644,5 @@
             if (settingsMap.containsKey(key)) {
                 settingsMap.remove(key);
-                Main.info(tr("Preference setting {0} has been removed since it is no longer used.", key));
+                Logging.info(tr("Preference setting {0} has been removed since it is no longer used.", key));
             }
         }
@@ -1656,5 +1657,5 @@
                     final String oldKey = entry.getKey();
                     final String newKey = entry.getValue();
-                    Main.info("Migrating old color key {0} => {1}", oldKey, newKey);
+                    Logging.info("Migrating old color key {0} => {1}", oldKey, newKey);
                     put(newKey, get(oldKey));
                     put(oldKey, null);
Index: trunk/src/org/openstreetmap/josm/data/Version.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/Version.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/Version.java	(revision 12620)
@@ -12,4 +12,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -60,5 +61,5 @@
             properties.load(revisionInfo);
         } catch (IOException e) {
-            Main.warn(e, tr("Error reading revision info from revision file: {0}", e.getMessage()));
+            Logging.log(Logging.LEVEL_WARN, tr("Error reading revision info from revision file: {0}", e.getMessage()), e);
         }
         String value = Optional.ofNullable(properties.getProperty("Revision")).orElse("").trim();
@@ -68,5 +69,5 @@
             } catch (NumberFormatException e) {
                 version = 0;
-                Main.warn(tr("Unexpected JOSM version number in revision file, value is ''{0}''", value));
+                Logging.warn(tr("Unexpected JOSM version number in revision file, value is ''{0}''", value));
             }
         } else {
@@ -105,5 +106,5 @@
         try (InputStream stream = Main.class.getResourceAsStream("/REVISION")) {
             if (stream == null) {
-                Main.warn(tr("The revision file ''/REVISION'' is missing."));
+                Logging.warn(tr("The revision file ''/REVISION'' is missing."));
                 version = 0;
                 releaseDescription = "";
@@ -112,5 +113,5 @@
             initFromRevisionInfo(stream);
         } catch (IOException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/cache/CacheEntryAttributes.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/CacheEntryAttributes.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/cache/CacheEntryAttributes.java	(revision 12620)
@@ -11,5 +11,5 @@
 
 import org.apache.commons.jcs.engine.ElementAttributes;
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -162,5 +162,5 @@
         for (Entry<String, String> e: map.entrySet()) {
             if (RESERVED_KEYS.contains(e.getKey())) {
-                Main.info("Metadata key configuration contains key {0} which is reserved for internal use");
+                Logging.info("Metadata key configuration contains key {0} which is reserved for internal use");
             } else {
                 attrs.put(e.getKey(), e.getValue());
@@ -191,5 +191,5 @@
      */
     public void setError(Exception error) {
-        setErrorMessage(Main.getErrorMessage(error));
+        setErrorMessage(Logging.getErrorMessage(error));
     }
 
Index: trunk/src/org/openstreetmap/josm/data/cache/HostLimitQueue.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/HostLimitQueue.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/cache/HostLimitQueue.java	(revision 12620)
@@ -12,5 +12,5 @@
 import java.util.concurrent.TimeUnit;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -67,7 +67,7 @@
                         url = job.getUrl();
                     } catch (IOException e) {
-                        Main.debug(e);
+                        Logging.debug(e);
                     }
-                    Main.debug("TMS - Skipping job {0} because host limit reached", url);
+                    Logging.debug("TMS - Skipping job {0} because host limit reached", url);
                 }
             }
@@ -90,5 +90,5 @@
                 // acquire my got interrupted, first offer back what was taken
                 if (!offer(job)) {
-                    Main.warn("Unable to offer back " + job);
+                    Logging.warn("Unable to offer back " + job);
                 }
                 throw e;
@@ -110,5 +110,5 @@
             // acquire my got interrupted, first offer back what was taken
             if (!offer(job)) {
-                Main.warn("Unable to offer back " + job);
+                Logging.warn("Unable to offer back " + job);
             }
             throw e;
@@ -209,5 +209,5 @@
             limit.release();
             if (limit.availablePermits() > hostLimit) {
-                Main.warn("More permits than it should be");
+                Logging.warn("More permits than it should be");
             }
         }
Index: trunk/src/org/openstreetmap/josm/data/cache/JCSCacheManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/JCSCacheManager.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/cache/JCSCacheManager.java	(revision 12620)
@@ -31,4 +31,5 @@
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.data.preferences.IntegerProperty;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -91,12 +92,12 @@
                 String msg = formatter.formatMessage(record);
                 if (record.getLevel().intValue() >= Level.SEVERE.intValue()) {
-                    Main.error(msg);
+                    Logging.error(msg);
                 } else if (record.getLevel().intValue() >= Level.WARNING.intValue()) {
-                    Main.warn(msg);
+                    Logging.warn(msg);
                     // downgrade INFO level to debug, as JCS is too verbose at INFO level
                 } else if (record.getLevel().intValue() >= Level.INFO.intValue()) {
-                    Main.debug(msg);
+                    Logging.debug(msg);
                 } else {
-                    Main.trace(msg);
+                    Logging.trace(msg);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/cache/JCSCachedTileLoaderJob.java	(revision 12620)
@@ -22,9 +22,9 @@
 import org.apache.commons.jcs.engine.behavior.ICacheElement;
 import org.openstreetmap.gui.jmapviewer.FeatureAdapter;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.cache.ICachedLoaderListener.LoadResult;
 import org.openstreetmap.josm.data.preferences.IntegerProperty;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -216,5 +216,5 @@
             return getUrl().getHost();
         } catch (IOException e) {
-            Main.trace(e);
+            Logging.trace(e);
             return null;
         }
@@ -264,5 +264,5 @@
             } catch (IOException e) {
                 listeners = null;
-                Main.trace(e);
+                Logging.trace(e);
             }
         }
@@ -406,5 +406,5 @@
             attributes.setError(e);
             LOG.log(Level.WARNING, "JCS - Exception during download {0}", getUrlNoException());
-            Main.warn(e);
+            Logging.warn(e);
             Thread.currentThread().interrupt();
         }
@@ -446,5 +446,5 @@
             } catch (NumberFormatException e) {
                 // ignore malformed Cache-Control headers
-                Main.trace(e);
+                Logging.trace(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/data/coor/LatLon.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/coor/LatLon.java	(revision 12620)
@@ -26,4 +26,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -396,5 +397,5 @@
         // (This should almost never happen.)
         if (java.lang.Double.isNaN(d)) {
-            Main.error("NaN in greatCircleDistance");
+            Logging.error("NaN in greatCircleDistance");
             d = PI * WGS84.a;
         }
Index: trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java	(revision 12620)
@@ -8,5 +8,4 @@
 import java.util.Objects;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
 import org.openstreetmap.josm.data.coor.EastNorth;
@@ -14,4 +13,5 @@
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.projection.Projecting;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.UncheckedParseException;
 import org.openstreetmap.josm.tools.date.DateUtils;
@@ -157,5 +157,5 @@
                 return time;
             } catch (UncheckedParseException e) {
-                Main.warn(e);
+                Logging.warn(e);
                 time = 0;
             }
Index: trunk/src/org/openstreetmap/josm/data/imagery/CachedAttributionBingAerialTileSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/CachedAttributionBingAerialTileSource.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/imagery/CachedAttributionBingAerialTileSource.java	(revision 12620)
@@ -12,9 +12,9 @@
 import org.openstreetmap.gui.jmapviewer.tilesources.BingAerialTileSource;
 import org.openstreetmap.gui.jmapviewer.tilesources.TileSourceInfo;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.io.CacheCustomContent;
 import org.openstreetmap.josm.io.OnlineResource;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.InputSource;
 
@@ -57,5 +57,5 @@
             URL u = getAttributionUrl();
             final String r = HttpClient.create(u).connect().fetchContent();
-            Main.info("Successfully loaded Bing attribution data.");
+            Logging.info("Successfully loaded Bing attribution data.");
             return r.getBytes("UTF-8");
         }
@@ -67,5 +67,5 @@
                 OnlineResource.ALL.checkOfflineAccess(attributionUrl, attributionUrl);
             } catch (MalformedURLException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         }
@@ -87,5 +87,5 @@
                     return ret;
                 } catch (IOException ex) {
-                    Main.warn(ex, "Could not connect to Bing API. Will retry in " + waitTimeSec + " seconds.");
+                    Logging.log(Logging.LEVEL_WARN, "Could not connect to Bing API. Will retry in " + waitTimeSec + " seconds.", ex);
                     Thread.sleep(TimeUnit.SECONDS.toMillis(waitTimeSec));
                     waitTimeSec *= 2;
Index: trunk/src/org/openstreetmap/josm/data/imagery/CachedTileLoaderFactory.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/CachedTileLoaderFactory.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/imagery/CachedTileLoaderFactory.java	(revision 12620)
@@ -16,4 +16,5 @@
 import org.openstreetmap.josm.data.preferences.StringProperty;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -47,5 +48,5 @@
                     Map.class);
         } catch (NoSuchMethodException | SecurityException e) {
-            Main.warn(e);
+            Logging.warn(e);
             throw new IllegalArgumentException(e);
         }
@@ -57,5 +58,5 @@
             defPath = new File(Main.pref.getCacheDirectory(), "tiles").getAbsolutePath();
         } catch (SecurityException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return new StringProperty("imagery.generic.loader.cachedir", defPath);
@@ -86,8 +87,8 @@
                     headers);
         } catch (IllegalArgumentException e) {
-            Main.warn(e);
+            Logging.warn(e);
             throw e;
         } catch (ReflectiveOperationException e) {
-            Main.warn(e);
+            Logging.warn(e);
             throw new IllegalArgumentException(e);
         }
Index: trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/imagery/ImageryInfo.java	(revision 12620)
@@ -34,4 +34,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.Utils;
@@ -421,5 +422,5 @@
                     }
                 } catch (IllegalArgumentException ex) {
-                    Main.warn(ex);
+                    Logging.warn(ex);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/data/imagery/ImageryLayerInfo.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/ImageryLayerInfo.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/imagery/ImageryLayerInfo.java	(revision 12620)
@@ -24,4 +24,5 @@
 import org.openstreetmap.josm.io.OnlineResource;
 import org.openstreetmap.josm.io.imagery.ImageryReader;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
@@ -82,5 +83,5 @@
                     add(i);
                 } catch (IllegalArgumentException e) {
-                    Main.warn("Unable to load imagery preference entry:"+e);
+                    Logging.warn("Unable to load imagery preference entry:"+e);
                 }
             }
@@ -150,5 +151,5 @@
                 OnlineResource.JOSM_WEBSITE.checkOfflineAccess(source, Main.getJOSMWebsite());
             } catch (OfflineAccessException e) {
-                Main.warn(e, false);
+                Logging.log(Logging.LEVEL_WARN, e);
                 online = false;
             }
@@ -163,8 +164,8 @@
             } catch (IOException ex) {
                 loadError = true;
-                Main.error(ex, false);
+                Logging.log(Logging.LEVEL_ERROR, ex);
             } catch (SAXException ex) {
                 loadError = true;
-                Main.error(ex);
+                Logging.error(ex);
             }
         }
@@ -205,5 +206,5 @@
                 if (idMap.containsKey(i.getId())) {
                     notUnique.add(i.getId());
-                    Main.error("Id ''{0}'' is not unique - used by ''{1}'' and ''{2}''!",
+                    Logging.error("Id ''{0}'' is not unique - used by ''{1}'' and ''{2}''!",
                             i.getId(), i.getName(), idMap.get(i.getId()).getName());
                     continue;
@@ -256,5 +257,5 @@
                         }
                     } else {
-                        Main.error("Default imagery ''{0}'' has no id. Skipping.", def.getName());
+                        Logging.error("Default imagery ''{0}'' has no id. Skipping.", def.getName());
                     }
                 }
@@ -279,5 +280,5 @@
             if (matchingDefault != null && !matchingDefault.equalsPref(info)) {
                 layers.set(i, matchingDefault);
-                Main.info(tr("Update imagery ''{0}''", info.getName()));
+                Logging.info(tr("Update imagery ''{0}''", info.getName()));
                 changed = true;
             }
@@ -300,5 +301,5 @@
                 remove(info.getValue());
                 drop.add(info.getKey());
-                Main.info(tr("Drop old imagery ''{0}''", info.getValue().getName()));
+                Logging.info(tr("Drop old imagery ''{0}''", info.getValue().getName()));
             }
         }
Index: trunk/src/org/openstreetmap/josm/data/imagery/OffsetBookmark.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/OffsetBookmark.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/imagery/OffsetBookmark.java	(revision 12620)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.gui.layer.AbstractTileSourceLayer;
 import org.openstreetmap.josm.gui.layer.ImageryLayer;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -78,5 +79,5 @@
         }
         if (projection_code == null) {
-            Main.error(tr("Projection ''{0}'' is not found, bookmark ''{1}'' is not usable", projection_code, name));
+            Logging.error(tr("Projection ''{0}'' is not found, bookmark ''{1}'' is not usable", projection_code, name));
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java	(revision 12620)
@@ -27,5 +27,4 @@
 import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
 import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTMSTileSource;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;
 import org.openstreetmap.josm.data.cache.CacheEntry;
@@ -35,4 +34,5 @@
 import org.openstreetmap.josm.data.preferences.LongProperty;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -124,5 +124,5 @@
             } catch (IOException e) {
                 LOG.log(Level.WARNING, "JCS TMS - error loading from cache for tile {0}: {1}", new Object[] {tile.getKey(), e.getMessage()});
-                Main.warn(e);
+                Logging.warn(e);
             }
         }
@@ -152,5 +152,5 @@
         } catch (IOException | IllegalArgumentException e) {
             // if we fail to submit the job, mark tile as loaded and set error message
-            Main.warn(e, false);
+            Logging.log(Logging.LEVEL_WARN, e);
             tile.finishLoading();
             tile.setError(e.getMessage());
Index: trunk/src/org/openstreetmap/josm/data/imagery/WMTSTileSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/imagery/WMTSTileSource.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/imagery/WMTSTileSource.java	(revision 12620)
@@ -58,4 +58,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -293,5 +294,5 @@
         this.layers = getCapabilities();
         if (info.getDefaultLayers().isEmpty()) {
-            Main.warn(tr("No default layer selected, choosing first layer."));
+            Logging.warn(tr("No default layer selected, choosing first layer."));
             if (!layers.isEmpty()) {
                 Layer first = layers.iterator().next();
@@ -383,5 +384,5 @@
             } catch (XMLStreamException e) {
                 cf.clear();
-                Main.warn(new String(data, StandardCharsets.UTF_8));
+                Logging.warn(new String(data, StandardCharsets.UTF_8));
                 throw new IllegalArgumentException(e);
             }
@@ -491,5 +492,5 @@
         if (layer.format == null) {
             // no format found - it's mandatory parameter - can't use this layer
-            Main.warn(tr("Can''t use layer {0} because no supported formats where found. Layer is available in formats: {1}",
+            Logging.warn(tr("Can''t use layer {0} because no supported formats where found. Layer is available in formats: {1}",
                     layer.getUserTitle(),
                     String.join(", ", unsupportedFormats)));
@@ -725,5 +726,5 @@
         }
         // if no layers is found, fallback to default mercator tile size. Maybe it will work
-        Main.warn("WMTS: Could not determine tile size. Using default tile size of: {0}", getDefaultTileSize());
+        Logging.warn("WMTS: Could not determine tile size. Using default tile size of: {0}", getDefaultTileSize());
         return getDefaultTileSize();
     }
Index: trunk/src/org/openstreetmap/josm/data/osm/DataSet.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/DataSet.java	(revision 12620)
@@ -55,4 +55,5 @@
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionManager;
 import org.openstreetmap.josm.tools.ListenerList;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
 
@@ -1010,8 +1011,8 @@
         OsmPrimitive result = getPrimitiveById(primitiveId);
         if (result == null && primitiveId != null) {
-            Main.warn(tr("JOSM expected to find primitive [{0} {1}] in dataset but it is not there. Please report this "
+            Logging.warn(tr("JOSM expected to find primitive [{0} {1}] in dataset but it is not there. Please report this "
                     + "at {2}. This is not a critical error, it should be safe to continue in your work.",
                     primitiveId.getType(), Long.toString(primitiveId.getUniqueId()), Main.getJOSMWebsite()));
-            Main.error(new Exception());
+            Logging.error(new Exception());
         }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/DatasetConsistencyTest.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/DatasetConsistencyTest.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/DatasetConsistencyTest.java	(revision 12620)
@@ -8,6 +8,6 @@
 import java.io.Writer;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -186,9 +186,9 @@
 
     private void printElapsedTime(long startTime) {
-        if (Main.isDebugEnabled()) {
+        if (Logging.isDebugEnabled()) {
             StackTraceElement item = Thread.currentThread().getStackTrace()[2];
             String operation = getClass().getSimpleName() + '.' + item.getMethodName();
             long elapsedTime = System.currentTimeMillis() - startTime;
-            Main.debug(tr("Test ''{0}'' completed in {1}",
+            Logging.debug(tr("Test ''{0}'' completed in {1}",
                     operation, Utils.getDurationString(elapsedTime)));
         }
@@ -216,5 +216,5 @@
             writer.println("Exception during dataset integrity test:");
             e.printStackTrace(writer);
-            Main.warn(e);
+            Logging.warn(e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/osm/FilterModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/FilterModel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/FilterModel.java	(revision 12620)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.gui.widgets.OSDLabel;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -51,5 +52,5 @@
                 filterMatcher.add(filter);
             } catch (ParseError e) {
-                Main.error(e);
+                Logging.error(e);
                 JOptionPane.showMessageDialog(
                         Main.parent,
Index: trunk/src/org/openstreetmap/josm/data/osm/MultipolygonBuilder.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/MultipolygonBuilder.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/MultipolygonBuilder.java	(revision 12620)
@@ -23,8 +23,8 @@
 import java.util.stream.Collectors;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.Geometry.PolygonIntersection;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.Pair;
@@ -203,5 +203,5 @@
             return makeFromPolygons(joinedWays);
         } catch (JoinedPolygonCreationException ex) {
-            Main.debug(ex);
+            Logging.debug(ex);
             return ex.getMessage();
         }
Index: trunk/src/org/openstreetmap/josm/data/osm/NoteData.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/NoteData.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/NoteData.java	(revision 12620)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.gui.JosmUserIdentityManager;
 import org.openstreetmap.josm.tools.ListenerList;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -137,5 +138,5 @@
                 } else {
                     // TODO merge comments?
-                    Main.info("Keeping existing note id={0} with uncommitted changes", String.valueOf(newNote.getId()));
+                    Logging.info("Keeping existing note id={0} with uncommitted changes", String.valueOf(newNote.getId()));
                 }
             }
@@ -162,6 +163,6 @@
         NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.OPENED, true);
         note.addComment(comment);
-        if (Main.isDebugEnabled()) {
-            Main.debug("Created note {0} with comment: {1}", note.getId(), text);
+        if (Logging.isDebugEnabled()) {
+            Logging.debug("Created note {0} with comment: {1}", note.getId(), text);
         }
         noteList.add(note);
@@ -181,6 +182,6 @@
             throw new IllegalStateException("Cannot add a comment to a closed note");
         }
-        if (Main.isDebugEnabled()) {
-            Main.debug("Adding comment to note {0}: {1}", note.getId(), text);
+        if (Logging.isDebugEnabled()) {
+            Logging.debug("Adding comment to note {0}: {1}", note.getId(), text);
         }
         NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.COMMENTED, true);
@@ -201,6 +202,6 @@
             throw new IllegalStateException("Cannot close a note that isn't open");
         }
-        if (Main.isDebugEnabled()) {
-            Main.debug("closing note {0} with comment: {1}", note.getId(), text);
+        if (Logging.isDebugEnabled()) {
+            Logging.debug("closing note {0} with comment: {1}", note.getId(), text);
         }
         NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.CLOSED, true);
@@ -223,7 +224,5 @@
             throw new IllegalStateException("Cannot reopen a note that isn't closed");
         }
-        if (Main.isDebugEnabled()) {
-            Main.debug("reopening note {0} with comment: {1}", note.getId(), text);
-        }
+        Logging.debug("reopening note {0} with comment: {1}", note.getId(), text);
         NoteComment comment = new NoteComment(new Date(), getCurrentUser(), text, NoteComment.Action.REOPENED, true);
         note.addComment(comment);
Index: trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/OsmPrimitive.java	(revision 12620)
@@ -27,4 +27,5 @@
 import org.openstreetmap.josm.gui.mappaint.StyleCache;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.template_engine.TemplateEngineDataProvider;
@@ -761,5 +762,5 @@
             return SearchCompiler.compile(Main.pref.get(prefName, defaultValue));
         } catch (ParseError e) {
-            Main.error(e, "Unable to compile pattern for " + prefName + ", trying default pattern:");
+            Logging.log(Logging.LEVEL_ERROR, "Unable to compile pattern for " + prefName + ", trying default pattern:", e);
         }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/QuadBuckets.java	(revision 12620)
@@ -10,7 +10,7 @@
 import java.util.NoSuchElementException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.coor.QuadTiling;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -598,5 +598,5 @@
         if (searchCache == null) {
             searchCache = root;
-            Main.info("bbox: " + searchBbox + " is out of the world");
+            Logging.info("bbox: " + searchBbox + " is out of the world");
         }
 
Index: trunk/src/org/openstreetmap/josm/data/osm/TagCollection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/TagCollection.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/TagCollection.java	(revision 12620)
@@ -22,5 +22,5 @@
 import java.util.stream.Stream;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -725,5 +725,5 @@
                 result += Integer.parseInt(value);
             } catch (NumberFormatException e) {
-                Main.trace(e);
+                Logging.trace(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/history/HistoryOsmPrimitive.java	(revision 12620)
@@ -13,5 +13,4 @@
 import java.util.Objects;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Changeset;
 import org.openstreetmap.josm.data.osm.Node;
@@ -26,4 +25,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.date.DateUtils;
 
@@ -354,5 +354,5 @@
             data.setVisible(visible);
         } catch (IllegalStateException e) {
-            Main.error(e, "Cannot change visibility for "+data+':');
+            Logging.log(Logging.LEVEL_ERROR, "Cannot change visibility for "+data+':', e);
         }
         data.setTimestamp(timestamp);
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/AbstractMapRenderer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/AbstractMapRenderer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/AbstractMapRenderer.java	(revision 12620)
@@ -20,4 +20,5 @@
 import org.openstreetmap.josm.gui.NavigatableComponent;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -157,5 +158,5 @@
             // On read, it would first check, if the way still has firstIdx+2 nodes, then check if the corresponding way nodes are still
             // the same and report changes in a more controlled manner.
-            Main.trace(e);
+            Logging.trace(e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapRendererFactory.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapRendererFactory.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/MapRendererFactory.java	(revision 12620)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.plugins.PluginHandler;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -138,8 +139,8 @@
                 return Class.forName(className, true, cl);
             } catch (final NoClassDefFoundError | ClassNotFoundException e) {
-                Main.trace(e);
+                Logging.trace(e);
             }
         }
-        Main.error(tr("Failed to load map renderer class ''{0}''. The class wasn''t found.", className));
+        Logging.error(tr("Failed to load map renderer class ''{0}''. The class wasn''t found.", className));
         return null;
     }
@@ -161,17 +162,18 @@
         Class<?> c = loadRendererClass(rendererClassName);
         if (c == null) {
-            Main.error(tr("Can''t activate map renderer class ''{0}'', because the class wasn''t found.", rendererClassName));
-            Main.error(tr("Activating the standard map renderer instead."));
+            Logging.error(tr("Can''t activate map renderer class ''{0}'', because the class wasn''t found.", rendererClassName));
+            Logging.error(tr("Activating the standard map renderer instead."));
             activateDefault();
         } else if (!AbstractMapRenderer.class.isAssignableFrom(c)) {
-            Main.error(tr("Can''t activate map renderer class ''{0}'', because it isn''t a subclass of ''{1}''.",
+            Logging.error(tr("Can''t activate map renderer class ''{0}'', because it isn''t a subclass of ''{1}''.",
                     rendererClassName, AbstractMapRenderer.class.getName()));
-            Main.error(tr("Activating the standard map renderer instead."));
+            Logging.error(tr("Activating the standard map renderer instead."));
             activateDefault();
         } else {
             Class<? extends AbstractMapRenderer> renderer = c.asSubclass(AbstractMapRenderer.class);
             if (!isRegistered(renderer)) {
-                Main.error(tr("Can''t activate map renderer class ''{0}'', because it isn''t registered as map renderer.", rendererClassName));
-                Main.error(tr("Activating the standard map renderer instead."));
+                Logging.error(tr("Can''t activate map renderer class ''{0}'', because it isn''t registered as map renderer.",
+                        rendererClassName));
+                Logging.error(tr("Activating the standard map renderer instead."));
                 activateDefault();
             } else {
@@ -306,5 +308,5 @@
             return AbstractMapRenderer.class.cast(c.newInstance(g, viewport, isInactiveMode));
         } catch (InvocationTargetException e) {
-            Main.debug(e);
+            Logging.debug(e);
             throw new MapRendererFactoryException(e.getCause());
         } catch (ReflectiveOperationException | IllegalArgumentException e) {
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/RenderBenchmarkCollector.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/RenderBenchmarkCollector.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/RenderBenchmarkCollector.java	(revision 12620)
@@ -9,4 +9,5 @@
 import org.openstreetmap.josm.data.osm.visitor.paint.StyledMapRenderer.StyleRecord;
 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -147,5 +148,5 @@
      */
     public static Supplier<RenderBenchmarkCollector> defaultBenchmarkSupplier() {
-        return () -> Main.isTraceEnabled() || Main.pref.getBoolean("mappaint.render.benchmark", false)
+        return () -> Logging.isTraceEnabled() || Main.pref.getBoolean("mappaint.render.benchmark", false)
                 ? new LoggingBenchmark() : new RenderBenchmarkCollector();
     }
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/StyledMapRenderer.java	(revision 12620)
@@ -241,6 +241,6 @@
             gv.setGlyphTransform(0, AffineTransform.getTranslateInstance(1000, 1000));
             Shape shape = gv.getGlyphOutline(0);
-            if (Main.isTraceEnabled()) {
-                Main.trace("#10446: shape: "+shape.getBounds());
+            if (Logging.isTraceEnabled()) {
+                Logging.trace("#10446: shape: {0}", shape.getBounds());
             }
             // x is about 1000 on normal stystems and about 2000 when the bug occurs
@@ -1129,6 +1129,6 @@
                                 (p1, p2) -> p1.append(p2, false)),
                         osm.isDisabled(), text);
-            } else if (Main.isTraceEnabled()) {
-                Main.trace("Couldn't find a correct label placement for " + osm + " / " + name);
+            } else {
+                Logging.trace("Couldn't find a correct label placement for {0} / {1}", osm, name);
             }
         });
Index: trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/Multipolygon.java	(revision 12620)
@@ -30,4 +30,5 @@
 import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.Geometry.AreaAndPerimeter;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -405,5 +406,5 @@
                 if (ds == null) {
                     // DataSet still not found. This should not happen, but a warning does no harm
-                    Main.warn("DataSet not found while resetting nodes in Multipolygon. " +
+                    Logging.warn("DataSet not found while resetting nodes in Multipolygon. " +
                             "This should not happen, you may report it to JOSM developers.");
                 } else if (wayIds.size() == 1) {
Index: trunk/src/org/openstreetmap/josm/data/preferences/AbstractToStringProperty.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/preferences/AbstractToStringProperty.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/preferences/AbstractToStringProperty.java	(revision 12620)
@@ -2,7 +2,7 @@
 package org.openstreetmap.josm.data.preferences;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.bugreport.BugReport;
 
@@ -89,5 +89,5 @@
                 return fromString(string);
             } catch (InvalidPreferenceValueException e) {
-                Main.warn(BugReport.intercept(e).put("key", key).put("value", string));
+                Logging.warn(BugReport.intercept(e).put("key", key).put("value", string));
             }
         }
Index: trunk/src/org/openstreetmap/josm/data/preferences/ParametrizedEnumProperty.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/preferences/ParametrizedEnumProperty.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/preferences/ParametrizedEnumProperty.java	(revision 12620)
@@ -3,4 +3,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -33,5 +34,5 @@
             return Enum.valueOf(enumClass, s);
         } catch (IllegalArgumentException e) {
-            Main.trace(e);
+            Logging.trace(e);
             return defaultValue;
         }
Index: trunk/src/org/openstreetmap/josm/data/preferences/PreferencesReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/preferences/PreferencesReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/preferences/PreferencesReader.java	(revision 12620)
@@ -30,7 +30,7 @@
 import javax.xml.validation.Validator;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.io.XmlStreamParsingException;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -146,7 +146,5 @@
                     version = Integer.parseInt(parser.getAttributeValue(null, "version"));
                 } catch (NumberFormatException e) {
-                    if (Main.isDebugEnabled()) {
-                        Main.debug(e.getMessage());
-                    }
+                    Logging.log(Logging.LEVEL_DEBUG, e);
                 }
                 parseRoot();
Index: trunk/src/org/openstreetmap/josm/data/preferences/StrokeProperty.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/preferences/StrokeProperty.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/preferences/StrokeProperty.java	(revision 12620)
@@ -8,5 +8,5 @@
 import java.util.stream.Collectors;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -78,5 +78,5 @@
 
             if (sumAbs < 1e-1) {
-                Main.error("Error in stroke dash format (all zeros): " + code);
+                Logging.error("Error in stroke dash format (all zeros): " + code);
                 dashes = Collections.emptyList();
             }
Index: trunk/src/org/openstreetmap/josm/data/projection/CustomProjection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/projection/CustomProjection.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/projection/CustomProjection.java	(revision 12620)
@@ -15,5 +15,4 @@
 import java.util.regex.Pattern;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.ProjectionBounds;
@@ -33,4 +32,5 @@
 import org.openstreetmap.josm.data.projection.proj.ProjParameters;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.bugreport.BugReport;
@@ -231,5 +231,5 @@
             update(pref);
         } catch (ProjectionConfigurationException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
             try {
                 update(null);
@@ -701,5 +701,5 @@
                 return Integer.valueOf(code.substring(5));
             } catch (NumberFormatException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
         }
@@ -858,5 +858,5 @@
                     }
                 } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/data/projection/Projections.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/projection/Projections.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/projection/Projections.java	(revision 12620)
@@ -45,4 +45,5 @@
 import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -181,5 +182,5 @@
                 }
             } catch (ProjectionConfigurationException e) {
-                Main.trace(e);
+                Logging.trace(e);
             }
         }
@@ -316,5 +317,5 @@
                     result.add(new ProjectionDefinition(code, name, definition));
                 } else {
-                    Main.warn("Failed to parse line from the EPSG projection definition: "+line);
+                    Logging.warn("Failed to parse line from the EPSG projection definition: "+line);
                 }
             }
@@ -339,5 +340,5 @@
                 proj = pc.getProjection();
             } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
-                Main.warn(e, "Unable to get projection "+code+" with "+pc+':');
+                Logging.log(Logging.LEVEL_WARN, "Unable to get projection "+code+" with "+pc+':', e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/data/projection/datum/NTV2GridShiftFile.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/projection/datum/NTV2GridShiftFile.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/projection/datum/NTV2GridShiftFile.java	(revision 12620)
@@ -29,5 +29,5 @@
 import java.util.Map;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -85,5 +85,5 @@
     private static void readBytes(InputStream in, byte[] b) throws IOException {
         if (in.read(b) < b.length) {
-            Main.error("Failed to read expected amount of bytes ("+ b.length +") from stream");
+            Logging.error("Failed to read expected amount of bytes ("+ b.length +") from stream");
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/projection/datum/NTV2SubGrid.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/projection/datum/NTV2SubGrid.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/projection/datum/NTV2SubGrid.java	(revision 12620)
@@ -25,5 +25,5 @@
 import java.nio.charset.StandardCharsets;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -152,5 +152,5 @@
     private static void readBytes(InputStream in, byte[] b) throws IOException {
         if (in.read(b) < b.length) {
-            Main.error("Failed to read expected amount of bytes ("+ b.length +") from stream");
+            Logging.error("Failed to read expected amount of bytes ("+ b.length +") from stream");
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/OsmValidator.java	(revision 12620)
@@ -61,4 +61,5 @@
 import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
 import org.openstreetmap.josm.gui.preferences.validator.ValidatorPreference;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -143,5 +144,5 @@
             allTestsMap.put(testClass.getName(), testClass.getConstructor().newInstance());
         } catch (ReflectiveOperationException e) {
-            Main.error(e);
+            Logging.error(e);
         }
     }
@@ -189,7 +190,7 @@
                     ignoredErrors.addAll(Files.readAllLines(path, StandardCharsets.UTF_8));
                 } catch (final FileNotFoundException e) {
-                    Main.debug(Main.getErrorMessage(e));
+                    Logging.debug(Logging.getErrorMessage(e));
                 } catch (final IOException e) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
             }
@@ -225,5 +226,5 @@
             }
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
         }
     }
@@ -355,11 +356,11 @@
     public static synchronized void initializeTests() {
         if (!testsInitialized) {
-            Main.debug("Initializing validator tests");
+            Logging.debug("Initializing validator tests");
             final long startTime = System.currentTimeMillis();
             initializeTests(getTests());
             testsInitialized = true;
-            if (Main.isDebugEnabled()) {
+            if (Logging.isDebugEnabled()) {
                 final long elapsedTime = System.currentTimeMillis() - startTime;
-                Main.debug("Initializing validator tests completed in " + Utils.getDurationString(elapsedTime));
+                Logging.debug("Initializing validator tests completed in {0}", Utils.getDurationString(elapsedTime));
             }
         }
@@ -377,5 +378,5 @@
                 }
             } catch (Exception e) { // NOPMD
-                Main.error(e);
+                Logging.error(e);
                 if (!GraphicsEnvironment.isHeadless()) {
                     JOptionPane.showMessageDialog(Main.parent,
Index: trunk/src/org/openstreetmap/josm/data/validation/Severity.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/Severity.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/Severity.java	(revision 12620)
@@ -7,6 +7,6 @@
 import java.awt.Color;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.preferences.ColorProperty;
+import org.openstreetmap.josm.tools.Logging;
 
 /** The error severity */
@@ -48,7 +48,5 @@
     public static void getColors() {
         for (Severity c : values()) {
-            if (Main.isDebugEnabled()) {
-                Main.debug(c.toString());
-            }
+            Logging.debug("{0}", c);
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/validation/Test.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/Test.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/Test.java	(revision 12620)
@@ -27,4 +27,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -153,5 +154,5 @@
         String startMessage = tr("Running test {0}", name);
         this.progressMonitor.beginTask(startMessage);
-        Main.debug(startMessage);
+        Logging.debug(startMessage);
         this.errors = new ArrayList<>(30);
         this.startTime = System.currentTimeMillis();
@@ -187,5 +188,5 @@
             // fix #11567 where elapsedTime is < 0
             long elapsedTime = Math.max(0, System.currentTimeMillis() - startTime);
-            Main.debug(tr("Test ''{0}'' completed in {1}", getName(), Utils.getDurationString(elapsedTime)));
+            Logging.debug(tr("Test ''{0}'' completed in {1}", getName(), Utils.getDurationString(elapsedTime)));
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/validation/routines/DomainValidator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/routines/DomainValidator.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/routines/DomainValidator.java	(revision 12620)
@@ -21,5 +21,5 @@
 import java.util.Locale;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -2052,5 +2052,5 @@
             }
         } catch (IllegalArgumentException e) { // input is not valid
-            Main.trace(e);
+            Logging.trace(e);
             return input;
         }
Index: trunk/src/org/openstreetmap/josm/data/validation/routines/UrlValidator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/routines/UrlValidator.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/routines/UrlValidator.java	(revision 12620)
@@ -29,5 +29,5 @@
 import java.util.regex.Pattern;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -450,5 +450,5 @@
             }
         } catch (URISyntaxException e) {
-            Main.trace(e);
+            Logging.trace(e);
             return false;
         }
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/Addresses.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/Addresses.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/Addresses.java	(revision 12620)
@@ -26,4 +26,5 @@
 import org.openstreetmap.josm.data.validation.TestError;
 import org.openstreetmap.josm.tools.Geometry;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
@@ -216,5 +217,5 @@
                     }
                 } else {
-                    Main.warn("Addresses test skipped chunck "+chunk+" for street part "+streetPart+" because p1 or p2 is null");
+                    Logging.warn("Addresses test skipped chunck "+chunk+" for street part "+streetPart+" because p1 or p2 is null");
                 }
             }
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/ConditionalKeys.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/ConditionalKeys.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/ConditionalKeys.java	(revision 12620)
@@ -13,5 +13,4 @@
 import java.util.regex.Pattern;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.validation.Severity;
@@ -19,4 +18,5 @@
 import org.openstreetmap.josm.data.validation.TestError;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
 
@@ -207,5 +207,5 @@
             }
         } catch (ConditionalParsingException ex) {
-            Main.debug(ex);
+            Logging.debug(ex);
             return ex.getMessage();
         }
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/CrossingWays.java	(revision 12620)
@@ -11,5 +11,4 @@
 import java.util.Objects;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.EastNorth;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -23,4 +22,5 @@
 import org.openstreetmap.josm.data.validation.util.ValUtil;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -268,5 +268,5 @@
             final EastNorth en2 = es1.getSecondNode().getEastNorth();
             if (en1 == null || en2 == null) {
-                Main.warn("Crossing ways test skipped "+es1);
+                Logging.warn("Crossing ways test skipped "+es1);
                 continue;
             }
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/Lanes.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/Lanes.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/Lanes.java	(revision 12620)
@@ -8,9 +8,9 @@
 import java.util.stream.Collectors;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.validation.Severity;
 import org.openstreetmap.josm.data.validation.Test;
 import org.openstreetmap.josm.data.validation.TestError;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -64,5 +64,5 @@
                 }
             } catch (NumberFormatException ignore) {
-                Main.debug(ignore.getMessage());
+                Logging.debug(ignore.getMessage());
             }
         }
@@ -82,5 +82,5 @@
         }
         } catch (NumberFormatException ignore) {
-            Main.debug(ignore.getMessage());
+            Logging.debug(ignore.getMessage());
         }
     }
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/MapCSSTagChecker.java	(revision 12620)
@@ -2,4 +2,5 @@
 package org.openstreetmap.josm.data.validation.tests;
 
+import static org.openstreetmap.josm.data.validation.tests.MapCSSTagChecker.FixCommand.evaluateObject;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
@@ -64,4 +65,5 @@
 import org.openstreetmap.josm.io.UTFInputStreamReader;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.Utils;
@@ -319,5 +321,6 @@
                                 check.errors.put(ai, Severity.valueOf(ai.key.substring("throw".length()).toUpperCase(Locale.ENGLISH)));
                             } catch (IllegalArgumentException e) {
-                                Main.warn(e, "Unsupported "+ai.key+" instruction. Allowed instructions are "+POSSIBLE_THROWS+'.');
+                                Logging.log(Logging.LEVEL_WARN,
+                                        "Unsupported "+ai.key+" instruction. Allowed instructions are "+POSSIBLE_THROWS+'.', e);
                             }
                         } else if ("fixAdd".equals(ai.key)) {
@@ -388,5 +391,5 @@
                             new GroupedMapCSSRule(map.getValue(), map.getKey())));
                 } catch (IllegalDataException e) {
-                    Main.error("Cannot add MapCss rule: "+e.getMessage());
+                    Logging.error("Cannot add MapCss rule: "+e.getMessage());
                     source.logError(e);
                 }
@@ -452,5 +455,5 @@
                 }
             } catch (IndexOutOfBoundsException ignore) {
-                Main.debug(ignore);
+                Logging.debug(ignore);
             }
             return null;
@@ -480,5 +483,5 @@
                     m.appendReplacement(sb, String.valueOf(argument).replace("^(", "").replace(")$", ""));
                 } catch (IndexOutOfBoundsException | IllegalArgumentException e) {
-                    Main.error(e, tr("Unable to replace argument {0} in {1}: {2}", argument, sb, e.getMessage()));
+                    Logging.log(Logging.LEVEL_ERROR, tr("Unable to replace argument {0} in {1}: {2}", argument, sb, e.getMessage()), e);
                 }
             }
@@ -735,5 +738,5 @@
             if (Main.pref.getBoolean("validator.check_assert_local_rules", false) && Utils.isLocalUrl(url)) {
                 for (String msg : checkAsserts(result.parseChecks)) {
-                    Main.warn(msg);
+                    Logging.warn(msg);
                 }
             }
@@ -752,7 +755,7 @@
             try {
                 if (!i.startsWith("resource:")) {
-                    Main.info(tr("Adding {0} to tag checker", i));
-                } else if (Main.isDebugEnabled()) {
-                    Main.debug(tr("Adding {0} to tag checker", i));
+                    Logging.info(tr("Adding {0} to tag checker", i));
+                } else if (Logging.isDebugEnabled()) {
+                    Logging.debug(tr("Adding {0} to tag checker", i));
                 }
                 addMapCSS(i);
@@ -761,9 +764,9 @@
                 }
             } catch (IOException | IllegalStateException | IllegalArgumentException ex) {
-                Main.warn(tr("Failed to add {0} to tag checker", i));
-                Main.warn(ex, false);
+                Logging.warn(tr("Failed to add {0} to tag checker", i));
+                Logging.log(Logging.LEVEL_WARN, ex);
             } catch (ParseException ex) {
-                Main.warn(tr("Failed to add {0} to tag checker", i));
-                Main.warn(ex);
+                Logging.warn(tr("Failed to add {0} to tag checker", i));
+                Logging.warn(ex);
             }
         }
@@ -780,11 +783,7 @@
         final DataSet ds = new DataSet();
         for (final TagCheck check : schecks) {
-            if (Main.isDebugEnabled()) {
-                Main.debug("Check: "+check);
-            }
+            Logging.debug("Check: {0}", check);
             for (final Map.Entry<String, Boolean> i : check.assertions.entrySet()) {
-                if (Main.isDebugEnabled()) {
-                    Main.debug("- Assertion: "+i);
-                }
+                Logging.debug("- Assertion: {0}", i);
                 final OsmPrimitive p = OsmUtils.createPrimitive(i.getKey());
                 // Build minimal ordered list of checks to run to test the assertion
@@ -798,7 +797,5 @@
                 ds.addPrimitive(p);
                 final Collection<TestError> pErrors = getErrorsForPrimitive(p, true, checksToRun);
-                if (Main.isDebugEnabled()) {
-                    Main.debug("- Errors: "+pErrors);
-                }
+                Logging.debug("- Errors: {0}", pErrors);
                 @SuppressWarnings({"EqualsBetweenInconvertibleTypes", "EqualsIncompatibleType"})
                 final boolean isError = pErrors.stream().anyMatch(e -> e.getTester().equals(check.rule));
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/MultipolygonTest.java	(revision 12620)
@@ -18,5 +18,4 @@
 import java.util.Set;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.ChangeCommand;
 import org.openstreetmap.josm.command.Command;
@@ -41,4 +40,5 @@
 import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.Geometry.PolygonIntersection;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -591,5 +591,5 @@
             final EastNorth en2 = es1.getSecondNode().getEastNorth();
             if (en1 == null || en2 == null) {
-                Main.warn("Crossing ways test (MP) skipped " + es1);
+                Logging.warn("Crossing ways test (MP) skipped " + es1);
                 continue;
             }
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/OpeningHourTest.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/OpeningHourTest.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/OpeningHourTest.java	(revision 12620)
@@ -15,5 +15,4 @@
 import javax.script.ScriptException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.command.ChangePropertyCommand;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -23,4 +22,5 @@
 import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -72,5 +72,5 @@
             }
         } else {
-            Main.warn("Unable to initialize OpeningHourTest because no JavaScript engine has been found");
+            Logging.warn("Unable to initialize OpeningHourTest because no JavaScript engine has been found");
         }
     }
@@ -207,5 +207,5 @@
                 prettifiedValue = (String) ((Invocable) ENGINE).invokeMethod(r, "prettifyValue");
             } catch (ScriptException | NoSuchMethodException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
             for (final Object i : getList(((Invocable) ENGINE).invokeMethod(r, "getErrors"))) {
@@ -219,5 +219,5 @@
             }
         } catch (ScriptException | NoSuchMethodException ex) {
-            Main.error(ex);
+            Logging.error(ex);
         }
         return errors;
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/TagChecker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/TagChecker.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/TagChecker.java	(revision 12620)
@@ -51,4 +51,5 @@
 import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.Utils;
@@ -205,5 +206,5 @@
                             tagcheckerfile = true;
                             if (!DEFAULT_SOURCES.contains(source)) {
-                                Main.info(tr("Adding {0} to tag checker", source));
+                                Logging.info(tr("Adding {0} to tag checker", source));
                             }
                         } else
@@ -211,5 +212,5 @@
                             ignorefile = true;
                             if (!DEFAULT_SOURCES.contains(source)) {
-                                Main.info(tr("Adding {0} to ignore tags", source));
+                                Logging.info(tr("Adding {0} to ignore tags", source));
                             }
                         }
@@ -238,5 +239,5 @@
                         default:
                             if (!key.startsWith(";")) {
-                                Main.warn("Unsupported TagChecker key: " + key);
+                                Logging.warn("Unsupported TagChecker key: " + key);
                             }
                         }
@@ -249,5 +250,5 @@
                                 checkerData.add(d);
                             } else {
-                                Main.error(tr("Invalid tagchecker line - {0}: {1}", err, line));
+                                Logging.error(tr("Invalid tagchecker line - {0}: {1}", err, line));
                             }
                         }
@@ -257,15 +258,15 @@
                         harmonizedKeys.put(harmonizeKey(line.substring(1)), okValue);
                     } else {
-                        Main.error(tr("Invalid spellcheck line: {0}", line));
+                        Logging.error(tr("Invalid spellcheck line: {0}", line));
                     }
                     if (isFirstLine) {
                         isFirstLine = false;
                         if (!(tagcheckerfile || ignorefile) && !DEFAULT_SOURCES.contains(source)) {
-                            Main.info(tr("Adding {0} to spellchecker", source));
+                            Logging.info(tr("Adding {0} to spellchecker", source));
                         }
                     }
                 }
             } catch (IOException e) {
-                Main.error(e);
+                Logging.error(e);
                 errorSources.append(source).append('\n');
             }
@@ -828,5 +829,5 @@
                 }
             } catch (IllegalStateException e) {
-                Main.error(e);
+                Logging.error(e);
                 description = null;
             }
@@ -871,8 +872,8 @@
                     data.add(new CheckerElement(exp));
                 } catch (IllegalStateException e) {
-                    Main.trace(e);
+                    Logging.trace(e);
                     return tr("Illegal expression ''{0}''", exp);
                 } catch (PatternSyntaxException e) {
-                    Main.trace(e);
+                    Logging.trace(e);
                     return tr("Illegal regular expression ''{0}''", exp);
                 }
Index: trunk/src/org/openstreetmap/josm/data/validation/tests/UnconnectedWays.java
===================================================================
--- trunk/src/org/openstreetmap/josm/data/validation/tests/UnconnectedWays.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/data/validation/tests/UnconnectedWays.java	(revision 12620)
@@ -33,4 +33,5 @@
 import org.openstreetmap.josm.gui.preferences.validator.ValidatorPreference;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -318,5 +319,5 @@
         public boolean nearby(Node n, double dist) {
             if (w == null) {
-                Main.debug("way null");
+                Logging.debug("way null");
                 return false;
             }
Index: trunk/src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/ExceptionDialogUtil.java	(revision 12620)
@@ -26,4 +26,5 @@
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.ExceptionUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;
 
@@ -92,5 +93,5 @@
      */
     public static void explainGeneric(Exception e) {
-        Main.error(e);
+        Logging.error(e);
         BugReportExceptionHandler.handleException(e);
     }
Index: trunk/src/org/openstreetmap/josm/gui/ExtendedDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/ExtendedDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/ExtendedDialog.java	(revision 12620)
@@ -41,4 +41,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.InputMapUtils;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.WindowGeometry;
@@ -413,6 +414,7 @@
                 // and the result differs from its default value
                 result = ExtendedDialog.DialogClosedOtherwise;
-                if (Main.isDebugEnabled()) {
-                    Main.debug(getClass().getName()+" ESC action performed ("+actionEvent+") from "+new Exception().getStackTrace()[1]);
+                if (Logging.isDebugEnabled()) {
+                    Logging.debug("{0} ESC action performed ({1}) from {2}",
+                            getClass().getName(), actionEvent, new Exception().getStackTrace()[1]);
                 }
                 setVisible(false);
@@ -442,6 +444,6 @@
         }
 
-        if (Main.isDebugEnabled()) {
-            Main.debug(getClass().getName()+".setVisible("+visible+") from "+new Exception().getStackTrace()[1]);
+        if (Logging.isDebugEnabled()) {
+            Logging.debug(getClass().getName()+".setVisible("+visible+") from "+new Exception().getStackTrace()[1]);
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/GettingStarted.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/GettingStarted.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/GettingStarted.java	(revision 12620)
@@ -30,4 +30,5 @@
 import org.openstreetmap.josm.io.OnlineResource;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OpenBrowser;
 import org.openstreetmap.josm.tools.WikiReader;
@@ -35,5 +36,5 @@
 /**
  * Panel that fills the main part of the program window when JOSM has just started.
- * 
+ *
  * It downloads and displays the so called <em>message of the day</em>, which
  * contains news about recent major changes, warning in case of outdated versions, etc.
@@ -151,5 +152,5 @@
                     ProxyPreference.removeProxyPreferenceListener(this);
                 } catch (IOException ex) {
-                    Main.warn(ex, tr("Failed to read MOTD. Exception was: {0}", ex.toString()));
+                    Logging.log(Logging.LEVEL_WARN, tr("Failed to read MOTD. Exception was: {0}", ex.toString()), ex);
                     content = "<html>" + STYLE + "<h1>" + "JOSM - " + tr("Java OpenStreetMap Editor")
                             + "</h1>\n<h2 align=\"center\">(" + tr("Message of the day not available") + ")</h2></html>";
Index: trunk/src/org/openstreetmap/josm/gui/HelpAwareOptionPane.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/HelpAwareOptionPane.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/HelpAwareOptionPane.java	(revision 12620)
@@ -24,5 +24,4 @@
 import javax.swing.event.ChangeListener;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.help.HelpBrowser;
 import org.openstreetmap.josm.gui.help.HelpUtil;
@@ -31,4 +30,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.InputMapUtils;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.WindowGeometry;
 
@@ -253,11 +253,11 @@
         switch (messageType) {
             case JOptionPane.ERROR_MESSAGE:
-                Main.error(title + " - " + msg);
+                Logging.error(title + " - " + msg);
                 break;
             case JOptionPane.WARNING_MESSAGE:
-                Main.warn(title + " - " + msg);
+                Logging.warn(title + " - " + msg);
                 break;
             default:
-                Main.info(title + " - " + msg);
+                Logging.info(title + " - " + msg);
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/JosmUserIdentityManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/JosmUserIdentityManager.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/JosmUserIdentityManager.java	(revision 12620)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -68,5 +69,5 @@
                     instance.initFromOAuth();
                 } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
-                    Main.error(e);
+                    Logging.error(e);
                     // Fall back to preferences if OAuth identification fails for any reason
                     instance.initFromPreferences();
@@ -231,5 +232,5 @@
             setFullyIdentified(info.getDisplayName(), info);
         } catch (IllegalArgumentException | OsmTransferException e) {
-            Main.error(e);
+            Logging.error(e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/MainApplication.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/MainApplication.java	(revision 12620)
@@ -223,5 +223,5 @@
         Logging.setLogLevel(logLevel);
         if (!args.showVersion() && !args.showHelp()) {
-            Main.info(tr("Log level is at {0} ({1}, {2})", logLevel.getLocalizedName(), logLevel.getName(), logLevel.intValue()));
+            Logging.info(tr("Log level is at {0} ({1}, {2})", logLevel.getLocalizedName(), logLevel.getName(), logLevel.intValue()));
         }
 
@@ -263,5 +263,5 @@
         boolean skipLoadingPlugins = args.hasOption(Option.SKIP_PLUGINS);
         if (skipLoadingPlugins) {
-            Main.info(tr("Plugin loading skipped"));
+            Logging.info(tr("Plugin loading skipped"));
         }
 
@@ -269,5 +269,5 @@
             // Enable debug in OAuth signpost via system preference, but only at trace level
             Utils.updateSystemProperty("debug", "true");
-            Main.info(tr("Enabled detailed debug level (trace)"));
+            Logging.info(tr("Enabled detailed debug level (trace)"));
         }
 
@@ -306,5 +306,5 @@
             CustomConfigurator.XMLCommandProcessor config = new CustomConfigurator.XMLCommandProcessor(Main.pref);
             for (String i : args.get(Option.LOAD_PREFERENCES)) {
-                info("Reading preferences from " + i);
+                Logging.info("Reading preferences from " + i);
                 try (InputStream is = openStream(new URL(i))) {
                     config.openAndReadXML(is);
@@ -318,6 +318,6 @@
             CertificateAmendment.addMissingCertificates();
         } catch (IOException | GeneralSecurityException ex) {
-            Main.warn(ex);
-            Main.warn(getErrorMessage(Utils.getRootCause(ex)));
+            Logging.warn(ex);
+            Logging.warn(Logging.getErrorMessage(Utils.getRootCause(ex)));
         }
         Authenticator.setDefault(DefaultAuthenticator.getInstance());
@@ -387,5 +387,5 @@
                 PlatformHookWindows.removeInsecureCertificates();
             } catch (NoSuchAlgorithmException | CertificateException | KeyStoreException | IOException e) {
-                error(e);
+                Logging.error(e);
             }
         }
@@ -402,5 +402,5 @@
             // Repaint manager is registered so late for a reason - there is lots of violation during startup process
             // but they don't seem to break anything and are difficult to fix
-            info("Enabled EDT checker, wrongful access to gui from non EDT thread will be printed to console");
+            Logging.info("Enabled EDT checker, wrongful access to gui from non EDT thread will be printed to console");
             RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
         }
@@ -443,6 +443,7 @@
                     Main.setOffline(OnlineResource.valueOf(s.toUpperCase(Locale.ENGLISH)));
                 } catch (IllegalArgumentException e) {
-                    Main.error(e, tr("''{0}'' is not a valid value for argument ''{1}''. Possible values are {2}, possibly delimited by commas.",
-                            s.toUpperCase(Locale.ENGLISH), Option.OFFLINE.getName(), Arrays.toString(OnlineResource.values())));
+                    Logging.log(Logging.LEVEL_ERROR,
+                            tr("''{0}'' is not a valid value for argument ''{1}''. Possible values are {2}, possibly delimited by commas.",
+                            s.toUpperCase(Locale.ENGLISH), Option.OFFLINE.getName(), Arrays.toString(OnlineResource.values())), e);
                     System.exit(1);
                     return;
@@ -452,5 +453,5 @@
         Set<OnlineResource> offline = Main.getOfflineResources();
         if (!offline.isEmpty()) {
-            Main.warn(trn("JOSM is running in offline mode. This resource will not be available: {0}",
+            Logging.warn(trn("JOSM is running in offline mode. This resource will not be available: {0}",
                     "JOSM is running in offline mode. These resources will not be available: {0}",
                     offline.size(), offline.size() == 1 ? offline.iterator().next() : Arrays.toString(offline.toArray())));
@@ -480,7 +481,7 @@
                                 Utils.updateSystemProperty("java.net.preferIPv6Addresses", "true");
                                 if (!wasv6) {
-                                    Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4 after next restart."));
+                                    Logging.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4 after next restart."));
                                 } else {
-                                    Main.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4."));
+                                    Logging.info(tr("Detected useable IPv6 network, prefering IPv6 over IPv4."));
                                 }
                                 hasv6 = true;
@@ -490,16 +491,14 @@
                     }
                 } catch (IOException | SecurityException e) {
-                    if (Main.isDebugEnabled()) {
-                        Main.debug("Exception while checking IPv6 connectivity: "+e);
-                    }
-                    Main.trace(e);
+                    Logging.debug("Exception while checking IPv6 connectivity: {0}", e);
+                    Logging.trace(e);
                 }
                 if (wasv6 && !hasv6) {
-                    Main.info(tr("Detected no useable IPv6 network, prefering IPv4 over IPv6 after next restart."));
+                    Logging.info(tr("Detected no useable IPv6 network, prefering IPv4 over IPv6 after next restart."));
                     Main.pref.put("validated.ipv6", hasv6); // be sure it is stored before the restart!
                     try {
                         RestartAction.restartJOSM();
                     } catch (IOException e) {
-                        Main.error(e);
+                        Logging.error(e);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/gui/MainFrame.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MainFrame.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/MainFrame.java	(revision 12620)
@@ -28,4 +28,5 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer.LayerStateChangeListener;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.WindowGeometry;
 
@@ -144,5 +145,5 @@
                 setExtendedState(windowState);
             } else {
-                Main.debug("Main window: maximizing not supported");
+                Logging.debug("Main window: maximizing not supported");
             }
         } else {
Index: trunk/src/org/openstreetmap/josm/gui/MapStatus.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/MapStatus.java	(revision 12620)
@@ -79,4 +79,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -203,5 +204,5 @@
         public void appendLogMessage(String message) {
             if (message != null && !message.isEmpty()) {
-                Main.info("appendLogMessage not implemented for background tasks. Message was: " + message);
+                Logging.info("appendLogMessage not implemented for background tasks. Message was: " + message);
             }
         }
@@ -357,5 +358,5 @@
                     oldMousePos = ms.mousePos;
                 } catch (ConcurrentModificationException ex) {
-                    Main.warn(ex);
+                    Logging.warn(ex);
                 } finally {
                     if (ds != null) {
@@ -415,10 +416,10 @@
                         EventQueue.invokeAndWait(new CollectorWorker(ms));
                     } catch (InvocationTargetException e) {
-                        Main.warn(e);
+                        Logging.warn(e);
                     }
                 }
             } catch (InterruptedException e) {
                 // Occurs frequently during JOSM shutdown, log set to trace only
-                Main.trace("InterruptedException in "+MapStatus.class.getSimpleName());
+                Logging.trace("InterruptedException in "+MapStatus.class.getSimpleName());
                 Thread.currentThread().interrupt();
             } finally {
@@ -686,5 +687,5 @@
             incomingMouseState.clear();
             if (!incomingMouseState.offer(ms)) {
-                Main.warn("Unable to handle new MouseState: " + ms);
+                Logging.warn("Unable to handle new MouseState: " + ms);
             }
         }
@@ -739,5 +740,5 @@
                     AWTEvent.KEY_EVENT_MASK | AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK);
         } catch (SecurityException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
             mv.addMouseMotionListener(mouseMotionListener);
             mv.addKeyListener(keyAdapter);
@@ -750,5 +751,5 @@
         } catch (SecurityException e) {
             // Don't care, awtListener probably wasn't registered anyway
-            Main.trace(e);
+            Logging.trace(e);
         }
         mv.removeMouseMotionListener(mouseMotionListener);
@@ -1111,5 +1112,5 @@
                 thread.interrupt();
             } catch (SecurityException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 12620)
@@ -174,5 +174,5 @@
         public void paint(MapViewGraphics graphics) {
             if (!warningPrinted) {
-                Main.debug("A layer triggered a repaint while being added: " + layer);
+                Logging.debug("A layer triggered a repaint while being added: " + layer);
                 warningPrinted = true;
             }
@@ -337,5 +337,5 @@
             if (!registeredLayers.containsKey(layer)) {
                 // The layer may have removed itself during attachToMapView()
-                Main.warn("Layer was removed during attachToMapView()");
+                Logging.warn("Layer was removed during attachToMapView()");
             } else {
                 registeredLayers.put(layer, painter);
@@ -385,5 +385,5 @@
         LayerPainter painter = registeredLayers.remove(layer);
         if (painter == null) {
-            Main.error("The painter for layer " + layer + " was not registered.");
+            Logging.error("The painter for layer " + layer + " was not registered.");
             return;
         }
@@ -414,5 +414,5 @@
      * Checks if virtual nodes should be drawn. Default is <code>false</code>
      * @return The virtual nodes property.
-     * @see Rendering#render(DataSet, boolean, Bounds)
+     * @see Rendering#render
      */
     public boolean isVirtualNodesEnabled() {
@@ -598,5 +598,5 @@
             //
             // But the application seems to work fine after, so let's just log the error
-            Main.error(e);
+            Logging.error(e);
         }
     }
@@ -843,5 +843,5 @@
     @Override
     public void repaint() {
-        if (Main.isTraceEnabled()) {
+        if (Logging.isTraceEnabled()) {
             invalidatedListener.traceRandomRepaint();
         }
Index: trunk/src/org/openstreetmap/josm/gui/MenuScroller.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MenuScroller.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/MenuScroller.java	(revision 12620)
@@ -29,4 +29,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.WindowGeometry;
 
@@ -464,6 +465,6 @@
             firstIndex += mwe.getWheelRotation();
             refreshMenu();
-            if (Main.isDebugEnabled()) {
-                Main.debug(getClass().getName()+" consuming event "+mwe);
+            if (Logging.isDebugEnabled()) {
+                Logging.debug("{0} consuming event {1}", getClass().getName(), mwe);
             }
             mwe.consume();
Index: trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/NavigatableComponent.java	(revision 12620)
@@ -61,4 +61,5 @@
 import org.openstreetmap.josm.gui.mappaint.mapcss.MapCSSStyleSource;
 import org.openstreetmap.josm.gui.util.CursorManager;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -718,5 +719,5 @@
                             Thread.sleep(1000L / fps);
                         } catch (InterruptedException ex) {
-                            Main.warn("InterruptedException in "+NavigatableComponent.class.getSimpleName()+" during smooth scrolling");
+                            Logging.warn("InterruptedException in "+NavigatableComponent.class.getSimpleName()+" during smooth scrolling");
                             Thread.currentThread().interrupt();
                         }
Index: trunk/src/org/openstreetmap/josm/gui/NoteSortDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/NoteSortDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/NoteSortDialog.java	(revision 12620)
@@ -13,6 +13,6 @@
 import javax.swing.JRadioButton;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.notes.Note;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -51,5 +51,5 @@
             lastActionSort.setSelected(true);
         } else {
-            Main.warn("sort mode not recognized");
+            Logging.warn("sort mode not recognized");
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/OsmPrimitivRenderer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/OsmPrimitivRenderer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/OsmPrimitivRenderer.java	(revision 12620)
@@ -13,8 +13,8 @@
 import javax.swing.table.TableCellRenderer;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -82,5 +82,5 @@
                 ((JLabel) def).setIcon(icon);
             } else {
-                Main.warn("Null icon for "+value.getDisplayType());
+                Logging.warn("Null icon for "+value.getDisplayType());
             }
             ((JLabel) def).setToolTipText(getComponentToolTipText(value));
Index: trunk/src/org/openstreetmap/josm/gui/SideButton.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/SideButton.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/SideButton.java	(revision 12620)
@@ -17,8 +17,8 @@
 import javax.swing.plaf.basic.BasicArrowButton;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.Destroyable;
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.ImageResource;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -42,5 +42,5 @@
                 ImageProvider.ImageSizes.SIDEBUTTON.getImageDimension()));
         } else if (getIcon() != null) { /* TODO: remove when calling code is fixed, replace by exception */
-            Main.warn("Old style SideButton usage for action " + action);
+            Logging.warn("Old style SideButton usage for action " + action);
             fixIcon(action);
         }
Index: trunk/src/org/openstreetmap/josm/gui/SplashScreen.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/SplashScreen.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/SplashScreen.java	(revision 12620)
@@ -40,4 +40,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.WindowGeometry;
@@ -233,7 +234,5 @@
         public void beginTask(String title) {
             if (title != null && !title.isEmpty()) {
-                if (Main.isDebugEnabled()) {
-                    Main.debug(title);
-                }
+                Logging.debug(title);
                 final MeasurableTask task = new MeasurableTask(title);
                 tasks.add(task);
@@ -264,7 +263,5 @@
         @Override
         public void subTask(String title) {
-            if (Main.isDebugEnabled()) {
-                Main.debug(title);
-            }
+            Logging.debug(title);
             latestSubtask = new SplashProgressMonitor(title, listener);
             tasks.add(latestSubtask);
@@ -299,6 +296,6 @@
             if (task instanceof MeasurableTask) {
                 ((MeasurableTask) task).finish();
-                if (Main.isDebugEnabled()) {
-                    Main.debug(tr("{0} completed in {1}", title, ((MeasurableTask) task).duration));
+                if (Logging.isDebugEnabled()) {
+                    Logging.debug(tr("{0} completed in {1}", title, ((MeasurableTask) task).duration));
                 }
                 listener.stateChanged(null);
Index: trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/autofilter/AutoFilterManager.java	(revision 12620)
@@ -54,4 +54,5 @@
 import org.openstreetmap.josm.gui.mappaint.mapcss.Selector;
 import org.openstreetmap.josm.gui.widgets.OSDLabel;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -182,5 +183,5 @@
                 values.add(s);
             } catch (NumberFormatException e) {
-                Main.trace(e);
+                Logging.trace(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/bbox/SlippyMapBBoxChooser.java	(revision 12620)
@@ -44,4 +44,5 @@
 import org.openstreetmap.josm.gui.layer.AbstractCachedTileSourceLayer;
 import org.openstreetmap.josm.gui.layer.TMSLayer;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -86,5 +87,5 @@
                     }
                 } catch (IllegalArgumentException ex) {
-                    Main.warn(ex);
+                    Logging.warn(ex);
                     if (ex.getMessage() != null && !ex.getMessage().isEmpty()) {
                         JOptionPane.showMessageDialog(Main.parent,
@@ -134,5 +135,5 @@
      */
     public SlippyMapBBoxChooser() {
-        debug = Main.isDebugEnabled();
+        debug = Logging.isDebugEnabled();
         SpringLayout springLayout = new SpringLayout();
         setLayout(springLayout);
Index: trunk/src/org/openstreetmap/josm/gui/bbox/TileSelectionBBoxChooser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/bbox/TileSelectionBBoxChooser.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/bbox/TileSelectionBBoxChooser.java	(revision 12620)
@@ -69,5 +69,5 @@
  *            // listen for BBOX events
  *            if (evt.getPropertyName().equals(BBoxChooser.BBOX_PROP)) {
- *               Main.info("new bbox based on OSM tiles selected: " + (Bounds)evt.getNewValue());
+ *               Logging.info("new bbox based on OSM tiles selected: " + (Bounds)evt.getNewValue());
  *            }
  *        }
Index: trunk/src/org/openstreetmap/josm/gui/conflict/pair/AbstractListMergeModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/conflict/pair/AbstractListMergeModel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/conflict/pair/AbstractListMergeModel.java	(revision 12620)
@@ -40,4 +40,5 @@
 import org.openstreetmap.josm.gui.widgets.OsmPrimitivesTableModel;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -736,5 +737,5 @@
                 return ((RelationMember) value).getMember();
             } else {
-                Main.error("Unknown object type: "+value);
+                Logging.error("Unknown object type: "+value);
                 return null;
             }
Index: trunk/src/org/openstreetmap/josm/gui/conflict/tags/MultiValueCellEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/conflict/tags/MultiValueCellEditor.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/conflict/tags/MultiValueCellEditor.java	(revision 12620)
@@ -21,6 +21,6 @@
 import javax.swing.table.TableCellEditor;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.widgets.JosmComboBox;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -167,5 +167,5 @@
             break;
         default:
-            Main.error("Unknown decision type in initEditor(): "+decision.getDecisionType());
+            Logging.error("Unknown decision type in initEditor(): "+decision.getDecisionType());
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/conflict/tags/MultiValueCellRenderer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/conflict/tags/MultiValueCellRenderer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/conflict/tags/MultiValueCellRenderer.java	(revision 12620)
@@ -14,8 +14,8 @@
 import javax.swing.table.TableCellRenderer;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.conflict.ConflictColors;
 import org.openstreetmap.josm.gui.widgets.JosmComboBox;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -71,5 +71,5 @@
                         break;
                     default:
-                        Main.error("Unknown decision type in renderColors(): "+decision.getDecisionType());
+                        Logging.error("Unknown decision type in renderColors(): "+decision.getDecisionType());
                     }
                 } else {
@@ -103,5 +103,5 @@
             break;
         default:
-            Main.error("Unknown decision type in renderValue(): "+decision.getDecisionType());
+            Logging.error("Unknown decision type in renderValue(): "+decision.getDecisionType());
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolutionUtil.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolutionUtil.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/conflict/tags/TagConflictResolutionUtil.java	(revision 12620)
@@ -20,4 +20,5 @@
 import org.openstreetmap.josm.data.osm.Tag;
 import org.openstreetmap.josm.data.osm.TagCollection;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 
@@ -216,5 +217,5 @@
                     // Can happen if a particular resolver has an invalid regular expression pattern
                     // but it should not stop the other automatic tag conflict resolution.
-                    Main.error(e);
+                    Logging.error(e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/datatransfer/AbstractStackTransferHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/datatransfer/AbstractStackTransferHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/datatransfer/AbstractStackTransferHandler.java	(revision 12620)
@@ -15,4 +15,5 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.bugreport.BugReport;
 
@@ -51,6 +52,7 @@
             if (df.supports(support)) {
                 try {
-                    if (Main.isDebugEnabled()) {
-                        Main.debug("{0} pasting {1} at {2}", df.getClass().getSimpleName(), Arrays.toString(support.getDataFlavors()), center);
+                    if (Logging.isDebugEnabled()) {
+                        Logging.debug("{0} pasting {1} at {2}",
+                                df.getClass().getSimpleName(), Arrays.toString(support.getDataFlavors()), center);
                     }
                     if (df.importData(support, layer, center)) {
@@ -58,5 +60,5 @@
                     }
                 } catch (UnsupportedFlavorException | IOException e) {
-                    Main.warn(e);
+                    Logging.warn(e);
                 } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
                     BugReport.intercept(e).put("paster", df).put("flavors", support::getDataFlavors).warn();
Index: trunk/src/org/openstreetmap/josm/gui/datatransfer/ClipboardUtils.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/datatransfer/ClipboardUtils.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/datatransfer/ClipboardUtils.java	(revision 12620)
@@ -13,6 +13,6 @@
 import java.io.IOException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -50,5 +50,5 @@
                 clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
             } catch (HeadlessException e) {
-                Main.warn("Headless. Using fake clipboard.", e);
+                Logging.warn("Headless. Using fake clipboard.", e);
                 clipboard = new Clipboard("fake");
             }
@@ -83,5 +83,5 @@
             }
         } catch (UnsupportedFlavorException | IOException ex) {
-            Main.error(ex);
+            Logging.error(ex);
         }
         return null;
@@ -109,15 +109,15 @@
                 // Clipboard currently unavailable.
                 // On some platforms, the system clipboard is unavailable while it is accessed by another application.
-                Main.trace("Clipboard unavailable.", e);
+                Logging.trace("Clipboard unavailable.", e);
                 try {
                     Thread.sleep(1);
                 } catch (InterruptedException ex) {
-                    Main.warn(ex, "InterruptedException in " + Utils.class.getSimpleName()
-                            + " while getting clipboard content");
+                    Logging.log(Logging.LEVEL_WARN, "InterruptedException in " + Utils.class.getSimpleName()
+                            + " while getting clipboard content", ex);
                     Thread.currentThread().interrupt();
                 }
             } catch (NullPointerException e) { // NOPMD
                 // JDK-6322854: On Linux/X11, NPE can happen for unknown reasons, on all versions of Java
-                Main.error(e);
+                Logging.error(e);
             }
         }
@@ -145,5 +145,5 @@
                 return Boolean.TRUE;
             } catch (IllegalStateException ex) {
-                Main.error(ex);
+                Logging.error(ex);
                 return Boolean.FALSE;
             }
Index: trunk/src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/datatransfer/OsmTransferHandler.java	(revision 12620)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.gui.datatransfer.importers.TextTagPaster;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -47,5 +48,5 @@
                     }
                 } catch (UnsupportedFlavorException | IOException e) {
-                    Main.warn(e);
+                    Logging.warn(e);
                 }
             }
@@ -96,8 +97,8 @@
             }
         } catch (IllegalStateException e) {
-            Main.debug(e);
+            Logging.debug(e);
         } catch (NullPointerException e) { // NOPMD
             // JDK-6322854: On Linux/X11, NPE can happen for unknown reasons, on all versions of Java
-            Main.error(e);
+            Logging.error(e);
         }
         return false;
Index: trunk/src/org/openstreetmap/josm/gui/datatransfer/importers/TextTagPaster.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/datatransfer/importers/TextTagPaster.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/datatransfer/importers/TextTagPaster.java	(revision 12620)
@@ -11,5 +11,5 @@
 import javax.swing.TransferHandler.TransferSupport;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.TextTagParser;
 
@@ -34,5 +34,5 @@
             return super.supports(support) && containsValidTags(support);
         } catch (UnsupportedFlavorException | IOException e) {
-            Main.warn(e);
+            Logging.warn(e);
             return false;
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ChangesetDialog.java	(revision 12620)
@@ -58,4 +58,5 @@
 import org.openstreetmap.josm.io.OnlineResource;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OpenBrowser;
 import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;
@@ -523,8 +524,8 @@
                         future.get();
                     } catch (InterruptedException e1) {
-                        Main.warn(e1, "InterruptedException in ChangesetDialog while downloading changeset header");
+                        Logging.log(Logging.LEVEL_WARN, "InterruptedException in ChangesetDialog while downloading changeset header", e1);
                         Thread.currentThread().interrupt();
                     } catch (ExecutionException e2) {
-                        Main.error(e2);
+                        Logging.error(e2);
                         BugReportExceptionHandler.handleException(e2.getCause());
                         return;
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ConflictDialog.java	(revision 12620)
@@ -68,4 +68,5 @@
 import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -318,5 +319,5 @@
     @Override
     public void onConflictsRemoved(ConflictCollection conflicts) {
-        Main.info("1 conflict has been resolved.");
+        Logging.info("1 conflict has been resolved.");
         refreshView();
     }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/FilterTableModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/FilterTableModel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/FilterTableModel.java	(revision 12620)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.gui.autofilter.AutoFilterManager;
 import org.openstreetmap.josm.gui.widgets.OSDLabel;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -267,5 +268,5 @@
                 return trc("filter", "F");
             default:
-                Main.warn("Unknown filter mode: " + f.mode);
+                Logging.warn("Unknown filter mode: " + f.mode);
             }
             break;
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/LatLonDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/LatLonDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/LatLonDialog.java	(revision 12620)
@@ -31,4 +31,5 @@
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.WindowGeometry;
@@ -249,5 +250,5 @@
             }
         } catch (IllegalArgumentException e) {
-            Main.trace(e);
+            Logging.trace(e);
             latLon = null;
         }
@@ -268,5 +269,5 @@
             en = parseEastNorth(tfEastNorth.getText());
         } catch (IllegalArgumentException e) {
-            Main.trace(e);
+            Logging.trace(e);
             en = null;
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java	(revision 12620)
@@ -79,4 +79,5 @@
 import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
 import org.openstreetmap.josm.tools.InputMapUtils;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.Utils;
@@ -490,5 +491,5 @@
                     }
                 } catch (IOException e) {
-                    Main.warn(e);
+                    Logging.warn(e);
                     error = true;
                 }
@@ -638,5 +639,5 @@
                 }
             } catch (IOException ex) {
-                Main.error(ex);
+                Logging.error(ex);
                 txtSource.append("<ERROR: failed to read file!>");
             }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/ToggleDialog.java	(revision 12620)
@@ -69,4 +69,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.WindowGeometry;
@@ -110,5 +111,5 @@
             } catch (IllegalArgumentException e) {
                 // Legacy settings
-                Main.trace(e);
+                Logging.trace(e);
                 return Boolean.parseBoolean(s) ? ButtonHidingType.DYNAMIC : ButtonHidingType.ALWAYS_SHOWN;
             }
@@ -708,5 +709,5 @@
                 new WindowGeometry(preferencePrefix+".geometry").applySafe(this);
             } catch (WindowGeometryException e) {
-                Main.debug(e);
+                Logging.debug(e);
                 ToggleDialog.this.setPreferredSize(ToggleDialog.this.getDefaultDetachedSize());
                 pack();
@@ -932,6 +933,6 @@
                         buttonActions.add(action);
                     } else {
-                        Main.warn("Button " + button + " doesn't have action defined");
-                        Main.error(new Exception());
+                        Logging.warn("Button " + button + " doesn't have action defined");
+                        Logging.error(new Exception());
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/UserListDialog.java	(revision 12620)
@@ -42,4 +42,5 @@
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OpenBrowser;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -199,5 +200,5 @@
                 return;
             if (users.size() > 10) {
-                Main.warn(tr("Only launching info browsers for the first {0} of {1} selected users", 10, users.size()));
+                Logging.warn(tr("Only launching info browsers for the first {0} of {1} selected users", 10, users.size()));
             }
             int num = Math.min(10, users.size());
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheManager.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetCacheManager.java	(revision 12620)
@@ -65,4 +65,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.InputMapUtils;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.StreamUtils;
 import org.openstreetmap.josm.tools.WindowGeometry;
@@ -404,5 +405,5 @@
                     }
                 } catch (IllegalStateException e) {
-                    Main.error(e);
+                    Logging.error(e);
                     JOptionPane.showMessageDialog(parent, e.getMessage(), tr("Error"), JOptionPane.ERROR_MESSAGE);
                 }
@@ -642,5 +643,5 @@
             } catch (IllegalStateException ex) {
                 alertAnonymousUser(parent);
-                Main.trace(ex);
+                Logging.trace(ex);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/BasicChangesetQueryPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/BasicChangesetQueryPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/BasicChangesetQueryPanel.java	(revision 12620)
@@ -25,4 +25,5 @@
 import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
 import org.openstreetmap.josm.io.ChangesetQuery;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -204,6 +205,6 @@
                 q = BasicQuery.valueOf(BasicQuery.class, value);
             } catch (IllegalArgumentException e) {
-                Main.warn(e, tr("Unexpected value for preference ''{0}'', got ''{1}''. Resetting to default query.",
-                        "changeset-query.basic.query", value));
+                Logging.log(Logging.LEVEL_WARN, tr("Unexpected value for preference ''{0}'', got ''{1}''. Resetting to default query.",
+                        "changeset-query.basic.query", value), e);
                 q = BasicQuery.MOST_RECENT_CHANGESETS;
             }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/ChangesetQueryDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/ChangesetQueryDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/ChangesetQueryDialog.java	(revision 12620)
@@ -20,5 +20,4 @@
 import javax.swing.JTabbedPane;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
 import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction;
@@ -27,4 +26,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.InputMapUtils;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.WindowGeometry;
 
@@ -204,5 +204,5 @@
                 setVisible(false);
             } catch (IllegalStateException e) {
-                Main.error(e);
+                Logging.error(e);
                 JOptionPane.showMessageDialog(ChangesetQueryDialog.this, e.getMessage(), tr("Error"), JOptionPane.ERROR_MESSAGE);
             }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/DateValidator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/DateValidator.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/DateValidator.java	(revision 12620)
@@ -12,6 +12,6 @@
 import javax.swing.text.JTextComponent;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -96,5 +96,5 @@
             } catch (DateTimeParseException e) {
                 // Try next format
-                Main.trace(e);
+                Logging.trace(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/TimeValidator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/TimeValidator.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/TimeValidator.java	(revision 12620)
@@ -12,6 +12,6 @@
 import javax.swing.text.JTextComponent;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.widgets.AbstractTextComponentValidator;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -101,5 +101,5 @@
             } catch (DateTimeParseException e) {
                 // Try next format
-                Main.trace(e);
+                Logging.trace(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/UrlBasedQueryPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/UrlBasedQueryPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/changeset/query/UrlBasedQueryPanel.java	(revision 12620)
@@ -27,4 +27,5 @@
 import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -138,5 +139,5 @@
             return ChangesetQuery.buildFromUrlQuery(url.getQuery());
         } catch (ChangesetQueryUrlException e) {
-            Main.warn(e);
+            Logging.warn(e);
             return null;
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/layer/LayerListTransferHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/layer/LayerListTransferHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/layer/LayerListTransferHandler.java	(revision 12620)
@@ -15,5 +15,4 @@
 import javax.swing.TransferHandler;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.gui.datatransfer.LayerTransferable;
@@ -21,4 +20,5 @@
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -124,8 +124,8 @@
             return true;
         } catch (UnsupportedFlavorException e) {
-            Main.warn("Flavor not supported", e);
+            Logging.warn("Flavor not supported", e);
             return false;
         } catch (IOException e) {
-            Main.warn("Error while pasting layer", e);
+            Logging.warn("Error while pasting layer", e);
             return false;
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java	(revision 12620)
@@ -105,4 +105,5 @@
 import org.openstreetmap.josm.tools.InputMapUtils;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OpenBrowser;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -1172,5 +1173,5 @@
                 Main.worker.execute(() -> displayHelp(uris));
             } catch (URISyntaxException e1) {
-                Main.error(e1);
+                Logging.error(e1);
             }
         }
@@ -1202,5 +1203,5 @@
                          */
                         if (osize > -1 && conn.getContentLength() != -1 && Math.abs(conn.getContentLength() - osize) > 200) {
-                            Main.info("{0} is a mediawiki redirect", u);
+                            Logging.info("{0} is a mediawiki redirect", u);
                             conn.disconnect();
                         } else {
@@ -1213,5 +1214,5 @@
                 }
             } catch (URISyntaxException | IOException e1) {
-                Main.error(e1);
+                Logging.error(e1);
             }
         }
@@ -1415,6 +1416,6 @@
                 tagRowSorter.convertRowIndexToModel(tagTable.getSelectedRow());
             } catch (IndexOutOfBoundsException ignore) {
-                Main.trace(ignore);
-                Main.trace("Clearing tagTable selection");
+                Logging.trace(ignore);
+                Logging.trace("Clearing tagTable selection");
                 tagTable.clearSelection();
             }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/properties/TagEditHelper.java	(revision 12620)
@@ -88,4 +88,5 @@
 import org.openstreetmap.josm.io.XmlWriter;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.Utils;
@@ -342,5 +343,5 @@
 
     private static void warnAboutParseError(SearchCompiler.ParseError parseError) {
-        Main.warn(parseError);
+        Logging.warn(parseError);
         JOptionPane.showMessageDialog(
                 Main.parent,
@@ -637,7 +638,5 @@
                    List<AutoCompletionListItem> valueList = autocomplete.getValues(getAutocompletionKeys(key));
                    valueList.sort(comparator);
-                   if (Main.isTraceEnabled()) {
-                       Main.trace("Focus gained by {0}, e={1}", values, e);
-                   }
+                   Logging.trace("Focus gained by {0}, e={1}", values, e);
                    values.setPossibleACItems(valueList);
                    values.getEditor().selectAll();
@@ -838,5 +837,5 @@
                     }
                 } catch (NumberFormatException ex) {
-                    Main.warn(ex);
+                    Logging.warn(ex);
                 }
                 JOptionPane.showMessageDialog(this, tr("Please enter integer number between 0 and {0}", MAX_LRU_TAGS_NUMBER));
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/ChildRelationBrowser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/ChildRelationBrowser.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/ChildRelationBrowser.java	(revision 12620)
@@ -46,4 +46,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
@@ -422,5 +423,5 @@
             } catch (OsmTransferException e) {
                 if (canceled) {
-                    Main.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
+                    Logging.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
                     return;
                 }
@@ -471,5 +472,5 @@
             } catch (OsmTransferException e) {
                 if (canceled) {
-                    Main.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
+                    Logging.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
                     return;
                 }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationMemberTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationMemberTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationMemberTask.java	(revision 12620)
@@ -25,4 +25,5 @@
 import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
 import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -139,5 +140,5 @@
         } catch (OsmTransferException e) {
             if (canceled) {
-                Main.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
+                Logging.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
                 return;
             }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/DownloadRelationTask.java	(revision 12620)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -105,5 +106,5 @@
         } catch (OsmTransferException | InvocationTargetException | InterruptedException e) {
             if (canceled) {
-                Main.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
+                Logging.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
                 return;
             }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/GenericRelationEditor.java	(revision 12620)
@@ -98,4 +98,5 @@
 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresets;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 import org.openstreetmap.josm.tools.Utils;
@@ -841,5 +842,5 @@
         int code = shortcut.getKeyCode();
         if (code != KeyEvent.VK_INSERT && (mods == 0 || mods == InputEvent.SHIFT_DOWN_MASK)) {
-            Main.info(tr("Sorry, shortcut \"{0}\" can not be enabled in Relation editor dialog"), shortcut);
+            Logging.info(tr("Sorry, shortcut \"{0}\" can not be enabled in Relation editor dialog"), shortcut);
             return;
         }
@@ -947,5 +948,5 @@
             return modified ? new ChangeCommand(orig, relation) : null;
         } catch (AddAbortException ign) {
-            Main.trace(ign);
+            Logging.trace(ign);
             return null;
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/MemberTransferHandler.java	(revision 12620)
@@ -14,5 +14,4 @@
 import javax.swing.TransferHandler;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
 import org.openstreetmap.josm.data.osm.PrimitiveData;
@@ -22,4 +21,5 @@
 import org.openstreetmap.josm.gui.datatransfer.RelationMemberTransferable;
 import org.openstreetmap.josm.gui.datatransfer.data.PrimitiveTransferData;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -91,5 +91,5 @@
             }
         } catch (IOException | UnsupportedFlavorException e) {
-            Main.warn(e);
+            Logging.warn(e);
             return false;
         }
@@ -147,5 +147,5 @@
             final OsmPrimitive p = destination.getLayer().data.getPrimitiveById(data);
             if (p == null) {
-                Main.warn(tr("Cannot add {0} since it is not part of dataset", data));
+                Logging.warn(tr("Cannot add {0} since it is not part of dataset", data));
                 return null;
             } else {
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/ParentRelationLoadingTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/ParentRelationLoadingTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/ParentRelationLoadingTask.java	(revision 12620)
@@ -23,4 +23,5 @@
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -179,5 +180,5 @@
         } catch (OsmTransferException e) {
             if (canceled) {
-                Main.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
+                Logging.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
                 return;
             }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationEditor.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationEditor.java	(revision 12620)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -107,5 +108,5 @@
                 }
             } catch (ReflectiveOperationException ex) {
-                Main.warn(ex);
+                Logging.warn(ex);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationTree.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationTree.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/RelationTree.java	(revision 12620)
@@ -26,4 +26,5 @@
 import org.openstreetmap.josm.io.OsmServerObjectReader;
 import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -132,5 +133,5 @@
                 return;
             if (lastException != null) {
-                Main.error(lastException);
+                Logging.error(lastException);
                 return;
             }
@@ -152,5 +153,5 @@
             } catch (OsmTransferException e) {
                 if (canceled) {
-                    Main.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
+                    Logging.warn(tr("Ignoring exception because task was canceled. Exception: {0}", e.toString()));
                     return;
                 }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedAfterSelection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedAfterSelection.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedAfterSelection.java	(revision 12620)
@@ -6,5 +6,4 @@
 import java.awt.event.ActionEvent;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.dialogs.relation.GenericRelationEditor.AddAbortException;
 import org.openstreetmap.josm.gui.dialogs.relation.IRelationEditor;
@@ -12,4 +11,5 @@
 import org.openstreetmap.josm.gui.dialogs.relation.SelectionTableModel;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -43,5 +43,5 @@
                     memberTableModel.getSelectionModel().getMaxSelectionIndex());
         } catch (AddAbortException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedAtEndAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedAtEndAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedAtEndAction.java	(revision 12620)
@@ -6,5 +6,4 @@
 import java.awt.event.ActionEvent;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.dialogs.relation.GenericRelationEditor.AddAbortException;
 import org.openstreetmap.josm.gui.dialogs.relation.IRelationEditor;
@@ -12,4 +11,5 @@
 import org.openstreetmap.josm.gui.dialogs.relation.SelectionTableModel;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -42,5 +42,5 @@
             memberTableModel.addMembersAtEnd(filterConfirmedPrimitives(selectionTableModel.getSelection()));
         } catch (AddAbortException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedAtStartAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedAtStartAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedAtStartAction.java	(revision 12620)
@@ -6,5 +6,4 @@
 import java.awt.event.ActionEvent;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.dialogs.relation.GenericRelationEditor.AddAbortException;
 import org.openstreetmap.josm.gui.dialogs.relation.IRelationEditor;
@@ -12,4 +11,5 @@
 import org.openstreetmap.josm.gui.dialogs.relation.SelectionTableModel;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -42,5 +42,5 @@
             memberTableModel.addMembersAtBeginning(filterConfirmedPrimitives(selectionTableModel.getSelection()));
         } catch (AddAbortException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedBeforeSelection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedBeforeSelection.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/AddSelectedBeforeSelection.java	(revision 12620)
@@ -6,5 +6,4 @@
 import java.awt.event.ActionEvent;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.dialogs.relation.GenericRelationEditor.AddAbortException;
 import org.openstreetmap.josm.gui.dialogs.relation.IRelationEditor;
@@ -12,4 +11,5 @@
 import org.openstreetmap.josm.gui.dialogs.relation.SelectionTableModel;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -43,5 +43,5 @@
                     memberTableModel.getSelectionModel().getMinSelectionIndex());
         } catch (AddAbortException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/PasteMembersAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/PasteMembersAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/relation/actions/PasteMembersAction.java	(revision 12620)
@@ -9,5 +9,4 @@
 import javax.swing.TransferHandler.TransferSupport;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
 import org.openstreetmap.josm.gui.dialogs.relation.IRelationEditor;
@@ -15,4 +14,5 @@
 import org.openstreetmap.josm.gui.dialogs.relation.MemberTransferHandler;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -38,5 +38,5 @@
             new MemberTransferHandler().importData(getSupport());
         } catch (IllegalStateException ex) {
-            Main.error(ex);
+            Logging.error(ex);
         }
     }
@@ -52,5 +52,5 @@
             setEnabled(new MemberTransferHandler().canImport(getSupport()));
         } catch (IllegalStateException ex) {
-            Main.error(ex);
+            Logging.error(ex);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/download/BookmarkList.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/BookmarkList.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/download/BookmarkList.java	(revision 12620)
@@ -40,4 +40,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -255,6 +256,6 @@
                 model.addElement(new HomeLocationBookmark());
             } catch (IllegalStateException e) {
-                Main.info(e.getMessage());
-                Main.trace(e);
+                Logging.info(e.getMessage());
+                Logging.trace(e);
             }
         }
@@ -267,5 +268,5 @@
                     bookmarks.add(new Bookmark(entry));
                 } catch (IllegalArgumentException e) {
-                    Main.error(e, tr("Error reading bookmark entry: %s", e.getMessage()));
+                    Logging.log(Logging.LEVEL_ERROR, tr("Error reading bookmark entry: %s", e.getMessage()), e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/download/DownloadDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/DownloadDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/download/DownloadDialog.java	(revision 12620)
@@ -49,4 +49,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.InputMapUtils;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OsmUrlToBounds;
 import org.openstreetmap.josm.tools.Utils;
@@ -147,5 +148,5 @@
             tpDownloadAreaSelectors.setSelectedIndex(DOWNLOAD_TAB.get());
         } catch (IndexOutOfBoundsException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
             DOWNLOAD_TAB.put(0);
         }
@@ -434,5 +435,5 @@
                 return new Bounds(value, ";");
             } catch (IllegalArgumentException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryList.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryList.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryList.java	(revision 12620)
@@ -50,4 +50,5 @@
 import org.openstreetmap.josm.gui.widgets.SearchTextResultListPanel;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -276,5 +277,5 @@
             } catch (IllegalArgumentException | DateTimeParseException e) {
                 // skip any corrupted item
-                Main.error(e);
+                Logging.error(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryWizardDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryWizardDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/download/OverpassQueryWizardDialog.java	(revision 12620)
@@ -26,4 +26,5 @@
 import org.openstreetmap.josm.gui.widgets.HistoryComboBox;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OpenBrowser;
 import org.openstreetmap.josm.tools.OverpassTurboQueryWizard;
@@ -140,5 +141,5 @@
             return Optional.of(query);
         } catch (UncheckedParseException ex) {
-            Main.error(ex);
+            Logging.error(ex);
             JOptionPane.showMessageDialog(
                     parentDialog,
Index: trunk/src/org/openstreetmap/josm/gui/download/PlaceSelection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/download/PlaceSelection.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/download/PlaceSelection.java	(revision 12620)
@@ -57,4 +57,5 @@
 import org.openstreetmap.josm.tools.HttpClient;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
@@ -267,5 +268,5 @@
                 if (!canceled) {
                     // Nominatim sometimes returns garbage, see #5934, #10643
-                    Main.warn(e, tr("Error occured with query ''{0}'': ''{1}''", urlString, e.getMessage()));
+                    Logging.log(Logging.LEVEL_WARN, tr("Error occured with query ''{0}'': ''{1}''", urlString, e.getMessage()), e);
                     GuiHelper.runInEDTAndWait(() -> HelpAwareOptionPane.showOptionDialog(
                             Main.parent,
Index: trunk/src/org/openstreetmap/josm/gui/help/HelpBrowser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/help/HelpBrowser.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/help/HelpBrowser.java	(revision 12620)
@@ -52,4 +52,5 @@
 import org.openstreetmap.josm.tools.InputMapUtils;
 import org.openstreetmap.josm.tools.LanguageInfo.LocaleType;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OpenBrowser;
 import org.openstreetmap.josm.tools.WindowGeometry;
@@ -142,6 +143,6 @@
             css = new String(cf.getByteContent(), StandardCharsets.ISO_8859_1);
         } catch (IOException e) {
-            Main.error(tr("Failed to read CSS file ''help-browser.css''. Exception is: {0}", e.toString()));
-            Main.error(e);
+            Logging.error(tr("Failed to read CSS file ''help-browser.css''. Exception is: {0}", e.toString()));
+            Logging.error(e);
             return ss;
         }
@@ -236,5 +237,5 @@
             help.getEditorKit().read(new StringReader(content), document, 0);
         } catch (IOException | BadLocationException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         help.setDocument(document);
@@ -300,30 +301,30 @@
             content = reader.fetchHelpTopicContent(url, true);
         } catch (MissingHelpContentException e) {
-            Main.trace(e);
+            Logging.trace(e);
             url = getHelpTopicUrl(buildAbsoluteHelpTopic(relativeHelpTopic, LocaleType.BASELANGUAGE));
             try {
                 content = reader.fetchHelpTopicContent(url, true);
             } catch (MissingHelpContentException e1) {
-                Main.trace(e1);
+                Logging.trace(e1);
                 url = getHelpTopicUrl(buildAbsoluteHelpTopic(relativeHelpTopic, LocaleType.ENGLISH));
                 try {
                     content = reader.fetchHelpTopicContent(url, true);
                 } catch (MissingHelpContentException e2) {
-                    Main.debug(e2);
+                    Logging.debug(e2);
                     this.url = url;
                     handleMissingHelpContent(relativeHelpTopic);
                     return;
                 } catch (HelpContentReaderException e2) {
-                    Main.error(e2);
+                    Logging.error(e2);
                     handleHelpContentReaderException(relativeHelpTopic, e2);
                     return;
                 }
             } catch (HelpContentReaderException e1) {
-                Main.error(e1);
+                Logging.error(e1);
                 handleHelpContentReaderException(relativeHelpTopic, e1);
                 return;
             }
         } catch (HelpContentReaderException e) {
-            Main.error(e);
+            Logging.error(e);
             handleHelpContentReaderException(relativeHelpTopic, e);
             return;
@@ -346,10 +347,10 @@
             content = reader.fetchHelpTopicContent(url, true);
         } catch (MissingHelpContentException e) {
-            Main.debug(e);
+            Logging.debug(e);
             this.url = url;
             handleMissingHelpContent(absoluteHelpTopic);
             return;
         } catch (HelpContentReaderException e) {
-            Main.error(e);
+            Logging.error(e);
             handleHelpContentReaderException(absoluteHelpTopic, e);
             return;
@@ -377,5 +378,5 @@
                 this.url = url;
             } catch (HelpContentReaderException e) {
-                Main.warn(e);
+                Logging.warn(e);
                 HelpAwareOptionPane.showOptionDialog(
                         Main.parent,
@@ -587,6 +588,6 @@
                     }
                 } catch (BadLocationException e) {
-                    Main.warn(tr("Bad location in HTML document. Exception was: {0}", e.toString()));
-                    Main.error(e);
+                    Logging.warn(tr("Bad location in HTML document. Exception was: {0}", e.toString()));
+                    Logging.error(e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/history/HistoryBrowserModel.java	(revision 12620)
@@ -42,4 +42,5 @@
 import org.openstreetmap.josm.gui.util.ChangeNotifier;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -138,5 +139,5 @@
             HistoryOsmPrimitive.forOsmPrimitive(primitive);
         } catch (IllegalArgumentException ign) {
-            Main.trace(ign);
+            Logging.trace(ign);
             return false;
         }
Index: trunk/src/org/openstreetmap/josm/gui/history/VersionTableModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/history/VersionTableModel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/history/VersionTableModel.java	(revision 12620)
@@ -6,8 +6,8 @@
 import javax.swing.table.AbstractTableModel;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Changeset;
 import org.openstreetmap.josm.data.osm.User;
 import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.date.DateUtils;
 
@@ -94,5 +94,5 @@
             }
         } catch (IllegalArgumentException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         fireTableDataChanged();
Index: trunk/src/org/openstreetmap/josm/gui/io/AbstractUploadTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/AbstractUploadTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/io/AbstractUploadTask.java	(revision 12620)
@@ -34,4 +34,5 @@
 import org.openstreetmap.josm.tools.ExceptionUtil;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.date.DateUtils;
@@ -298,5 +299,5 @@
             }
         }
-        Main.warn(tr("Error header \"{0}\" did not match with an expected pattern", errorHeader));
+        Logging.warn(tr("Error header \"{0}\" did not match with an expected pattern", errorHeader));
         handleUploadConflictForUnknownConflict();
     }
@@ -313,5 +314,5 @@
             handleUploadPreconditionFailedConflict(e, conflict);
         } else {
-            Main.warn(tr("Error header \"{0}\" did not match with an expected pattern", e.getErrorHeader()));
+            Logging.warn(tr("Error header \"{0}\" did not match with an expected pattern", e.getErrorHeader()));
             ExceptionDialogUtil.explainPreconditionFailed(e);
         }
Index: trunk/src/org/openstreetmap/josm/gui/io/CredentialDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/CredentialDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/io/CredentialDialog.java	(revision 12620)
@@ -39,4 +39,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.InputMapUtils;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.WindowGeometry;
 
@@ -113,5 +114,5 @@
             setAlwaysOnTop(true);
         } catch (SecurityException e) {
-            Main.warn(e, tr("Failed to put Credential Dialog always on top. Caught security exception."));
+            Logging.log(Logging.LEVEL_WARN, tr("Failed to put Credential Dialog always on top. Caught security exception."), e);
         }
         build();
Index: trunk/src/org/openstreetmap/josm/gui/io/DownloadFileTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/DownloadFileTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/io/DownloadFileTask.java	(revision 12620)
@@ -19,8 +19,8 @@
 import java.util.zip.ZipFile;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.PleaseWaitDialog;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
@@ -133,7 +133,7 @@
             }
             if (!canceled) {
-                Main.info(tr("Download finished"));
+                Logging.info(tr("Download finished"));
                 if (unpack) {
-                    Main.info(tr("Unpacking {0} into {1}", file.getAbsolutePath(), file.getParent()));
+                    Logging.info(tr("Unpacking {0} into {1}", file.getAbsolutePath(), file.getParent()));
                     unzipFileRecursively(file, file.getParent());
                     Utils.deleteFile(file);
@@ -143,5 +143,5 @@
             String msg = tr("Cannot download file ''{0}''. Its download link ''{1}'' is not a valid URL. Skipping download.",
                     file.getName(), address);
-            Main.warn(msg);
+            Logging.warn(msg);
             throw new DownloadException(msg, e);
         } catch (IOException e) {
@@ -160,5 +160,5 @@
             download();
         } catch (DownloadException e) {
-            Main.error(e);
+            Logging.error(e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/io/DownloadOpenChangesetsTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/DownloadOpenChangesetsTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/io/DownloadOpenChangesetsTask.java	(revision 12620)
@@ -25,4 +25,5 @@
 import org.openstreetmap.josm.io.OsmServerUserInfoReader;
 import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -65,5 +66,5 @@
                     + "You have either chosen to work anonymously or you are not entitled<br>"
                     + "to know the identity of the user on whose behalf you are working.");
-            Main.warn(msg);
+            Logging.warn(msg);
             if (!GraphicsEnvironment.isHeadless()) {
                 JOptionPane.showMessageDialog(GuiHelper.getFrameForComponent(parent),
@@ -113,5 +114,6 @@
                 im.setPartiallyIdentified(im.getUserName());
             }
-            Main.warn(e, tr("Failed to retrieve user infos for the current JOSM user. Exception was: {0}", e.toString()));
+            Logging.log(Logging.LEVEL_WARN,
+                    tr("Failed to retrieve user infos for the current JOSM user. Exception was: {0}", e.toString()), e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/io/SaveLayerTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/SaveLayerTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/io/SaveLayerTask.java	(revision 12620)
@@ -6,5 +6,4 @@
 import java.util.Optional;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.SaveAction;
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
@@ -12,4 +11,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -57,5 +57,5 @@
             }
         } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
-            Main.error(e);
+            Logging.error(e);
             setLastException(e);
         }
Index: trunk/src/org/openstreetmap/josm/gui/io/SaveLayersDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/SaveLayersDialog.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/io/SaveLayersDialog.java	(revision 12620)
@@ -55,4 +55,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.InputMapUtils;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.UserCancelException;
 import org.openstreetmap.josm.tools.Utils;
@@ -446,5 +447,5 @@
                 closeDialog();
             } catch (UserCancelException ignore) {
-                Main.trace(ignore);
+                Logging.trace(ignore);
             }
         }
@@ -575,8 +576,8 @@
                     currentFuture.get();
                 } catch (CancellationException e) {
-                    Main.trace(e);
+                    Logging.trace(e);
                     model.setUploadState(layer, UploadOrSaveState.CANCELED);
                 } catch (InterruptedException | ExecutionException e) {
-                    Main.error(e);
+                    Logging.error(e);
                     model.setUploadState(layer, UploadOrSaveState.FAILED);
                     ExceptionDialogUtil.explainException(e);
@@ -585,5 +586,5 @@
                     model.setUploadState(layer, UploadOrSaveState.CANCELED);
                 } else if (currentTask.isFailed()) {
-                    Main.error(currentTask.getLastException());
+                    Logging.error(currentTask.getLastException());
                     ExceptionDialogUtil.explainException(currentTask.getLastException());
                     model.setUploadState(layer, UploadOrSaveState.FAILED);
@@ -616,8 +617,8 @@
                     currentFuture.get();
                 } catch (CancellationException e) {
-                    Main.trace(e);
+                    Logging.trace(e);
                     model.setSaveState(layerInfo.getLayer(), UploadOrSaveState.CANCELED);
                 } catch (InterruptedException | ExecutionException e) {
-                    Main.error(e);
+                    Logging.error(e);
                     model.setSaveState(layerInfo.getLayer(), UploadOrSaveState.FAILED);
                     ExceptionDialogUtil.explainException(e);
@@ -627,5 +628,5 @@
                 } else if (currentTask.isFailed()) {
                     if (currentTask.getLastException() != null) {
-                        Main.error(currentTask.getLastException());
+                        Logging.error(currentTask.getLastException());
                         ExceptionDialogUtil.explainException(currentTask.getLastException());
                     }
@@ -642,5 +643,5 @@
             if (numProblems == 0)
                 return;
-            Main.warn(numProblems + " problems occured during upload/save");
+            Logging.warn(numProblems + " problems occured during upload/save");
             String msg = trn(
                     "<html>An upload and/or save operation of one layer with modifications<br>"
Index: trunk/src/org/openstreetmap/josm/gui/io/UploadLayerTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/UploadLayerTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/io/UploadLayerTask.java	(revision 12620)
@@ -9,5 +9,4 @@
 import java.util.Set;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.upload.CyclicUploadDependencyException;
 import org.openstreetmap.josm.data.APIDataSet;
@@ -25,4 +24,5 @@
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -91,5 +91,5 @@
         if (p.isDeleted()) {
             // we tried to delete an already deleted primitive.
-            Main.warn(tr("Object ''{0}'' is already deleted on the server. Skipping this object and retrying to upload.",
+            Logging.warn(tr("Object ''{0}'' is already deleted on the server. Skipping this object and retrying to upload.",
                     p.getDisplayName(DefaultNameFormatter.getInstance())));
             processedPrimitives.addAll(writer.getProcessedPrimitives());
@@ -134,5 +134,5 @@
         } catch (OsmTransferException sxe) {
             if (isCanceled()) {
-                Main.info("Ignoring exception caught because upload is canceled. Exception is: " + sxe);
+                Logging.info("Ignoring exception caught because upload is canceled. Exception is: " + sxe);
                 return;
             }
Index: trunk/src/org/openstreetmap/josm/gui/io/UploadPrimitivesTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/UploadPrimitivesTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/io/UploadPrimitivesTask.java	(revision 12620)
@@ -38,4 +38,5 @@
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -200,5 +201,5 @@
             }
             monitor.appendLogMessage(msg);
-            Main.warn(msg);
+            Logging.warn(msg);
             processedPrimitives.addAll(writer.getProcessedPrimitives());
             processedPrimitives.add(p);
@@ -224,9 +225,9 @@
             SwingUtilities.invokeAndWait(r);
         } catch (InterruptedException e) {
-            Main.trace(e);
+            Logging.trace(e);
             lastException = e;
             Thread.currentThread().interrupt();
         } catch (InvocationTargetException e) {
-            Main.trace(e);
+            Logging.trace(e);
             lastException = new OsmTransferException(e.getCause());
         }
@@ -249,5 +250,5 @@
                     break;
                 } catch (OsmTransferCanceledException e) {
-                    Main.error(e);
+                    Logging.error(e);
                     uploadCanceled = true;
                     break uploadloop;
@@ -292,5 +293,5 @@
         } catch (OsmTransferException e) {
             if (uploadCanceled) {
-                Main.info(tr("Ignoring caught exception because upload is canceled. Exception is: {0}", e.toString()));
+                Logging.info(tr("Ignoring caught exception because upload is canceled. Exception is: {0}", e.toString()));
             } else {
                 lastException = e;
Index: trunk/src/org/openstreetmap/josm/gui/io/UploadStrategy.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/UploadStrategy.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/io/UploadStrategy.java	(revision 12620)
@@ -7,4 +7,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -96,5 +97,5 @@
         UploadStrategy strategy = fromPreference(v);
         if (strategy == null) {
-            Main.warn(tr("Unexpected value for key ''{0}'' in preferences, got ''{1}''", "osm-server.upload-strategy", v));
+            Logging.warn(tr("Unexpected value for key ''{0}'' in preferences, got ''{1}''", "osm-server.upload-strategy", v));
             return DEFAULT_UPLOAD_STRATEGY;
         }
Index: trunk/src/org/openstreetmap/josm/gui/io/UploadStrategySelectionPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/io/UploadStrategySelectionPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/io/UploadStrategySelectionPanel.java	(revision 12620)
@@ -36,4 +36,5 @@
 import org.openstreetmap.josm.io.Capabilities;
 import org.openstreetmap.josm.io.OsmApi;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -336,5 +337,5 @@
         } catch (NumberFormatException e) {
             // don't save invalid value to preferences
-            Main.trace(e);
+            Logging.trace(e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/layer/AbstractCachedTileSourceLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/AbstractCachedTileSourceLayer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/AbstractCachedTileSourceLayer.java	(revision 12620)
@@ -10,5 +10,4 @@
 import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
 import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTMSTileSource;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;
 import org.openstreetmap.josm.data.cache.JCSCacheManager;
@@ -17,4 +16,5 @@
 import org.openstreetmap.josm.data.imagery.TileLoaderFactory;
 import org.openstreetmap.josm.data.preferences.IntegerProperty;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -91,5 +91,5 @@
             return cache;
         } catch (IOException e) {
-            Main.warn(e);
+            Logging.warn(e);
             return null;
         }
@@ -131,5 +131,5 @@
                         CachedTileLoaderFactory.PROP_TILECACHE_DIR.get());
             } catch (IOException e) {
-                Main.warn(e);
+                Logging.warn(e);
                 return null;
             }
Index: trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java	(revision 12620)
@@ -115,4 +115,5 @@
 import org.openstreetmap.josm.io.WMSLayerImporter;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MemoryManager;
 import org.openstreetmap.josm.tools.MemoryManager.MemoryHandle;
@@ -275,7 +276,5 @@
         } catch (MalformedURLException e) {
             // ignore, assume that this is not a file
-            if (Main.isDebugEnabled()) {
-                Main.debug(e.getMessage());
-            }
+            Logging.log(Logging.LEVEL_DEBUG, e);
         }
 
@@ -294,7 +293,5 @@
         tile.setLoaded(success);
         invalidateLater();
-        if (Main.isDebugEnabled()) {
-            Main.debug("tileLoadingFinished() tile: " + tile + " success: " + success);
-        }
+        Logging.debug("tileLoadingFinished() tile: {0} success: {1}", tile, success);
     }
 
@@ -437,5 +434,5 @@
                 } catch (IOException e) {
                     // silence exceptions
-                    Main.trace(e);
+                    Logging.trace(e);
                 }
 
@@ -595,5 +592,5 @@
                 Math.pow(2d, ZOOM_OFFSET.get()) * visibileTiles // use offset to decide, how many tiles are visible
                 * 4);
-        Main.info("AbstractTileSourceLayer: estimated visible tiles: {0}, estimated cache size: {1}", visibileTiles, ret);
+        Logging.info("AbstractTileSourceLayer: estimated visible tiles: {0}, estimated cache size: {1}", visibileTiles, ret);
         return ret;
     }
@@ -702,7 +699,5 @@
 
     private void zoomChanged(boolean invalidate) {
-        if (Main.isDebugEnabled()) {
-            Main.debug("zoomChanged(): " + currentZoomLevel);
-        }
+        Logging.debug("zoomChanged(): {0}", currentZoomLevel);
         if (tileLoader instanceof TMSCachedTileLoader) {
             ((TMSCachedTileLoader) tileLoader).cancelOutstandingTasks();
@@ -733,7 +728,5 @@
     public boolean zoomIncreaseAllowed() {
         boolean zia = currentZoomLevel < this.getMaxZoomLvl();
-        if (Main.isDebugEnabled()) {
-            Main.debug("zoomIncreaseAllowed(): " + zia + ' ' + currentZoomLevel + " vs. " + this.getMaxZoomLvl());
-        }
+        Logging.debug("zoomIncreaseAllowed(): {0} {1} vs. {2}", zia, currentZoomLevel, this.getMaxZoomLvl());
         return zia;
     }
@@ -747,10 +740,8 @@
         if (zoomIncreaseAllowed()) {
             currentZoomLevel++;
-            if (Main.isDebugEnabled()) {
-                Main.debug("increasing zoom level to: " + currentZoomLevel);
-            }
+            Logging.debug("increasing zoom level to: {0}", currentZoomLevel);
             zoomChanged();
         } else {
-            Main.warn("Current zoom level ("+currentZoomLevel+") could not be increased. "+
+            Logging.warn("Current zoom level ("+currentZoomLevel+") could not be increased. "+
                     "Max.zZoom Level "+this.getMaxZoomLvl()+" reached.");
             return false;
@@ -793,7 +784,5 @@
     public boolean zoomDecreaseAllowed() {
         boolean zda = currentZoomLevel > this.getMinZoomLvl();
-        if (Main.isDebugEnabled()) {
-            Main.debug("zoomDecreaseAllowed(): " + zda + ' ' + currentZoomLevel + " vs. " + this.getMinZoomLvl());
-        }
+        Logging.debug("zoomDecreaseAllowed(): {0} {1} vs. {2}", zda, currentZoomLevel, this.getMinZoomLvl());
         return zda;
     }
@@ -806,7 +795,5 @@
     public boolean decreaseZoomLevel() {
         if (zoomDecreaseAllowed()) {
-            if (Main.isDebugEnabled()) {
-                Main.debug("decreasing zoom level to: " + currentZoomLevel);
-            }
+            Logging.debug("decreasing zoom level to: {0}", currentZoomLevel);
             currentZoomLevel--;
             zoomChanged();
@@ -879,5 +866,5 @@
         // if there is more than 18 tiles on screen in any direction, do not load all tiles!
         if (ts.tooLarge()) {
-            Main.warn("Not downloading all tiles because there is more than 18 tiles on an axis!");
+            Logging.warn("Not downloading all tiles because there is more than 18 tiles on an axis!");
             return;
         }
@@ -900,7 +887,5 @@
     public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
         boolean done = (infoflags & (ERROR | FRAMEBITS | ALLBITS)) != 0;
-        if (Main.isDebugEnabled()) {
-            Main.debug("imageUpdate() done: " + done + " calling repaint");
-        }
+        Logging.debug("imageUpdate() done: {0} calling repaint", done);
 
         if (done) {
@@ -1136,5 +1121,5 @@
         }
 
-        if (Main.isDebugEnabled()) {
+        if (Logging.isDebugEnabled()) {
             // draw tile outline in semi-transparent red
             g.setColor(new Color(255, 0, 0, 50));
@@ -1495,6 +1480,6 @@
             missedTiles = newlyMissedTiles;
         }
-        if (Main.isDebugEnabled() && !missedTiles.isEmpty()) {
-            Main.debug("still missed "+missedTiles.size()+" in the end");
+        if (Logging.isDebugEnabled() && !missedTiles.isEmpty()) {
+            Logging.debug("still missed {0} in the end", missedTiles.size());
         }
         g.setColor(Color.red);
@@ -1523,5 +1508,5 @@
             myDrawString(g, tr("No tiles at this zoom level"), 120, 120);
         }
-        if (Main.isDebugEnabled()) {
+        if (Logging.isDebugEnabled()) {
             myDrawString(g, tr("Current zoom: {0}", currentZoomLevel), 50, 140);
             myDrawString(g, tr("Display zoom: {0}", displayZoomLevel), 50, 155);
@@ -1547,7 +1532,5 @@
      */
     private Tile getTileForPixelpos(int px, int py) {
-        if (Main.isDebugEnabled()) {
-            Main.debug("getTileForPixelpos("+px+", "+py+')');
-        }
+        Logging.debug("getTileForPixelpos({0}, {1})", px, py);
         TileXY xy = coordinateConverter.getTileforPixel(px, py, currentZoomLevel);
         return getTile(xy.getXIndex(), xy.getYIndex(), currentZoomLevel);
@@ -1729,5 +1712,5 @@
                 this.progressMonitor.setCustomText(tr("Downloaded {0}/{1} tiles", processed, totalCount));
             } else {
-                Main.warn("Tile loading failure: " + tile + " - " + tile.getErrorMessage());
+                Logging.warn("Tile loading failure: " + tile + " - " + tile.getErrorMessage());
             }
         }
@@ -1825,5 +1808,5 @@
                         memory = manager.allocateMemory("tile source layer", getEstimatedCacheSize(), Object::new);
                     } catch (NotEnoughMemoryException e) {
-                        Main.warn("Could not allocate tile source memory", e);
+                        Logging.warn("Could not allocate tile source memory", e);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/NoteLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/NoteLayer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/NoteLayer.java	(revision 12620)
@@ -44,4 +44,5 @@
 import org.openstreetmap.josm.tools.ColorHelper;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.date.DateUtils;
 
@@ -183,5 +184,5 @@
                         // See #11123 - https://bugs.openjdk.java.net/browse/JDK-6719550
                         // Ignore the exception, as Netbeans does: http://hg.netbeans.org/main-silver/rev/c96f4d5fbd20
-                        Main.error(e, false);
+                        Logging.log(Logging.LEVEL_ERROR, e);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 12620)
@@ -108,4 +108,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.date.DateUtils;
 
@@ -535,5 +536,5 @@
             visitor.merge(progressMonitor);
         } catch (DataIntegrityProblemException e) {
-            Main.error(e);
+            Logging.error(e);
             JOptionPane.showMessageDialog(
                     Main.parent,
@@ -816,5 +817,5 @@
                     }
                 } catch (NumberFormatException e) {
-                    Main.trace(e);
+                    Logging.trace(e);
                 }
             }
@@ -836,5 +837,5 @@
                     }
                 } catch (NumberFormatException e) {
-                    Main.trace(e);
+                    Logging.trace(e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/TMSLayer.java	(revision 12620)
@@ -13,5 +13,4 @@
 import org.openstreetmap.gui.jmapviewer.tilesources.TMSTileSource;
 import org.openstreetmap.gui.jmapviewer.tilesources.TemplatedTMSTileSource;
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;
 import org.openstreetmap.josm.data.imagery.CachedAttributionBingAerialTileSource;
@@ -21,4 +20,5 @@
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.data.preferences.IntegerProperty;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -71,5 +71,5 @@
     protected TMSTileSource getTileSource() {
         return getTileSourceStatic(info, () -> {
-            Main.debug("Attribution loaded, running loadAllErrorTiles");
+            Logging.debug("Attribution loaded, running loadAllErrorTiles");
             this.loadAllErrorTiles(false);
         });
Index: trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java	(revision 12620)
@@ -30,4 +30,5 @@
 import org.openstreetmap.josm.gui.layer.imagery.TileSourceDisplaySettings;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -132,5 +133,5 @@
                 Projection proj = Projections.getProjectionByCode(code);
                 if (proj != null) {
-                    Main.info(tr("Reprojecting layer {0} from {1} to {2}. For best image quality and performance,"
+                    Logging.info(tr("Reprojecting layer {0} from {1} to {2}. For best image quality and performance,"
                             + " switch to one of the supported projections: {3}",
                             getName(), proj.toCode(), Main.getProjection().toCode(), Utils.join(", ", getNativeProjections())));
@@ -138,5 +139,5 @@
                 }
             }
-            Main.warn(tr("Unable to find supported projection for layer {0}. Using {1}.", getName(), requested.toCode()));
+            Logging.warn(tr("Unable to find supported projection for layer {0}. Using {1}.", getName(), requested.toCode()));
             return requested;
         }
Index: trunk/src/org/openstreetmap/josm/gui/layer/WMTSLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/WMTSLayer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/WMTSLayer.java	(revision 12620)
@@ -15,4 +15,5 @@
 import org.openstreetmap.josm.data.projection.Projection;
 import org.openstreetmap.josm.gui.layer.imagery.TileSourceDisplaySettings;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -63,5 +64,5 @@
             return null;
         } catch (IOException e) {
-            Main.warn(e);
+            Logging.warn(e);
             throw new IllegalArgumentException(e);
         }
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/CorrelateGpxWithImages.java	(revision 12620)
@@ -82,4 +82,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Utils;
@@ -291,5 +292,5 @@
 
                 } catch (SAXException ex) {
-                    Main.error(ex);
+                    Logging.error(ex);
                     JOptionPane.showMessageDialog(
                             Main.parent,
@@ -300,5 +301,5 @@
                     return;
                 } catch (IOException ex) {
-                    Main.error(ex);
+                    Logging.error(ex);
                     JOptionPane.showMessageDialog(
                             Main.parent,
@@ -934,5 +935,5 @@
                 sldSeconds.setValue((int) (deciSeconds % 60));
             } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
-                Main.warn(e);
+                Logging.warn(e);
                 JOptionPane.showMessageDialog(Main.parent,
                         tr("An error occurred while trying to match the photos to the GPX track."
@@ -1014,5 +1015,5 @@
                 delta = r.b;
             } catch (IndexOutOfBoundsException ex) {
-                Main.debug(ex);
+                Logging.debug(ex);
                 JOptionPane.showMessageDialog(Main.parent,
                         tr("The selected photos do not contain time information."),
@@ -1020,5 +1021,5 @@
                 return;
             } catch (NoGpxTimestamps ex) {
-                Main.debug(ex);
+                Logging.debug(ex);
                 JOptionPane.showMessageDialog(Main.parent,
                         tr("The selected GPX track does not contain timestamps. Please select another one."),
@@ -1133,5 +1134,5 @@
                 return Double.valueOf(value);
             } catch (NumberFormatException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java	(revision 12620)
@@ -68,4 +68,5 @@
 import org.openstreetmap.josm.io.JpgImporter;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -195,5 +196,5 @@
                 addRecursiveFiles(files, selection);
             } catch (IllegalStateException e) {
-                Main.debug(e);
+                Logging.debug(e);
                 rememberError(e.getMessage());
             }
@@ -241,5 +242,5 @@
                         canonical = f.getCanonicalPath();
                     } catch (IOException e) {
-                        Main.error(e);
+                        Logging.error(e);
                         rememberError(tr("Unable to get canonical path for directory {0}\n",
                                 f.getAbsolutePath()));
@@ -735,5 +736,5 @@
 
                 if (Utils.deleteFile(toDelete.getFile())) {
-                    Main.info("File "+toDelete.getFile()+" deleted. ");
+                    Logging.info("File "+toDelete.getFile()+" deleted. ");
                 } else {
                     JOptionPane.showMessageDialog(
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageDisplay.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageDisplay.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageDisplay.java	(revision 12620)
@@ -28,4 +28,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.ExifReader;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -86,5 +87,5 @@
                     Thread.sleep(5);
                 } catch (InterruptedException e) {
-                    Main.warn("InterruptedException in "+getClass().getSimpleName()+" while loading image "+file.getPath());
+                    Logging.warn("InterruptedException in "+getClass().getSimpleName()+" while loading image "+file.getPath());
                     Thread.currentThread().interrupt();
                 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ImageEntry.java	(revision 12620)
@@ -8,9 +8,9 @@
 import java.util.Date;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.CachedLatLon;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.tools.ExifReader;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 
 import com.drew.imaging.jpeg.JpegMetadataReader;
@@ -440,5 +440,5 @@
             metadata = JpegMetadataReader.readMetadata(file);
         } catch (CompoundException | IOException ex) {
-            Main.error(ex);
+            Logging.error(ex);
             setExifTime(null);
             setExifCoor(null);
@@ -452,5 +452,5 @@
             setExifTime(ExifReader.readTime(metadata));
         } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException ex) {
-            Main.warn(ex);
+            Logging.warn(ex);
             setExifTime(null);
         }
@@ -465,5 +465,5 @@
             }
         } catch (MetadataException ex) {
-            Main.debug(ex);
+            Logging.debug(ex);
         }
 
@@ -489,5 +489,5 @@
             setPos(getExifCoor());
         } catch (MetadataException | IndexOutOfBoundsException ex) { // (other exceptions, e.g. #5271)
-            Main.error("Error reading EXIF from file: " + ex);
+            Logging.error("Error reading EXIF from file: " + ex);
             setExifCoor(null);
             setPos(null);
@@ -500,5 +500,5 @@
             }
         } catch (IndexOutOfBoundsException ex) { // (other exceptions, e.g. #5271)
-            Main.debug(ex);
+            Logging.debug(ex);
         }
 
Index: trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/geoimage/ThumbsLoader.java	(revision 12620)
@@ -22,8 +22,9 @@
 import org.openstreetmap.josm.data.cache.JCSCacheManager;
 import org.openstreetmap.josm.tools.ExifReader;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
  * Loads thumbnail previews for a list of images from a {@link GeoImageLayer}.
- * 
+ *
  * Thumbnails are loaded in the background and cached on disk for the next session.
  */
@@ -69,6 +70,6 @@
                         Main.pref.getCacheDirectory().getPath() + File.separator + "geoimage-thumbnails");
             } catch (IOException e) {
-                Main.warn("Failed to initialize cache for geoimage-thumbnails");
-                Main.warn(e);
+                Logging.warn("Failed to initialize cache for geoimage-thumbnails");
+                Logging.warn(e);
             }
         }
@@ -77,5 +78,5 @@
     @Override
     public void run() {
-        Main.debug("Load Thumbnails");
+        Logging.debug("Load Thumbnails");
         tracker = new MediaTracker(Main.map.mapView);
         for (ImageEntry entry : data) {
@@ -104,9 +105,9 @@
                 BufferedImageCacheEntry cacheEntry = cache.get(cacheIdent);
                 if (cacheEntry != null && cacheEntry.getImage() != null) {
-                    Main.debug(" from cache");
+                    Logging.debug(" from cache");
                     return cacheEntry.getImage();
                 }
             } catch (IOException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
         }
@@ -117,10 +118,10 @@
             tracker.waitForID(0);
         } catch (InterruptedException e) {
-            Main.error(" InterruptedException while loading thumb");
+            Logging.error(" InterruptedException while loading thumb");
             Thread.currentThread().interrupt();
             return null;
         }
         if (tracker.isErrorID(1) || img.getWidth(null) <= 0 || img.getHeight(null) <= 0) {
-            Main.error(" Invalid image");
+            Logging.error(" Invalid image");
             return null;
         }
@@ -154,5 +155,5 @@
                 Thread.sleep(10);
             } catch (InterruptedException e) {
-                Main.warn("InterruptedException while drawing thumb");
+                Logging.warn("InterruptedException while drawing thumb");
                 Thread.currentThread().interrupt();
             }
@@ -162,5 +163,5 @@
 
         if (scaledBI.getWidth() <= 0 || scaledBI.getHeight() <= 0) {
-            Main.error(" Invalid image");
+            Logging.error(" Invalid image");
             return null;
         }
@@ -171,6 +172,6 @@
                 cache.put(cacheIdent, new BufferedImageCacheEntry(output.toByteArray()));
             } catch (IOException e) {
-                Main.warn("Failed to save geoimage thumb to cache");
-                Main.warn(e);
+                Logging.warn("Failed to save geoimage thumb to cache");
+                Logging.warn(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertToDataLayerAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertToDataLayerAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/ConvertToDataLayerAction.java	(revision 12620)
@@ -37,4 +37,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.UncheckedParseException;
 import org.openstreetmap.josm.tools.date.DateUtils;
@@ -84,5 +85,5 @@
                                 n.setTimestamp(DateUtils.fromString(timestr));
                             } catch (UncheckedParseException e) {
-                                Main.warn(e, false);
+                                Logging.log(Logging.LEVEL_WARN, e);
                             }
                         }
@@ -133,5 +134,5 @@
                     }
                 } else {
-                    Main.warn("Invalid gpx.to-osm-mapping Einstein setting: expecting even number of entries");
+                    Logging.warn("Invalid gpx.to-osm-mapping Einstein setting: expecting even number of entries");
                 }
                 ds.addPrimitive(node);
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadWmsAlongTrackAction.java	(revision 12620)
@@ -27,4 +27,5 @@
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -66,5 +67,5 @@
                     }
                 } catch (InterruptedException ex) {
-                    Main.warn("InterruptedException in "+getClass().getSimpleName()+" while precaching WMS");
+                    Logging.warn("InterruptedException in "+getClass().getSimpleName()+" while precaching WMS");
                     Thread.currentThread().interrupt();
                 }
Index: trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/gpx/GpxDrawHelper.java	(revision 12620)
@@ -55,4 +55,5 @@
 import org.openstreetmap.josm.tools.ColorScale;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -280,5 +281,5 @@
             return ColorMode.fromIndex(i);
         } catch (IndexOutOfBoundsException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return ColorMode.NONE;
@@ -472,8 +473,8 @@
 
         // show some debug info
-        if (Main.isDebugEnabled() && !visibleSegments.isEmpty()) {
+        if (Logging.isDebugEnabled() && !visibleSegments.isEmpty()) {
             final long timeDiff = System.currentTimeMillis() - timeStart;
 
-            Main.debug("gpxdraw::draw takes " +
+            Logging.debug("gpxdraw::draw takes " +
                          Utils.getDurationString(timeDiff) +
                          "(" +
Index: trunk/src/org/openstreetmap/josm/gui/layer/imagery/ColorfulFilter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/imagery/ColorfulFilter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/imagery/ColorfulFilter.java	(revision 12620)
@@ -13,5 +13,5 @@
 import java.util.Optional;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -40,5 +40,5 @@
         DataBuffer destBuffer = dest.getRaster().getDataBuffer();
         if (!(srcBuffer instanceof DataBufferByte) || !(destBuffer instanceof DataBufferByte)) {
-            Main.trace("Cannot apply color filter: Images do not use DataBufferByte.");
+            Logging.trace("Cannot apply color filter: Images do not use DataBufferByte.");
             return src;
         }
@@ -46,5 +46,5 @@
         int type = src.getType();
         if (type != dest.getType()) {
-            Main.trace("Cannot apply color filter: Src / Dest differ in type (" + type + '/' + dest.getType() + ')');
+            Logging.trace("Cannot apply color filter: Src / Dest differ in type (" + type + '/' + dest.getType() + ')');
             return src;
         }
@@ -73,5 +73,5 @@
             break;
         default:
-            Main.trace("Cannot apply color filter: Source image is of wrong type (" + type + ").");
+            Logging.trace("Cannot apply color filter: Source image is of wrong type (" + type + ").");
             return src;
         }
@@ -86,5 +86,5 @@
         byte[] destPixels = dest.getData();
         if (srcPixels.length != destPixels.length) {
-            Main.trace("Cannot apply color filter: Source/Dest lengths differ.");
+            Logging.trace("Cannot apply color filter: Source/Dest lengths differ.");
             return;
         }
Index: trunk/src/org/openstreetmap/josm/gui/layer/imagery/ColorfulImageProcessor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/imagery/ColorfulImageProcessor.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/imagery/ColorfulImageProcessor.java	(revision 12620)
@@ -6,7 +6,7 @@
 import java.util.Map;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.layer.ImageProcessor;
 import org.openstreetmap.josm.io.session.SessionAwareReadApply;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -63,7 +63,5 @@
                 setColorfulness(Double.parseDouble(cStr));
             } catch (NumberFormatException e) {
-                if (Main.isTraceEnabled()) {
-                    Main.trace(e);
-                }
+                Logging.trace(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/layer/imagery/GammaImageProcessor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/imagery/GammaImageProcessor.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/imagery/GammaImageProcessor.java	(revision 12620)
@@ -9,7 +9,7 @@
 import java.util.Map;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.layer.ImageProcessor;
 import org.openstreetmap.josm.io.session.SessionAwareReadApply;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -58,5 +58,5 @@
             }
         } catch (IllegalArgumentException ignore) {
-            Main.trace(ignore);
+            Logging.trace(ignore);
         }
         final int type = image.getTransparency() == Transparency.OPAQUE ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
@@ -73,7 +73,5 @@
                 setGamma(Double.parseDouble(cStr));
             } catch (NumberFormatException e) {
-                if (Main.isTraceEnabled()) {
-                    Main.trace(e);
-                }
+                Logging.trace(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/layer/imagery/SharpenImageProcessor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/imagery/SharpenImageProcessor.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/imagery/SharpenImageProcessor.java	(revision 12620)
@@ -8,7 +8,7 @@
 import java.util.Map;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.layer.ImageProcessor;
 import org.openstreetmap.josm.io.session.SessionAwareReadApply;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -100,7 +100,5 @@
                 setSharpenLevel(Float.parseFloat(vStr));
             } catch (NumberFormatException e) {
-                if (Main.isTraceEnabled()) {
-                    Main.trace(e);
-                }
+                Logging.trace(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/DefaultMarkerProducers.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/DefaultMarkerProducers.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/DefaultMarkerProducers.java	(revision 12620)
@@ -10,9 +10,9 @@
 import java.util.Optional;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.gpx.Extensions;
 import org.openstreetmap.josm.data.gpx.GpxConstants;
 import org.openstreetmap.josm.data.gpx.GpxLink;
 import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -51,5 +51,5 @@
                     audioMarker.syncOffset = Double.parseDouble(exts.get("sync-offset"));
                 } catch (NumberFormatException nfe) {
-                    Main.warn(nfe);
+                    Logging.warn(nfe);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/Marker.java	(revision 12620)
@@ -23,5 +23,4 @@
 import javax.swing.ImageIcon;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
 import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
@@ -35,4 +34,5 @@
 import org.openstreetmap.josm.gui.MapView;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.template_engine.ParseError;
 import org.openstreetmap.josm.tools.template_engine.TemplateEngineDataProvider;
@@ -145,6 +145,6 @@
                 return new TemplateParser(s).parse();
             } catch (ParseError e) {
-                Main.debug(e);
-                Main.warn("Unable to parse template engine pattern ''{0}'' for property {1}. Using default (''{2}'') instead",
+                Logging.debug(e);
+                Logging.warn("Unable to parse template engine pattern ''{0}'' for property {1}. Using default (''{2}'') instead",
                         s, getKey(), super.getDefaultValueAsString());
                 return getDefaultValue();
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/MarkerLayer.java	(revision 12620)
@@ -51,4 +51,5 @@
 import org.openstreetmap.josm.io.audio.AudioPlayer;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -127,5 +128,5 @@
                     offset = Double.valueOf(exts.get("offset"));
                 } catch (NumberFormatException nfe) {
-                    Main.warn(nfe);
+                    Logging.warn(nfe);
                 }
             }
@@ -276,5 +277,5 @@
             }
         } catch (URISyntaxException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return true;
Index: trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/layer/markerlayer/WebMarker.java	(revision 12620)
@@ -11,5 +11,4 @@
 import javax.swing.JOptionPane;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.gpx.GpxConstants;
@@ -18,4 +17,5 @@
 import org.openstreetmap.josm.gui.Notification;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OpenBrowser;
 
@@ -67,5 +67,5 @@
                 setErroneous(path.isEmpty() || !new File(path).exists());
             } catch (SecurityException e) {
-                Main.warn(e);
+                Logging.warn(e);
                 setErroneous(true);
             }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/Cascade.java	(revision 12620)
@@ -11,7 +11,7 @@
 import java.util.regex.Pattern;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.mappaint.mapcss.CSSColors;
 import org.openstreetmap.josm.tools.ColorHelper;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -75,5 +75,5 @@
         if (res == null) {
             if (!suppressWarnings) {
-                Main.warn(String.format("Unable to convert property %s to type %s: found %s of type %s!", key, klass, o, o.getClass()));
+                Logging.warn(String.format("Unable to convert property %s to type %s: found %s of type %s!", key, klass, o, o.getClass()));
             }
             return def;
@@ -181,7 +181,5 @@
                 return Float.valueOf((String) o);
             } catch (NumberFormatException e) {
-                if (Main.isDebugEnabled()) {
-                    Main.debug('\'' + (String) o + "' cannot be converted to float");
-                }
+                Logging.debug("'{0}' cannot be converted to float", o);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/MapPaintStyles.java	(revision 12620)
@@ -35,4 +35,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.ListenerList;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -157,5 +158,5 @@
             String msg = "Mappaint style \""+namespace+"\" ("+ref.source.getDisplayString()+") icon \"" + ref.iconName + "\" not found.";
             ref.source.logWarning(msg);
-            Main.warn(msg);
+            Logging.warn(msg);
             return null;
         }
@@ -176,5 +177,5 @@
         ImageIcon i = getIconProvider(ref, false).setSize(width, height).get();
         if (i == null) {
-            Main.warn("Mappaint style \""+namespace+"\" ("+ref.source.getDisplayString()+") icon \"" + ref.iconName + "\" not found.");
+            Logging.warn("Mappaint style \""+namespace+"\" ("+ref.source.getDisplayString()+") icon \"" + ref.iconName + "\" not found.");
             return null;
         }
@@ -308,14 +309,14 @@
                 Main.fileWatcher.registerStyleSource(source);
             } catch (IOException | IllegalStateException | IllegalArgumentException e) {
-                Main.error(e);
-            }
-        }
-        if (Main.isDebugEnabled() || !source.isValid()) {
+                Logging.error(e);
+            }
+        }
+        if (Logging.isDebugEnabled() || !source.isValid()) {
             final long elapsedTime = System.currentTimeMillis() - startTime;
             String message = "Initializing map style " + source.url + " completed in " + Utils.getDurationString(elapsedTime);
             if (!source.isValid()) {
-                Main.warn(message + " (" + source.getErrors().size() + " errors, " + source.getWarnings().size() + " warnings)");
+                Logging.warn(message + " (" + source.getErrors().size() + " errors, " + source.getWarnings().size() + " warnings)");
             } else {
-                Main.debug(message);
+                Logging.debug(message);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSetting.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSetting.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/StyleSetting.java	(revision 12620)
@@ -11,4 +11,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -80,10 +81,10 @@
             String label = c.get("label", null, String.class);
             if (label == null) {
-                Main.warn("property 'label' required for boolean style setting");
+                Logging.warn("property 'label' required for boolean style setting");
                 return null;
             }
             Boolean def = c.get("default", null, Boolean.class);
             if (def == null) {
-                Main.warn("property 'default' required for boolean style setting");
+                Logging.warn("property 'default' required for boolean style setting");
                 return null;
             }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/ExpressionFactory.java	(revision 12620)
@@ -24,5 +24,4 @@
 import java.util.zip.CRC32;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.search.SearchCompiler;
 import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
@@ -41,4 +40,5 @@
 import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.RightAndLefthandTraffic;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
@@ -266,5 +266,5 @@
                 return new Color(r, g, b);
             } catch (IllegalArgumentException e) {
-                Main.trace(e);
+                Logging.trace(e);
                 return null;
             }
@@ -285,5 +285,5 @@
                 return new Color(r, g, b, alpha);
             } catch (IllegalArgumentException e) {
-                Main.trace(e);
+                Logging.trace(e);
                 return null;
             }
@@ -301,5 +301,5 @@
                 return Color.getHSBColor(h, s, b);
             } catch (IllegalArgumentException e) {
-                Main.trace(e);
+                Logging.trace(e);
                 return null;
             }
@@ -636,5 +636,5 @@
                 return RotationAngle.parseCardinalRotation(cardinal);
             } catch (IllegalArgumentException ignore) {
-                Main.trace(ignore);
+                Logging.trace(ignore);
                 return null;
             }
@@ -677,5 +677,5 @@
                 m = SearchCompiler.compile(searchStr);
             } catch (ParseError ex) {
-                Main.trace(ex);
+                Logging.trace(ex);
                 return null;
             }
@@ -876,5 +876,5 @@
                 return Utils.decodeUrl(s);
             } catch (IllegalStateException e) {
-                Main.debug(e);
+                Logging.debug(e);
                 return s;
             }
@@ -1310,5 +1310,5 @@
                 throw new JosmRuntimeException(ex);
             } catch (InvocationTargetException ex) {
-                Main.error(ex);
+                Logging.error(ex);
                 return null;
             }
@@ -1381,5 +1381,5 @@
                 throw new JosmRuntimeException(ex);
             } catch (InvocationTargetException ex) {
-                Main.error(ex);
+                Logging.error(ex);
                 return null;
             }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSParser.jj	(revision 12620)
@@ -18,5 +18,4 @@
 import java.util.Locale;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.preferences.ColorProperty;
 import org.openstreetmap.josm.gui.mappaint.Keyword;
@@ -42,4 +41,5 @@
 import org.openstreetmap.josm.tools.ColorHelper;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Utils;
@@ -394,5 +394,5 @@
             String msg = tr("Detected deprecated ''{0}'' in ''{1}'' which will be removed shortly. Use ''{2}'' instead.",
                             "@media", sheet.getDisplayString(), "@supports");
-            Main.error(msg);
+            Logging.error(msg);
             sheet.logWarning(msg);
         }
@@ -626,5 +626,5 @@
             rule() w()
         } catch (MapCSSException mex) {
-            Main.error(mex);
+            Logging.error(mex);
             error_skipto(RBRACE, mex);
             w();
@@ -1207,6 +1207,6 @@
     }
     
-    Main.error("Skipping to the next rule, because of an error:");
-    Main.error(e);
+    Logging.error("Skipping to the next rule, because of an error:");
+    Logging.error(e);
     if (sheet != null) {
         sheet.logError(e);
@@ -1232,5 +1232,5 @@
                 t.image.contains("\n")) {
             ParseException e = new ParseException(String.format("Warning: end of line while reading an unquoted string at line %s column %s.", t.beginLine, t.beginColumn));
-            Main.error(e);
+            Logging.error(e);
             if (sheet != null) {
                 sheet.logError(e);
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSource.java	(revision 12620)
@@ -29,5 +29,4 @@
 import java.util.zip.ZipFile;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Version;
 import org.openstreetmap.josm.data.osm.AbstractPrimitive;
@@ -62,4 +61,5 @@
 import org.openstreetmap.josm.tools.JosmRuntimeException;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -437,14 +437,14 @@
                 }
             } catch (IOException e) {
-                Main.warn(tr("Failed to load Mappaint styles from ''{0}''. Exception was: {1}", url, e.toString()));
-                Main.error(e);
+                Logging.warn(tr("Failed to load Mappaint styles from ''{0}''. Exception was: {1}", url, e.toString()));
+                Logging.error(e);
                 logError(e);
             } catch (TokenMgrError e) {
-                Main.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
-                Main.error(e);
+                Logging.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
+                Logging.error(e);
                 logError(e);
             } catch (ParseException e) {
-                Main.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
-                Main.error(e);
+                Logging.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
+                Logging.error(e);
                 logError(new ParseException(e.getMessage())); // allow e to be garbage collected, it links to the entire token stream
             }
@@ -489,6 +489,6 @@
                     default:
                         final RuntimeException e = new JosmRuntimeException(MessageFormat.format("Unknown MapCSS base selector {0}", base));
-                        Main.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
-                        Main.error(e);
+                        Logging.warn(tr("Failed to parse Mappaint styles from ''{0}''. Error was: {1}", url, e.getMessage()));
+                        Logging.error(e);
                         logError(e);
                 }
@@ -583,5 +583,5 @@
         for (Entry<String, Cascade> e : mc.getLayers()) {
             if ("default".equals(e.getKey())) {
-                Main.warn("setting requires layer identifier e.g. 'setting::my_setting {...}'");
+                Logging.warn("setting requires layer identifier e.g. 'setting::my_setting {...}'");
                 continue;
             }
@@ -592,5 +592,5 @@
                 set = BooleanStyleSetting.create(c, this, e.getKey());
             } else {
-                Main.warn("Unkown setting type: "+type);
+                Logging.warn("Unkown setting type: "+type);
             }
             if (set != null) {
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/mapcss/Selector.java	(revision 12620)
@@ -13,5 +13,4 @@
 import java.util.regex.PatternSyntaxException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -27,4 +26,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.Geometry;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
@@ -336,5 +336,5 @@
                     };
                 } catch (NoSuchElementException ignore) {
-                    Main.trace(ignore);
+                    Logging.trace(ignore);
                     containsFinder = new ContainsFinder(e);
                 }
@@ -473,5 +473,5 @@
                     if (!c.applies(env)) return false;
                 } catch (PatternSyntaxException e) {
-                    Main.error(e, "PatternSyntaxException while applying condition" + c + ':');
+                    Logging.log(Logging.LEVEL_ERROR, "PatternSyntaxException while applying condition" + c + ':', e);
                     return false;
                 }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/LineElement.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/LineElement.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/LineElement.java	(revision 12620)
@@ -8,5 +8,4 @@
 import java.util.Optional;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
@@ -20,4 +19,5 @@
 import org.openstreetmap.josm.gui.mappaint.MultiCascade;
 import org.openstreetmap.josm.gui.mappaint.mapcss.Instruction.RelativeFloat;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -456,5 +456,5 @@
                     realWidth = Float.parseFloat(widthTag);
                 } catch (NumberFormatException nfe) {
-                    Main.warn(nfe);
+                    Logging.warn(nfe);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/mappaint/styleelement/NodeElement.java	(revision 12620)
@@ -27,4 +27,5 @@
 import org.openstreetmap.josm.gui.util.RotationAngle;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -130,5 +131,5 @@
                         rotationAngle = RotationAngle.buildStaticRotation(rotationKW.val);
                     } catch (IllegalArgumentException ignore) {
-                        Main.trace(ignore);
+                        Logging.trace(ignore);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/FullyAutomaticAuthorizationUI.java	(revision 12620)
@@ -29,5 +29,4 @@
 import javax.swing.text.html.HTMLEditorKit;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Preferences;
 import org.openstreetmap.josm.data.oauth.OAuthToken;
@@ -50,4 +49,5 @@
 import org.openstreetmap.josm.io.auth.CredentialsManager;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
@@ -185,5 +185,5 @@
             }
         } catch (CredentialsAgentException e) {
-            Main.error(e);
+            Logging.error(e);
             tfUserName.setText("");
             tfPassword.setText("");
@@ -472,5 +472,5 @@
                 }
             };
-            Main.error(e);
+            Logging.error(e);
             GuiHelper.runInEDT(r);
         }
Index: trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/OsmOAuthAuthorizationClient.java	(revision 12620)
@@ -20,5 +20,4 @@
 import java.util.regex.Pattern;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.oauth.OAuthParameters;
 import org.openstreetmap.josm.data.oauth.OAuthToken;
@@ -29,4 +28,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -180,8 +180,8 @@
             }
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
             return null;
         }
-        Main.warn("No authenticity_token found in response!");
+        Logging.warn("No authenticity_token found in response!");
         return null;
     }
@@ -193,5 +193,5 @@
                 .get("Cookie");
         if (setCookies == null) {
-            Main.warn("No 'Set-Cookie' in response header!");
+            Logging.warn("No 'Set-Cookie' in response header!");
             return null;
         }
@@ -220,5 +220,5 @@
             }
         }
-        Main.warn("No suitable 'Set-Cookie' in response header found! {0}", setCookies);
+        Logging.warn("No suitable 'Set-Cookie' in response header found! {0}", setCookies);
         return null;
     }
@@ -329,5 +329,5 @@
                         userName));
         } catch (OsmOAuthAuthorizationException e) {
-            Main.debug(e);
+            Logging.debug(e);
             throw new OsmLoginFailedException(e.getCause());
         } catch (IOException e) {
Index: trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveAccessTokenTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveAccessTokenTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveAccessTokenTask.java	(revision 12620)
@@ -9,5 +9,4 @@
 import javax.swing.JOptionPane;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.oauth.OAuthParameters;
 import org.openstreetmap.josm.data.oauth.OAuthToken;
@@ -19,4 +18,5 @@
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -87,8 +87,8 @@
             accessToken = client.getAccessToken(getProgressMonitor().createSubTaskMonitor(0, false));
         } catch (OsmTransferCanceledException e) {
-            Main.trace(e);
+            Logging.trace(e);
             return;
         } catch (final OsmOAuthAuthorizationException e) {
-            Main.error(e);
+            Logging.error(e);
             GuiHelper.runInEDT(this::alertRetrievingAccessTokenFailed);
             accessToken = null;
Index: trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveRequestTokenTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveRequestTokenTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/RetrieveRequestTokenTask.java	(revision 12620)
@@ -9,5 +9,4 @@
 import javax.swing.JOptionPane;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.oauth.OAuthParameters;
 import org.openstreetmap.josm.data.oauth.OAuthToken;
@@ -19,4 +18,5 @@
 import org.openstreetmap.josm.io.OsmTransferException;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -81,8 +81,8 @@
             requestToken = client.getRequestToken(getProgressMonitor().createSubTaskMonitor(0, false));
         } catch (OsmTransferCanceledException e) {
-            Main.trace(e);
+            Logging.trace(e);
             return;
         } catch (final OsmOAuthAuthorizationException e) {
-            Main.error(e);
+            Logging.error(e);
             GuiHelper.runInEDT(this::alertRetrievingRequestTokenFailed);
             requestToken = null;
Index: trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/oauth/TestAccessTokenTask.java	(revision 12620)
@@ -12,5 +12,4 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.oauth.OAuthParameters;
 import org.openstreetmap.josm.data.oauth.OAuthToken;
@@ -25,4 +24,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.XmlParsingException;
@@ -253,9 +253,9 @@
         } catch (OsmOAuthAuthorizationException e) {
             if (canceled) return;
-            Main.error(e);
+            Logging.error(e);
             alertFailedSigning();
         } catch (OsmApiException e) {
             if (canceled) return;
-            Main.error(e);
+            Logging.error(e);
             if (e.getResponseCode() == HttpURLConnection.HTTP_INTERNAL_ERROR) {
                 alertInternalError();
@@ -271,5 +271,5 @@
         } catch (OsmTransferException e) {
             if (canceled) return;
-            Main.error(e);
+            Logging.error(e);
             alertFailedConnection();
         }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/DefaultTabPreferenceSetting.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/DefaultTabPreferenceSetting.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/DefaultTabPreferenceSetting.java	(revision 12620)
@@ -10,6 +10,6 @@
 import javax.swing.JTabbedPane;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -105,5 +105,5 @@
                 } catch (IllegalArgumentException e) {
                     // Ignore exception and return false below
-                    Main.debug(Main.getErrorMessage(e));
+                    Logging.debug(Logging.getErrorMessage(e));
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/PreferenceTabbedPane.java	(revision 12620)
@@ -64,4 +64,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;
 
@@ -499,5 +500,5 @@
                 }
             } else if (!(setting instanceof SubPreferenceSetting)) {
-                Main.warn("Ignoring preferences "+setting);
+                Logging.warn("Ignoring preferences "+setting);
             }
         }
@@ -507,5 +508,5 @@
             }
         } catch (IllegalArgumentException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
     }
@@ -600,5 +601,5 @@
                     }
                 } catch (SecurityException ex) {
-                    Main.error(ex);
+                    Logging.error(ex);
                 } catch (RuntimeException ex) { // NOPMD
                     // allow to change most settings even if e.g. a plugin fails
@@ -617,5 +618,5 @@
                 sps.addGui(this);
             } catch (SecurityException ex) {
-                Main.error(ex);
+                Logging.error(ex);
             } catch (RuntimeException ex) { // NOPMD
                 BugReportExceptionHandler.handleException(ex);
Index: trunk/src/org/openstreetmap/josm/gui/preferences/SourceEditor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/SourceEditor.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/SourceEditor.java	(revision 12620)
@@ -94,4 +94,5 @@
 import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
@@ -993,5 +994,5 @@
                     break;
                 default:
-                    Main.error("Unsupported source type: "+sourceType);
+                    Logging.error("Unsupported source type: "+sourceType);
                     return;
                 }
@@ -1515,5 +1516,5 @@
                 for (Iterator<ExtendedSourceEntry> it = sources.iterator(); it.hasNext();) {
                     if ("xml".equals(it.next().styleType)) {
-                        Main.debug("Removing XML source entry");
+                        Logging.debug("Removing XML source entry");
                         it.remove();
                     }
@@ -1544,5 +1545,5 @@
                         Matcher m = Pattern.compile("^\t([^:]+): *(.+)$").matcher(line);
                         if (!m.matches()) {
-                            Main.error(tr(getStr(I18nString.ILLEGAL_FORMAT_OF_ENTRY), url, line));
+                            Logging.error(tr(getStr(I18nString.ILLEGAL_FORMAT_OF_ENTRY), url, line));
                             continue;
                         }
@@ -1579,5 +1580,5 @@
                                 } catch (NumberFormatException e) {
                                     // ignore
-                                    Main.trace(e);
+                                    Logging.trace(e);
                                 }
                             } else if ("style-type".equals(key)) {
@@ -1592,5 +1593,5 @@
                             sources.add(last);
                         } else {
-                            Main.error(tr(getStr(I18nString.ILLEGAL_FORMAT_OF_ENTRY), url, line));
+                            Logging.error(tr(getStr(I18nString.ILLEGAL_FORMAT_OF_ENTRY), url, line));
                         }
                     }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/SourceEntry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/SourceEntry.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/SourceEntry.java	(revision 12620)
@@ -7,5 +7,5 @@
 import java.util.regex.Pattern;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -153,5 +153,5 @@
             return m.group(1);
         } else {
-            Main.warn("Unexpected URL format: "+url);
+            Logging.warn("Unexpected URL format: "+url);
             return url;
         }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/ToolbarPreferences.java	(revision 12620)
@@ -72,4 +72,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -662,5 +663,5 @@
                     return true;
                 } catch (IOException | UnsupportedFlavorException e) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
                 return false;
@@ -681,5 +682,5 @@
                         }
                     } catch (IOException | UnsupportedFlavorException e) {
-                        Main.error(e);
+                        Logging.error(e);
                     }
                     movingComponent = "";
@@ -1022,10 +1023,10 @@
                     Object tb = action.getValue("toolbar");
                     if (tb == null) {
-                        Main.info(tr("Toolbar action without name: {0}",
+                        Logging.info(tr("Toolbar action without name: {0}",
                         action.getClass().getName()));
                         continue;
                     } else if (!(tb instanceof String)) {
                         if (!(tb instanceof Boolean) || (Boolean) tb) {
-                            Main.info(tr("Strange toolbar value: {0}",
+                            Logging.info(tr("Strange toolbar value: {0}",
                             action.getClass().getName()));
                         }
@@ -1035,5 +1036,5 @@
                         Action r = actions.get(toolbar);
                         if (r != null && r != action && !toolbar.startsWith(IMAGERY_PREFIX)) {
-                            Main.info(tr("Toolbar action {0} overwritten: {1} gets {2}",
+                            Logging.info(tr("Toolbar action {0} overwritten: {1} gets {2}",
                             toolbar, r.getClass().getName(), action.getClass().getName()));
                         }
@@ -1096,5 +1097,5 @@
                     result.add(a);
                 } else {
-                    Main.info("Could not load tool definition "+s);
+                    Logging.info("Could not load tool definition "+s);
                 }
             }
@@ -1112,10 +1113,10 @@
         String toolbar = (String) action.getValue("toolbar");
         if (toolbar == null) {
-            Main.info(tr("Registered toolbar action without name: {0}",
+            Logging.info(tr("Registered toolbar action without name: {0}",
                 action.getClass().getName()));
         } else {
             Action r = regactions.get(toolbar);
             if (r != null) {
-                Main.info(tr("Registered toolbar action {0} overwritten: {1} gets {2}",
+                Logging.info(tr("Registered toolbar action {0} overwritten: {1} gets {2}",
                     toolbar, r.getClass().getName(), action.getClass().getName()));
             }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/advanced/AdvancedPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/advanced/AdvancedPreference.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/advanced/AdvancedPreference.java	(revision 12620)
@@ -51,4 +51,5 @@
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -338,5 +339,5 @@
                         Main.pref.save();
                     } catch (IOException e) {
-                        Main.warn(e, "IOException while saving preferences:");
+                        Logging.log(Logging.LEVEL_WARN, "IOException while saving preferences:", e);
                     }
                     readPreferences(Main.pref);
Index: trunk/src/org/openstreetmap/josm/gui/preferences/display/ColorPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/display/ColorPreference.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/display/ColorPreference.java	(revision 12620)
@@ -48,4 +48,5 @@
 import org.openstreetmap.josm.tools.ColorHelper;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -118,5 +119,5 @@
             Color color = ColorHelper.html2color(html);
             if (color == null) {
-                Main.warn("Unable to get color from '"+html+"' for color preference '"+value+'\'');
+                Logging.warn("Unable to get color from '"+html+"' for color preference '"+value+'\'');
             }
             row.add(value);
Index: trunk/src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/display/GPXSettingsPanel.java	(revision 12620)
@@ -32,4 +32,5 @@
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.template_engine.ParseError;
 import org.openstreetmap.josm.tools.template_engine.TemplateParser;
@@ -430,5 +431,5 @@
             case 4: colorTypeTime.setSelected(true); break;
             case 5: colorTypeHeatMap.setSelected(true); break;
-            default: Main.warn("Unknown color type: " + colorType);
+            default: Logging.warn("Unknown color type: " + colorType);
             }
             int ccts = Main.pref.getInteger("draw.rawgps.colorTracksTune", layerName, 45);
@@ -557,5 +558,5 @@
             parser.parse();
         } catch (ParseError e) {
-            Main.warn(e);
+            Logging.warn(e);
             JOptionPane.showMessageDialog(Main.parent,
                     tr("Incorrect waypoint label pattern: {0}", e.getMessage()), tr("Incorrect pattern"), JOptionPane.ERROR_MESSAGE);
@@ -567,5 +568,5 @@
             parser.parse();
         } catch (ParseError e) {
-            Main.warn(e);
+            Logging.warn(e);
             JOptionPane.showMessageDialog(Main.parent,
                     tr("Incorrect audio waypoint label pattern: {0}", e.getMessage()), tr("Incorrect pattern"), JOptionPane.ERROR_MESSAGE);
Index: trunk/src/org/openstreetmap/josm/gui/preferences/display/LafPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/display/LafPreference.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/display/LafPreference.java	(revision 12620)
@@ -40,4 +40,5 @@
 import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.date.DateUtils;
 
@@ -104,5 +105,5 @@
             } catch (ReflectiveOperationException ex) {
                 // just debug, Quaqua may not even be installed...
-                Main.debug(ex);
+                Logging.debug(ex);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/imagery/AddWMSLayerPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/imagery/AddWMSLayerPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/imagery/AddWMSLayerPanel.java	(revision 12620)
@@ -17,5 +17,4 @@
 import javax.swing.JScrollPane;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
 import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryType;
@@ -25,4 +24,5 @@
 import org.openstreetmap.josm.io.imagery.WMSImagery;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -79,9 +79,9 @@
                 formats.setSelectedItem(wms.getPreferredFormats());
             } catch (MalformedURLException ex1) {
-                Main.error(ex1, false);
+                Logging.log(Logging.LEVEL_ERROR, ex1);
                 JOptionPane.showMessageDialog(getParent(), tr("Invalid service URL."),
                         tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
             } catch (IOException ex2) {
-                Main.error(ex2, false);
+                Logging.log(Logging.LEVEL_ERROR, ex2);
                 JOptionPane.showMessageDialog(getParent(), tr("Could not retrieve WMS layer list."),
                         tr("WMS Error"), JOptionPane.ERROR_MESSAGE);
@@ -90,5 +90,5 @@
                 String title = tr("WMS Error");
                 StringBuilder message = new StringBuilder(tr("Could not parse WMS layer list."));
-                Main.error(ex3, "Could not parse WMS layer list. Incoming data:\n"+incomingData);
+                Logging.log(Logging.LEVEL_ERROR, "Could not parse WMS layer list. Incoming data:\n"+incomingData, ex3);
                 if ((incomingData.startsWith("<html>") || incomingData.startsWith("<HTML>"))
                   && (incomingData.endsWith("</html>") || incomingData.endsWith("</HTML>"))) {
Index: trunk/src/org/openstreetmap/josm/gui/preferences/imagery/CacheContentsPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/imagery/CacheContentsPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/imagery/CacheContentsPanel.java	(revision 12620)
@@ -35,4 +35,5 @@
 import org.openstreetmap.josm.gui.widgets.ButtonColumn;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 
@@ -97,5 +98,5 @@
                 }
             } else {
-                Main.warn("Could not parse the key: {0}. No colon found", key);
+                Logging.warn("Could not parse the key: {0}. No colon found", key);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreference.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/imagery/ImageryPreference.java	(revision 12620)
@@ -72,4 +72,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OpenBrowser;
 
@@ -791,5 +792,5 @@
                     htmlPane = new JosmEditorPane(url);
                 } catch (IOException e1) {
-                    Main.trace(e1);
+                    Logging.trace(e1);
                     // give a second chance with a default Locale 'en'
                     try {
@@ -797,5 +798,5 @@
                         htmlPane = new JosmEditorPane(url);
                     } catch (IOException e2) {
-                        Main.debug(e2);
+                        Logging.debug(e2);
                         JOptionPane.showMessageDialog(gui, tr("EULA license URL not available: {0}", eulaUrl));
                         return false;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/map/MapPaintPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/map/MapPaintPreference.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/map/MapPaintPreference.java	(revision 12620)
@@ -33,4 +33,5 @@
 import org.openstreetmap.josm.gui.preferences.TabPreferenceSetting;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -166,5 +167,5 @@
             }
         } catch (RuntimeException ignore) { // NOPMD
-            Main.debug(ignore);
+            Logging.debug(ignore);
         }
         return null;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/map/TaggingPresetPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/map/TaggingPresetPreference.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/map/TaggingPresetPreference.java	(revision 12620)
@@ -35,4 +35,5 @@
 import org.openstreetmap.josm.gui.tagging.presets.TaggingPresetReader;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
@@ -58,5 +59,5 @@
                             canLoad = true;
                         } catch (IOException e) {
-                            Main.warn(e, tr("Could not read tagging preset source: {0}", source));
+                            Logging.log(Logging.LEVEL_WARN, tr("Could not read tagging preset source: {0}", source), e);
                             ExtendedDialog ed = new ExtendedDialog(Main.parent, tr("Error"),
                                     tr("Yes"), tr("No"), tr("Cancel"));
@@ -73,5 +74,5 @@
                         } catch (SAXException e) {
                             // We will handle this in step with validation
-                            Main.trace(e);
+                            Logging.trace(e);
                         }
 
@@ -83,5 +84,5 @@
                             // Should not happen, but at least show message
                             String msg = tr("Could not read tagging preset source {0}", source);
-                            Main.error(e, msg);
+                            Logging.log(Logging.LEVEL_ERROR, msg, e);
                             JOptionPane.showMessageDialog(Main.parent, msg);
                             return false;
@@ -96,5 +97,5 @@
                                         source, e.getLineNumber(), e.getColumnNumber(), Utils.escapeReservedCharactersHTML(e.getMessage()));
                             }
-                            Main.warn(e, errorMessage);
+                            Logging.log(Logging.LEVEL_WARN, errorMessage, e);
                         } catch (SAXException e) {
                             if (canLoad) {
@@ -107,9 +108,9 @@
                                         source, Utils.escapeReservedCharactersHTML(e.getMessage()));
                             }
-                            Main.warn(e, errorMessage);
+                            Logging.log(Logging.LEVEL_ERROR, errorMessage, e);
                         }
 
                         if (errorMessage != null) {
-                            Main.error(errorMessage);
+                            Logging.error(errorMessage);
                             int result = JOptionPane.showConfirmDialog(Main.parent, new JLabel(errorMessage), tr("Error"),
                                     JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.ERROR_MESSAGE);
Index: trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreference.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreference.java	(revision 12620)
@@ -62,4 +62,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -386,5 +387,5 @@
                         ));
             } catch (InterruptedException | InvocationTargetException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreferencesModel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreferencesModel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginPreferencesModel.java	(revision 12620)
@@ -20,4 +20,5 @@
 import org.openstreetmap.josm.plugins.PluginHandler;
 import org.openstreetmap.josm.plugins.PluginInformation;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -350,5 +351,5 @@
                     }
                 } catch (PluginException e) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginUpdatePolicyPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginUpdatePolicyPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/plugin/PluginUpdatePolicyPanel.java	(revision 12620)
@@ -25,4 +25,5 @@
 import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
 import org.openstreetmap.josm.plugins.PluginHandler;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -188,5 +189,5 @@
             } catch (NumberFormatException e) {
                 // ignore - load from preference pluginmanager.time-based-update.interval
-                Main.trace(e);
+                Logging.trace(e);
             }
             if (days <= 0) {
Index: trunk/src/org/openstreetmap/josm/gui/preferences/projection/CustomProjectionChoice.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/projection/CustomProjectionChoice.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/projection/CustomProjectionChoice.java	(revision 12620)
@@ -33,4 +33,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -104,5 +105,5 @@
                         test.update(input.getText());
                     } catch (ProjectionConfigurationException ex) {
-                        Main.warn(ex);
+                        Logging.warn(ex);
                         error = ex.getMessage();
                         valStatus.setIcon(ImageProvider.get("data", "error"));
Index: trunk/src/org/openstreetmap/josm/gui/preferences/projection/GaussKruegerProjectionChoice.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/projection/GaussKruegerProjectionChoice.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/projection/GaussKruegerProjectionChoice.java	(revision 12620)
@@ -7,5 +7,5 @@
 import java.util.Collections;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -40,5 +40,5 @@
             return Integer.parseInt(zone) - 2;
         } catch (NumberFormatException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return defaultIndex;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/projection/LambertCC9ZonesProjectionChoice.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/projection/LambertCC9ZonesProjectionChoice.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/projection/LambertCC9ZonesProjectionChoice.java	(revision 12620)
@@ -11,7 +11,7 @@
 import javax.swing.JPanel;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -83,5 +83,5 @@
                     return Collections.singleton(String.valueOf(zoneval+1));
             } catch (NumberFormatException ex) {
-                Main.warn(ex);
+                Logging.warn(ex);
             }
         }
@@ -99,5 +99,5 @@
             return Integer.parseInt(zone) - 1;
         } catch (NumberFormatException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return defaultIndex;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/projection/LambertProjectionChoice.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/projection/LambertProjectionChoice.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/projection/LambertProjectionChoice.java	(revision 12620)
@@ -11,7 +11,7 @@
 import javax.swing.JPanel;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -77,5 +77,5 @@
                     return Collections.singleton(zonestring);
             } catch (NumberFormatException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
         }
@@ -93,5 +93,5 @@
             return Integer.parseInt(zone) - 1;
         } catch (NumberFormatException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return defaultIndex;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/projection/UTMFranceDOMProjectionChoice.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/projection/UTMFranceDOMProjectionChoice.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/projection/UTMFranceDOMProjectionChoice.java	(revision 12620)
@@ -7,5 +7,5 @@
 import java.util.Collections;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -47,5 +47,5 @@
             return Integer.parseInt(zone) - 1;
         } catch (NumberFormatException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return defaultIndex;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/projection/UTMProjectionChoice.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/projection/UTMProjectionChoice.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/projection/UTMProjectionChoice.java	(revision 12620)
@@ -16,6 +16,6 @@
 import javax.swing.JRadioButton;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -139,5 +139,5 @@
                     return Arrays.asList(zonestring, hem.toString());
             } catch (NumberFormatException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
         }
@@ -170,5 +170,5 @@
             return Integer.parseInt(zone) - 1;
         } catch (NumberFormatException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return defaultIndex;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/remotecontrol/RemoteControlPreference.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/remotecontrol/RemoteControlPreference.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/remotecontrol/RemoteControlPreference.java	(revision 12620)
@@ -39,4 +39,5 @@
 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.PlatformHookWindows;
 
@@ -127,8 +128,8 @@
                             tr("Certificate has been successfully installed.") :
                             tr("Certificate is already installed. Nothing to do.");
-                    Main.info(msg);
+                    Logging.info(msg);
                     JOptionPane.showMessageDialog(wrapper, msg);
                 } catch (IOException | GeneralSecurityException ex) {
-                    Main.error(ex);
+                    Logging.error(ex);
                 }
             });
@@ -138,5 +139,5 @@
                     KeyStore ks = PlatformHookWindows.getRootKeystore();
                     if (ks.containsAlias(RemoteControlHttpsServer.ENTRY_ALIAS)) {
-                        Main.info(tr("Removing certificate {0} from root keystore.", RemoteControlHttpsServer.ENTRY_ALIAS));
+                        Logging.info(tr("Removing certificate {0} from root keystore.", RemoteControlHttpsServer.ENTRY_ALIAS));
                         ks.deleteEntry(RemoteControlHttpsServer.ENTRY_ALIAS);
                         msg = tr("Certificate has been successfully uninstalled.");
@@ -144,8 +145,8 @@
                         msg = tr("Certificate is not installed. Nothing to do.");
                     }
-                    Main.info(msg);
+                    Logging.info(msg);
                     JOptionPane.showMessageDialog(wrapper, msg);
                 } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException ex) {
-                    Main.error(ex);
+                    Logging.error(ex);
                 }
             });
Index: trunk/src/org/openstreetmap/josm/gui/preferences/server/ApiUrlTestTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/server/ApiUrlTestTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/server/ApiUrlTestTask.java	(revision 12620)
@@ -13,5 +13,4 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.HelpAwareOptionPane;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
@@ -21,4 +20,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
@@ -191,5 +191,5 @@
                 Capabilities.CapabilitiesParser.parse(new InputSource(connection.getResponse().getContent()));
             } catch (SAXException | ParserConfigurationException e) {
-                Main.warn(e);
+                Logging.warn(e);
                 alertInvalidCapabilities();
                 return;
@@ -200,5 +200,5 @@
                 // ignore exceptions
                 return;
-            Main.error(e);
+            Logging.error(e);
             alertConnectionFailed();
             return;
Index: trunk/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreferencesPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreferencesPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/server/AuthenticationPreferencesPanel.java	(revision 12620)
@@ -23,4 +23,5 @@
 import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.io.auth.CredentialsManager;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -121,5 +122,5 @@
             rbOAuth.setSelected(true);
         } else {
-            Main.warn(tr("Unsupported value in preference ''{0}'', got ''{1}''. Using authentication method ''Basic Authentication''.",
+            Logging.warn(tr("Unsupported value in preference ''{0}'', got ''{1}''. Using authentication method ''Basic Authentication''.",
                     "osm-server.auth-method", authMethod));
             rbBasicAuthentication.setSelected(true);
Index: trunk/src/org/openstreetmap/josm/gui/preferences/server/BasicAuthenticationPreferencesPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/server/BasicAuthenticationPreferencesPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/server/BasicAuthenticationPreferencesPanel.java	(revision 12620)
@@ -15,5 +15,4 @@
 import javax.swing.JPanel;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.widgets.JosmPasswordField;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
@@ -23,4 +22,5 @@
 import org.openstreetmap.josm.io.auth.CredentialsAgentException;
 import org.openstreetmap.josm.io.auth.CredentialsManager;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -107,7 +107,7 @@
             }
         } catch (CredentialsAgentException e) {
-            Main.error(e);
-            Main.warn(tr("Failed to retrieve OSM credentials from credential manager."));
-            Main.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));
+            Logging.error(e);
+            Logging.warn(tr("Failed to retrieve OSM credentials from credential manager."));
+            Logging.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));
             tfOsmUserName.setText("");
             tfOsmPassword.setText("");
@@ -127,7 +127,7 @@
             cm.store(RequestorType.SERVER, OsmApi.getOsmApi().getHost(), pa);
         } catch (CredentialsAgentException e) {
-            Main.error(e);
-            Main.warn(tr("Failed to save OSM credentials to credential manager."));
-            Main.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));
+            Logging.error(e);
+            Logging.warn(tr("Failed to save OSM credentials to credential manager."));
+            Logging.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAccessTokenHolder.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAccessTokenHolder.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAccessTokenHolder.java	(revision 12620)
@@ -4,5 +4,4 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Preferences;
 import org.openstreetmap.josm.data.oauth.OAuthToken;
@@ -10,4 +9,5 @@
 import org.openstreetmap.josm.io.auth.CredentialsAgentException;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -154,7 +154,7 @@
             token = cm.lookupOAuthAccessToken();
         } catch (CredentialsAgentException e) {
-            Main.error(e);
-            Main.warn(tr("Failed to retrieve OAuth Access Token from credential manager"));
-            Main.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));
+            Logging.error(e);
+            Logging.warn(tr("Failed to retrieve OAuth Access Token from credential manager"));
+            Logging.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));
         }
         saveToPreferences = pref.getBoolean("oauth.access-token.save-to-preferences", true);
@@ -185,7 +185,7 @@
             }
         } catch (CredentialsAgentException e) {
-            Main.error(e);
-            Main.warn(tr("Failed to store OAuth Access Token to credentials manager"));
-            Main.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));
+            Logging.error(e);
+            Logging.warn(tr("Failed to store OAuth Access Token to credentials manager"));
+            Logging.warn(tr("Current credential manager is of type ''{0}''", cm.getClass().getName()));
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/server/OAuthAuthenticationPreferencesPanel.java	(revision 12620)
@@ -34,4 +34,5 @@
 import org.openstreetmap.josm.io.auth.CredentialsManager;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.UserCancelException;
 
@@ -318,5 +319,5 @@
                 wizard.showDialog();
             } catch (UserCancelException ignore) {
-                Main.trace(ignore);
+                Logging.trace(ignore);
                 return;
             }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/server/OsmApiUrlInputPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/server/OsmApiUrlInputPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/server/OsmApiUrlInputPanel.java	(revision 12620)
@@ -37,4 +37,5 @@
 import org.openstreetmap.josm.io.OsmTransferCanceledException;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -156,5 +157,5 @@
                 OsmApi.getOsmApi().initialize(null);
             } catch (OsmTransferCanceledException | OsmApiInitializationException ex) {
-                Main.warn(ex);
+                Logging.warn(ex);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/server/ProxyPreferencesPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/server/ProxyPreferencesPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/server/ProxyPreferencesPanel.java	(revision 12620)
@@ -37,4 +37,5 @@
 import org.openstreetmap.josm.io.auth.CredentialsManager;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -345,5 +346,5 @@
 
         if (pp.equals(ProxyPolicy.USE_SYSTEM_SETTINGS) && !DefaultProxySelector.willJvmRetrieveSystemProxies()) {
-            Main.warn(tr("JOSM is configured to use proxies from the system setting, but the JVM is not configured to retrieve them. " +
+            Logging.warn(tr("JOSM is configured to use proxies from the system setting, but the JVM is not configured to retrieve them. " +
                          "Resetting preferences to ''No proxy''"));
             pp = ProxyPolicy.NO_PROXY;
@@ -364,5 +365,5 @@
             }
         } catch (CredentialsAgentException e) {
-            Main.error(e);
+            Logging.error(e);
             tfProxyHttpUser.setText("");
             tfProxyHttpPassword.setText("");
@@ -436,5 +437,5 @@
             cm.store(RequestorType.PROXY, tfProxyHttpHost.getText(), pa);
         } catch (CredentialsAgentException e) {
-            Main.error(e);
+            Logging.error(e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/preferences/shortcut/PrefJPanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/preferences/shortcut/PrefJPanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/preferences/shortcut/PrefJPanel.java	(revision 12620)
@@ -45,5 +45,4 @@
 import javax.swing.table.TableRowSorter;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.preferences.ColorProperty;
 import org.openstreetmap.josm.gui.util.GuiHelper;
@@ -51,4 +50,5 @@
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.gui.widgets.SelectAllOnFocusGainedDecorator;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
 
@@ -110,5 +110,5 @@
                     }
                 } catch (IllegalArgumentException | IllegalAccessException e) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
             }
@@ -390,5 +390,5 @@
                 model.fireTableDataChanged();
             } catch (PatternSyntaxException | ClassCastException ex) {
-                Main.warn(ex);
+                Logging.warn(ex);
             }
         }
Index: trunk/src/org/openstreetmap/josm/gui/progress/NullProgressMonitor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/progress/NullProgressMonitor.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/progress/NullProgressMonitor.java	(revision 12620)
@@ -5,4 +5,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -26,14 +27,10 @@
     @Override
     public void beginTask(String title) {
-        if (Main.isDebugEnabled()) {
-            Main.debug(title);
-        }
+        Logging.debug(title);
     }
 
     @Override
     public void beginTask(String title, int ticks) {
-        if (Main.isDebugEnabled()) {
-            Main.debug(title);
-        }
+        Logging.debug(title);
     }
 
@@ -60,7 +57,5 @@
     @Override
     public void indeterminateSubTask(String title) {
-        if (Main.isDebugEnabled()) {
-            Main.debug(title);
-        }
+        Logging.debug(title);
     }
 
@@ -107,7 +102,5 @@
     @Override
     public void subTask(String title) {
-        if (Main.isDebugEnabled()) {
-            Main.debug(title);
-        }
+        Logging.debug(title);
     }
 
Index: trunk/src/org/openstreetmap/josm/gui/tagging/TagTable.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/TagTable.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/TagTable.java	(revision 12620)
@@ -27,5 +27,4 @@
 import javax.swing.text.JTextComponent;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.TagMap;
@@ -36,4 +35,5 @@
 import org.openstreetmap.josm.gui.widgets.JosmTable;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -421,6 +421,6 @@
     public void setAutoCompletionManager(AutoCompletionManager autocomplete) {
         if (autocomplete == null) {
-            Main.warn("argument autocomplete should not be null. Aborting.");
-            Thread.dumpStack();
+            Logging.warn("argument autocomplete should not be null. Aborting.");
+            Logging.error(new Exception());
             return;
         }
Index: trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletingComboBox.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletingComboBox.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletingComboBox.java	(revision 12620)
@@ -26,4 +26,5 @@
 import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
 import org.openstreetmap.josm.gui.widgets.JosmComboBox;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -327,13 +328,13 @@
         if (useFixedLocale) {
             Locale oldLocale = privateInputContext.getLocale();
-            Main.info("Using English input method");
+            Logging.info("Using English input method");
             if (!privateInputContext.selectInputMethod(new Locale("en", "US"))) {
                 // Unable to use English keyboard layout, disable the feature
-                Main.warn("Unable to use English input method");
+                Logging.warn("Unable to use English input method");
                 useFixedLocale = false;
                 if (oldLocale != null) {
-                    Main.info("Restoring input method to " + oldLocale);
+                    Logging.info("Restoring input method to " + oldLocale);
                     if (!privateInputContext.selectInputMethod(oldLocale)) {
-                        Main.warn("Unable to restore input method to " + oldLocale);
+                        Logging.warn("Unable to restore input method to " + oldLocale);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletingTextField.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletingTextField.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/ac/AutoCompletingTextField.java	(revision 12620)
@@ -23,4 +23,5 @@
 import org.openstreetmap.josm.gui.util.CellEditorSupport;
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -91,5 +92,5 @@
                 } catch (NumberFormatException e) {
                     // either the new text or the current text isn't a number. We continue with autocompletion
-                    Main.trace(e);
+                    Logging.trace(e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPreset.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPreset.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPreset.java	(revision 12620)
@@ -60,4 +60,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.template_engine.ParseError;
@@ -217,5 +218,5 @@
                 GuiHelper.runInEDT(() -> result.attachImageIcon(this));
             } else {
-                Main.warn(toString() + ": " + PRESET_ICON_ERROR_MSG_PREFIX + iconName);
+                Logging.warn(toString() + ": " + PRESET_ICON_ERROR_MSG_PREFIX + iconName);
             }
         });
@@ -236,5 +237,5 @@
             this.nameTemplate = new TemplateParser(pattern).parse();
         } catch (ParseError e) {
-            Main.error("Error while parsing " + pattern + ": " + e.getMessage());
+            Logging.error("Error while parsing " + pattern + ": " + e.getMessage());
             throw new SAXException(e);
         }
@@ -245,5 +246,5 @@
             this.nameTemplateFilter = SearchCompiler.compile(filter);
         } catch (SearchCompiler.ParseError e) {
-            Main.error("Error while parsing" + filter + ": " + e.getMessage());
+            Logging.error("Error while parsing" + filter + ": " + e.getMessage());
             throw new SAXException(e);
         }
Index: trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetItem.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetItem.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetItem.java	(revision 12620)
@@ -24,4 +24,5 @@
 import org.openstreetmap.josm.gui.tagging.ac.AutoCompletionList;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -119,5 +120,5 @@
             return Integer.valueOf(str);
         } catch (NumberFormatException e) {
-            Main.trace(e);
+            Logging.trace(e);
         }
         return null;
Index: trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetNameTemplateList.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetNameTemplateList.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetNameTemplateList.java	(revision 12620)
@@ -7,6 +7,6 @@
 import java.util.List;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -37,5 +37,5 @@
     private void buildPresetsWithPattern() {
         synchronized (this) {
-            Main.debug("Building list of presets with name template");
+            Logging.debug("Building list of presets with name template");
             presetsWithPattern.clear();
             for (TaggingPreset tp : TaggingPresets.getTaggingPresets()) {
Index: trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetReader.java	(revision 12620)
@@ -43,4 +43,5 @@
 import org.openstreetmap.josm.io.CachedFile;
 import org.openstreetmap.josm.io.UTFInputStreamReader;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.XmlObjectParser;
@@ -210,5 +211,5 @@
                     lastIdIterators.push(it);
                 } else {
-                    Main.warn("Ignoring reference '"+ref+"' denoting an empty chunk");
+                    Logging.warn("Ignoring reference '"+ref+"' denoting an empty chunk");
                 }
                 continue;
@@ -360,6 +361,6 @@
                 readAll(source, validate, allPresets);
             } catch (IOException e) {
-                Main.error(e, false);
-                Main.error(source);
+                Logging.log(Logging.LEVEL_ERROR, e);
+                Logging.error(source);
                 if (source.startsWith("http")) {
                     Main.addNetworkError(source, e);
@@ -374,6 +375,6 @@
                 }
             } catch (SAXException | IllegalArgumentException e) {
-                Main.error(e);
-                Main.error(source);
+                Logging.error(e);
+                Logging.error(source);
                 JOptionPane.showMessageDialog(
                         Main.parent,
Index: trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresets.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresets.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/presets/TaggingPresets.java	(revision 12620)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.gui.tagging.presets.items.Roles;
 import org.openstreetmap.josm.gui.tagging.presets.items.Roles.Role;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
@@ -71,7 +72,7 @@
                 JMenu m = p.group != null ? submenus.get(p.group) : Main.main.menu.presetsMenu;
                 if (m == null && p.group != null) {
-                    Main.error("No tagging preset submenu for " + p.group);
+                    Logging.error("No tagging preset submenu for " + p.group);
                 } else if (m == null) {
-                    Main.error("No tagging preset menu. Tagging preset " + p + " won't be available there");
+                    Logging.error("No tagging preset menu. Tagging preset " + p + " won't be available there");
                 } else if (p instanceof TaggingPresetSeparator) {
                     m.add(new JSeparator());
Index: trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/ComboMultiSelect.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/ComboMultiSelect.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/ComboMultiSelect.java	(revision 12620)
@@ -38,4 +38,5 @@
 import org.openstreetmap.josm.tools.AlphanumComparator;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -397,15 +398,15 @@
         } else {
             if (values != null) {
-                Main.warn(tr("Warning in tagging preset \"{0}-{1}\": "
+                Logging.warn(tr("Warning in tagging preset \"{0}-{1}\": "
                         + "Ignoring ''{2}'' attribute as ''{3}'' elements are given.",
                         key, text, "values", "list_entry"));
             }
             if (display_values != null || locale_display_values != null) {
-                Main.warn(tr("Warning in tagging preset \"{0}-{1}\": "
+                Logging.warn(tr("Warning in tagging preset \"{0}-{1}\": "
                         + "Ignoring ''{2}'' attribute as ''{3}'' elements are given.",
                         key, text, "display_values", "list_entry"));
             }
             if (short_descriptions != null || locale_short_descriptions != null) {
-                Main.warn(tr("Warning in tagging preset \"{0}-{1}\": "
+                Logging.warn(tr("Warning in tagging preset \"{0}-{1}\": "
                         + "Ignoring ''{2}'' attribute as ''{3}'' elements are given.",
                         key, text, "short_descriptions", "list_entry"));
@@ -439,11 +440,11 @@
                         valueArray = (String[]) method.invoke(null);
                     } else {
-                        Main.error(tr("Broken tagging preset \"{0}-{1}\" - Java method given in ''values_from'' is not \"{2}\"", key, text,
+                        Logging.error(tr("Broken tagging preset \"{0}-{1}\" - Java method given in ''values_from'' is not \"{2}\"", key, text,
                                 "public static String[] methodName()"));
                     }
                 } catch (ReflectiveOperationException e) {
-                    Main.error(tr("Broken tagging preset \"{0}-{1}\" - Java method given in ''values_from'' threw {2} ({3})", key, text,
+                    Logging.error(tr("Broken tagging preset \"{0}-{1}\" - Java method given in ''values_from'' threw {2} ({3})", key, text,
                             e.getClass().getName(), e.getMessage()));
-                    Main.debug(e);
+                    Logging.debug(e);
                 }
             }
@@ -464,14 +465,14 @@
 
         if (displayArray.length != valueArray.length) {
-            Main.error(tr("Broken tagging preset \"{0}-{1}\" - number of items in ''display_values'' must be the same as in ''values''",
+            Logging.error(tr("Broken tagging preset \"{0}-{1}\" - number of items in ''display_values'' must be the same as in ''values''",
                             key, text));
-            Main.error(tr("Detailed information: {0} <> {1}", Arrays.toString(displayArray), Arrays.toString(valueArray)));
+            Logging.error(tr("Detailed information: {0} <> {1}", Arrays.toString(displayArray), Arrays.toString(valueArray)));
             displayArray = valueArray;
         }
 
         if (shortDescriptionsArray != null && shortDescriptionsArray.length != valueArray.length) {
-            Main.error(tr("Broken tagging preset \"{0}-{1}\" - number of items in ''short_descriptions'' must be the same as in ''values''",
+            Logging.error(tr("Broken tagging preset \"{0}-{1}\" - number of items in ''short_descriptions'' must be the same as in ''values''",
                             key, text));
-            Main.error(tr("Detailed information: {0} <> {1}", Arrays.toString(shortDescriptionsArray), Arrays.toString(valueArray)));
+            Logging.error(tr("Detailed information: {0} <> {1}", Arrays.toString(shortDescriptionsArray), Arrays.toString(valueArray)));
             shortDescriptionsArray = null;
         }
Index: trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/Text.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/Text.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/tagging/presets/items/Text.java	(revision 12620)
@@ -30,4 +30,5 @@
 import org.openstreetmap.josm.gui.widgets.JosmTextField;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -84,5 +85,5 @@
                 } catch (NumberFormatException ex) {
                     // Ignore - cannot auto-increment if last was non-numeric
-                    Main.trace(ex);
+                    Logging.trace(ex);
                 }
             } else if (!usage.hadKeys() || PROP_FILL_DEFAULT.get() || "force".equals(use_last_as_default)) {
@@ -142,5 +143,5 @@
                     pnl.add(aibutton, GBC.std());
                 } catch (ParseException ex) {
-                    Main.error("Cannot parse auto-increment value of '" + ai + "' into an integer");
+                    Logging.error("Cannot parse auto-increment value of '" + ai + "' into an integer");
                 }
             }
@@ -202,5 +203,5 @@
         String v = getValue(value);
         if (v == null) {
-            Main.error("No 'last value' support for component " + value);
+            Logging.error("No 'last value' support for component " + value);
             return;
         }
Index: trunk/src/org/openstreetmap/josm/gui/util/AdvancedKeyPressDetector.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/util/AdvancedKeyPressDetector.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/util/AdvancedKeyPressDetector.java	(revision 12620)
@@ -19,6 +19,6 @@
 import javax.swing.Timer;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.ListenerList;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -108,5 +108,5 @@
             Toolkit.getDefaultToolkit().addAWTEventListener(this, AWTEvent.KEY_EVENT_MASK);
         } catch (SecurityException ex) {
-            Main.warn(ex);
+            Logging.warn(ex);
         }
         timer = new Timer(0, e -> {
@@ -130,22 +130,23 @@
         set.clear();
         if (!keyListeners.isEmpty()) {
-            Main.warn(tr("Some of the key listeners forgot to remove themselves: {0}"), keyListeners.toString());
+            Logging.warn(tr("Some of the key listeners forgot to remove themselves: {0}"), keyListeners.toString());
         }
         if (!modifierListeners.isEmpty()) {
-            Main.warn(tr("Some of the key modifier listeners forgot to remove themselves: {0}"), modifierListeners.toString());
+            Logging.warn(tr("Some of the key modifier listeners forgot to remove themselves: {0}"), modifierListeners.toString());
         }
         if (modifierExListeners.hasListeners()) {
-            Main.warn(tr("Some of the key modifier listeners forgot to remove themselves: {0}"), modifierExListeners.toString());
+            Logging.warn(tr("Some of the key modifier listeners forgot to remove themselves: {0}"), modifierExListeners.toString());
         }
         try {
             Toolkit.getDefaultToolkit().removeAWTEventListener(this);
         } catch (SecurityException ex) {
-            Main.warn(ex);
+            Logging.warn(ex);
         }
     }
 
     private void processKeyEvent(KeyEvent e) {
-        if (Main.isTraceEnabled()) {
-            Main.trace("AdvancedKeyPressDetector enabled="+enabled+" => processKeyEvent("+e+") from "+new Exception().getStackTrace()[2]);
+        if (Logging.isTraceEnabled()) {
+            Logging.trace("AdvancedKeyPressDetector enabled={0} => processKeyEvent({1}) from {2}",
+                    enabled, e, new Exception().getStackTrace()[2]);
         }
         if (e.getID() == KeyEvent.KEY_PRESSED) {
@@ -154,7 +155,5 @@
             } else if (set.add(e.getKeyCode()) && enabled && isFocusInMainWindow()) {
                 for (KeyPressReleaseListener q: keyListeners) {
-                    if (Main.isTraceEnabled()) {
-                        Main.trace(q+" => doKeyPressed("+e+')');
-                    }
+                    Logging.trace("{0} => doKeyPressed({1})", q, e);
                     q.doKeyPressed(e);
                 }
@@ -165,7 +164,5 @@
                 if (set.remove(e.getKeyCode()) && enabled && isFocusInMainWindow()) {
                     for (KeyPressReleaseListener q: keyListeners) {
-                        if (Main.isTraceEnabled()) {
-                            Main.trace(q+" => doKeyReleased("+e+')');
-                        }
+                        Logging.trace("{0} => doKeyReleased({1})", q, e);
                         q.doKeyReleased(e);
                     }
@@ -222,6 +219,6 @@
     public final void setEnabled(boolean enabled) {
         this.enabled = enabled;
-        if (Main.isTraceEnabled()) {
-            Main.trace("AdvancedKeyPressDetector enabled="+enabled+" from "+new Exception().getStackTrace()[1]);
+        if (Logging.isTraceEnabled()) {
+            Logging.trace("AdvancedKeyPressDetector enabled={0} from {1}", enabled, new Exception().getStackTrace()[1]);
         }
     }
Index: trunk/src/org/openstreetmap/josm/gui/util/GuiHelper.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/util/GuiHelper.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/util/GuiHelper.java	(revision 12620)
@@ -58,4 +58,5 @@
 import org.openstreetmap.josm.tools.ImageProvider.ImageSizes;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.bugreport.BugReport;
 import org.openstreetmap.josm.tools.bugreport.ReportedException;
@@ -122,5 +123,5 @@
                 SwingUtilities.invokeAndWait(task);
             } catch (InterruptedException | InvocationTargetException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         }
@@ -163,5 +164,5 @@
                 return callable.call();
             } catch (Exception e) { // NOPMD
-                Main.error(e);
+                Logging.error(e);
                 return null;
             }
@@ -172,5 +173,5 @@
                 return task.get();
             } catch (InterruptedException | ExecutionException e) {
-                Main.error(e);
+                Logging.error(e);
                 return null;
             }
@@ -389,5 +390,5 @@
     public static void setUIFont(String name) {
         CheckParameterUtil.ensureParameterNotNull(name, "name");
-        Main.info("Setting "+name+" as the default UI font");
+        Logging.info("Setting "+name+" as the default UI font");
         Enumeration<?> keys = UIManager.getDefaults().keys();
         while (keys.hasMoreElements()) {
@@ -520,5 +521,5 @@
             return JOptionPane.getFrameForComponent(parentComponent);
         } catch (HeadlessException e) {
-            Main.debug(e);
+            Logging.debug(e);
             return null;
         }
Index: trunk/src/org/openstreetmap/josm/gui/widgets/AbstractIdTextField.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/widgets/AbstractIdTextField.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/widgets/AbstractIdTextField.java	(revision 12620)
@@ -4,6 +4,6 @@
 import javax.swing.text.JTextComponent;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.datatransfer.ClipboardUtils;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -39,5 +39,5 @@
             }
         } catch (ReflectiveOperationException e) {
-            Main.error(e);
+            Logging.error(e);
         } finally {
             this.validator = validator;
Index: trunk/src/org/openstreetmap/josm/gui/widgets/ChangesetIdTextField.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/widgets/ChangesetIdTextField.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/widgets/ChangesetIdTextField.java	(revision 12620)
@@ -6,5 +6,5 @@
 import javax.swing.text.JTextComponent;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -84,5 +84,5 @@
                 } catch (NumberFormatException e) {
                     // Ignored
-                    Main.trace(e);
+                    Logging.trace(e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/widgets/CompileSearchTextDecorator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/widgets/CompileSearchTextDecorator.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/widgets/CompileSearchTextDecorator.java	(revision 12620)
@@ -9,6 +9,6 @@
 import javax.swing.text.JTextComponent;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.search.SearchCompiler;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -47,5 +47,5 @@
             textComponent.setToolTipText(ex.getMessage());
             filter = SearchCompiler.Always.INSTANCE;
-            Main.debug(ex);
+            Logging.debug(ex);
         }
         textComponent.firePropertyChange("filter", 0, 1);
Index: trunk/src/org/openstreetmap/josm/gui/widgets/JosmHTMLFactory.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/widgets/JosmHTMLFactory.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/widgets/JosmHTMLFactory.java	(revision 12620)
@@ -10,5 +10,5 @@
 import javax.swing.text.html.HTMLEditorKit.HTMLFactory;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -29,5 +29,5 @@
                     return new JosmImageView(elem);
                 } catch (NoSuchFieldException | SecurityException e) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/gui/widgets/JosmImageView.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/widgets/JosmImageView.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/widgets/JosmImageView.java	(revision 12620)
@@ -15,6 +15,6 @@
 import javax.swing.text.html.ImageView;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -68,5 +68,5 @@
             }
         } catch (IllegalArgumentException | ReflectiveOperationException | SecurityException e) {
-           Main.error(e);
+           Logging.error(e);
        }
     }
Index: trunk/src/org/openstreetmap/josm/gui/widgets/JosmPasswordField.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/widgets/JosmPasswordField.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/widgets/JosmPasswordField.java	(revision 12620)
@@ -14,4 +14,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -126,7 +127,7 @@
                         pasteAction.actionPerformed(e);
                     } catch (NullPointerException npe) { // NOPMD
-                        Main.error(npe, "NullPointerException occured because of JDK bug 6322854. "
+                        Logging.log(Logging.LEVEL_ERROR, "NullPointerException occured because of JDK bug 6322854. "
                                 +"Copy/Paste operation has not been performed. Please complain to Oracle: "+
-                                "https://bugs.openjdk.java.net/browse/JDK-6322854");
+                                "https://bugs.openjdk.java.net/browse/JDK-6322854", npe);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/gui/widgets/OsmIdTextField.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/widgets/OsmIdTextField.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/widgets/OsmIdTextField.java	(revision 12620)
@@ -10,8 +10,8 @@
 import javax.swing.text.JTextComponent;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.osm.PrimitiveId;
 import org.openstreetmap.josm.data.osm.SimplePrimitiveId;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -111,5 +111,5 @@
                     } catch (IllegalArgumentException ex) {
                         try {
-                            Main.trace(ex);
+                            Logging.trace(ex);
                             long id = Long.parseLong(s);
                             if (id <= 0) {
@@ -125,5 +125,5 @@
                             }
                         } catch (IllegalArgumentException ex2) {
-                            Main.trace(ex2);
+                            Logging.trace(ex2);
                             return false;
                         }
Index: trunk/src/org/openstreetmap/josm/gui/widgets/TextContextualPopupMenu.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/widgets/TextContextualPopupMenu.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/gui/widgets/TextContextualPopupMenu.java	(revision 12620)
@@ -25,4 +25,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -196,5 +197,5 @@
                 undo.undo();
             } catch (CannotUndoException ex) {
-                Main.trace(ex);
+                Logging.trace(ex);
             } finally {
                 updateUndoState();
@@ -229,5 +230,5 @@
                 undo.redo();
             } catch (CannotRedoException ex) {
-                Main.trace(ex);
+                Logging.trace(ex);
             } finally {
                 updateRedoState();
Index: trunk/src/org/openstreetmap/josm/io/AbstractReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/AbstractReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/AbstractReader.java	(revision 12620)
@@ -12,5 +12,4 @@
 import java.util.Map.Entry;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Changeset;
 import org.openstreetmap.josm.data.osm.DataSet;
@@ -25,4 +24,5 @@
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -105,5 +105,5 @@
                 }
                 if (n.isDeleted()) {
-                    Main.info(tr("Deleted node {0} is part of way {1}", id, w.getId()));
+                    Logging.info(tr("Deleted node {0} is part of way {1}", id, w.getId()));
                 } else {
                     wayNodes.add(n);
@@ -112,5 +112,5 @@
             w.setNodes(wayNodes);
             if (w.hasIncompleteNodes()) {
-                Main.info(tr("Way {0} with {1} nodes has incomplete nodes because at least one node was missing in the loaded data.",
+                Logging.info(tr("Way {0} with {1} nodes has incomplete nodes because at least one node was missing in the loaded data.",
                           externalWayId, w.getNodesCount()));
             }
@@ -176,5 +176,5 @@
                 }
                 if (primitive.isDeleted()) {
-                    Main.info(tr("Deleted member {0} is used by relation {1}", primitive.getId(), relation.getId()));
+                    Logging.info(tr("Deleted member {0} is used by relation {1}", primitive.getId(), relation.getId()));
                 } else {
                     relationMembers.add(new RelationMember(rm.getRole(), primitive));
Index: trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java	(revision 12620)
@@ -9,5 +9,4 @@
 import java.util.List;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.DataSource;
@@ -18,4 +17,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -75,5 +75,5 @@
                     final OsmTransferCanceledException canceledException = new OsmTransferCanceledException("Operation canceled");
                     canceledException.initCause(ex);
-                    Main.warn(canceledException);
+                    Logging.warn(canceledException);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/io/CacheCustomContent.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/CacheCustomContent.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/CacheCustomContent.java	(revision 12620)
@@ -12,4 +12,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -99,5 +100,5 @@
             return false;
         } catch (OfflineAccessException e) {
-            Main.trace(e);
+            Logging.trace(e);
             return true;
         }
@@ -187,8 +188,8 @@
             this.data = new byte[input.available()];
             if (input.read(this.data) < this.data.length) {
-                Main.error("Failed to read expected contents from "+path);
+                Logging.error("Failed to read expected contents from "+path);
             }
         } catch (IOException e) {
-            Main.trace(e);
+            Logging.trace(e);
             if (!isOffline()) {
                 this.data = updateForce();
@@ -205,5 +206,5 @@
             output.flush();
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/io/CachedFile.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/CachedFile.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/CachedFile.java	(revision 12620)
@@ -29,4 +29,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 import org.openstreetmap.josm.tools.Utils;
@@ -327,5 +328,5 @@
             file = getFile();
         } catch (IOException ex) {
-            Main.warn(ex, false);
+            Logging.log(Logging.LEVEL_WARN, ex);
         }
         if (file == null)
@@ -351,6 +352,7 @@
         } catch (IOException e) {
             if (file.getName().endsWith(".zip")) {
-                Main.warn(e, tr("Failed to open file with extension ''{2}'' and namepart ''{3}'' in zip file ''{0}''. Exception was: {1}",
-                        file.getName(), e.toString(), extension, namepart));
+                Logging.log(Logging.LEVEL_WARN,
+                        tr("Failed to open file with extension ''{2}'' and namepart ''{3}'' in zip file ''{0}''. Exception was: {1}",
+                        file.getName(), e.toString(), extension, namepart), e);
             }
         }
@@ -389,5 +391,5 @@
             }
         } catch (MalformedURLException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
     }
@@ -422,5 +424,5 @@
             checkOfflineAccess(urlStr);
         } catch (OfflineAccessException e) {
-            Main.trace(e);
+            Logging.trace(e);
             offline = true;
         }
@@ -471,7 +473,5 @@
             final HttpClient.Response con = activeConnection.connect();
             if (ifModifiedSince != null && con.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
-                if (Main.isDebugEnabled()) {
-                    Main.debug("304 Not Modified ("+urlStr+')');
-                }
+                Logging.debug("304 Not Modified ({0})", urlStr);
                 if (localFile == null)
                     throw new AssertionError();
@@ -491,10 +491,10 @@
                         Arrays.asList(Long.toString(System.currentTimeMillis()), localFile.toString()));
             } else {
-                Main.warn(tr("Failed to rename file {0} to {1}.",
+                Logging.warn(tr("Failed to rename file {0} to {1}.",
                 destDirFile.getPath(), localFile.getPath()));
             }
         } catch (IOException e) {
             if (age >= maxAgeMillis && age < maxAgeMillis*2) {
-                Main.warn(tr("Failed to load {0}, use cached file and retry next time: {1}", urlStr, e));
+                Logging.warn(tr("Failed to load {0}, use cached file and retry next time: {1}", urlStr, e));
                 return localFile;
             } else {
Index: trunk/src/org/openstreetmap/josm/io/Capabilities.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/Capabilities.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/Capabilities.java	(revision 12620)
@@ -13,5 +13,5 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.Attributes;
@@ -161,5 +161,5 @@
 
     private static void warnIllegalValue(String attr, String elem, Object val) {
-        Main.warn(tr("Illegal value of attribute ''{0}'' of element ''{1}'' in server capabilities. Got ''{2}''", attr, elem, val));
+        Logging.warn(tr("Illegal value of attribute ''{0}'' of element ''{1}'' in server capabilities. Got ''{2}''", attr, elem, val));
     }
 
Index: trunk/src/org/openstreetmap/josm/io/CertificateAmendment.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/CertificateAmendment.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/CertificateAmendment.java	(revision 12620)
@@ -29,4 +29,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -144,5 +145,5 @@
             }
         } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException | IllegalStateException e) {
-            Main.error(e);
+            Logging.error(e);
         }
 
@@ -166,6 +167,6 @@
             }
             if (certificateIsMissing(keyStore, cert)) {
-                if (Main.isDebugEnabled()) {
-                    Main.debug(tr("Adding certificate for TLS connections: {0}", cert.getSubjectX500Principal().getName()));
+                if (Logging.isDebugEnabled()) {
+                    Logging.debug(tr("Adding certificate for TLS connections: {0}", cert.getSubjectX500Principal().getName()));
                 }
                 String alias = "josm:" + new File(certAmend.id).getName();
Index: trunk/src/org/openstreetmap/josm/io/ChangesetClosedException.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/ChangesetClosedException.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/ChangesetClosedException.java	(revision 12620)
@@ -9,5 +9,5 @@
 import java.util.regex.Pattern;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.date.DateUtils;
 
@@ -78,9 +78,9 @@
                 closedOn = DateUtils.newOsmApiDateTimeFormat().parse(m.group(2));
             } catch (ParseException ex) {
-                Main.error(tr("Failed to parse date ''{0}'' replied by server.", m.group(2)));
-                Main.error(ex);
+                Logging.error(tr("Failed to parse date ''{0}'' replied by server.", m.group(2)));
+                Logging.error(ex);
             }
         } else {
-            Main.error(tr("Unexpected format of error header for conflict in changeset update. Got ''{0}''", errorHeader));
+            Logging.error(tr("Unexpected format of error header for conflict in changeset update. Got ''{0}''", errorHeader));
         }
     }
Index: trunk/src/org/openstreetmap/josm/io/ChangesetQuery.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/ChangesetQuery.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/ChangesetQuery.java	(revision 12620)
@@ -16,9 +16,9 @@
 import java.util.stream.Stream;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.gui.JosmUserIdentityManager;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.date.DateUtils;
@@ -267,5 +267,5 @@
         CheckParameterUtil.ensureParameterNotNull(changesetIds, "changesetIds");
         if (changesetIds.size() > MAX_CHANGESETS_NUMBER) {
-            Main.warn("Changeset query built with more than " + MAX_CHANGESETS_NUMBER + " changeset ids (" + changesetIds.size() + ')');
+            Logging.warn("Changeset query built with more than " + MAX_CHANGESETS_NUMBER + " changeset ids (" + changesetIds.size() + ')');
         }
         this.changesetIds = changesetIds;
@@ -471,5 +471,5 @@
                         break;
                     default:
-                        Main.warn("Unable to parse time: " + entry.getValue());
+                        Logging.warn("Unable to parse time: " + entry.getValue());
                     }
                     break;
Index: trunk/src/org/openstreetmap/josm/io/DefaultProxySelector.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/DefaultProxySelector.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/DefaultProxySelector.java	(revision 12620)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.gui.preferences.server.ProxyPreferencesPanel;
 import org.openstreetmap.josm.gui.preferences.server.ProxyPreferencesPanel.ProxyPolicy;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -93,11 +94,11 @@
             port = Integer.parseInt(value);
         } catch (NumberFormatException e) {
-            Main.error(tr("Unexpected format for port number in preference ''{0}''. Got ''{1}''.", property, value));
-            Main.error(tr("The proxy will not be used."));
+            Logging.error(tr("Unexpected format for port number in preference ''{0}''. Got ''{1}''.", property, value));
+            Logging.error(tr("The proxy will not be used."));
             return 0;
         }
         if (port <= 0 || port > 65_535) {
-            Main.error(tr("Illegal port number in preference ''{0}''. Got {1}.", property, port));
-            Main.error(tr("The proxy will not be used."));
+            Logging.error(tr("Illegal port number in preference ''{0}''. Got {1}.", property, port));
+            Logging.error(tr("The proxy will not be used."));
             return 0;
         }
@@ -116,5 +117,5 @@
             proxyPolicy = ProxyPolicy.fromName(value);
             if (proxyPolicy == null) {
-                Main.warn(tr("Unexpected value for preference ''{0}'' found. Got ''{1}''. Will use no proxy.",
+                Logging.warn(tr("Unexpected value for preference ''{0}'' found. Got ''{1}''. Will use no proxy.",
                         ProxyPreferencesPanel.PROXY_POLICY, value));
                 proxyPolicy = ProxyPolicy.NO_PROXY;
@@ -128,6 +129,6 @@
                 httpProxySocketAddress = new InetSocketAddress(host, port);
             } else {
-                Main.warn(tr("Unexpected parameters for HTTP proxy. Got host ''{0}'' and port ''{1}''.", host, port));
-                Main.warn(tr("The proxy will not be used."));
+                Logging.warn(tr("Unexpected parameters for HTTP proxy. Got host ''{0}'' and port ''{1}''.", host, port));
+                Logging.warn(tr("The proxy will not be used."));
             }
         }
@@ -140,6 +141,6 @@
                 socksProxySocketAddress = new InetSocketAddress(host, port);
             } else {
-                Main.warn(tr("Unexpected parameters for SOCKS proxy. Got host ''{0}'' and port ''{1}''.", host, port));
-                Main.warn(tr("The proxy will not be used."));
+                Logging.warn(tr("Unexpected parameters for SOCKS proxy. Got host ''{0}'' and port ''{1}''.", host, port));
+                Logging.warn(tr("The proxy will not be used."));
             }
         }
@@ -153,5 +154,6 @@
     public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
         // Just log something. The network stack will also throw an exception which will be caught somewhere else
-        Main.error(tr("Connection to proxy ''{0}'' for URI ''{1}'' failed. Exception was: {2}", sa.toString(), uri.toString(), ioe.toString()));
+        Logging.error(tr("Connection to proxy ''{0}'' for URI ''{1}'' failed. Exception was: {2}",
+                sa.toString(), uri.toString(), ioe.toString()));
         // Remember errors to give a friendly user message asking to review proxy configuration
         errorResources.add(uri.toString());
@@ -203,5 +205,5 @@
         case USE_SYSTEM_SETTINGS:
             if (!jvmWillUseSystemProxies) {
-                Main.warn(tr("The JVM is not configured to lookup proxies from the system settings. "+
+                Logging.warn(tr("The JVM is not configured to lookup proxies from the system settings. "+
                         "The property ''java.net.useSystemProxies'' was missing at startup time.  Will not use a proxy."));
                 return NO_PROXY_LIST;
Index: trunk/src/org/openstreetmap/josm/io/FileImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/FileImporter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/FileImporter.java	(revision 12620)
@@ -16,4 +16,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;
@@ -89,5 +90,5 @@
     public boolean importDataHandleExceptions(File f, ProgressMonitor progressMonitor) {
         try {
-            Main.info("Open file: " + f.getAbsolutePath() + " (" + f.length() + " bytes)");
+            Logging.info("Open file: " + f.getAbsolutePath() + " (" + f.length() + " bytes)");
             importData(f, progressMonitor);
             return true;
@@ -110,5 +111,5 @@
 
     private static void displayError(File f, Exception e) {
-        Main.error(e);
+        Logging.error(e);
         HelpAwareOptionPane.showMessageDialogInEDT(
                 Main.parent,
@@ -137,9 +138,9 @@
     public boolean importDataHandleExceptions(List<File> files, ProgressMonitor progressMonitor) {
         try {
-            Main.info("Open "+files.size()+" files");
+            Logging.info("Open "+files.size()+" files");
             importData(files, progressMonitor);
             return true;
         } catch (IOException | IllegalDataException e) {
-            Main.error(e);
+            Logging.error(e);
             HelpAwareOptionPane.showMessageDialogInEDT(
                     Main.parent,
Index: trunk/src/org/openstreetmap/josm/io/FileWatcher.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/FileWatcher.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/FileWatcher.java	(revision 12620)
@@ -23,4 +23,5 @@
 import org.openstreetmap.josm.gui.preferences.SourceEntry;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -44,5 +45,5 @@
             thread = new Thread((Runnable) this::processEvents, "File Watcher");
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
         }
     }
@@ -104,7 +105,5 @@
      */
     private void processEvents() {
-        if (Main.isDebugEnabled()) {
-            Main.debug("File watcher thread started");
-        }
+        Logging.debug("File watcher thread started");
         while (true) {
 
@@ -140,8 +139,8 @@
                     SourceEntry rule = ruleMap.get(fullPath);
                     if (style != null) {
-                        Main.info("Map style "+style.getDisplayString()+" has been modified. Reloading style...");
+                        Logging.info("Map style "+style.getDisplayString()+" has been modified. Reloading style...");
                         Main.worker.submit(new MapPaintStyleLoader(Collections.singleton(style)));
                     } else if (rule != null) {
-                        Main.info("Validator rule "+rule.getDisplayString()+" has been modified. Reloading rule...");
+                        Logging.info("Validator rule "+rule.getDisplayString()+" has been modified. Reloading rule...");
                         MapCSSTagChecker tagChecker = OsmValidator.getTest(MapCSSTagChecker.class);
                         if (tagChecker != null) {
@@ -149,9 +148,9 @@
                                 tagChecker.addMapCSS(rule.url);
                             } catch (IOException | ParseException e) {
-                                Main.warn(e);
+                                Logging.warn(e);
                             }
                         }
-                    } else if (Main.isDebugEnabled()) {
-                        Main.debug("Received "+kind.name()+" event for unregistered file: "+fullPath);
+                    } else if (Logging.isDebugEnabled()) {
+                        Logging.debug("Received {0} event for unregistered file: {1}", kind.name(), fullPath);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java	(revision 12620)
@@ -18,5 +18,4 @@
 import javax.json.stream.JsonGenerator;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.EastNorth;
@@ -34,4 +33,5 @@
 import org.openstreetmap.josm.gui.mappaint.ElemStyles;
 import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 
@@ -135,6 +135,6 @@
                 geomObj.add("coordinates", multiPolygon);
             } catch (MultipolygonBuilder.JoinedPolygonCreationException ex) {
-                Main.warn("GeoJSON: Failed to export multipolygon {0}", r.getUniqueId());
-                Main.warn(ex);
+                Logging.warn("GeoJSON: Failed to export multipolygon {0}", r.getUniqueId());
+                Logging.warn(ex);
             }
         }
Index: trunk/src/org/openstreetmap/josm/io/GpxExporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxExporter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/GpxExporter.java	(revision 12620)
@@ -35,4 +35,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -205,5 +206,5 @@
             fo.flush();
         } catch (IOException ex) {
-            Main.error(ex);
+            Logging.error(ex);
             JOptionPane.showMessageDialog(Main.parent, tr("Error while exporting {0}:\n{1}", fn, ex.getMessage()),
                     tr("Error"), JOptionPane.ERROR_MESSAGE);
Index: trunk/src/org/openstreetmap/josm/io/GpxImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxImporter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/GpxImporter.java	(revision 12620)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -105,5 +106,5 @@
             addLayers(loadLayers(r.getGpxData(), parsedProperly, fileName, tr("Markers from {0}", fileName)));
         } catch (SAXException e) {
-            Main.error(e);
+            Logging.error(e);
             throw new IOException(tr("Parsing data for layer ''{0}'' failed", fileName), e);
         }
@@ -184,5 +185,5 @@
             return loadLayers(r.getGpxData(), parsedProperly, gpxLayerName, markerLayerName);
         } catch (SAXException e) {
-            Main.error(e);
+            Logging.error(e);
             throw new IOException(tr("Parsing data for layer ''{0}'' failed", gpxLayerName), e);
         }
Index: trunk/src/org/openstreetmap/josm/io/GpxReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/GpxReader.java	(revision 12620)
@@ -17,5 +17,4 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
@@ -27,4 +26,5 @@
 import org.openstreetmap.josm.data.gpx.ImmutableGpxTrack;
 import org.openstreetmap.josm.data.gpx.WayPoint;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.Attributes;
@@ -581,10 +581,10 @@
                     message += ' ' + tr("(at line {0}, column {1})", spe.getLineNumber(), spe.getColumnNumber());
                 }
-                Main.warn(message);
+                Logging.warn(message);
                 return false;
             } else
                 throw e;
         } catch (ParserConfigurationException e) {
-            Main.error(e); // broken SAXException chaining
+            Logging.error(e); // broken SAXException chaining
             throw new SAXException(e);
         }
Index: trunk/src/org/openstreetmap/josm/io/InvalidXmlCharacterFilter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/InvalidXmlCharacterFilter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/InvalidXmlCharacterFilter.java	(revision 12620)
@@ -5,5 +5,5 @@
 import java.io.Reader;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -64,5 +64,5 @@
         if (in < 0x20 && INVALID_CHARS[in]) {
             if (firstWarning) {
-                Main.warn("Invalid xml character encountered: '"+in+"'.");
+                Logging.warn("Invalid xml character encountered: '"+in+"'.");
                 firstWarning = false;
             }
Index: trunk/src/org/openstreetmap/josm/io/MessageNotifier.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/MessageNotifier.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/MessageNotifier.java	(revision 12620)
@@ -30,4 +30,5 @@
 import org.openstreetmap.josm.io.auth.JosmPreferencesCredentialAgent;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -86,5 +87,5 @@
                 }
             } catch (OsmTransferException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
         }
@@ -97,8 +98,8 @@
         int interval = PROP_INTERVAL.get();
         if (Main.isOffline(OnlineResource.OSM_API)) {
-            Main.info(tr("{0} not available (offline mode)", tr("Message notifier")));
+            Logging.info(tr("{0} not available (offline mode)", tr("Message notifier")));
         } else if (!isRunning() && interval > 0 && isUserEnoughIdentified()) {
             task = EXECUTOR.scheduleAtFixedRate(WORKER, 0, TimeUnit.MINUTES.toSeconds(interval), TimeUnit.SECONDS);
-            Main.info("Message notifier active (checks every "+interval+" minute"+(interval > 1 ? "s" : "")+')');
+            Logging.info("Message notifier active (checks every "+interval+" minute"+(interval > 1 ? "s" : "")+')');
         }
     }
@@ -110,5 +111,5 @@
         if (isRunning()) {
             task.cancel(false);
-            Main.info("Message notifier inactive");
+            Logging.info("Message notifier inactive");
             task = null;
         }
@@ -153,5 +154,5 @@
                 }
             } catch (CredentialsAgentException e) {
-                Main.warn(e, "Unable to get credentials:");
+                Logging.log(Logging.LEVEL_WARN, "Unable to get credentials:", e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/MultiFetchServerObjectReader.java	(revision 12620)
@@ -38,4 +38,5 @@
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -51,8 +52,8 @@
  *    reader.parseOsm();
  *    if (!reader.getMissingPrimitives().isEmpty()) {
- *        Main.info("There are missing primitives: " + reader.getMissingPrimitives());
+ *        Logging.info("There are missing primitives: " + reader.getMissingPrimitives());
  *    }
  *    if (!reader.getSkippedWays().isEmpty()) {
- *       Main.info("There are skipped ways: " + reader.getMissingPrimitives());
+ *       Logging.info("There are skipped ways: " + reader.getMissingPrimitives());
  *    }
  * </pre>
@@ -343,5 +344,5 @@
                 }
             } catch (InterruptedException | ExecutionException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         }
@@ -487,5 +488,5 @@
             } catch (OsmApiException e) {
                 if (e.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
-                    Main.info(tr("Server replied with response code 404, retrying with an individual request for each object."));
+                    Logging.info(tr("Server replied with response code 404, retrying with an individual request for each object."));
                     return singleGetIdPackage(type, pkg, progressMonitor);
                 } else {
@@ -524,5 +525,5 @@
                 }
             } catch (IOException ex) {
-                Main.warn(ex);
+                Logging.warn(ex);
             }
             return result;
@@ -552,5 +553,5 @@
                 }
             } catch (IOException ex) {
-                Main.warn(ex);
+                Logging.warn(ex);
             }
             return result;
@@ -591,5 +592,5 @@
                 } catch (OsmApiException e) {
                     if (e.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND) {
-                        Main.info(tr("Server replied with response code 404 for id {0}. Skipping.", Long.toString(id)));
+                        Logging.info(tr("Server replied with response code 404 for id {0}. Skipping.", Long.toString(id)));
                         result.missingPrimitives.add(new SimplePrimitiveId(id, type));
                     } else {
Index: trunk/src/org/openstreetmap/josm/io/NameFinder.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/NameFinder.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/NameFinder.java	(revision 12620)
@@ -13,5 +13,4 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
@@ -21,4 +20,5 @@
 import org.openstreetmap.josm.tools.HttpClient;
 import org.openstreetmap.josm.tools.HttpClient.Response;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OsmUrlToBounds;
 import org.openstreetmap.josm.tools.UncheckedParseException;
@@ -250,8 +250,8 @@
                 }
             } catch (NumberFormatException ex) {
-                Main.error(ex); // SAXException does not chain correctly
+                Logging.error(ex); // SAXException does not chain correctly
                 throw new SAXException(ex.getMessage(), ex);
             } catch (NullPointerException ex) { // NOPMD
-                Main.error(ex); // SAXException does not chain correctly
+                Logging.error(ex); // SAXException does not chain correctly
                 throw new SAXException(tr("Null pointer exception, possibly some missing tags."), ex);
             }
Index: trunk/src/org/openstreetmap/josm/io/NoteExporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/NoteExporter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/NoteExporter.java	(revision 12620)
@@ -9,8 +9,8 @@
 import java.io.OutputStream;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.actions.ExtensionFileFilter;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.NoteLayer;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -37,5 +37,5 @@
     @Override
     public void exportData(File file, Layer layer) throws IOException {
-        Main.info("exporting notes to file: " + file);
+        Logging.info("exporting notes to file: " + file);
         if (layer instanceof NoteLayer) {
             try (OutputStream os = new FileOutputStream(file);
Index: trunk/src/org/openstreetmap/josm/io/NoteImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/NoteImporter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/NoteImporter.java	(revision 12620)
@@ -14,4 +14,5 @@
 import org.openstreetmap.josm.gui.layer.NoteLayer;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -32,6 +33,6 @@
     @Override
     public void importData(final File file, ProgressMonitor progressMonitor) throws IOException {
-        if (Main.isDebugEnabled()) {
-            Main.debug("importing notes file " + file.getAbsolutePath());
+        if (Logging.isDebugEnabled()) {
+            Logging.debug("importing notes file {0}", file.getAbsolutePath());
         }
         try (InputStream is = Compression.getUncompressedFileInputStream(file)) {
@@ -41,6 +42,6 @@
             }
         } catch (SAXException e) {
-            Main.error("error opening up notes file");
-            Main.error(e, true);
+            Logging.error("error opening up notes file");
+            Logging.error(e);
             throw new IOException(e.getMessage(), e);
         }
Index: trunk/src/org/openstreetmap/josm/io/NoteReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/NoteReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/NoteReader.java	(revision 12620)
@@ -14,5 +14,4 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.notes.Note;
@@ -20,4 +19,5 @@
 import org.openstreetmap.josm.data.notes.NoteComment.Action;
 import org.openstreetmap.josm.data.osm.User;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.date.DateUtils;
@@ -218,5 +218,5 @@
             Utils.parseSafeSAX(inputSource, parser);
         } catch (ParserConfigurationException e) {
-            Main.error(e); // broken SAXException chaining
+            Logging.error(e); // broken SAXException chaining
             throw new SAXException(e);
         }
Index: trunk/src/org/openstreetmap/josm/io/OsmApi.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OsmApi.java	(revision 12620)
@@ -37,4 +37,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.XmlParsingException;
@@ -155,5 +156,5 @@
             host = (new URL(serverUrl)).getHost();
         } catch (MalformedURLException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return host;
@@ -212,5 +213,5 @@
                 initializeCapabilities(cache.updateIfRequiredString());
             } catch (SAXParseException parseException) {
-                Main.trace(parseException);
+                Logging.trace(parseException);
                 // XML parsing may fail if JOSM previously stored a corrupted capabilities document (see #8278)
                 // In that case, force update and try again
@@ -219,12 +220,12 @@
             if (capabilities == null) {
                 if (Main.isOffline(OnlineResource.OSM_API)) {
-                    Main.warn(tr("{0} not available (offline mode)", tr("OSM API")));
+                    Logging.warn(tr("{0} not available (offline mode)", tr("OSM API")));
                 } else {
-                    Main.error(tr("Unable to initialize OSM API."));
+                    Logging.error(tr("Unable to initialize OSM API."));
                 }
                 return;
             } else if (!capabilities.supportsVersion("0.6")) {
-                Main.error(tr("This version of JOSM is incompatible with the configured server."));
-                Main.error(tr("It supports protocol version 0.6, while the server says it supports {0} to {1}.",
+                Logging.error(tr("This version of JOSM is incompatible with the configured server."));
+                Logging.error(tr("It supports protocol version 0.6, while the server says it supports {0} to {1}.",
                         capabilities.get("version", "minimum"), capabilities.get("version", "maximum")));
                 return;
@@ -243,5 +244,5 @@
                 for (Layer l : Main.getLayerManager().getLayersOfType(ImageryLayer.class)) {
                     if (((ImageryLayer) l).getInfo().isBlacklisted()) {
-                        Main.info(tr("Removed layer {0} because it is not allowed by the configured API.", l.getName()));
+                        Logging.info(tr("Removed layer {0} because it is not allowed by the configured API.", l.getName()));
                         Main.getLayerManager().removeLayer(l);
                     }
@@ -284,5 +285,5 @@
             osmWriter.flush();
         } catch (IOException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return swriter.toString();
@@ -303,5 +304,5 @@
             osmWriter.flush();
         } catch (IOException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return swriter.toString();
@@ -552,5 +553,5 @@
 
     private void sleepAndListen(int retry, ProgressMonitor monitor) throws OsmTransferCanceledException {
-        Main.info(tr("Waiting 10 seconds ... "));
+        Logging.info(tr("Waiting 10 seconds ... "));
         for (int i = 0; i < 10; i++) {
             if (monitor != null) {
@@ -562,9 +563,9 @@
                 Thread.sleep(1000);
             } catch (InterruptedException ex) {
-                Main.warn("InterruptedException in "+getClass().getSimpleName()+" during sleep");
+                Logging.warn("InterruptedException in "+getClass().getSimpleName()+" during sleep");
                 Thread.currentThread().interrupt();
             }
         }
-        Main.info(tr("OK - trying again."));
+        Logging.info(tr("OK - trying again."));
     }
 
@@ -652,10 +653,10 @@
 
                 final HttpClient.Response response = client.connect();
-                Main.info(response.getResponseMessage());
+                Logging.info(response.getResponseMessage());
                 int retCode = response.getResponseCode();
 
                 if (retCode >= 500 && retries-- > 0) {
                     sleepAndListen(retries, monitor);
-                    Main.info(tr("Starting retry {0} of {1}.", getMaxRetries() - retries, getMaxRetries()));
+                    Logging.info(tr("Starting retry {0} of {1}.", getMaxRetries() - retries, getMaxRetries()));
                     continue;
                 }
@@ -667,7 +668,7 @@
                 if (response.getHeaderField("Error") != null) {
                     errorHeader = response.getHeaderField("Error");
-                    Main.error("Error header: " + errorHeader);
+                    Logging.error("Error header: " + errorHeader);
                 } else if (retCode != HttpURLConnection.HTTP_OK && responseBody.length() > 0) {
-                    Main.error("Error body: " + responseBody);
+                    Logging.error("Error body: " + responseBody);
                 }
                 activeConnection.disconnect();
@@ -859,5 +860,5 @@
             throw new OsmTransferException(tr("Note upload failed"));
         } catch (SAXException | IOException e) {
-            Main.error(e, true);
+            Logging.error(e);
             throw new OsmTransferException(tr("Error parsing note response from server"), e);
         }
Index: trunk/src/org/openstreetmap/josm/io/OsmApiException.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmApiException.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OsmApiException.java	(revision 12620)
@@ -3,5 +3,5 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -146,5 +146,5 @@
         } catch (IllegalArgumentException e) {
             // Ignored
-            Main.trace(e);
+            Logging.trace(e);
         }
         try {
@@ -157,5 +157,5 @@
         } catch (IllegalArgumentException e) {
             // Ignored
-            Main.trace(e);
+            Logging.trace(e);
         }
         return sb.toString();
Index: trunk/src/org/openstreetmap/josm/io/OsmChangeImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmChangeImporter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OsmChangeImporter.java	(revision 12620)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -43,5 +44,5 @@
             importData(Compression.getUncompressedFileInputStream(file), file, progressMonitor);
         } catch (FileNotFoundException e) {
-            Main.error(e);
+            Logging.error(e);
             throw new IOException(tr("File ''{0}'' does not exist.", file.getName()), e);
         }
Index: trunk/src/org/openstreetmap/josm/io/OsmChangesetContentParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmChangesetContentParser.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OsmChangesetContentParser.java	(revision 12620)
@@ -12,5 +12,4 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.ChangesetDataSet;
 import org.openstreetmap.josm.data.osm.ChangesetDataSet.ChangesetModificationType;
@@ -18,4 +17,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.XmlParsingException;
@@ -69,5 +69,5 @@
                 break;
             default:
-                Main.warn(tr("Unsupported start element ''{0}'' in changeset content at position ({1},{2}). Skipping.",
+                Logging.warn(tr("Unsupported start element ''{0}'' in changeset content at position ({1},{2}). Skipping.",
                         qName, locator.getLineNumber(), locator.getColumnNumber()));
             }
@@ -99,5 +99,5 @@
                 break;
             default:
-                Main.warn(tr("Unsupported end element ''{0}'' in changeset content at position ({1},{2}). Skipping.",
+                Logging.warn(tr("Unsupported end element ''{0}'' in changeset content at position ({1},{2}). Skipping.",
                         qName, locator.getLineNumber(), locator.getColumnNumber()));
             }
Index: trunk/src/org/openstreetmap/josm/io/OsmConnection.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmConnection.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OsmConnection.java	(revision 12620)
@@ -23,4 +23,5 @@
 import org.openstreetmap.josm.io.auth.CredentialsManager;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -148,5 +149,5 @@
         } else {
             String msg = tr("Unexpected value for preference ''{0}''. Got ''{1}''.", "osm-server.auth-method", authMethod);
-            Main.warn(msg);
+            Logging.warn(msg);
             throw new OsmTransferException(msg);
         }
Index: trunk/src/org/openstreetmap/josm/io/OsmExporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmExporter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OsmExporter.java	(revision 12620)
@@ -19,4 +19,5 @@
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -91,5 +92,5 @@
             layer.onPostSaveToFile();
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
             JOptionPane.showMessageDialog(
                     Main.parent,
@@ -106,5 +107,5 @@
                 }
             } catch (IOException e2) {
-                Main.error(e2);
+                Logging.error(e2);
                 JOptionPane.showMessageDialog(
                         Main.parent,
Index: trunk/src/org/openstreetmap/josm/io/OsmHistoryReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmHistoryReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OsmHistoryReader.java	(revision 12620)
@@ -11,5 +11,4 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.history.HistoryDataSet;
 import org.openstreetmap.josm.data.osm.history.HistoryOsmPrimitive;
@@ -17,4 +16,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.Attributes;
@@ -94,5 +94,5 @@
             Utils.parseSafeSAX(inputSource, new Parser());
         } catch (ParserConfigurationException e) {
-            Main.error(e); // broken SAXException chaining
+            Logging.error(e); // broken SAXException chaining
             throw new SAXException(e);
         } finally {
Index: trunk/src/org/openstreetmap/josm/io/OsmImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmImporter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OsmImporter.java	(revision 12620)
@@ -18,4 +18,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.gui.util.GuiHelper;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -79,5 +80,5 @@
             importData(in, file, progressMonitor);
         } catch (FileNotFoundException e) {
-            Main.error(e);
+            Logging.error(e);
             throw new IOException(tr("File ''{0}'' does not exist.", file.getName()), e);
         }
Index: trunk/src/org/openstreetmap/josm/io/OsmReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OsmReader.java	(revision 12620)
@@ -21,5 +21,4 @@
 import javax.xml.stream.XMLStreamReader;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.DataSource;
@@ -43,4 +42,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.UncheckedParseException;
 import org.openstreetmap.josm.tools.Utils;
@@ -202,5 +202,5 @@
                 Bounds copy = new Bounds(bounds);
                 bounds.normalize();
-                Main.info("Bbox " + copy + " is out of the world, normalized to " + bounds);
+                Logging.info("Bbox " + copy + " is out of the world, normalized to " + bounds);
             }
             DataSource src = new DataSource(bounds, origin);
@@ -225,5 +225,5 @@
                 nd.setCoor(ll);
             } catch (NumberFormatException e) {
-                Main.trace(e);
+                Logging.trace(e);
             }
         }
@@ -277,5 +277,5 @@
         }
         if (w.isDeleted() && !nodeIds.isEmpty()) {
-            Main.info(tr("Deleted way {0} contains nodes", w.getUniqueId()));
+            Logging.info(tr("Deleted way {0} contains nodes", w.getUniqueId()));
             nodeIds = new ArrayList<>();
         }
@@ -327,5 +327,5 @@
         }
         if (r.isDeleted() && !members.isEmpty()) {
-            Main.info(tr("Deleted relation {0} contains members", r.getUniqueId()));
+            Logging.info(tr("Deleted relation {0} contains members", r.getUniqueId()));
             members = new ArrayList<>();
         }
@@ -410,7 +410,7 @@
         if (printWarning && ("note".equals(element) || "meta".equals(element))) {
             // we know that Overpass API returns those elements
-            Main.debug(tr("Undefined element ''{0}'' found in input stream. Skipping.", element));
+            Logging.debug(tr("Undefined element ''{0}'' found in input stream. Skipping.", element));
         } else if (printWarning) {
-            Main.info(tr("Undefined element ''{0}'' found in input stream. Skipping.", element));
+            Logging.info(tr("Undefined element ''{0}'' found in input stream. Skipping.", element));
         }
         while (true) {
@@ -505,5 +505,5 @@
                             Long.toString(current.getUniqueId()), versionString));
                 } else if (version < 0 && current.isNew()) {
-                    Main.warn(tr("Normalizing value of attribute ''version'' of element {0} to {2}, API version is ''{3}''. Got {1}.",
+                    Logging.warn(tr("Normalizing value of attribute ''version'' of element {0} to {2}, API version is ''{3}''. Got {1}.",
                             current.getUniqueId(), version, 0, "0.6"));
                     version = 0;
@@ -539,8 +539,8 @@
                 current.setChangesetId(Integer.parseInt(v));
             } catch (IllegalArgumentException e) {
-                Main.debug(e.getMessage());
+                Logging.debug(e.getMessage());
                 if (current.isNew()) {
                     // for a new primitive we just log a warning
-                    Main.info(tr("Illegal value for attribute ''changeset'' on new object {1}. Got {0}. Resetting to 0.",
+                    Logging.info(tr("Illegal value for attribute ''changeset'' on new object {1}. Got {0}. Resetting to 0.",
                             v, current.getUniqueId()));
                     current.setChangesetId(0);
@@ -551,6 +551,6 @@
             } catch (IllegalStateException e) {
                 // thrown for positive changeset id on new primitives
-                Main.debug(e);
-                Main.info(e.getMessage());
+                Logging.debug(e);
+                Logging.info(e.getMessage());
                 current.setChangesetId(0);
             }
@@ -558,5 +558,5 @@
                 if (current.isNew()) {
                     // for a new primitive we just log a warning
-                    Main.info(tr("Illegal value for attribute ''changeset'' on new object {1}. Got {0}. Resetting to 0.",
+                    Logging.info(tr("Illegal value for attribute ''changeset'' on new object {1}. Got {0}. Resetting to 0.",
                             v, current.getUniqueId()));
                     current.setChangesetId(0);
Index: trunk/src/org/openstreetmap/josm/io/OsmServerChangesetReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerChangesetReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerChangesetReader.java	(revision 12620)
@@ -13,5 +13,4 @@
 import java.util.List;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.osm.Changeset;
 import org.openstreetmap.josm.data.osm.ChangesetDataSet;
@@ -20,4 +19,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.XmlParsingException;
 
@@ -69,5 +69,5 @@
                 result = OsmChangesetParser.parse(in, monitor.createSubTaskMonitor(1, true));
             } catch (IOException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
         } catch (OsmTransferException e) {
@@ -110,5 +110,5 @@
                 result = changesets.get(0);
             } catch (IOException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
         } catch (OsmTransferException e) {
@@ -160,5 +160,5 @@
                     ret.addAll(changesets);
                 } catch (IOException e) {
-                    Main.warn(e);
+                    Logging.warn(e);
                 }
                 monitor.worked(1);
@@ -201,5 +201,5 @@
                 result = parser.parse(monitor.createSubTaskMonitor(1, true));
             } catch (IOException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
         } catch (XmlParsingException e) {
Index: trunk/src/org/openstreetmap/josm/io/OsmServerReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OsmServerReader.java	(revision 12620)
@@ -21,4 +21,5 @@
 import org.openstreetmap.josm.io.auth.CredentialsManager;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.openstreetmap.josm.tools.XmlParsingException;
@@ -48,5 +49,5 @@
             doAuthenticate = OsmApi.isUsingOAuth() && CredentialsManager.getInstance().lookupOAuthAccessToken() != null;
         } catch (CredentialsAgentException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
     }
@@ -186,5 +187,5 @@
                 response = client.connect(progressMonitor);
             } catch (IOException e) {
-                Main.error(e);
+                Logging.error(e);
                 OsmTransferException ote = new OsmTransferException(
                         tr("Could not connect to the OSM server. Please check your internet connection."), e);
@@ -221,5 +222,5 @@
             return response.fetchContent();
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
             return tr("Reading error text failed.");
         }
Index: trunk/src/org/openstreetmap/josm/io/OverpassDownloadReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/OverpassDownloadReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/OverpassDownloadReader.java	(revision 12620)
@@ -19,5 +19,4 @@
 import javax.xml.stream.XMLStreamException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.DataSource;
@@ -27,4 +26,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.UncheckedParseException;
 import org.openstreetmap.josm.tools.Utils;
@@ -168,9 +168,9 @@
                         break;
                     default:
-                        Main.warn("Unsupported syntax: " + matcher.group(1));
+                        Logging.warn("Unsupported syntax: " + matcher.group(1));
                 }
             } catch (UncheckedParseException ex) {
                 final String msg = tr("Failed to evaluate {0}", matcher.group());
-                Main.warn(ex, msg);
+                Logging.log(Logging.LEVEL_WARN, msg, ex);
                 matcher.appendReplacement(sb, "// " + msg + "\n");
             }
@@ -245,5 +245,5 @@
                     reader = readerClass.getDeclaredConstructor().newInstance();
                 } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/io/audio/AudioPlayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/audio/AudioPlayer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/audio/AudioPlayer.java	(revision 12620)
@@ -7,4 +7,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -210,5 +211,5 @@
             return audioPlayer;
         } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException ex) {
-            Main.error(ex);
+            Logging.error(ex);
             return null;
         }
@@ -223,5 +224,5 @@
                 pause();
             } catch (InterruptedException | IOException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
             audioPlayer.playingUrl = null;
@@ -238,6 +239,6 @@
             soundPlayer = new JavaFxMediaPlayer();
         } catch (NoClassDefFoundError | InterruptedException e) {
-            Main.debug(e);
-            Main.warn("Java FX is unavailable. Falling back to Java Sound API");
+            Logging.debug(e);
+            Logging.warn("Java FX is unavailable. Falling back to Java Sound API");
             soundPlayer = new JavaSoundPlayer(leadIn, calibration);
         }
@@ -298,10 +299,10 @@
                     command.ok(stateChange);
                 } catch (AudioException | IOException | SecurityException | IllegalArgumentException startPlayingException) {
-                    Main.error(startPlayingException);
+                    Logging.error(startPlayingException);
                     command.failed(startPlayingException); // sets state
                 }
             } catch (AudioException | IOException e) {
                 state = State.NOTPLAYING;
-                Main.error(e);
+                Logging.error(e);
             }
         }
Index: trunk/src/org/openstreetmap/josm/io/audio/AudioUtil.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/audio/AudioUtil.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/audio/AudioUtil.java	(revision 12620)
@@ -16,4 +16,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -46,5 +47,5 @@
             return naturalLength / calibration;
         } catch (UnsupportedAudioFileException | IOException e) {
-            Main.debug(e);
+            Logging.debug(e);
             return 0.0;
         }
@@ -62,5 +63,5 @@
         else
             msg = tr(msg);
-        Main.error(msg);
+        Logging.error(msg);
         if (!GraphicsEnvironment.isHeadless()) {
             JOptionPane.showMessageDialog(Main.parent,
Index: trunk/src/org/openstreetmap/josm/io/audio/JavaSoundPlayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/audio/JavaSoundPlayer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/audio/JavaSoundPlayer.java	(revision 12620)
@@ -15,8 +15,8 @@
 import javax.sound.sampled.UnsupportedAudioFileException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.io.audio.AudioPlayer.Execute;
 import org.openstreetmap.josm.io.audio.AudioPlayer.State;
 import org.openstreetmap.josm.tools.ListenerList;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -90,5 +90,5 @@
                     if (skippedBytes == 0) {
                         // Avoid inifinite loop
-                        Main.warn("Unable to skip bytes from audio input stream");
+                        Logging.warn("Unable to skip bytes from audio input stream");
                         bytesToSkip = 0;
                     }
Index: trunk/src/org/openstreetmap/josm/io/auth/CredentialsManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/auth/CredentialsManager.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/auth/CredentialsManager.java	(revision 12620)
@@ -7,9 +7,9 @@
 import java.util.Objects;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.oauth.OAuthToken;
 import org.openstreetmap.josm.gui.JosmUserIdentityManager;
 import org.openstreetmap.josm.io.OsmApi;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -104,5 +104,5 @@
             }
         } catch (CredentialsAgentException ex) {
-            Main.debug(ex);
+            Logging.debug(ex);
             return null;
         }
Index: trunk/src/org/openstreetmap/josm/io/auth/DefaultAuthenticator.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/auth/DefaultAuthenticator.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/auth/DefaultAuthenticator.java	(revision 12620)
@@ -8,6 +8,6 @@
 import java.util.Objects;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.io.OsmApi;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Pair;
 
@@ -65,5 +65,5 @@
             return new PasswordAuthentication(response.getUsername(), response.getPassword());
         } catch (CredentialsAgentException e) {
-            Main.error(e);
+            Logging.error(e);
             return null;
         }
Index: trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/imagery/ImageryReader.java	(revision 12620)
@@ -15,5 +15,4 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
 import org.openstreetmap.josm.data.imagery.ImageryInfo.ImageryBounds;
@@ -24,4 +23,5 @@
 import org.openstreetmap.josm.tools.JosmRuntimeException;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.Utils;
@@ -97,5 +97,5 @@
             throw e;
         } catch (ParserConfigurationException e) {
-            Main.error(e); // broken SAXException chaining
+            Logging.error(e); // broken SAXException chaining
             throw new SAXException(e);
         }
@@ -219,5 +219,5 @@
                                         atts.getValue("max-lon"), ",");
                     } catch (IllegalArgumentException e) {
-                        Main.trace(e);
+                        Logging.trace(e);
                         break;
                     }
@@ -252,5 +252,5 @@
                         shape.addPoint(atts.getValue("lat"), atts.getValue("lon"));
                     } catch (IllegalArgumentException e) {
-                        Main.trace(e);
+                        Logging.trace(e);
                         break;
                     }
Index: trunk/src/org/openstreetmap/josm/io/imagery/WMSImagery.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/imagery/WMSImagery.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/imagery/WMSImagery.java	(revision 12620)
@@ -25,5 +25,4 @@
 import javax.xml.parsers.ParserConfigurationException;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
@@ -31,4 +30,5 @@
 import org.openstreetmap.josm.tools.HttpClient;
 import org.openstreetmap.josm.tools.HttpClient.Response;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.w3c.dom.Document;
@@ -223,5 +223,5 @@
             serviceUrl = new URL(serviceUrlStr);
         } catch (HeadlessException e) {
-            Main.warn(e);
+            Logging.warn(e);
             return;
         }
@@ -229,6 +229,6 @@
         final Response response = HttpClient.create(getCapabilitiesUrl).connect();
         final String incomingData = response.fetchContent();
-        Main.debug("Server response to Capabilities request:");
-        Main.debug(incomingData);
+        Logging.debug("Server response to Capabilities request:");
+        Logging.debug(incomingData);
 
         if (response.getResponseCode() >= 400) {
@@ -239,5 +239,5 @@
             DocumentBuilder builder = Utils.newSafeDOMBuilder();
             builder.setEntityResolver((publicId, systemId) -> {
-                Main.info("Ignoring DTD " + publicId + ", " + systemId);
+                Logging.info("Ignoring DTD " + publicId + ", " + systemId);
                 return new InputSource(new StringReader(""));
             });
@@ -267,5 +267,5 @@
                 String baseURL = child.getAttribute("xlink:href");
                 if (!baseURL.equals(serviceUrlStr)) {
-                    Main.info("GetCapabilities specifies a different service URL: " + baseURL);
+                    Logging.info("GetCapabilities specifies a different service URL: " + baseURL);
                     serviceUrl = new URL(baseURL);
                 }
@@ -283,5 +283,5 @@
         boolean isFormatSupported = isImageFormatSupported(format);
         if (!isFormatSupported) {
-            Main.info("Skipping unsupported image format {0}", format);
+            Logging.info("Skipping unsupported image format {0}", format);
         }
         return isFormatSupported;
Index: trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/nmea/NmeaReader.java	(revision 12620)
@@ -16,5 +16,4 @@
 import java.util.Optional;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.data.gpx.GpxConstants;
@@ -23,4 +22,5 @@
 import org.openstreetmap.josm.data.gpx.WayPoint;
 import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.date.DateUtils;
 
@@ -209,5 +209,5 @@
 
         } catch (IllegalDataException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
     }
@@ -480,7 +480,7 @@
         } catch (IllegalArgumentException | IndexOutOfBoundsException | IllegalDataException ex) {
             if (ps.malformed < 5) {
-                Main.warn(ex);
+                Logging.warn(ex);
             } else {
-                Main.debug(ex);
+                Logging.debug(ex);
             }
             ps.malformed++;
Index: trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpServer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpServer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpServer.java	(revision 12620)
@@ -10,4 +10,5 @@
 
 import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -37,6 +38,6 @@
             instance4.start();
         } catch (IOException ex) {
-            Main.debug(ex);
-            Main.warn(marktr("Cannot start IPv4 remotecontrol server on port {0}: {1}"),
+            Logging.debug(ex);
+            Logging.warn(marktr("Cannot start IPv4 remotecontrol server on port {0}: {1}"),
                     Integer.toString(port), ex.getLocalizedMessage());
         }
@@ -47,6 +48,6 @@
             /* only show error when we also have no IPv4 */
             if (instance4 == null) {
-                Main.debug(ex);
-                Main.warn(marktr("Cannot start IPv6 remotecontrol server on port {0}: {1}"),
+                Logging.debug(ex);
+                Logging.warn(marktr("Cannot start IPv6 remotecontrol server on port {0}: {1}"),
                     Integer.toString(port), ex.getLocalizedMessage());
             }
@@ -63,5 +64,5 @@
                 instance4.stopServer();
             } catch (IOException ioe) {
-                Main.error(ioe);
+                Logging.error(ioe);
             }
             instance4 = null;
@@ -71,5 +72,5 @@
                 instance6.stopServer();
             } catch (IOException ioe) {
-                Main.error(ioe);
+                Logging.error(ioe);
             }
             instance6 = null;
@@ -96,5 +97,5 @@
     @Override
     public void run() {
-        Main.info(marktr("RemoteControl::Accepting remote connections on {0}:{1}"),
+        Logging.info(marktr("RemoteControl::Accepting remote connections on {0}:{1}"),
                 server.getInetAddress(), Integer.toString(server.getLocalPort()));
         while (true) {
@@ -105,5 +106,5 @@
             } catch (SocketException e) {
                 if (!server.isClosed()) {
-                    Main.error(e);
+                    Logging.error(e);
                 } else {
                     // stop the thread automatically if server is stopped
@@ -111,5 +112,5 @@
                 }
             } catch (IOException ioe) {
-                Main.error(ioe);
+                Logging.error(ioe);
             }
         }
@@ -122,5 +123,5 @@
      */
     public void stopServer() throws IOException {
-        Main.info(marktr("RemoteControl::Server {0}:{1} stopped."),
+        Logging.info(marktr("RemoteControl::Server {0}:{1} stopped."),
         server.getInetAddress(), Integer.toString(server.getLocalPort()));
         server.close();
Index: trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpsServer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpsServer.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/remotecontrol/RemoteControlHttpsServer.java	(revision 12620)
@@ -41,4 +41,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.preferences.StringProperty;
+import org.openstreetmap.josm.tools.Logging;
 
 import sun.security.util.ObjectIdentifier;
@@ -208,5 +209,5 @@
 
         if (!path.toFile().exists()) {
-            Main.debug("No keystore found, creating a new one");
+            Logging.debug("No keystore found, creating a new one");
 
             // Create new keystore like previous one generated with JDK keytool as follows:
@@ -252,7 +253,7 @@
             ks.load(in, KEYSTORE_PASSWORD.get().toCharArray());
 
-            if (Main.isDebugEnabled()) {
+            if (Logging.isDebugEnabled()) {
                 for (Enumeration<String> aliases = ks.aliases(); aliases.hasMoreElements();) {
-                    Main.debug("Alias in JOSM keystore: "+aliases.nextElement());
+                    Logging.debug("Alias in JOSM keystore: {0}", aliases.nextElement());
                 }
             }
@@ -278,7 +279,7 @@
         sslContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
 
-        if (Main.isTraceEnabled()) {
-            Main.trace("SSL Context protocol: " + sslContext.getProtocol());
-            Main.trace("SSL Context provider: " + sslContext.getProvider());
+        if (Logging.isTraceEnabled()) {
+            Logging.trace("SSL Context protocol: {0}", sslContext.getProtocol());
+            Logging.trace("SSL Context provider: {0}", sslContext.getProvider());
         }
 
@@ -316,6 +317,6 @@
                 instance4.start();
             } catch (IOException | GeneralSecurityException ex) {
-                Main.debug(ex);
-                Main.warn(marktr("Cannot start IPv4 remotecontrol https server on port {0}: {1}"),
+                Logging.debug(ex);
+                Logging.warn(marktr("Cannot start IPv4 remotecontrol https server on port {0}: {1}"),
                         Integer.toString(port), ex.getLocalizedMessage());
             }
@@ -326,6 +327,6 @@
                 /* only show error when we also have no IPv4 */
                 if (instance4 == null) {
-                    Main.debug(ex);
-                    Main.warn(marktr("Cannot start IPv6 remotecontrol https server on port {0}: {1}"),
+                    Logging.debug(ex);
+                    Logging.warn(marktr("Cannot start IPv6 remotecontrol https server on port {0}: {1}"),
                         Integer.toString(port), ex.getLocalizedMessage());
                 }
@@ -342,5 +343,5 @@
                 instance4.stopServer();
             } catch (IOException ioe) {
-                Main.error(ioe);
+                Logging.error(ioe);
             }
             instance4 = null;
@@ -350,5 +351,5 @@
                 instance6.stopServer();
             } catch (IOException ioe) {
-                Main.error(ioe);
+                Logging.error(ioe);
             }
             instance6 = null;
@@ -372,6 +373,6 @@
         // Create SSL Server factory
         SSLServerSocketFactory factory = sslContext.getServerSocketFactory();
-        if (Main.isTraceEnabled()) {
-            Main.trace("SSL factory - Supported Cipher suites: "+Arrays.toString(factory.getSupportedCipherSuites()));
+        if (Logging.isTraceEnabled()) {
+            Logging.trace("SSL factory - Supported Cipher suites: {0}", Arrays.toString(factory.getSupportedCipherSuites()));
         }
 
@@ -379,12 +380,12 @@
             RemoteControl.getInet6Address() : RemoteControl.getInet4Address());
 
-        if (Main.isTraceEnabled() && server instanceof SSLServerSocket) {
+        if (Logging.isTraceEnabled() && server instanceof SSLServerSocket) {
             SSLServerSocket sslServer = (SSLServerSocket) server;
-            Main.trace("SSL server - Enabled Cipher suites: "+Arrays.toString(sslServer.getEnabledCipherSuites()));
-            Main.trace("SSL server - Enabled Protocols: "+Arrays.toString(sslServer.getEnabledProtocols()));
-            Main.trace("SSL server - Enable Session Creation: "+sslServer.getEnableSessionCreation());
-            Main.trace("SSL server - Need Client Auth: "+sslServer.getNeedClientAuth());
-            Main.trace("SSL server - Want Client Auth: "+sslServer.getWantClientAuth());
-            Main.trace("SSL server - Use Client Mode: "+sslServer.getUseClientMode());
+            Logging.trace("SSL server - Enabled Cipher suites: {0}", Arrays.toString(sslServer.getEnabledCipherSuites()));
+            Logging.trace("SSL server - Enabled Protocols: {0}", Arrays.toString(sslServer.getEnabledProtocols()));
+            Logging.trace("SSL server - Enable Session Creation: {0}", sslServer.getEnableSessionCreation());
+            Logging.trace("SSL server - Need Client Auth: {0}", sslServer.getNeedClientAuth());
+            Logging.trace("SSL server - Want Client Auth: {0}", sslServer.getWantClientAuth());
+            Logging.trace("SSL server - Use Client Mode: {0}", sslServer.getUseClientMode());
         }
     }
@@ -395,5 +396,5 @@
     @Override
     public void run() {
-        Main.info(marktr("RemoteControl::Accepting secure remote connections on {0}:{1}"),
+        Logging.info(marktr("RemoteControl::Accepting secure remote connections on {0}:{1}"),
                 server.getInetAddress(), Integer.toString(server.getLocalPort()));
         while (true) {
@@ -401,21 +402,21 @@
                 @SuppressWarnings("resource")
                 Socket request = server.accept();
-                if (Main.isTraceEnabled() && request instanceof SSLSocket) {
+                if (Logging.isTraceEnabled() && request instanceof SSLSocket) {
                     SSLSocket sslSocket = (SSLSocket) request;
-                    Main.trace("SSL socket - Enabled Cipher suites: "+Arrays.toString(sslSocket.getEnabledCipherSuites()));
-                    Main.trace("SSL socket - Enabled Protocols: "+Arrays.toString(sslSocket.getEnabledProtocols()));
-                    Main.trace("SSL socket - Enable Session Creation: "+sslSocket.getEnableSessionCreation());
-                    Main.trace("SSL socket - Need Client Auth: "+sslSocket.getNeedClientAuth());
-                    Main.trace("SSL socket - Want Client Auth: "+sslSocket.getWantClientAuth());
-                    Main.trace("SSL socket - Use Client Mode: "+sslSocket.getUseClientMode());
-                    Main.trace("SSL socket - Session: "+sslSocket.getSession());
+                    Logging.trace("SSL socket - Enabled Cipher suites: {0}", Arrays.toString(sslSocket.getEnabledCipherSuites()));
+                    Logging.trace("SSL socket - Enabled Protocols: {0}", Arrays.toString(sslSocket.getEnabledProtocols()));
+                    Logging.trace("SSL socket - Enable Session Creation: {0}", sslSocket.getEnableSessionCreation());
+                    Logging.trace("SSL socket - Need Client Auth: {0}", sslSocket.getNeedClientAuth());
+                    Logging.trace("SSL socket - Want Client Auth: {0}", sslSocket.getWantClientAuth());
+                    Logging.trace("SSL socket - Use Client Mode: {0}", sslSocket.getUseClientMode());
+                    Logging.trace("SSL socket - Session: {0}", sslSocket.getSession());
                 }
                 RequestProcessor.processRequest(request);
             } catch (SocketException e) {
                 if (!server.isClosed()) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
             } catch (IOException ioe) {
-                Main.error(ioe);
+                Logging.error(ioe);
             }
         }
@@ -428,5 +429,5 @@
      */
     public void stopServer() throws IOException {
-        Main.info(marktr("RemoteControl::Server {0}:{1} stopped."),
+        Logging.info(marktr("RemoteControl::Server {0}:{1} stopped."),
         server.getInetAddress(), Integer.toString(server.getLocalPort()));
         server.close();
Index: trunk/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/remotecontrol/RequestProcessor.java	(revision 12620)
@@ -25,5 +25,4 @@
 import java.util.regex.Pattern;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.help.HelpUtil;
 import org.openstreetmap.josm.io.remotecontrol.handler.AddNodeHandler;
@@ -41,4 +40,5 @@
 import org.openstreetmap.josm.io.remotecontrol.handler.RequestHandler.RequestHandlerForbiddenException;
 import org.openstreetmap.josm.io.remotecontrol.handler.VersionHandler;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -119,9 +119,9 @@
         String commandWithSlash = '/' + command;
         if (handlers.get(commandWithSlash) != null) {
-            Main.info("RemoteControl: ignoring duplicate command " + command
+            Logging.info("RemoteControl: ignoring duplicate command " + command
                     + " with handler " + handler.getName());
         } else {
             if (!silent) {
-                Main.info("RemoteControl: adding command \"" +
+                Logging.info("RemoteControl: adding command \"" +
                     command + "\" (handled by " + handler.getSimpleName() + ')');
             }
@@ -161,5 +161,5 @@
                 return;
             }
-            Main.info("RemoteControl received: " + get);
+            Logging.info("RemoteControl received: " + get);
 
             StringTokenizer st = new StringTokenizer(get);
@@ -247,11 +247,11 @@
                     out.flush();
                 } catch (RequestHandlerErrorException ex) {
-                    Main.debug(ex);
+                    Logging.debug(ex);
                     sendError(out);
                 } catch (RequestHandlerBadRequestException ex) {
-                    Main.debug(ex);
+                    Logging.debug(ex);
                     sendBadRequest(out, ex.getMessage());
                 } catch (RequestHandlerForbiddenException ex) {
-                    Main.debug(ex);
+                    Logging.debug(ex);
                     sendForbidden(out, ex.getMessage());
                 }
@@ -259,11 +259,11 @@
 
         } catch (IOException ioe) {
-            Main.debug(Main.getErrorMessage(ioe));
+            Logging.debug(Logging.getErrorMessage(ioe));
         } catch (ReflectiveOperationException e) {
-            Main.error(e);
+            Logging.error(e);
             try {
                 sendError(out);
             } catch (IOException e1) {
-                Main.warn(e1);
+                Logging.warn(e1);
             }
         } finally {
@@ -271,5 +271,5 @@
                 request.close();
             } catch (IOException e) {
-                Main.debug(Main.getErrorMessage(e));
+                Logging.debug(Logging.getErrorMessage(e));
             }
         }
@@ -402,5 +402,5 @@
                 handler = handlers.get(cmd).getConstructor().newInstance();
             } catch (ReflectiveOperationException ex) {
-                Main.error(ex);
+                Logging.error(ex);
                 return null;
             }
@@ -410,5 +410,5 @@
             return w.toString();
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
             return null;
         }
Index: trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/AddNodeHandler.java	(revision 12620)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -77,5 +78,5 @@
 
         // Parse the arguments
-        Main.info("Adding node at (" + lat + ", " + lon + ')');
+        Logging.info("Adding node at (" + lat + ", " + lon + ')');
 
         // Create a new node
Index: trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/FeaturesHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/FeaturesHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/FeaturesHandler.java	(revision 12620)
@@ -4,7 +4,7 @@
 import static org.openstreetmap.josm.tools.I18n.tr;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
 import org.openstreetmap.josm.io.remotecontrol.RequestProcessor;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -37,5 +37,5 @@
                    buf.append(info);
                } else {
-                   Main.warn("Unknown handler {0} passed to /features request", s);
+                   Logging.warn("Unknown handler {0} passed to /features request", s);
                }
             }
Index: trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImageryHandler.java	(revision 12620)
@@ -13,4 +13,5 @@
 import org.openstreetmap.josm.gui.util.GuiHelper;
 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -77,5 +78,5 @@
                 imgInfo.setDefaultMinZoom(Integer.parseInt(minZoom));
             } catch (NumberFormatException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         }
@@ -85,5 +86,5 @@
                 imgInfo.setDefaultMaxZoom(Integer.parseInt(maxZoom));
             } catch (NumberFormatException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         }
@@ -97,5 +98,5 @@
             for (ImageryLayer layer : Main.getLayerManager().getLayersOfType(ImageryLayer.class)) {
                 if (layer.getInfo().equals(imgInfo)) {
-                    Main.info("Imagery layer already exists: "+imgInfo);
+                    Logging.info("Imagery layer already exists: "+imgInfo);
                     return;
                 }
@@ -106,5 +107,5 @@
                 Main.getLayerManager().addLayer(ImageryLayer.create(imgInfo));
             } catch (IllegalArgumentException e) {
-                Main.error(e, false);
+                Logging.log(Logging.LEVEL_ERROR, e);
             }
         });
Index: trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/ImportHandler.java	(revision 12620)
@@ -14,4 +14,5 @@
 import org.openstreetmap.josm.actions.downloadtasks.DownloadTask;
 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -36,5 +37,5 @@
                 // For compatibility reasons with older instances of JOSM, arbitrary choice of DownloadOsmTask
                 // As of 2015-04, Overpass Turbo requires this branch of code ...
-                Main.debug("Remote control, /import: defaulting to DownloadOsmTask");
+                Logging.debug("Remote control, /import: defaulting to DownloadOsmTask");
                 new DownloadOsmTask().loadUrl(isLoadInNewLayer(), url.toExternalForm(), null);
             } else if (Main.pref.getBoolean("remotecontrol.import.interactive", true)) {
@@ -48,6 +49,6 @@
             }
         } catch (RuntimeException ex) { // NOPMD
-            Main.warn("RemoteControl: Error parsing import remote control request:");
-            Main.error(ex);
+            Logging.warn("RemoteControl: Error parsing import remote control request:");
+            Logging.error(ex);
             throw new RequestHandlerErrorException(ex);
         }
Index: trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadAndZoomHandler.java	(revision 12620)
@@ -29,4 +29,5 @@
 import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
 import org.openstreetmap.josm.tools.Utils;
@@ -114,5 +115,5 @@
             if (command.equals(myCommand)) {
                 if (!PermissionPrefWithDefault.LOAD_DATA.isAllowed()) {
-                    Main.info("RemoteControl: download forbidden by preferences");
+                    Logging.info("RemoteControl: download forbidden by preferences");
                 } else {
                     Area toDownload = null;
@@ -138,5 +139,5 @@
                     }
                     if (toDownload != null && toDownload.isEmpty()) {
-                        Main.info("RemoteControl: no download necessary");
+                        Logging.info("RemoteControl: no download necessary");
                     } else {
                         Future<?> future = osmTask.download(newLayer, new Bounds(minlat, minlon, maxlat, maxlon),
@@ -147,6 +148,6 @@
             }
         } catch (RuntimeException ex) { // NOPMD
-            Main.warn("RemoteControl: Error parsing load_and_zoom remote control request:");
-            Main.error(ex);
+            Logging.warn("RemoteControl: Error parsing load_and_zoom remote control request:");
+            Logging.error(ex);
             throw new RequestHandlerErrorException(ex);
         }
@@ -200,5 +201,5 @@
                 });
             } catch (SearchCompiler.ParseError ex) {
-                Main.error(ex);
+                Logging.error(ex);
                 throw new RequestHandlerErrorException(ex);
             }
@@ -284,5 +285,5 @@
                         toSelect.add(SimplePrimitiveId.fromString(item));
                     } catch (IllegalArgumentException ex) {
-                        Main.warn(ex, "RemoteControl: invalid selection '" + item + "' ignored");
+                        Logging.log(Logging.LEVEL_WARN, "RemoteControl: invalid selection '" + item + "' ignored", ex);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/LoadObjectHandler.java	(revision 12620)
@@ -18,4 +18,5 @@
 import org.openstreetmap.josm.io.remotecontrol.AddTagsDialog;
 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -59,5 +60,5 @@
     protected void handleRequest() throws RequestHandlerErrorException, RequestHandlerBadRequestException {
         if (!PermissionPrefWithDefault.LOAD_DATA.isAllowed()) {
-            Main.info("RemoteControl: download forbidden by preferences");
+            Logging.info("RemoteControl: download forbidden by preferences");
         }
         if (!ps.isEmpty()) {
@@ -102,5 +103,5 @@
                     ps.add(SimplePrimitiveId.fromString(i));
                 } catch (IllegalArgumentException e) {
-                    Main.warn(e, "RemoteControl: invalid selection '"+i+"' ignored.");
+                    Logging.log(Logging.LEVEL_WARN, "RemoteControl: invalid selection '"+i+"' ignored.", e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/remotecontrol/handler/RequestHandler.java	(revision 12620)
@@ -20,4 +20,5 @@
 import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.io.remotecontrol.PermissionPrefWithDefault;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -148,5 +149,5 @@
         if (permissionPref != null && permissionPref.pref != null && !Main.pref.getBoolean(permissionPref.pref, permissionPref.defaultVal)) {
             String err = MessageFormat.format("RemoteControl: ''{0}'' forbidden by preferences", myCommand);
-            Main.info(err);
+            Logging.info(err);
             throw new RequestHandlerForbiddenException(err);
         }
@@ -228,5 +229,5 @@
                 if (value == null || value.isEmpty()) {
                     error = true;
-                    Main.warn('\'' + myCommand + "' remote control request must have '" + key + "' parameter");
+                    Logging.warn('\'' + myCommand + "' remote control request must have '" + key + "' parameter");
                     missingKeys.add(key);
                 }
@@ -241,5 +242,5 @@
             for (String par: args.keySet()) {
                 if (!knownParams.contains(par)) {
-                    Main.warn("Unknown remote control parameter {0}, skipping it", par);
+                    Logging.warn("Unknown remote control parameter {0}, skipping it", par);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionExporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionExporter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionExporter.java	(revision 12620)
@@ -12,9 +12,9 @@
 import javax.swing.SwingConstants;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.layer.Layer;
 import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
 import org.openstreetmap.josm.gui.layer.geoimage.ImageEntry;
 import org.openstreetmap.josm.tools.GBC;
+import org.openstreetmap.josm.tools.Logging;
 import org.w3c.dom.Element;
 
@@ -66,5 +66,5 @@
 
             if (entry.getFile() == null) {
-                Main.warn("No file attribute for image - skipping entry");
+                Logging.warn("No file attribute for image - skipping entry");
                 break;
             }
Index: trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionImporter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/session/GeoImageSessionImporter.java	(revision 12620)
@@ -10,5 +10,4 @@
 import java.util.List;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.coor.LatLon;
 import org.openstreetmap.josm.gui.layer.GpxLayer;
@@ -18,4 +17,5 @@
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.io.IllegalDataException;
+import org.openstreetmap.josm.tools.Logging;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
@@ -117,5 +117,5 @@
             // TODO: handle thumbnail loading
         } catch (NumberFormatException e) {
-            Main.trace(e);
+            Logging.trace(e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/io/session/ImagerySessionImporter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/ImagerySessionImporter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/session/ImagerySessionImporter.java	(revision 12620)
@@ -8,5 +8,4 @@
 import java.util.Map;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.Preferences;
 import org.openstreetmap.josm.data.imagery.ImageryInfo;
@@ -23,4 +22,5 @@
 import org.openstreetmap.josm.io.IllegalDataException;
 import org.openstreetmap.josm.io.session.SessionReader.ImportSupport;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.w3c.dom.Element;
@@ -50,11 +50,11 @@
                 String zoomStr = attributes.get("zoom-level");
                 if (zoomStr != null) {
-                        support.addPostLayersTask(() -> {
-                            try {
-                                tsLayer.setZoomLevel(Integer.parseInt(zoomStr));
-                            } catch (NumberFormatException e) {
-                                Main.warn(e);
-                            }
-                        });
+                    support.addPostLayersTask(() -> {
+                        try {
+                            tsLayer.setZoomLevel(Integer.parseInt(zoomStr));
+                        } catch (NumberFormatException e) {
+                            Logging.warn(e);
+                        }
+                    });
                 }
             }
Index: trunk/src/org/openstreetmap/josm/io/session/SessionReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/session/SessionReader.java	(revision 12620)
@@ -45,4 +45,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.Utils;
@@ -447,5 +448,5 @@
             active = !activeAtt.isEmpty() ? (Integer.parseInt(activeAtt)-1) : -1;
         } catch (NumberFormatException e) {
-            Main.warn("Unsupported value for 'active' layer attribute. Ignoring it. Error was: "+e.getMessage());
+            Logging.warn("Unsupported value for 'active' layer attribute. Ignoring it. Error was: "+e.getMessage());
             active = -1;
         }
@@ -468,5 +469,5 @@
                         idx = Integer.valueOf(e.getAttribute("index"));
                     } catch (NumberFormatException ex) {
-                        Main.warn(ex);
+                        Logging.warn(ex);
                     }
                     if (idx == null) {
@@ -485,5 +486,5 @@
                                 d = Integer.valueOf(sd);
                             } catch (NumberFormatException ex) {
-                                Main.warn(ex);
+                                Logging.warn(ex);
                             }
                             if (d != null) {
@@ -567,5 +568,5 @@
                 }
                 if (exception != null) {
-                    Main.error(exception);
+                    Logging.error(exception);
                     if (!GraphicsEnvironment.isHeadless()) {
                         CancelOrContinueDialog dialog = new CancelOrContinueDialog();
@@ -607,5 +608,5 @@
                     layer.setOpacity(opacity);
                 } catch (NumberFormatException ex) {
-                    Main.warn(ex);
+                    Logging.warn(ex);
                 }
             }
@@ -625,5 +626,5 @@
                     Double.parseDouble(centerEl.getAttribute("lon")));
         } catch (NumberFormatException ex) {
-            Main.warn(ex);
+            Logging.warn(ex);
         }
         if (center == null) return null;
@@ -634,5 +635,5 @@
             return new SessionViewportData(center, scale);
         } catch (NumberFormatException ex) {
-            Main.warn(ex);
+            Logging.warn(ex);
             return null;
         }
Index: trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/io/session/SessionWriter.java	(revision 12620)
@@ -43,4 +43,5 @@
 import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
 import org.openstreetmap.josm.tools.JosmRuntimeException;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.MultiMap;
 import org.openstreetmap.josm.tools.Utils;
@@ -241,5 +242,5 @@
                     int depIndex = layers.indexOf(depLayer);
                     if (depIndex == -1) {
-                        Main.warn("Unable to find " + depLayer);
+                        Logging.warn("Unable to find " + depLayer);
                     } else {
                         depsInt.add(depIndex+1);
Index: trunk/src/org/openstreetmap/josm/plugins/PluginDownloadTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginDownloadTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginDownloadTask.java	(revision 12620)
@@ -23,4 +23,5 @@
 import org.openstreetmap.josm.tools.CheckParameterUtil;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -117,5 +118,5 @@
             if (pi.downloadlink == null) {
                 String msg = tr("Cannot download plugin ''{0}''. Its download link is not known. Skipping download.", pi.name);
-                Main.warn(msg);
+                Logging.warn(msg);
                 throw new PluginDownloadException(msg);
             }
@@ -131,5 +132,5 @@
             String msg = tr("Cannot download plugin ''{0}''. Its download link ''{1}'' is not a valid URL. Skipping download.",
                     pi.name, pi.downloadlink);
-            Main.warn(msg);
+            Logging.warn(msg);
             throw new PluginDownloadException(msg, e);
         } catch (IOException e) {
@@ -150,5 +151,5 @@
             String message = tr("Failed to create plugin directory ''{0}''", pluginDir.toString());
             lastException = new PluginDownloadException(message);
-            Main.error(message);
+            Logging.error(message);
             failed.addAll(toUpdate);
             return;
@@ -159,5 +160,5 @@
                 return;
             String message = tr("Downloading Plugin {0}...", d.name);
-            Main.info(message);
+            Logging.info(message);
             progressMonitor.subTask(message);
             progressMonitor.worked(1);
@@ -167,5 +168,5 @@
             } catch (PluginDownloadException e) {
                 lastException = e;
-                Main.error(e);
+                Logging.error(e);
                 failed.add(d);
                 continue;
Index: trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginHandler.java	(revision 12620)
@@ -69,4 +69,5 @@
 import org.openstreetmap.josm.tools.I18n;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.SubclassFilteredCollection;
 import org.openstreetmap.josm.tools.Utils;
@@ -304,5 +305,5 @@
             sources.add(org.openstreetmap.josm.gui.MainApplication.class.getClassLoader());
         } catch (SecurityException ex) {
-            Main.debug(ex);
+            Logging.debug(ex);
             sources.add(ImageProvider.class.getClassLoader());
         }
@@ -414,5 +415,5 @@
     public static boolean checkAndConfirmPluginUpdate(Component parent) {
         if (!checkOfflineAccess()) {
-            Main.info(tr("{0} not available (offline mode)", tr("Plugin update")));
+            Logging.info(tr("{0} not available (offline mode)", tr("Plugin update")));
             return false;
         }
@@ -456,7 +457,7 @@
         case "never":
             if ("pluginmanager.version-based-update.policy".equals(togglePreferenceKey)) {
-                Main.info(tr("Skipping plugin update after JOSM upgrade. Automatic update at startup is disabled."));
+                Logging.info(tr("Skipping plugin update after JOSM upgrade. Automatic update at startup is disabled."));
             } else if ("pluginmanager.time-based-update.policy".equals(togglePreferenceKey)) {
-                Main.info(tr("Skipping plugin update after elapsed update interval. Automatic update at startup is disabled."));
+                Logging.info(tr("Skipping plugin update after elapsed update interval. Automatic update at startup is disabled."));
             }
             return false;
@@ -464,7 +465,7 @@
         case "always":
             if ("pluginmanager.version-based-update.policy".equals(togglePreferenceKey)) {
-                Main.info(tr("Running plugin update after JOSM upgrade. Automatic update at startup is enabled."));
+                Logging.info(tr("Running plugin update after JOSM upgrade. Automatic update at startup is enabled."));
             } else if ("pluginmanager.time-based-update.policy".equals(togglePreferenceKey)) {
-                Main.info(tr("Running plugin update after elapsed update interval. Automatic update at startup is disabled."));
+                Logging.info(tr("Running plugin update after elapsed update interval. Automatic update at startup is disabled."));
             }
             return true;
@@ -474,5 +475,5 @@
 
         default:
-            Main.warn(tr("Unexpected value ''{0}'' for preference ''{1}''. Assuming value ''ask''.", policy, togglePreferenceKey));
+            Logging.warn(tr("Unexpected value ''{0}'' for preference ''{1}''. Assuming value ''ask''.", policy, togglePreferenceKey));
         }
 
@@ -529,5 +530,5 @@
                     OnlineResource.JOSM_WEBSITE.checkOfflineAccess(updateSite, Main.getJOSMWebsite());
                 } catch (OfflineAccessException e) {
-                    Main.trace(e);
+                    Logging.trace(e);
                     return false;
                 }
@@ -614,12 +615,12 @@
                             RestartAction.restartJOSM();
                         } catch (IOException e) {
-                            Main.error(e);
+                            Logging.error(e);
                         }
                     } else {
-                        Main.warn("No plugin downloaded, restart canceled");
+                        Logging.warn("No plugin downloaded, restart canceled");
                     }
                 });
             } else {
-                Main.warn("No plugin to download, operation canceled");
+                Logging.warn("No plugin to download, operation canceled");
             }
         });
@@ -776,5 +777,5 @@
             Class<?> klass = plugin.loadClass(pluginClassLoader);
             if (klass != null) {
-                Main.info(tr("loading plugin ''{0}'' (version {1})", plugin.name, plugin.localversion));
+                Logging.info(tr("loading plugin ''{0}'' (version {1})", plugin.name, plugin.localversion));
                 PluginProxy pluginProxy = plugin.load(klass, pluginClassLoader);
                 pluginList.add(pluginProxy);
@@ -784,5 +785,5 @@
         } catch (PluginException e) {
             pluginLoadingExceptions.put(plugin.name, e);
-            Main.error(e);
+            Logging.error(e);
             if (e.getCause() instanceof ClassNotFoundException) {
                 msg = tr("<html>Could not load plugin {0} because the plugin<br>main class ''{1}'' was not found.<br>"
@@ -791,5 +792,5 @@
         } catch (RuntimeException e) { // NOPMD
             pluginLoadingExceptions.put(plugin.name, e);
-            Main.error(e);
+            Logging.error(e);
         }
         if (msg != null && confirmDisablePlugin(parent, msg, plugin.name)) {
@@ -919,5 +920,5 @@
                 task.run();
             } catch (RuntimeException e) { // NOPMD
-                Main.error(e);
+                Logging.error(e);
                 return null;
             }
@@ -968,13 +969,9 @@
             monitor.beginTask(tr("Determining plugins to load..."));
             Set<String> plugins = new HashSet<>(Main.pref.getCollection("plugins", new LinkedList<String>()));
-            if (Main.isDebugEnabled()) {
-                Main.debug("Plugins list initialized to " + plugins);
-            }
+            Logging.debug("Plugins list initialized to {0}", plugins);
             String systemProp = System.getProperty("josm.plugins");
             if (systemProp != null) {
                 plugins.addAll(Arrays.asList(systemProp.split(",")));
-                if (Main.isDebugEnabled()) {
-                    Main.debug("josm.plugins system property set to '" + systemProp+"'. Plugins list is now " + plugins);
-                }
+                Logging.debug("josm.plugins system property set to '{0}'. Plugins list is now {1}", systemProp, plugins);
             }
             monitor.subTask(tr("Removing deprecated plugins..."));
@@ -982,7 +979,5 @@
             monitor.subTask(tr("Removing unmaintained plugins..."));
             filterUnmaintainedPlugins(parent, plugins);
-            if (Main.isDebugEnabled()) {
-                Main.debug("Plugins list is finally set to " + plugins);
-            }
+            Logging.debug("Plugins list is finally set to {0}", plugins);
             Map<String, PluginInformation> infos = loadLocallyAvailablePluginInformation(monitor.createSubTaskMonitor(1, false));
             List<PluginInformation> ret = new LinkedList<>();
@@ -1053,6 +1048,6 @@
                     }
                 } catch (PluginException e) {
-                    Main.warn(tr("Failed to find plugin {0}", name));
-                    Main.error(e);
+                    Logging.warn(tr("Failed to find plugin {0}", name));
+                    Logging.error(e);
                 }
             }
@@ -1097,6 +1092,6 @@
                 }
             } catch (RuntimeException e) { // NOPMD
-                Main.warn(tr("Failed to download plugin information list"));
-                Main.error(e);
+                Logging.warn(tr("Failed to download plugin information list"));
+                Logging.error(e);
                 // don't abort in case of error, continue with downloading plugins below
             }
@@ -1142,5 +1137,5 @@
                     pluginDownloadTask.run();
                 } catch (RuntimeException e) { // NOPMD
-                    Main.error(e);
+                    Logging.error(e);
                     alertFailedPluginUpdate(parent, pluginsToUpdate);
                     return plugins;
@@ -1268,6 +1263,6 @@
             String pluginName = updatedPlugin.getName().substring(0, updatedPlugin.getName().length() - 8);
             if (plugin.exists() && !plugin.delete() && dowarn) {
-                Main.warn(tr("Failed to delete outdated plugin ''{0}''.", plugin.toString()));
-                Main.warn(tr("Failed to install already downloaded plugin ''{0}''. " +
+                Logging.warn(tr("Failed to delete outdated plugin ''{0}''.", plugin.toString()));
+                Logging.warn(tr("Failed to install already downloaded plugin ''{0}''. " +
                         "Skipping installation. JOSM is still going to load the old plugin version.",
                         pluginName));
@@ -1279,6 +1274,6 @@
             } catch (IOException e) {
                 if (dowarn) {
-                    Main.warn(e, tr("Failed to install plugin ''{0}'' from temporary download file ''{1}''. {2}",
-                            plugin.toString(), updatedPlugin.toString(), e.getLocalizedMessage()));
+                    Logging.log(Logging.LEVEL_WARN, tr("Failed to install plugin ''{0}'' from temporary download file ''{1}''. {2}",
+                            plugin.toString(), updatedPlugin.toString(), e.getLocalizedMessage()), e);
                 }
                 continue;
@@ -1286,7 +1281,7 @@
             // Install plugin
             if (!updatedPlugin.renameTo(plugin) && dowarn) {
-                Main.warn(tr("Failed to install plugin ''{0}'' from temporary download file ''{1}''. Renaming failed.",
+                Logging.warn(tr("Failed to install plugin ''{0}'' from temporary download file ''{1}''. Renaming failed.",
                         plugin.toString(), updatedPlugin.toString()));
-                Main.warn(tr("Failed to install already downloaded plugin ''{0}''. " +
+                Logging.warn(tr("Failed to install already downloaded plugin ''{0}''. " +
                         "Skipping installation. JOSM is still going to load the old plugin version.",
                         pluginName));
@@ -1306,10 +1301,10 @@
                 new JarFile(jar).close();
             } catch (IOException e) {
-                Main.warn(e);
+                Logging.warn(e);
                 return false;
             }
             return true;
         } else if (jar != null) {
-            Main.warn("Invalid jar file ''"+jar+"'' (exists: "+jar.exists()+", canRead: "+jar.canRead()+')');
+            Logging.warn("Invalid jar file ''"+jar+"'' (exists: "+jar.exists()+", canRead: "+jar.canRead()+')');
         }
         return false;
@@ -1351,5 +1346,5 @@
                 pi.updateFromJar(new PluginInformation(downloadedPluginFile, pi.name));
             } catch (PluginException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         }
@@ -1405,5 +1400,5 @@
             return task.get();
         } catch (InterruptedException | ExecutionException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return -1;
Index: trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginInformation.java	(revision 12620)
@@ -29,4 +29,5 @@
 import org.openstreetmap.josm.tools.ImageProvider;
 import org.openstreetmap.josm.tools.LanguageInfo;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 
@@ -201,5 +202,5 @@
         String s = Optional.ofNullable(attr.getValue(lang+"Plugin-Link")).orElseGet(() -> attr.getValue("Plugin-Link"));
         if (s != null && !Utils.isValidUrl(s)) {
-            Main.info(tr("Invalid URL ''{0}'' in plugin {1}", s, name));
+            Logging.info(tr("Invalid URL ''{0}'' in plugin {1}", s, name));
             s = null;
         }
@@ -213,6 +214,6 @@
                     s = tr(s);
                 } catch (IllegalArgumentException e) {
-                    Main.debug(e);
-                    Main.info(tr("Invalid plugin description ''{0}'' in plugin {1}", s, name));
+                    Logging.debug(e);
+                    Logging.info(tr("Invalid plugin description ''{0}'' in plugin {1}", s, name));
                 }
             }
@@ -230,8 +231,8 @@
                 mainversion = Integer.parseInt(s);
             } catch (NumberFormatException e) {
-                Main.warn(tr("Invalid plugin main version ''{0}'' in plugin {1}", s, name));
+                Logging.warn(tr("Invalid plugin main version ''{0}'' in plugin {1}", s, name));
             }
         } else {
-            Main.warn(tr("Missing plugin main version in plugin {0}", name));
+            Logging.warn(tr("Missing plugin main version in plugin {0}", name));
         }
         author = attr.getValue("Author");
@@ -265,5 +266,5 @@
                     }
                 } catch (NumberFormatException e) {
-                    Main.error(e);
+                    Logging.error(e);
                 }
             }
@@ -391,5 +392,5 @@
             }
         } catch (IOException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
 
Index: trunk/src/org/openstreetmap/josm/plugins/PluginListParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginListParser.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginListParser.java	(revision 12620)
@@ -13,5 +13,5 @@
 import java.util.List;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 
 /**
@@ -103,5 +103,5 @@
             }
         } catch (PluginListParseException ex) {
-            Main.error(ex);
+            Logging.error(ex);
         }
     }
Index: trunk/src/org/openstreetmap/josm/plugins/PluginProxy.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/PluginProxy.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/plugins/PluginProxy.java	(revision 12620)
@@ -4,8 +4,8 @@
 import java.util.List;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.MapFrame;
 import org.openstreetmap.josm.gui.download.DownloadSelection;
 import org.openstreetmap.josm.gui.preferences.PreferenceSetting;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.bugreport.BugReportExceptionHandler;
 
@@ -66,6 +66,6 @@
             plugin.getClass().getMethod("mapFrameInitialized", MapFrame.class, MapFrame.class).invoke(plugin, oldFrame, newFrame);
         } catch (NoSuchMethodException e) {
-            Main.trace(e);
-            Main.debug("Plugin "+plugin+" does not define mapFrameInitialized");
+            Logging.trace(e);
+            Logging.debug("Plugin "+plugin+" does not define mapFrameInitialized");
         } catch (ReflectiveOperationException | IllegalArgumentException | NoClassDefFoundError e) {
             handlePluginException(e);
@@ -78,6 +78,6 @@
             return (PreferenceSetting) plugin.getClass().getMethod("getPreferenceSetting").invoke(plugin);
         } catch (NoSuchMethodException e) {
-            Main.trace(e);
-            Main.debug("Plugin "+plugin+" does not define getPreferenceSetting");
+            Logging.trace(e);
+            Logging.debug("Plugin "+plugin+" does not define getPreferenceSetting");
             return null;
         } catch (ReflectiveOperationException | IllegalArgumentException | NoClassDefFoundError e) {
@@ -92,6 +92,6 @@
             plugin.getClass().getMethod("addDownloadSelection", List.class).invoke(plugin, list);
         } catch (NoSuchMethodException e) {
-            Main.trace(e);
-            Main.debug("Plugin "+plugin+" does not define addDownloadSelection");
+            Logging.trace(e);
+            Logging.debug("Plugin "+plugin+" does not define addDownloadSelection");
         } catch (ReflectiveOperationException | IllegalArgumentException | NoClassDefFoundError e) {
             handlePluginException(e);
Index: trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/plugins/ReadLocalPluginInformationTask.java	(revision 12620)
@@ -14,9 +14,9 @@
 import java.util.Map;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.gui.PleaseWaitRunnable;
 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
 import org.openstreetmap.josm.gui.progress.ProgressMonitor;
 import org.openstreetmap.josm.io.OsmTransferException;
+import org.openstreetmap.josm.tools.Logging;
 import org.xml.sax.SAXException;
 
@@ -96,6 +96,6 @@
                 processLocalPluginInformationFile(f);
             } catch (PluginListParseException e) {
-                Main.warn(tr("Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
-                Main.error(e);
+                Logging.warn(tr("Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
+                Logging.error(e);
             }
             monitor.worked(1);
@@ -123,6 +123,6 @@
                 }
             } catch (PluginException e) {
-                Main.warn(e, "PluginException: ");
-                Main.warn(tr("Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
+                Logging.log(Logging.LEVEL_WARN, "PluginException: ", e);
+                Logging.warn(tr("Failed to scan file ''{0}'' for plugin information. Skipping.", fname));
             }
             monitor.worked(1);
Index: trunk/src/org/openstreetmap/josm/plugins/ReadRemotePluginInformationTask.java
===================================================================
--- trunk/src/org/openstreetmap/josm/plugins/ReadRemotePluginInformationTask.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/plugins/ReadRemotePluginInformationTask.java	(revision 12620)
@@ -39,4 +39,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.HttpClient;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Utils;
 import org.xml.sax.SAXException;
@@ -164,5 +165,5 @@
         } catch (MalformedURLException e) {
             if (canceled) return null;
-            Main.error(e);
+            Logging.error(e);
             return null;
         } catch (IOException e) {
@@ -184,7 +185,7 @@
         final String msg = e.getMessage();
         if (details == null || details.isEmpty()) {
-            Main.error(e.getClass().getSimpleName()+": " + msg);
+            Logging.error(e.getClass().getSimpleName()+": " + msg);
         } else {
-            Main.error(msg + " - Details:\n" + details);
+            Logging.error(msg + " - Details:\n" + details);
         }
 
@@ -227,5 +228,5 @@
         File pluginDir = Main.pref.getPluginsDirectory();
         if (!pluginDir.exists() && !pluginDir.mkdirs()) {
-            Main.warn(tr("Failed to create plugin directory ''{0}''. Cannot cache plugin list from plugin site ''{1}''.",
+            Logging.warn(tr("Failed to create plugin directory ''{0}''. Cannot cache plugin list from plugin site ''{1}''.",
                     pluginDir.toString(), site));
         }
@@ -237,5 +238,5 @@
         } catch (IOException e) {
             // just failed to write the cache file. No big deal, but log the exception anyway
-            Main.error(e);
+            Logging.error(e);
         }
     }
@@ -276,6 +277,6 @@
             availablePlugins.addAll(filterDeprecatedPlugins(pis));
         } catch (PluginListParseException e) {
-            Main.error(tr("Failed to parse plugin list document from site ''{0}''. Skipping site. Exception was: {1}", site, e.toString()));
-            Main.error(e);
+            Logging.error(tr("Failed to parse plugin list document from site ''{0}''. Skipping site. Exception was: {1}", site, e.toString()));
+            Logging.error(e);
         }
     }
Index: trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/ExceptionUtil.java	(revision 12620)
@@ -55,5 +55,5 @@
      */
     public static String explainOsmApiInitializationException(OsmApiInitializationException e) {
-        Main.error(e);
+        Logging.error(e);
         return tr(
                 "<html>Failed to initialize communication with the OSM server {0}.<br>"
@@ -70,5 +70,5 @@
      */
     public static String explainMissingOAuthAccessTokenException(MissingOAuthAccessTokenException e) {
-        Main.error(e);
+        Logging.error(e);
         return tr(
                 "<html>Failed to authenticate at the OSM server ''{0}''.<br>"
@@ -143,5 +143,5 @@
      */
     public static String explainPreconditionFailed(OsmApiException e) {
-        Main.error(e);
+        Logging.error(e);
         Pair<OsmPrimitive, Collection<OsmPrimitive>> conflict = parsePreconditionFailed(e.getErrorHeader());
         if (conflict != null) {
@@ -262,5 +262,5 @@
      */
     public static String explainFailedBasicAuthentication(OsmApiException e) {
-        Main.error(e);
+        Logging.error(e);
         return tr("<html>"
                 + "Authentication at the OSM server with the username ''{0}'' failed.<br>"
@@ -279,5 +279,5 @@
      */
     public static String explainFailedOAuthAuthentication(OsmApiException e) {
-        Main.error(e);
+        Logging.error(e);
         return tr("<html>"
                 + "Authentication at the OSM server with the OAuth token ''{0}'' failed.<br>"
@@ -296,5 +296,5 @@
      */
     public static String explainFailedAuthorisation(OsmApiException e) {
-        Main.error(e);
+        Logging.error(e);
         String header = e.getErrorHeader();
         String body = e.getErrorBody();
@@ -334,5 +334,5 @@
      */
     public static String explainFailedOAuthAuthorisation(OsmApiException e) {
-        Main.error(e);
+        Logging.error(e);
         return tr("<html>"
                 + "Authorisation at the OSM server with the OAuth token ''{0}'' failed.<br>"
@@ -353,5 +353,5 @@
      */
     public static String explainClientTimeout(OsmApiException e) {
-        Main.error(e);
+        Logging.error(e);
         return tr("<html>"
                 + "Communication with the OSM server ''{0}'' timed out. Please retry later."
@@ -368,5 +368,5 @@
      */
     public static String explainGenericOsmApiException(OsmApiException e) {
-        Main.error(e);
+        Logging.error(e);
         return tr("<html>"
                 + "Communication with the OSM server ''{0}''failed. The server replied<br>"
@@ -389,5 +389,5 @@
      */
     public static String explainConflict(OsmApiException e) {
-        Main.error(e);
+        Logging.error(e);
         String msg = e.getErrorHeader();
         if (msg != null) {
@@ -399,6 +399,6 @@
                     closeDate = DateUtils.newOsmApiDateTimeFormat().parse(m.group(2));
                 } catch (ParseException ex) {
-                    Main.error(tr("Failed to parse date ''{0}'' replied by server.", m.group(2)));
-                    Main.error(ex);
+                    Logging.error(tr("Failed to parse date ''{0}'' replied by server.", m.group(2)));
+                    Logging.error(ex);
                 }
                 if (closeDate == null) {
@@ -437,5 +437,5 @@
      */
     public static String explainChangesetClosedException(ChangesetClosedException e) {
-        Main.error(e);
+        Logging.error(e);
         return tr(
                 "<html>Failed to upload to changeset <strong>{0}</strong><br>"
@@ -457,5 +457,5 @@
             msg = e.toString();
         }
-        Main.error(e);
+        Logging.error(e);
         return Utils.escapeReservedCharactersHTML(msg);
     }
@@ -476,5 +476,5 @@
         } catch (MalformedURLException ex) {
             // shouldn't happen
-            Main.trace(ex);
+            Logging.trace(ex);
         }
 
@@ -493,5 +493,5 @@
      */
     public static String explainNestedSocketException(OsmTransferException e) {
-        Main.error(e);
+        Logging.error(e);
         return tr("<html>Failed to open a connection to the remote server<br>" + "''{0}''.<br>"
                 + "Please check your internet connection.", e.getUrl())+"</html>";
@@ -508,5 +508,5 @@
     public static String explainNestedIOException(OsmTransferException e) {
         IOException ioe = getNestedException(e, IOException.class);
-        Main.error(e);
+        Logging.error(e);
         return tr("<html>Failed to upload data to or download data from<br>" + "''{0}''<br>"
                 + "due to a problem with transferring data.<br>"
@@ -525,5 +525,5 @@
     public static String explainNestedIllegalDataException(OsmTransferException e) {
         IllegalDataException ide = getNestedException(e, IllegalDataException.class);
-        Main.error(e);
+        Logging.error(e);
         return tr("<html>Failed to download data. "
                 + "Its format is either unsupported, ill-formed, and/or inconsistent.<br>"
@@ -541,5 +541,5 @@
     public static String explainOfflineAccessException(OsmTransferException e) {
         OfflineAccessException oae = getNestedException(e, OfflineAccessException.class);
-        Main.error(e);
+        Logging.error(e);
         return tr("<html>Failed to download data.<br>"
                 + "<br>Details: {0}</html>", oae != null ? oae.getMessage() : "null");
@@ -554,5 +554,5 @@
      */
     public static String explainInternalServerError(OsmTransferException e) {
-        Main.error(e);
+        Logging.error(e);
         return tr("<html>The OSM server<br>" + "''{0}''<br>" + "reported an internal server error.<br>"
                 + "This is most likely a temporary problem. Please try again later.", e.getUrl())+"</html>";
@@ -576,5 +576,5 @@
             message += tr("<br>Error message(untranslated): {0}", errorHeader);
         }
-        Main.error(e);
+        Logging.error(e);
         return "<html>" + message + "</html>";
     }
@@ -588,5 +588,5 @@
      */
     public static String explainBandwidthLimitExceeded(OsmApiException e) {
-        Main.error(e);
+        Logging.error(e);
         // TODO: Write a proper error message
         return explainGenericOsmApiException(e);
@@ -605,5 +605,5 @@
                 + "it. Please carefully check the server''s address ''{0}'' for typos.",
                 getUrlFromException(e));
-        Main.error(e);
+        Logging.error(e);
         return "<html>" + message + "</html>";
     }
@@ -624,8 +624,8 @@
         } catch (MalformedURLException ex) {
             // shouldn't happen
-            Main.trace(e);
-        }
-
-        Main.error(e);
+            Logging.trace(e);
+        }
+
+        Logging.error(e);
         return tr("<html>Failed to open a connection to the remote server<br>" + "''{0}''.<br>"
                 + "Host name ''{1}'' could not be resolved. <br>"
@@ -719,5 +719,5 @@
      */
     public static String explainException(Exception e) {
-        Main.error(e);
+        Logging.error(e);
         if (e instanceof OsmTransferException) {
             return explainOsmTransferException((OsmTransferException) e);
@@ -732,5 +732,5 @@
                 return new URL(e.getAccessedUrl()).getHost();
             } catch (MalformedURLException e1) {
-                Main.warn(e1);
+                Logging.warn(e1);
             }
         }
Index: trunk/src/org/openstreetmap/josm/tools/ExifReader.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ExifReader.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/ExifReader.java	(revision 12620)
@@ -46,5 +46,5 @@
             return readTime(metadata);
         } catch (JpegProcessingException | IOException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         return null;
@@ -112,6 +112,6 @@
                         date.setTime(date.getTime() + (long) (TimeUnit.SECONDS.toMillis(1) * Double.parseDouble("0." + subSeconds)));
                     } catch (NumberFormatException e) {
-                        Main.warn("Failed parsing sub seconds from [{0}]", subSeconds);
-                        Main.warn(e);
+                        Logging.warn("Failed parsing sub seconds from [{0}]", subSeconds);
+                        Logging.warn(e);
                     }
                 }
@@ -119,5 +119,5 @@
             }
         } catch (UncheckedParseException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         return null;
@@ -146,5 +146,5 @@
             return dir == null ? null : dir.getInteger(ExifIFD0Directory.TAG_ORIENTATION);
         } catch (JpegProcessingException | IOException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         return null;
@@ -163,5 +163,5 @@
             return readLatLon(dirGps);
         } catch (JpegProcessingException | IOException | MetadataException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         return null;
@@ -197,5 +197,5 @@
             return readDirection(dirGps);
         } catch (JpegProcessingException | IOException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         return null;
@@ -255,5 +255,5 @@
             return readSpeed(dirGps);
         } catch (JpegProcessingException | IOException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         return null;
@@ -299,5 +299,5 @@
             return readElevation(dirGps);
         } catch (JpegProcessingException | IOException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         return null;
Index: trunk/src/org/openstreetmap/josm/tools/GeoUrlToBounds.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/GeoUrlToBounds.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/GeoUrlToBounds.java	(revision 12620)
@@ -41,5 +41,5 @@
                 lat = Double.parseDouble(m.group("lat"));
             } catch (NumberFormatException e) {
-                Main.warn(tr("URL does not contain valid {0}", tr("latitude")), e);
+                Logging.warn(tr("URL does not contain valid {0}", tr("latitude")), e);
                 return null;
             }
@@ -47,5 +47,5 @@
                 lon = Double.parseDouble(m.group("lon"));
             } catch (NumberFormatException e) {
-                Main.warn(tr("URL does not contain valid {0}", tr("longitude")), e);
+                Logging.warn(tr("URL does not contain valid {0}", tr("longitude")), e);
                 return null;
             }
@@ -53,5 +53,5 @@
                 zoom = m.group("zoom") != null ? Integer.parseInt(m.group("zoom")) : 18;
             } catch (NumberFormatException e) {
-                Main.warn(tr("URL does not contain valid {0}", tr("zoom")), e);
+                Logging.warn(tr("URL does not contain valid {0}", tr("zoom")), e);
                 return null;
             }
Index: trunk/src/org/openstreetmap/josm/tools/Geometry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Geometry.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/Geometry.java	(revision 12620)
@@ -932,6 +932,6 @@
             outerInner = MultipolygonBuilder.joinWays(multiPolygon);
         } catch (MultipolygonBuilder.JoinedPolygonCreationException ex) {
-            Main.trace(ex);
-            Main.debug("Invalid multipolygon " + multiPolygon);
+            Logging.trace(ex);
+            Logging.debug("Invalid multipolygon " + multiPolygon);
             return false;
         }
Index: trunk/src/org/openstreetmap/josm/tools/HttpClient.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/HttpClient.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/HttpClient.java	(revision 12620)
@@ -111,5 +111,5 @@
 
         if ("PUT".equals(requestMethod) || "POST".equals(requestMethod) || "DELETE".equals(requestMethod)) {
-            Main.info("{0} {1} ({2}) ...", requestMethod, url, Utils.getSizeString(requestBody.length, Locale.getDefault()));
+            Logging.info("{0} {1} ({2}) ...", requestMethod, url, Utils.getSizeString(requestBody.length, Locale.getDefault()));
             connection.setFixedLengthStreamingMode(requestBody.length);
             connection.setDoOutput(true);
@@ -125,5 +125,5 @@
                 connection.connect();
                 final boolean hasReason = reasonForRequest != null && !reasonForRequest.isEmpty();
-                Main.info("{0} {1}{2} -> {3}{4}",
+                Logging.info("{0} {1}{2} -> {3}{4}",
                         requestMethod, url, hasReason ? (" (" + reasonForRequest + ')') : "",
                         connection.getResponseCode(),
@@ -132,6 +132,6 @@
                                 : ""
                 );
-                if (Main.isDebugEnabled()) {
-                    Main.debug("RESPONSE: " + connection.getHeaderFields());
+                if (Logging.isDebugEnabled()) {
+                    Logging.debug("RESPONSE: {0}", connection.getHeaderFields());
                 }
                 if (DefaultAuthenticator.getInstance().isEnabled() && connection.getResponseCode() == HttpURLConnection.HTTP_UNAUTHORIZED) {
@@ -139,6 +139,6 @@
                 }
             } catch (IOException e) {
-                Main.info("{0} {1} -> !!!", requestMethod, url);
-                Main.warn(e);
+                Logging.info("{0} {1} -> !!!", requestMethod, url);
+                Logging.warn(e);
                 //noinspection ThrowableResultOfMethodCallIgnored
                 Main.addNetworkError(url, Utils.getRootCause(e));
@@ -154,5 +154,5 @@
                     url = new URL(url, redirectLocation);
                     maxRedirects--;
-                    Main.info(tr("Download redirected to ''{0}''", redirectLocation));
+                    Logging.info(tr("Download redirected to ''{0}''", redirectLocation));
                     return connect();
                 } else if (maxRedirects == 0) {
@@ -210,11 +210,11 @@
                     String content = this.fetchContent();
                     if (content.isEmpty()) {
-                        Main.debug("Server did not return any body");
+                        Logging.debug("Server did not return any body");
                     } else {
-                        Main.debug("Response body: ");
-                        Main.debug(this.fetchContent());
+                        Logging.debug("Response body: ");
+                        Logging.debug(this.fetchContent());
                     }
                 } else {
-                    Main.debug("Server returned content: {0} of length: {1}. Not printing.", contentType, this.getContentLength());
+                    Logging.debug("Server returned content: {0} of length: {1}. Not printing.", contentType, this.getContentLength());
                 }
             }
@@ -283,5 +283,5 @@
                 in = connection.getInputStream();
             } catch (IOException ioe) {
-                Main.debug(ioe);
+                Logging.debug(ioe);
                 in = Optional.ofNullable(connection.getErrorStream()).orElseGet(() -> new ByteArrayInputStream(new byte[]{}));
             }
@@ -291,5 +291,5 @@
             if (uncompress) {
                 final String contentType = getContentType();
-                Main.debug("Uncompressing input stream according to Content-Type header: {0}", contentType);
+                Logging.debug("Uncompressing input stream according to Content-Type header: {0}", contentType);
                 compression = Compression.forContentType(contentType);
             }
@@ -299,5 +299,5 @@
                         contentDisposition != null ? contentDisposition : "");
                 if (matcher.find()) {
-                    Main.debug("Uncompressing input stream according to Content-Disposition header: {0}", contentDisposition);
+                    Logging.debug("Uncompressing input stream according to Content-Disposition header: {0}", contentDisposition);
                     compression = Compression.byExtension(matcher.group(1));
                 }
@@ -661,5 +661,5 @@
                 Thread.sleep(100);
             } catch (InterruptedException ex) {
-                Main.warn("InterruptedException in " + HttpClient.class + " during cancel");
+                Logging.warn("InterruptedException in " + HttpClient.class + " during cancel");
                 Thread.currentThread().interrupt();
             }
Index: trunk/src/org/openstreetmap/josm/tools/I18n.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/I18n.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/I18n.java	(revision 12620)
@@ -487,5 +487,5 @@
         } catch (IOException e) {
             // Ignore
-            Main.trace(e);
+            Logging.trace(e);
         }
     }
@@ -517,5 +517,5 @@
         } catch (IOException e) {
             // Ignore exception
-            Main.trace(e);
+            Logging.trace(e);
         }
         return false;
@@ -643,5 +643,5 @@
             }
         } catch (IOException e) {
-            Main.trace(e);
+            Logging.trace(e);
             return false;
         }
@@ -670,5 +670,5 @@
             } else {
                 if (!"en".equals(l.getLanguage())) {
-                    Main.info(tr("Unable to find translation for the locale {0}. Reverting to {1}.",
+                    Logging.info(tr("Unable to find translation for the locale {0}. Reverting to {1}.",
                             LanguageInfo.getDisplayName(l), LanguageInfo.getDisplayName(Locale.getDefault())));
                 } else {
Index: trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/ImageProvider.java	(revision 12620)
@@ -642,5 +642,5 @@
             } else {
                 if (!suppressWarnings) {
-                    Main.error(tr("Failed to locate image ''{0}''", name));
+                    Logging.error(tr("Failed to locate image ''{0}''", name));
                 }
                 return null;
@@ -917,5 +917,5 @@
                     img = read(Utils.fileToURL(cf.getFile()), false, false);
                 } catch (IOException e) {
-                    Main.warn(e, "IOException while reading HTTP image:");
+                    Logging.log(Logging.LEVEL_WARN, "IOException while reading HTTP image:", e);
                 }
                 return img == null ? null : new ImageResource(img);
@@ -924,5 +924,5 @@
             }
         } catch (IOException e) {
-            Main.debug(e);
+            Logging.debug(e);
             return null;
         }
@@ -947,5 +947,5 @@
                     bytes = Utils.decodeUrl(data).getBytes(StandardCharsets.UTF_8);
                 } catch (IllegalArgumentException ex) {
-                    Main.warn(ex, "Unable to decode URL data part: "+ex.getMessage() + " (" + data + ')');
+                    Logging.log(Logging.LEVEL_WARN, "Unable to decode URL data part: "+ex.getMessage() + " (" + data + ')', ex);
                     return null;
                 }
@@ -960,5 +960,5 @@
                 }
                 if (svg == null) {
-                    Main.warn("Unable to process svg: "+s);
+                    Logging.warn("Unable to process svg: "+s);
                     return null;
                 }
@@ -974,5 +974,5 @@
                     return img == null ? null : new ImageResource(img);
                 } catch (IOException e) {
-                    Main.warn(e, "IOException while reading image:");
+                    Logging.log(Logging.LEVEL_WARN, "IOException while reading image:", e);
                 }
             }
@@ -1059,5 +1059,5 @@
                             img = read(new ByteArrayInputStream(buf), false, false);
                         } catch (IOException e) {
-                            Main.warn(e);
+                            Logging.warn(e);
                         }
                         return img == null ? null : new ImageResource(img);
@@ -1068,5 +1068,5 @@
             }
         } catch (IOException e) {
-            Main.warn(e, tr("Failed to handle zip file ''{0}''. Exception was: {1}", archive.getName(), e.toString()));
+            Logging.log(Logging.LEVEL_WARN, tr("Failed to handle zip file ''{0}''. Exception was: {1}", archive.getName(), e.toString()), e);
         }
         return null;
@@ -1096,9 +1096,9 @@
                 // hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/dc4322602480/src/share/classes/com/sun/imageio/plugins/png/PNGImageReader.java#l656
                 img = read(path, false, true);
-                if (Main.isDebugEnabled() && isTransparencyForced(img)) {
-                    Main.debug("Transparency has been forced for image "+path.toExternalForm());
+                if (Logging.isDebugEnabled() && isTransparencyForced(img)) {
+                    Logging.debug("Transparency has been forced for image {0}", path);
                 }
             } catch (IOException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
             return img == null ? null : new ImageResource(img);
@@ -1139,7 +1139,7 @@
                         return u;
                 } catch (SecurityException e) {
-                    Main.warn(e, tr(
+                    Logging.log(Logging.LEVEL_WARN, tr(
                             "Failed to access directory ''{0}'' for security reasons. Exception was: {1}",
-                            name, e.toString()));
+                            name, e.toString()), e);
                 }
 
@@ -1154,7 +1154,7 @@
                     return u;
             } catch (SecurityException e) {
-                Main.warn(e, tr(
+                Logging.log(Logging.LEVEL_WARN, tr(
                         "Failed to access directory ''{0}'' for security reasons. Exception was: {1}", dir, e
-                        .toString()));
+                        .toString()), e);
             }
         }
@@ -1226,11 +1226,11 @@
             }
         } catch (SAXReturnException e) {
-            Main.trace(e);
+            Logging.trace(e);
             return e.getResult();
         } catch (IOException | SAXException | ParserConfigurationException e) {
-            Main.warn("Parsing " + base + fn + " failed:\n" + e);
+            Logging.warn("Parsing " + base + fn + " failed:\n" + e);
             return null;
         }
-        Main.warn("Parsing " + base + fn + " failed: Unexpected content.");
+        Logging.warn("Parsing " + base + fn + " failed: Unexpected content.");
         return null;
     }
@@ -1251,7 +1251,5 @@
         }
         if (GraphicsEnvironment.isHeadless()) {
-            if (Main.isDebugEnabled()) {
-                Main.debug("Cursors are not available in headless mode. Returning null for '"+name+'\'');
-            }
+            Logging.debug("Cursors are not available in headless mode. Returning null for '{0}'", name);
             return null;
         }
@@ -1465,6 +1463,6 @@
      */
     public static BufferedImage createImageFromSvg(SVGDiagram svg, Dimension dim) {
-        if (Main.isTraceEnabled()) {
-            Main.trace(String.format("createImageFromSvg: %s %s", svg.getXMLBase(), dim));
+        if (Logging.isTraceEnabled()) {
+            Logging.trace("createImageFromSvg: {0} {1}", svg.getXMLBase(), dim);
         }
         float sourceWidth = svg.getWidth();
@@ -1504,5 +1502,5 @@
             }
         } catch (SVGException ex) {
-            Main.error(ex, "Unable to load svg:");
+            Logging.log(Logging.LEVEL_ERROR, "Unable to load svg:", ex);
             return null;
         }
@@ -1724,7 +1722,5 @@
                     bi = new BufferedImage(bi.getColorModel(), bi.getRaster(), bi.isAlphaPremultiplied(), properties);
                     if (enforceTransparency) {
-                        if (Main.isTraceEnabled()) {
-                            Main.trace("Enforcing image transparency of "+stream+" for "+color);
-                        }
+                        Logging.trace("Enforcing image transparency of {0} for {1}", stream, color);
                         bi = makeImageTransparent(bi, color);
                     }
@@ -1734,5 +1730,5 @@
             // On Windows, ComponentColorModel.getRGBComponent can fail with "UnsatisfiedLinkError: no awt in java.library.path", see #13973
             // Then it can leads to "NoClassDefFoundError: Could not initialize class sun.awt.image.ShortInterleavedRaster", see #15079
-            Main.error(e);
+            Logging.error(e);
         } finally {
             reader.dispose();
@@ -1781,5 +1777,5 @@
                                                 return new Color(r, g, b);
                                             } else {
-                                                Main.warn("Unable to translate TransparentColor '"+value+"' with color model "+model);
+                                                Logging.warn("Unable to translate TransparentColor '"+value+"' with color model "+model);
                                             }
                                         }
@@ -1794,5 +1790,5 @@
         } catch (IIOException | NumberFormatException e) {
             // JAI doesn't like some JPEG files with error "Inconsistent metadata read from stream" (see #10267)
-            Main.warn(e);
+            Logging.warn(e);
         }
         return null;
@@ -1807,5 +1803,5 @@
             return new Color(rgb[0], rgb[1], rgb[2]);
         } catch (IllegalArgumentException e) {
-            Main.error(e);
+            Logging.error(e);
             return null;
         }
Index: trunk/src/org/openstreetmap/josm/tools/ImageWarp.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ImageWarp.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/ImageWarp.java	(revision 12620)
@@ -63,5 +63,5 @@
             this.stride = stride;
             this.cache = new HashMap<>();
-            this.consistencyTest = Main.isDebugEnabled();
+            this.consistencyTest = Logging.isDebugEnabled();
             if (consistencyTest) {
                 deletedRows = new HashSet<>();
Index: trunk/src/org/openstreetmap/josm/tools/ListenerList.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/ListenerList.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/ListenerList.java	(revision 12620)
@@ -200,5 +200,5 @@
         @Override
         protected void failAdd(T listener) {
-            Main.trace("Previous addition of the listener");
+            Logging.trace("Previous addition of the listener");
             dumpStack(listenersAdded.get(listener));
             super.failAdd(listener);
@@ -207,5 +207,5 @@
         @Override
         protected void failRemove(T listener) {
-            Main.trace("Previous removal of the listener");
+            Logging.trace("Previous removal of the listener");
             dumpStack(listenersRemoved.get(listener));
             super.failRemove(listener);
@@ -214,8 +214,8 @@
         private static void dumpStack(StackTraceElement ... stackTraceElements) {
             if (stackTraceElements == null) {
-                Main.trace("  - (no trace recorded)");
+                Logging.trace("  - (no trace recorded)");
             } else {
                 Stream.of(stackTraceElements).limit(20).forEach(
-                        e -> Main.trace(e.getClassName() + "." + e.getMethodName() + " line " + e.getLineNumber()));
+                        e -> Logging.trace(e.getClassName() + "." + e.getMethodName() + " line " + e.getLineNumber()));
             }
         }
@@ -242,5 +242,5 @@
      */
     public static <T> ListenerList<T> create() {
-        if (Main.isTraceEnabled()) {
+        if (Logging.isTraceEnabled()) {
             return new TracingListenerList<>();
         } else {
Index: trunk/src/org/openstreetmap/josm/tools/Logging.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Logging.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/Logging.java	(revision 12620)
@@ -113,4 +113,13 @@
 
     /**
+     * Prints an error message for the given Throwable if logging is on.
+     * @param t The throwable object causing the error.
+     * @since 12620
+     */
+    public static void error(Throwable t) {
+        logWithStackTrace(Logging.LEVEL_ERROR, t);
+    }
+
+    /**
      * Prints a warning message if logging is on.
      * @param message The message to print.
@@ -131,4 +140,13 @@
 
     /**
+     * Prints a warning message for the given Throwable if logging is on.
+     * @param t The throwable object causing the error.
+     * @since 12620
+     */
+    public static void warn(Throwable t) {
+        logWithStackTrace(Logging.LEVEL_WARN, t);
+    }
+
+    /**
      * Prints a info message if logging is on.
      * @param message The message to print.
@@ -149,4 +167,13 @@
 
     /**
+     * Prints a info message for the given Throwable if logging is on.
+     * @param t The throwable object causing the error.
+     * @since 12620
+     */
+    public static void info(Throwable t) {
+        logWithStackTrace(Logging.LEVEL_INFO, t);
+    }
+
+    /**
      * Prints a debug message if logging is on.
      * @param message The message to print.
@@ -167,4 +194,13 @@
 
     /**
+     * Prints a debug message for the given Throwable if logging is on.
+     * @param t The throwable object causing the error.
+     * @since 12620
+     */
+    public static void debug(Throwable t) {
+        logWithStackTrace(Logging.LEVEL_DEBUG, t);
+    }
+
+    /**
      * Prints a trace message if logging is on.
      * @param message The message to print.
@@ -185,7 +221,17 @@
 
     /**
-     * Logs a throwable that happened.
+     * Prints a trace message for the given Throwable if logging is on.
+     * @param t The throwable object causing the error.
+     * @since 12620
+     */
+    public static void trace(Throwable t) {
+        logWithStackTrace(Logging.LEVEL_TRACE, t);
+    }
+
+    /**
+     * Logs a throwable that happened. The stack trace is not added to the log.
      * @param level The level.
      * @param t The throwable that should be logged.
+     * @see #logWithStackTrace(Level, Throwable)
      */
     public static void log(Level level, Throwable t) {
@@ -194,8 +240,9 @@
 
     /**
-     * Logs a throwable that happened.
+     * Logs a throwable that happened. The stack trace is not added to the log.
      * @param level The level.
      * @param message An additional error message
      * @param t The throwable that caused the message
+     * @see #logWithStackTrace(Level, String, Throwable)
      */
     public static void log(Level level, String message, Throwable t) {
@@ -207,4 +254,5 @@
      * @param level The level.
      * @param t The throwable that should be logged.
+     * @see #log(Level, Throwable)
      */
     public static void logWithStackTrace(Level level, Throwable t) {
@@ -217,4 +265,5 @@
      * @param message An additional error message
      * @param t The throwable that should be logged.
+     * @see #logWithStackTrace(Level, Throwable)
      */
     public static void logWithStackTrace(Level level, String message, Throwable t) {
@@ -231,5 +280,5 @@
 
     private static void logPrivate(Level level, Supplier<String> supplier) {
-        // all log methods immeadiately call one of the logPrivate methods.
+        // all log methods immediately call one of the logPrivate methods.
         if (LOGGER.isLoggable(level)) {
             StackTraceElement callingMethod = BugReport.getCallingMethod(1, Logging.class.getName(), name -> !"logPrivate".equals(name));
@@ -242,9 +291,29 @@
      *
      * For formatting text, you should use the {@link #debug(String, Object...)} message
-     * @param level A lvele constant. You can e.g. use {@link Logging#LEVEL_ERROR}
-     * @return <code>true</code> if debug is enabled.
+     * @param level A level constant. You can e.g. use {@link Logging#LEVEL_ERROR}
+     * @return <code>true</code> if log level is enabled.
      */
     public static boolean isLoggingEnabled(Level level) {
         return LOGGER.isLoggable(level);
+    }
+
+    /**
+     * Determines if debug log level is enabled.
+     * Useful to avoid costly construction of debug messages when not enabled.
+     * @return {@code true} if log level is at least debug, {@code false} otherwise
+     * @since 12620
+     */
+    public static boolean isDebugEnabled() {
+        return isLoggingEnabled(Logging.LEVEL_DEBUG);
+    }
+
+    /**
+     * Determines if trace log level is enabled.
+     * Useful to avoid costly construction of trace messages when not enabled.
+     * @return {@code true} if log level is at least trace, {@code false} otherwise
+     * @since 12620
+     */
+    public static boolean isTraceEnabled() {
+        return isLoggingEnabled(Logging.LEVEL_TRACE);
     }
 
Index: trunk/src/org/openstreetmap/josm/tools/MemoryManager.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/MemoryManager.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/MemoryManager.java	(revision 12620)
@@ -52,5 +52,5 @@
                 throw new IllegalArgumentException("Factory did not return a content element.");
             }
-            Main.info(MessageFormat.format("Allocate for {0}: {1} MB of memory. Available: {2} MB.",
+            Logging.info(MessageFormat.format("Allocate for {0}: {1} MB of memory. Available: {2} MB.",
                     name, maxBytes / 1024 / 1024, getAvailableMemory() / 1024 / 1024));
             MemoryHandle<T> handle = new ManualFreeMemoryHandle<>(name, content, maxBytes);
Index: trunk/src/org/openstreetmap/josm/tools/OpenBrowser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/OpenBrowser.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/OpenBrowser.java	(revision 12620)
@@ -41,5 +41,5 @@
         CheckParameterUtil.ensureParameterNotNull(uri, "uri");
 
-        Main.info(tr("Opening URL: {0}", uri));
+        Logging.info(tr("Opening URL: {0}", uri));
 
         if (Desktop.isDesktopSupported()) {
@@ -59,18 +59,18 @@
                         // Workaround for KDE (Desktop API is severely flawed)
                         // see https://bugs.openjdk.java.net/browse/JDK-6486393
-                        Main.warn(e, "Desktop class failed. Platform dependent fall back for open url in browser.");
+                        Logging.log(Logging.LEVEL_WARN, "Desktop class failed. Platform dependent fall back for open url in browser.", e);
                         displayUrlFallback(uri);
                     }
                 }
             } catch (IOException e) {
-                Main.warn(e);
+                Logging.warn(e);
                 return e.getMessage();
             }
         } else {
             try {
-                Main.warn("Desktop class is not supported. Platform dependent fall back for open url in browser.");
+                Logging.warn("Desktop class is not supported. Platform dependent fall back for open url in browser.");
                 displayUrlFallback(uri);
             } catch (IOException e) {
-                Main.debug(e);
+                Logging.debug(e);
                 return e.getMessage();
             }
@@ -91,5 +91,5 @@
             return displayUrl(new URI(url));
         } catch (URISyntaxException e) {
-            Main.debug(e);
+            Logging.debug(e);
             return e.getMessage();
         }
Index: trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/OsmUrlToBounds.java	(revision 12620)
@@ -42,5 +42,5 @@
             }
         } catch (IllegalArgumentException ex) {
-            Main.error(ex);
+            Logging.error(ex);
         }
         Bounds b = parseShortLink(url);
@@ -82,5 +82,5 @@
             }
         } catch (IllegalArgumentException | ArrayIndexOutOfBoundsException ex) {
-            Main.error(ex, url);
+            Logging.log(Logging.LEVEL_ERROR, url, ex);
         }
         return b;
@@ -102,5 +102,5 @@
         String[] parts = coordPart.split("/");
         if (parts.length < 3) {
-            Main.warn(tr("URL does not contain {0}/{1}/{2}", tr("zoom"), tr("latitude"), tr("longitude")));
+            Logging.warn(tr("URL does not contain {0}/{1}/{2}", tr("zoom"), tr("latitude"), tr("longitude")));
             return null;
         }
@@ -109,5 +109,5 @@
             zoom = Integer.parseInt(parts[0]);
         } catch (NumberFormatException e) {
-            Main.warn(tr("URL does not contain valid {0}", tr("zoom")), e);
+            Logging.warn(tr("URL does not contain valid {0}", tr("zoom")), e);
             return null;
         }
@@ -116,5 +116,5 @@
             lat = Double.parseDouble(parts[1]);
         } catch (NumberFormatException e) {
-            Main.warn(tr("URL does not contain valid {0}", tr("latitude")), e);
+            Logging.warn(tr("URL does not contain valid {0}", tr("latitude")), e);
             return null;
         }
@@ -122,5 +122,5 @@
             lon = Double.parseDouble(parts[2]);
         } catch (NumberFormatException e) {
-            Main.warn(tr("URL does not contain valid {0}", tr("longitude")), e);
+            Logging.warn(tr("URL does not contain valid {0}", tr("longitude")), e);
             return null;
         }
Index: trunk/src/org/openstreetmap/josm/tools/PlatformHook.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/PlatformHook.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/PlatformHook.java	(revision 12620)
@@ -281,5 +281,5 @@
                     openUrl(url);
                 } catch (IOException e) {
-                    Main.warn(e);
+                    Logging.warn(e);
                 }
             }
Index: trunk/src/org/openstreetmap/josm/tools/PlatformHookOsx.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/PlatformHookOsx.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/PlatformHookOsx.java	(revision 12620)
@@ -75,5 +75,5 @@
         } catch (ReflectiveOperationException | SecurityException | IllegalArgumentException ex) {
             // We'll just ignore this for now. The user will still be able to close JOSM by closing all its windows.
-            Main.warn("Failed to register with OSX: " + ex);
+            Logging.warn("Failed to register with OSX: " + ex);
         }
         checkExpiredJava();
@@ -113,5 +113,5 @@
             return Class.forName("com.apple.eawt."+className);
         } catch (ClassNotFoundException e) {
-            Main.trace(e);
+            Logging.trace(e);
             // Java 9 handlers
             return Class.forName("java.awt.desktop."+className);
@@ -132,5 +132,5 @@
                     Window.class, boolean.class).invoke(eawtFullScreenUtilities, window, Boolean.TRUE);
         } catch (ReflectiveOperationException | SecurityException | IllegalArgumentException e) {
-            Main.warn("Failed to register with OSX: " + e);
+            Logging.warn("Failed to register with OSX: " + e);
         }
     }
@@ -139,6 +139,6 @@
     @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-        if (Main.isDebugEnabled()) {
-            Main.debug("OSX handler: "+method.getName()+" - "+Arrays.toString(args));
+        if (Logging.isDebugEnabled()) {
+            Logging.debug("OSX handler: {0} - {1}", method.getName(), Arrays.toString(args));
         }
         switch (method.getName()) {
@@ -156,5 +156,5 @@
                                         Thread.sleep(25);
                                     } catch (InterruptedException e) {
-                                        Main.warn(e);
+                                        Logging.warn(e);
                                         Thread.currentThread().interrupt();
                                     }
@@ -165,5 +165,5 @@
                     }
                 } catch (ReflectiveOperationException | SecurityException | IllegalArgumentException ex) {
-                    Main.warn("Failed to access open files event: " + ex);
+                    Logging.warn("Failed to access open files event: " + ex);
                 }
             }
@@ -175,5 +175,5 @@
                     args[1].getClass().getDeclaredMethod(closed ? "performQuit" : "cancelQuit").invoke(args[1]);
                 } catch (IllegalAccessException e) {
-                    Main.debug(e);
+                    Logging.debug(e);
                     // with Java 9, module java.desktop does not export com.apple.eawt, use new Desktop API instead
                     Class.forName("java.awt.desktop.QuitResponse").getMethod(closed ? "performQuit" : "cancelQuit").invoke(args[1]);
@@ -188,5 +188,5 @@
             break;
         default:
-            Main.warn("OSX unsupported method: "+method.getName());
+            Logging.warn("OSX unsupported method: "+method.getName());
         }
         return null;
@@ -399,5 +399,5 @@
               .append(')');
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         return sb.toString();
Index: trunk/src/org/openstreetmap/josm/tools/PlatformHookUnixoid.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/PlatformHookUnixoid.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/PlatformHookUnixoid.java	(revision 12620)
@@ -90,5 +90,5 @@
                 return;
             } catch (IOException | URISyntaxException e) {
-                Main.warn(e);
+                Logging.warn(e);
             }
         }
@@ -125,5 +125,5 @@
         } catch (IOException e) {
             // lsb_release is not available on all Linux systems, so don't log at warning level
-            Main.debug(e);
+            Logging.debug(e);
             return false;
         }
@@ -164,5 +164,5 @@
             }
         } catch (IOException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
         return null;
@@ -241,5 +241,5 @@
                 }
             } catch (IOException e) {
-                Main.debug(e);
+                Logging.debug(e);
                 // Non LSB-compliant Linux system. List of common fallback release files: http://linuxmafia.com/faq/Admin/release-files.html
                 for (LinuxReleaseInfo info : new LinuxReleaseInfo[]{
@@ -343,5 +343,5 @@
                     } catch (IOException e) {
                         // Ignore
-                        Main.trace(e);
+                        Logging.trace(e);
                     }
                 }
Index: trunk/src/org/openstreetmap/josm/tools/PlatformHookWindows.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/PlatformHookWindows.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/PlatformHookWindows.java	(revision 12620)
@@ -177,5 +177,5 @@
                 }
             } catch (NumberFormatException | ReflectiveOperationException e) {
-                Main.error(e);
+                Logging.error(e);
             }
         }
@@ -304,5 +304,5 @@
             sb.append(" (").append(getCurrentBuild()).append(')');
         } catch (ReflectiveOperationException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         return sb.toString();
@@ -346,5 +346,5 @@
             insecurePubKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(INSECURE_PUBLIC_KEY));
         } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
-            Main.error(e);
+            Logging.error(e);
             return;
         }
@@ -362,6 +362,6 @@
                 } catch (InvalidKeyException | NoSuchProviderException | SignatureException e) {
                     // If exception this is not a certificate related to JOSM, just trace it
-                    Main.trace(alias + " --> " + e.getClass().getName());
-                    Main.trace(e);
+                    Logging.trace(alias + " --> " + e.getClass().getName());
+                    Logging.trace(e);
                 }
             }
@@ -385,9 +385,9 @@
             JOptionPane.showMessageDialog(Main.parent, message.toString(), tr("Warning"), JOptionPane.WARNING_MESSAGE);
             for (String alias : insecureCertificates) {
-                Main.warn(tr("Removing insecure certificate from {0} keystore: {1}", WINDOWS_ROOT, alias));
+                Logging.warn(tr("Removing insecure certificate from {0} keystore: {1}", WINDOWS_ROOT, alias));
                 try {
                     ks.deleteEntry(alias);
                 } catch (KeyStoreException e) {
-                    Main.error(e, tr("Unable to remove insecure certificate from keystore: {0}", e.getMessage()));
+                    Logging.log(Logging.LEVEL_ERROR, tr("Unable to remove insecure certificate from keystore: {0}", e.getMessage()), e);
                 }
             }
@@ -404,10 +404,10 @@
             if (alias != null) {
                 // JOSM certificate found, return
-                Main.debug(tr("JOSM localhost certificate found in {0} keystore: {1}", WINDOWS_ROOT, alias));
+                Logging.debug(tr("JOSM localhost certificate found in {0} keystore: {1}", WINDOWS_ROOT, alias));
                 return false;
             }
         } catch (ArrayIndexOutOfBoundsException e) {
             // catch error of JDK-8172244 as bug seems to not be fixed anytime soon
-            Main.error(e, "JDK-8172244 occured. Abort HTTPS setup");
+            Logging.log(Logging.LEVEL_ERROR, "JDK-8172244 occured. Abort HTTPS setup", e);
             return false;
         }
@@ -425,5 +425,5 @@
         }
         // install it to Windows-ROOT keystore, used by IE, Chrome and Safari, but not by Firefox
-        Main.info(tr("Adding JOSM localhost certificate to {0} keystore", WINDOWS_ROOT));
+        Logging.info(tr("Adding JOSM localhost certificate to {0} keystore", WINDOWS_ROOT));
         ks.setEntry(entryAlias, trustedCert, null);
         return true;
@@ -508,5 +508,5 @@
         Path templateFile = FileSystems.getDefault().getPath(javaLibPath, templateFileName);
         if (!Files.isReadable(templateFile)) {
-            Main.warn("extended font config - unable to find font config template file {0}", templateFile.toString());
+            Logging.warn("extended font config - unable to find font config template file {0}", templateFile.toString());
             return;
         }
@@ -532,9 +532,9 @@
                             extras.add(entry);
                         } else {
-                            Main.trace("extended font config - already registered font for charset ''{0}'' - skipping ''{1}''",
+                            Logging.trace("extended font config - already registered font for charset ''{0}'' - skipping ''{1}''",
                                     entry.charset, entry.name);
                         }
                     } else {
-                        Main.trace("extended font config - Font ''{0}'' not found on system - skipping", entry.name);
+                        Logging.trace("extended font config - Font ''{0}'' not found on system - skipping", entry.name);
                     }
                 }
@@ -548,5 +548,5 @@
                     String prevValue = props.getProperty(key);
                     if (prevValue != null && !prevValue.equals(value)) {
-                        Main.warn("extended font config - overriding ''{0}={1}'' with ''{2}''", key, prevValue, value);
+                        Logging.warn("extended font config - overriding ''{0}={1}'' with ''{2}''", key, prevValue, value);
                     }
                     w.append(key + '=' + value + '\n');
@@ -561,5 +561,5 @@
                     String prevValue = props.getProperty(key);
                     if (prevValue != null && !prevValue.equals(value)) {
-                        Main.warn("extended font config - overriding ''{0}={1}'' with ''{2}''", key, prevValue, value);
+                        Logging.warn("extended font config - overriding ''{0}={1}'' with ''{2}''", key, prevValue, value);
                     }
                     w.append(key + '=' + value + '\n');
@@ -575,5 +575,5 @@
             Utils.updateSystemProperty("sun.awt.fontconfig", fontconfigFile.toString());
         } catch (IOException ex) {
-            Main.error(ex);
+            Logging.error(ex);
         }
     }
@@ -603,6 +603,6 @@
             fontsAvail.add(""); // for devanagari
         } catch (IOException ex) {
-            Main.error(ex, false);
-            Main.warn("extended font config - failed to load available Fonts");
+            Logging.log(Logging.LEVEL_ERROR, ex);
+            Logging.warn("extended font config - failed to load available Fonts");
             fontsAvail = null;
         }
Index: trunk/src/org/openstreetmap/josm/tools/RightAndLefthandTraffic.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/RightAndLefthandTraffic.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/RightAndLefthandTraffic.java	(revision 12620)
@@ -117,13 +117,13 @@
                 }
             } catch (UserCancelException ex) {
-                Main.warn(ex);
+                Logging.warn(ex);
             } catch (JosmRuntimeException ex) {
                 // Workaround to #10511 / #14185. To remove when #10511 is solved
-                Main.error(ex);
+                Logging.error(ex);
             }
         }
         if (optimizedWays.isEmpty()) {
             // Problem: don't optimize
-            Main.warn("Unable to join left-driving countries polygons");
+            Logging.warn("Unable to join left-driving countries polygons");
             optimizedWays.addAll(ways);
         }
@@ -142,6 +142,6 @@
             if (r.isMultipolygon() && LEFT.equals(r.get(DRIVING_SIDE)) &&
                 "inner".equals(r.getMembersFor(s).iterator().next().getRole())) {
-                if (Main.isDebugEnabled()) {
-                    Main.debug("Skipping " + w.get("name:en") + " because inner part of " + r.get("name:en"));
+                if (Logging.isDebugEnabled()) {
+                    Logging.debug("Skipping {0} because inner part of {1}", w.get("name:en"), r.get("name:en"));
                 }
                 return;
@@ -169,5 +169,5 @@
            return OsmReader.parseDataSet(is, null).getWays();
         } catch (IllegalDataException | IOException ex) {
-            Main.trace(ex);
+            Logging.trace(ex);
             return Collections.emptyList();
         }
Index: trunk/src/org/openstreetmap/josm/tools/Shortcut.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Shortcut.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/Shortcut.java	(revision 12620)
@@ -286,7 +286,7 @@
         public boolean add(Shortcut shortcut) {
             // expensive consistency check only in debug mode
-            if (Main.isDebugEnabled()
+            if (Logging.isDebugEnabled()
                     && stream().map(Shortcut::getShortText).anyMatch(shortcut.getShortText()::equals)) {
-                Main.warn(new AssertionError(shortcut.getShortText() + " already added"));
+                Logging.warn(new AssertionError(shortcut.getShortText() + " already added"));
             }
             return super.add(shortcut);
@@ -430,5 +430,5 @@
         } else if (existing.isPresent()) {
             // this always is a logic error in the hook
-            Main.error("CONFLICT WITH SYSTEM KEY " + shortText + ": " + existing.get());
+            Logging.error("CONFLICT WITH SYSTEM KEY " + shortText + ": " + existing.get());
             return null;
         }
@@ -475,5 +475,5 @@
                 int newmodifier = findNewOsxModifier(requestedGroup);
                 if (!findShortcut(requestedKey, newmodifier).isPresent()) {
-                    Main.info("Reassigning OSX shortcut '" + shortText + "' from Meta to Ctrl because of conflict with " + conflict);
+                    Logging.info("Reassigning OSX shortcut '" + shortText + "' from Meta to Ctrl because of conflict with " + conflict);
                     return reassignShortcut(shortText, longText, requestedKey, conflict, requestedGroup, requestedKey, newmodifier);
                 }
@@ -483,5 +483,5 @@
                     int newmodifier = getGroupModifier(m);
                     if (!findShortcut(k, newmodifier).isPresent()) {
-                        Main.info("Reassigning shortcut '" + shortText + "' from " + modifier + " to " + newmodifier +
+                        Logging.info("Reassigning shortcut '" + shortText + "' from " + modifier + " to " + newmodifier +
                                 " because of conflict with " + conflict);
                         return reassignShortcut(shortText, longText, requestedKey, conflict, m, k, newmodifier);
@@ -512,5 +512,5 @@
             int m, int k, int newmodifier) {
         Shortcut newsc = new Shortcut(shortText, longText, requestedKey, m, k, newmodifier, false, false);
-        Main.info(tr("Silent shortcut conflict: ''{0}'' moved by ''{1}'' to ''{2}''.",
+        Logging.info(tr("Silent shortcut conflict: ''{0}'' moved by ''{1}'' to ''{2}''.",
             shortText, conflict.getShortText(), newsc.getKeyText()));
         newsc.saveDefault();
Index: trunk/src/org/openstreetmap/josm/tools/Territories.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Territories.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/Territories.java	(revision 12620)
@@ -62,5 +62,5 @@
         GeoPropertyIndex<Boolean> gpi = iso3166Cache.get(code);
         if (gpi == null) {
-            Main.warn(tr("Unknown territory id: {0}", code));
+            Logging.warn(tr("Unknown territory id: {0}", code));
             return false;
         }
Index: trunk/src/org/openstreetmap/josm/tools/Utils.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/Utils.java	(revision 12620)
@@ -405,5 +405,5 @@
         CheckParameterUtil.ensureParameterNotNull(out, "out");
         if (!out.exists() && !out.mkdirs()) {
-            Main.warn("Unable to create directory "+out.getPath());
+            Logging.warn("Unable to create directory "+out.getPath());
         }
         File[] files = in.listFiles();
@@ -477,5 +477,5 @@
         boolean result = file.delete();
         if (!result) {
-            Main.warn(tr(warnMsg, file.getPath()));
+            Logging.warn(tr(warnMsg, file.getPath()));
         }
         return result;
@@ -503,5 +503,5 @@
         boolean result = dir.mkdirs();
         if (!result) {
-            Main.warn(tr(warnMsg, dir.getPath()));
+            Logging.warn(tr(warnMsg, dir.getPath()));
         }
         return result;
@@ -518,5 +518,5 @@
             c.close();
         } catch (IOException e) {
-            Main.warn(e);
+            Logging.warn(e);
         }
     }
@@ -542,5 +542,5 @@
                 return f.toURI().toURL();
             } catch (MalformedURLException ex) {
-                Main.error("Unable to convert filename " + f.getAbsolutePath() + " to URL");
+                Logging.error("Unable to convert filename " + f.getAbsolutePath() + " to URL");
             }
         }
@@ -763,6 +763,6 @@
         // Positions the stream at the beginning of first entry
         ZipEntry ze = zis.getNextEntry();
-        if (ze != null && Main.isDebugEnabled()) {
-            Main.debug("Zip entry: "+ze.getName());
+        if (ze != null && Logging.isDebugEnabled()) {
+            Logging.debug("Zip entry: {0}", ze.getName());
         }
         return zis;
@@ -878,6 +878,6 @@
      */
     public static String execOutput(List<String> command) throws IOException {
-        if (Main.isDebugEnabled()) {
-            Main.debug(join(" ", command));
+        if (Logging.isDebugEnabled()) {
+            Logging.debug(join(" ", command));
         }
         Process p = new ProcessBuilder(command).start();
@@ -909,5 +909,5 @@
         File josmTmpDir = new File(tmpDir, "JOSM");
         if (!josmTmpDir.exists() && !josmTmpDir.mkdirs()) {
-            Main.warn("Unable to create temp directory " + josmTmpDir);
+            Logging.warn("Unable to create temp directory " + josmTmpDir);
         }
         return josmTmpDir;
@@ -1216,5 +1216,5 @@
                 return true;
             } catch (MalformedURLException e) {
-                Main.trace(e);
+                Logging.trace(e);
             }
         }
@@ -1279,9 +1279,9 @@
         if (value != null) {
             String old = System.setProperty(key, value);
-            if (Main.isDebugEnabled() && !value.equals(old)) {
+            if (Logging.isDebugEnabled() && !value.equals(old)) {
                 if (!key.toLowerCase(Locale.ENGLISH).contains("password")) {
-                    Main.debug("System property '" + key + "' set to '" + value + "'. Old value was '" + old + '\'');
+                    Logging.debug("System property '" + key + "' set to '" + value + "'. Old value was '" + old + '\'');
                 } else {
-                    Main.debug("System property '" + key + "' changed.");
+                    Logging.debug("System property '" + key + "' changed.");
                 }
             }
@@ -1318,10 +1318,8 @@
     public static Document parseSafeDOM(InputStream is) throws ParserConfigurationException, IOException, SAXException {
         long start = System.currentTimeMillis();
-        if (Main.isDebugEnabled()) {
-            Main.debug("Starting DOM parsing of " + is);
-        }
+        Logging.debug("Starting DOM parsing of {0}", is);
         Document result = newSafeDOMBuilder().parse(is);
-        if (Main.isDebugEnabled()) {
-            Main.debug("DOM parsing done in " + getDurationString(System.currentTimeMillis() - start));
+        if (Logging.isDebugEnabled()) {
+            Logging.debug("DOM parsing done in {0}", getDurationString(System.currentTimeMillis() - start));
         }
         return result;
@@ -1355,10 +1353,8 @@
     public static void parseSafeSAX(InputSource is, DefaultHandler dh) throws ParserConfigurationException, SAXException, IOException {
         long start = System.currentTimeMillis();
-        if (Main.isDebugEnabled()) {
-            Main.debug("Starting SAX parsing of " + is + " using " + dh);
-        }
+        Logging.debug("Starting SAX parsing of {0} using {1}", is, dh);
         newSafeSAXParser().parse(is, dh);
-        if (Main.isDebugEnabled()) {
-            Main.debug("SAX parsing done in " + getDurationString(System.currentTimeMillis() - start));
+        if (Logging.isDebugEnabled()) {
+            Logging.debug("SAX parsing done in {0}", getDurationString(System.currentTimeMillis() - start));
         }
     }
@@ -1665,5 +1661,5 @@
             } catch (NoSuchFieldException e) {
                 // Field is gone with Java 9, there's a method instead
-                Main.trace(e);
+                Logging.trace(e);
                 value = c.getDeclaredMethod("getProperty", String.class).invoke(null, "JRE_EXPIRATION_DATE");
             }
@@ -1672,5 +1668,5 @@
             }
         } catch (IllegalArgumentException | ReflectiveOperationException | SecurityException | ParseException e) {
-            Main.debug(e);
+            Logging.debug(e);
         }
         return null;
@@ -1688,5 +1684,5 @@
                     .connect().fetchContent().split("\n")[0];
         } catch (IOException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         return null;
Index: trunk/src/org/openstreetmap/josm/tools/WindowGeometry.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/WindowGeometry.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/WindowGeometry.java	(revision 12620)
@@ -89,5 +89,5 @@
             initFromPreferences(preferenceKey);
         } catch (WindowGeometryException e) {
-            Main.debug(e);
+            Logging.debug(e);
             initFromWindowGeometry(defaultGeometry);
         }
@@ -248,5 +248,5 @@
                 return new WindowGeometry(new Point(x, y), new Dimension(w, h));
             } else {
-                Main.warn(tr("Ignoring malformed geometry: {0}", arg));
+                Logging.warn(tr("Ignoring malformed geometry: {0}", arg));
             }
         }
Index: trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/XmlObjectParser.java	(revision 12620)
@@ -160,5 +160,5 @@
                 }
             } catch (ReflectiveOperationException | IllegalArgumentException e) {
-                Main.error(e); // SAXException does not dump inner exceptions.
+                Logging.error(e); // SAXException does not dump inner exceptions.
                 throwException(e);
             }
@@ -206,5 +206,5 @@
                     return f;
                 } catch (NoSuchFieldException ex) {
-                    Main.trace(ex);
+                    Logging.trace(ex);
                     fields.put(s, null);
                     return null;
@@ -254,5 +254,5 @@
             } catch (SAXException e) {
                 // Exception very unlikely to happen, so no need to translate this
-                Main.error(e, "Cannot disable 'load-external-dtd' feature:");
+                Logging.log(Logging.LEVEL_ERROR, "Cannot disable 'load-external-dtd' feature:", e);
             }
             reader.parse(new InputSource(in));
Index: trunk/src/org/openstreetmap/josm/tools/bugreport/BugReportQueue.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/bugreport/BugReportQueue.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/bugreport/BugReportQueue.java	(revision 12620)
@@ -56,7 +56,7 @@
         Logging.logWithStackTrace(Logging.LEVEL_ERROR, "Handled by bug report queue", report.getCause());
         if (suppressAllMessages || suppressFor.stream().anyMatch(report::isSame)) {
-            Main.info("User requested to skip error " + report);
+            Logging.info("User requested to skip error " + report);
         } else if (reportsToDisplay.size() > 100 || reportsToDisplay.stream().filter(report::isSame).count() >= 10) {
-            Main.warn("Too many errors. Dropping " + report);
+            Logging.warn("Too many errors. Dropping " + report);
         } else {
             reportsToDisplay.add(report);
@@ -109,5 +109,5 @@
     private SuppressionMode displayFor(ReportedException e) {
         if (handlers.stream().anyMatch(p -> p.test(e))) {
-            Main.trace("Intercepted by handler.");
+            Logging.trace("Intercepted by handler.");
             return SuppressionMode.NONE;
         }
Index: trunk/src/org/openstreetmap/josm/tools/bugreport/BugReportSender.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/bugreport/BugReportSender.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/bugreport/BugReportSender.java	(revision 12620)
@@ -28,4 +28,5 @@
 import org.openstreetmap.josm.tools.HttpClient;
 import org.openstreetmap.josm.tools.HttpClient.Response;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.OpenBrowser;
 import org.openstreetmap.josm.tools.Utils;
@@ -64,9 +65,9 @@
             String openBrowserError = OpenBrowser.displayUrl(getJOSMTicketURL() + "?pdata_stored=" + debugTextPasteId);
             if (openBrowserError != null) {
-                Main.warn(openBrowserError);
+                Logging.warn(openBrowserError);
                 failed(openBrowserError);
             }
         } catch (BugReportSenderException e) {
-            Main.warn(e);
+            Logging.warn(e);
             failed(e.getMessage());
         }
Index: trunk/src/org/openstreetmap/josm/tools/bugreport/JosmUpdatePanel.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/bugreport/JosmUpdatePanel.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/bugreport/JosmUpdatePanel.java	(revision 12620)
@@ -17,4 +17,5 @@
 import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.ImageProvider;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.WikiReader;
 
@@ -63,5 +64,5 @@
             return Integer.parseInt(testedString.trim());
         } catch (NumberFormatException | IOException e) {
-            Main.warn(e, "Unable to detect latest version of JOSM:");
+            Logging.log(Logging.LEVEL_WARN, "Unable to detect latest version of JOSM:", e);
             return -1;
         }
@@ -98,5 +99,5 @@
             Main.platform.openUrl(Main.getJOSMWebsite());
         } catch (IOException ex) {
-            Main.warn(ex, "Unable to access JOSM website:");
+            Logging.log(Logging.LEVEL_WARN, "Unable to access JOSM website:", ex);
         }
     }
Index: trunk/src/org/openstreetmap/josm/tools/bugreport/ReportedException.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/bugreport/ReportedException.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/bugreport/ReportedException.java	(revision 12620)
@@ -19,5 +19,5 @@
 import java.util.function.Supplier;
 
-import org.openstreetmap.josm.Main;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.StreamUtils;
 
@@ -219,5 +219,5 @@
             }
         } catch (RuntimeException t) { // NOPMD
-            Main.warn(t);
+            Logging.warn(t);
             string = "<Error calling toString()>";
         }
Index: trunk/src/org/openstreetmap/josm/tools/date/DateUtils.java
===================================================================
--- trunk/src/org/openstreetmap/josm/tools/date/DateUtils.java	(revision 12619)
+++ trunk/src/org/openstreetmap/josm/tools/date/DateUtils.java	(revision 12620)
@@ -18,7 +18,7 @@
 import javax.xml.datatype.DatatypeFactory;
 
-import org.openstreetmap.josm.Main;
 import org.openstreetmap.josm.data.preferences.BooleanProperty;
 import org.openstreetmap.josm.tools.CheckParameterUtil;
+import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.UncheckedParseException;
 
@@ -51,5 +51,5 @@
             fact = DatatypeFactory.newInstance();
         } catch (DatatypeConfigurationException e) {
-            Main.error(e);
+            Logging.error(e);
         }
         XML_DATE = fact;
