diff --git a/.gitignore b/.gitignore
index 4d4593de18d4846f4dc71f2711ec99415a603c01..57f16fb67c1b1589981416b323d7a9debc728665 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,13 +1,41 @@
-.idea/
-.settings/
-workspace/
-build/
+/build*
+/workspace
+setting.xml
+release/
 target/
-bin/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+icy.log
+
+### IntelliJ IDEA ###
+.idea/
+*.iws
 *.iml
-*.eml
-*.jar
-.project
+*.ipr
+
+### Eclipse ###
+.apt_generated
 .classpath
-export.jardesc
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+### Mac OS ###
 **/.DS_Store
+Icon?
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index e8a27876fb45a14827ea7722a3f5c947b878d13c..3c35a3a8f19ad318164554235b2fc39cbee4a626 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,11 +7,11 @@
     <parent>
         <artifactId>pom-icy</artifactId>
         <groupId>org.bioimageanalysis.icy</groupId>
-        <version>2.2.0</version>
+        <version>3.0.0-a.1</version>
     </parent>
 
     <artifactId>micromanager</artifactId>
-    <version>2.0.0</version>
+    <version>2.0.0-a.1</version>
 
     <name>MicroManager for Icy</name>
     <description>
@@ -20,10 +20,6 @@
         Compatible with Micro-Manager 1.4.19 or above but we recommend to use the current last (1.4.23 / nightly build)
     </description>
 
-    <properties>
-        <artifact-to-extract>MMCoreJ,MMJ_</artifact-to-extract>
-    </properties>
-
     <dependencies>
         <dependency>
             <groupId>org.micromanager</groupId>
@@ -40,7 +36,7 @@
     <repositories>
         <repository>
             <id>icy</id>
-            <url>https://icy-nexus.pasteur.fr/repository/Icy/</url>
+            <url>https://nexus-icy.pasteur.cloud/repository/icy/</url>
         </repository>
     </repositories>
 </project>
\ No newline at end of file
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/MicroManager.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/MicroManager.java
index 91a63054c7178b17753ff3c596b35abc6442130c..f695b7a4f2a70d8b6ad6865639413d5b7ff56b63 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/MicroManager.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/MicroManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,21 +18,24 @@
 
 package plugins.tprovoost.Microscopy.MicroManager;
 
-import icy.common.Version;
-import icy.file.FileUtil;
-import icy.gui.dialog.MessageDialog;
-import icy.gui.frame.progress.FailedAnnounceFrame;
-import icy.image.IcyBufferedImage;
-import icy.main.Icy;
-import icy.sequence.Sequence;
-import icy.system.IcyExceptionHandler;
-import icy.system.thread.ThreadUtil;
-import icy.util.ClassUtil;
-import icy.util.StringUtil;
 import mmcorej.CMMCore;
 import mmcorej.MMCoreJ;
 import mmcorej.StrVector;
 import mmcorej.TaggedImage;
+import org.bioimageanalysis.icy.Icy;
+import org.bioimageanalysis.icy.common.Version;
+import org.bioimageanalysis.icy.common.reflect.ClassUtil;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+import org.bioimageanalysis.icy.gui.dialog.MessageDialog;
+import org.bioimageanalysis.icy.gui.frame.progress.FailedAnnounceFrame;
+import org.bioimageanalysis.icy.io.FileUtil;
+import org.bioimageanalysis.icy.model.image.IcyBufferedImage;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.bioimageanalysis.icy.system.thread.ThreadUtil;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.json.JSONObject;
 import org.micromanager.MMStudio;
 import org.micromanager.MMVersion;
@@ -85,6 +88,7 @@ public class MicroManager {
     /**
      * @return the MicroManager main frame instance.
      */
+    @Contract(pure = true)
     public static MMMainFrame getInstance() {
         // initialize micro manager if needed --> NO ! we need to init ourself
         // if (instance == null)
@@ -96,14 +100,16 @@ public class MicroManager {
     /**
      * @return the MicroManager version
      */
-    public static Version getMMVersion() {
+    @Contract(value = " -> new", pure = true)
+    public static @NotNull Version getMMVersion() {
         // is this method really safe ??
-        return new Version(MMVersion.VERSION_STRING);
+        return Version.fromString(MMVersion.VERSION_STRING);
     }
 
     /**
      * @return the core listener list.
      */
+    @Contract(pure = true)
     public static List<CoreListener> getCoreListeners() {
         final List<CoreListener> result;
 
@@ -136,6 +142,7 @@ public class MicroManager {
     /**
      * @return the acquisition listener list.
      */
+    @Contract(pure = true)
     public static List<AcquisitionListener> getAcquisitionListeners() {
         final List<AcquisitionListener> result;
 
@@ -170,6 +177,7 @@ public class MicroManager {
     /**
      * @return the live listener list.
      */
+    @Contract(pure = true)
     public static List<LiveListener> getLiveListeners() {
         final List<LiveListener> result;
 
@@ -210,49 +218,13 @@ public class MicroManager {
         }
     }
 
-    /**
-     * @param listener the <i>acquisition</i> listener to register
-     * @deprecated Use {@link #addAcquisitionListener(AcquisitionListener)} instead.
-     */
-    @Deprecated
-    public static void registerListener(final AcquisitionListener listener) {
-        addAcquisitionListener(listener);
-    }
-
-    /**
-     * @param listener the <i>acquisition</i> listener to remove
-     * @deprecated Use {@link #removeAcquisitionListener(AcquisitionListener)} instead.
-     */
-    @Deprecated
-    public static void removeListener(final AcquisitionListener listener) {
-        removeAcquisitionListener(listener);
-    }
-
-    /**
-     * @param listener the <i>live</i> listener to register
-     * @deprecated Use {@link #addLiveListener(LiveListener)} instead.
-     */
-    @Deprecated
-    public static void registerListener(final LiveListener listener) {
-        addLiveListener(listener);
-    }
-
-    /**
-     * @param listener the <i>live</i> listener to remove
-     * @deprecated Use {@link #removeLiveListener(LiveListener)} instead.
-     */
-    @Deprecated
-    public static void removeListener(final LiveListener listener) {
-        removeLiveListener(listener);
-    }
-
     /**
      * Use this to access micro-manager main object to access low level function that
      * are not been implemented in Icy's micro-Manager.
      *
      * @return The micro-manager main studio object.
      */
-    public static MMStudio getMMStudio() {
+    public static @Nullable MMStudio getMMStudio() {
         final MMMainFrame inst = getInstance();
         if (inst == null)
             return null;
@@ -271,7 +243,7 @@ public class MicroManager {
      *
      * @return The micro-manager core object
      */
-    public static CMMCore getCore() {
+    public static @Nullable CMMCore getCore() {
         final MMStudio mmstudio = getMMStudio();
         if (mmstudio == null)
             return null;
@@ -389,7 +361,7 @@ public class MicroManager {
     /**
      * @return The acquisition engine wrapper from MicroManager.
      */
-    public static AcquisitionWrapperEngine getAcquisitionEngine() {
+    public static @Nullable AcquisitionWrapperEngine getAcquisitionEngine() {
         final MMStudio mmstudio = getMMStudio();
         if (mmstudio == null)
             return null;
@@ -400,7 +372,7 @@ public class MicroManager {
     /**
      * @return The internal new acquisition engine from MicroManager.
      */
-    public static IAcquisitionEngine2010 getAcquisitionEngine2010() {
+    public static @Nullable IAcquisitionEngine2010 getAcquisitionEngine2010() {
         final MMStudio mmstudio = getMMStudio();
         if (mmstudio == null)
             return null;
@@ -412,7 +384,7 @@ public class MicroManager {
      * @return The engine settings for the most recently started acquisition sequence, or return
      * null if you never started an acquisition.
      */
-    public static SequenceSettings getAcquisitionSettings() {
+    public static @Nullable SequenceSettings getAcquisitionSettings() {
         final AcquisitionWrapperEngine acqEngine = getAcquisitionEngine();
         if (acqEngine == null)
             return null;
@@ -424,7 +396,7 @@ public class MicroManager {
      * @return The summaryMetadata for the most recently started acquisition sequence, or return
      * null if you never started an acquisition.
      */
-    public static JSONObject getAcquisitionMetaData() {
+    public static @Nullable JSONObject getAcquisitionMetaData() {
         final AcquisitionWrapperEngine acqEngine = getAcquisitionEngine();
         if (acqEngine == null)
             return null;
@@ -499,7 +471,7 @@ public class MicroManager {
      * {@link #addAcquisitionListener(AcquisitionListener)}<br>
      * @throws Exception if an error occurred while retrieved last tagged images
      */
-    public static List<TaggedImage> getLastTaggedImage() throws Exception {
+    public static @NotNull List<TaggedImage> getLastTaggedImage() throws Exception {
         final CMMCore core = MicroManager.getCore();
 
         if (core == null || !core.isSequenceRunning())
@@ -567,7 +539,7 @@ public class MicroManager {
      * @return next captured image as List of {@link TaggedImage} or an empty list if the continuous acquisition is not running
      * @throws Exception if an error occurred
      */
-    public static List<TaggedImage> getNextTaggedImage() throws Exception {
+    public static @NotNull List<TaggedImage> getNextTaggedImage() throws Exception {
         final CMMCore core = MicroManager.getCore();
 
         if (core == null || !core.isSequenceRunning())
@@ -575,16 +547,19 @@ public class MicroManager {
 
         final boolean[] done = new boolean[]{false};
         final LiveListener listener = new LiveListener() {
+            @Contract(pure = true)
             @Override
             public void liveStopped() {
                 done[0] = true;
             }
 
+            @Contract(pure = true)
             @Override
             public void liveStarted() {
                 // nothing here
             }
 
+            @Contract(pure = true)
             @Override
             public void liveImgReceived(final List<TaggedImage> images) {
                 done[0] = true;
@@ -642,7 +617,7 @@ public class MicroManager {
      * @return the captured image as List of {@link TaggedImage}
      * @throws Exception if an error occurred
      */
-    public static List<TaggedImage> snapTaggedImage() throws Exception {
+    public static @NotNull List<TaggedImage> snapTaggedImage() throws Exception {
         final CMMCore core = MicroManager.getCore();
         if (core == null)
             return new ArrayList<>();
@@ -846,7 +821,7 @@ public class MicroManager {
      * @return the list of sequence corresponding to the last sequence acquisition or * <code>null</code> if no acquisition was done.
      * @see #startAcquisition(int, double)
      */
-    public static List<Sequence> getAcquisitionResult() {
+    public static @Nullable List<Sequence> getAcquisitionResult() {
         if ((acquisitionManager == null) || acquisitionManager.getSequences().isEmpty())
             return null;
 
@@ -923,7 +898,7 @@ public class MicroManager {
      * @return the current camera binning mode (String format)
      * @throws Exception if an error occurred
      */
-    private static String getBinningAsString(final CMMCore core, final String camera) throws Exception {
+    private static String getBinningAsString(final @NotNull CMMCore core, final String camera) throws Exception {
         return core.getProperty(camera, MMCoreJ.getG_Keyword_Binning());
     }
 
@@ -1175,7 +1150,7 @@ public class MicroManager {
     /**
      * @return all available config group
      */
-    public static List<String> getConfigGroups() {
+    public static @NotNull List<String> getConfigGroups() {
         final CMMCore core = getCore();
         if (core == null)
             return new ArrayList<>();
@@ -1193,7 +1168,7 @@ public class MicroManager {
      * @param group group name
      * @return all available config preset for the specified group
      */
-    public static List<String> getConfigs(final String group) {
+    public static @NotNull List<String> getConfigs(final String group) {
         final CMMCore core = getCore();
         if (core == null)
             return new ArrayList<>();
@@ -1278,6 +1253,7 @@ public class MicroManager {
     /**
      * @return internal preset name set on last call to {@link #setConfigForGroup(String, String, boolean)} method (workaround for MM empty preset name bug)
      */
+    @Contract(pure = true)
     public static String getInternalSetPreset() {
         if (inConfigSet)
             return lastPresetSet;
@@ -1336,7 +1312,7 @@ public class MicroManager {
      * @see #getChannelGroup()
      * @see #getConfigs(String)
      */
-    public static List<String> getChannelConfigs() {
+    public static @NotNull List<String> getChannelConfigs() {
         return getConfigs(MicroManager.getChannelGroup());
     }
 
@@ -1408,6 +1384,7 @@ public class MicroManager {
      * @return <code>true</code> if Micro-Manager is initialized / loaded.<br>
      * @see MicromanagerPlugin#init()
      */
+    @Contract(pure = true)
     public static boolean isInitialized() {
         return instance != null;
     }
@@ -1450,17 +1427,19 @@ public class MicroManager {
             }
             catch (final Throwable t) {
                 // an fatal error occurred, force error on version checking then...
-                version = new Version("1");
+                version = new Version(1);
             }
 
             // cannot get version or wrong version ?
-            if ((version == null) || version.isLower(new Version("1.4.19")))
+            if ((version == null) || version.isLower(new Version(1, 4, 19)))
             // || version.isGreater(new Version("1.4.22")))
             {
                 MessageDialog.showDialog("Error while loading Micro-Manager",
-                        "Your version of Micro-Manager seems to not be compatible !\n" + "This plugin is only compatible with version 1.4.19 or above.\n"
-                                + "Also check that you are using the same architecture for Icy and Micro-Manager (32/64 bits)\n"
-                                + "You need to restart Icy to redefine the Micro-Manager folder.",
+                        """
+                                Your version of Micro-Manager seems to not be compatible !
+                                This plugin is only compatible with version 1.4.19 or above.
+                                Also check that you are using the same architecture for Icy and Micro-Manager (32/64 bits)
+                                You need to restart Icy to redefine the Micro-Manager folder.""",
                         MessageDialog.ERROR_MESSAGE);
                 // so user can change the defined MM folder
                 MMUtils.resetLibrayPath();
@@ -1480,9 +1459,7 @@ public class MicroManager {
                     instance = new MMMainFrame();
                 }
                 catch (final Throwable e) {
-                    IcyExceptionHandler.showErrorMessage(e, true, true);
-                    MessageDialog.showDialog("Error while loading Micro-Manager", e.getMessage() + "\nYou may try to restart Icy to fix the issue.",
-                            MessageDialog.ERROR_MESSAGE);
+                    IcyLogger.error(MicroManager.class, e, "Error while loading Micro-Manager.", "You may try to restart Icy to fix the issue.");
                     return;
                 }
 
@@ -1529,8 +1506,7 @@ public class MicroManager {
                 cleanOldMM();
             }
             catch (final Throwable e) {
-                IcyExceptionHandler.showErrorMessage(e, true, true);
-                new FailedAnnounceFrame("An error occurred while initializing Micro-Manager (see console output for more details).");
+                IcyLogger.error(MicroManager.class, e, "Error while initializing Micro-Manager.");
 
                 // shutdown everything
                 shutdown();
@@ -1543,8 +1519,10 @@ public class MicroManager {
             // cannot load class --> version mismatch probably
             MessageDialog
                     .showDialog("Cannot load Micro-Manager",
-                            "Your version of Micro-Manager seems to not be compatible !\n" + "This plugin is only compatible with version 1.4.19 or above.\n"
-                                    + "Also check that you are using the same architecture for Icy and Micro-Manager (32/64 bits).",
+                            """
+                                    Your version of Micro-Manager seems to not be compatible !
+                                    This plugin is only compatible with version 1.4.19 or above.
+                                    Also check that you are using the same architecture for Icy and Micro-Manager (32/64 bits).""",
                             MessageDialog.ERROR_MESSAGE);
         }
     }
@@ -1609,17 +1587,17 @@ public class MicroManager {
                 stopLiveMode();
             }
             catch (final Throwable t) {
-                IcyExceptionHandler.showErrorMessage(t, true);
+                IcyLogger.error(MicroManager.class, t);
             }
         }
 
-        if (liveListeners != null)
-            liveListeners.clear();
-        if (acqListeners != null)
-            acqListeners.clear();
+        //if (liveListeners != null)
+        liveListeners.clear();
+        //if (acqListeners != null)
+        acqListeners.clear();
         StageMover.clearListener();
-        if (metadatas != null)
-            metadatas.clear();
+        //if (metadatas != null)
+        metadatas.clear();
 
         // stop live listener
         if (liveManager != null) {
@@ -1674,8 +1652,7 @@ public class MicroManager {
 
                 final JSONObject tags = image.tags;
 
-                final boolean firstImage = (MDUtils.getPositionIndex(tags) == 0) && (MDUtils.getFrameIndex(tags) == 0) && (MDUtils.getChannelIndex(tags) == 0)
-                        && (MDUtils.getSliceIndex(tags) == 0);
+                final boolean firstImage = (MDUtils.getPositionIndex(tags) == 0) && (MDUtils.getFrameIndex(tags) == 0) && (MDUtils.getChannelIndex(tags) == 0) && (MDUtils.getSliceIndex(tags) == 0);
                 final boolean newAcquisition = (acquisitionManager == null) || acquisitionManager.isDone();
 
                 // first acquisition image or new acquisition --> create the new acquisition
@@ -1717,7 +1694,7 @@ public class MicroManager {
                     l.acqImgReveived(image);
             }
             catch (final Exception e) {
-                IcyExceptionHandler.showErrorMessage(e, true);
+                IcyLogger.error(MicroManager.class, e);
             }
         }
     }
@@ -1753,7 +1730,7 @@ public class MicroManager {
                                 catch (final Exception e) {
                                     // can happen with advanced acquisition set with a lower time
                                     // interval than current exposure time
-                                    IcyExceptionHandler.showErrorMessage(e, true);
+                                    IcyLogger.error(MicroManager.class, e);
                                 }
                             }
                         }
@@ -1769,7 +1746,7 @@ public class MicroManager {
                     }
                     catch (final Exception e) {
                         // should not happen
-                        IcyExceptionHandler.showErrorMessage(e, true);
+                        IcyLogger.error(MicroManager.class, e);
                     }
                 }
 
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/core/AcquisitionHandler.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/core/AcquisitionHandler.java
index fe236a8283da4e2bb7c5040b84b2a58312330368..f5c973d93d9f63ca8467533644a79772765f2529 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/core/AcquisitionHandler.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/core/AcquisitionHandler.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,15 +18,16 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.core;
 
-import icy.gui.frame.IcyFrame;
-import icy.gui.frame.IcyFrameAdapter;
-import icy.gui.frame.IcyFrameEvent;
-import icy.gui.util.GuiUtil;
-import icy.sequence.Sequence;
-import icy.system.IcyExceptionHandler;
-import icy.system.thread.ThreadUtil;
-import icy.util.ReflectionUtil;
 import mmcorej.TaggedImage;
+import org.bioimageanalysis.icy.common.reflect.ReflectionUtil;
+import org.bioimageanalysis.icy.gui.GuiUtil;
+import org.bioimageanalysis.icy.gui.frame.IcyFrame;
+import org.bioimageanalysis.icy.gui.frame.IcyFrameAdapter;
+import org.bioimageanalysis.icy.gui.frame.IcyFrameEvent;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.bioimageanalysis.icy.system.thread.ThreadUtil;
+import org.jetbrains.annotations.NotNull;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.micromanager.MMStudio;
@@ -65,7 +66,7 @@ public class AcquisitionHandler implements AcquisitionListener {
         MicroManager.addAcquisitionListener(this);
     }
 
-    private void initDialog(final MMMainFrame mainFrame) {
+    private void initDialog(final @NotNull MMMainFrame mainFrame) {
         final MMStudio mmstudio = mainFrame.getMMStudio();
 
         try {
@@ -73,7 +74,7 @@ public class AcquisitionHandler implements AcquisitionListener {
             advAcqDialog = (AcqControlDlg) ReflectionUtil.getFieldObject(mmstudio, "acqControlWin_");
         }
         catch (final Exception ex) {
-            System.err.println("Warning: cannot retrieve AcqControlDlg from Micro-Manager.");
+            IcyLogger.warn(this.getClass(), ex, "Cannot retrieve AcqControlDlg from Micro-Manager.");
         }
 
         // not existing yet ? --> create it now
@@ -85,7 +86,7 @@ public class AcquisitionHandler implements AcquisitionListener {
                 ReflectionUtil.getField(mmstudio.getClass(), "acqControlWin_").set(mmstudio, advAcqDialog);
             }
             catch (final Exception ex) {
-                System.err.println("Warning: cannot set AcqControlDlg from Micro-Manager.");
+                IcyLogger.warn(this.getClass(), ex, "Cannot set AcqControlDlg from Micro-Manager.");
             }
         }
 
@@ -199,7 +200,7 @@ public class AcquisitionHandler implements AcquisitionListener {
                 MicroManager.stopLiveMode();
         }
         catch (final Exception e) {
-            IcyExceptionHandler.showErrorMessage(e, false);
+            IcyLogger.error(this.getClass(), e);
         }
     }
 
@@ -229,7 +230,7 @@ public class AcquisitionHandler implements AcquisitionListener {
             });
         }
         catch (final JSONException e) {
-            IcyExceptionHandler.showErrorMessage(e, true);
+            IcyLogger.error(this.getClass(), e);
         }
     }
 
@@ -246,7 +247,7 @@ public class AcquisitionHandler implements AcquisitionListener {
                 MicroManager.startLiveMode();
             }
             catch (final Exception e) {
-                IcyExceptionHandler.showErrorMessage(e, true);
+                IcyLogger.error(this.getClass(), e);
             }
 
             liveModeWasRunning = false;
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/core/AcquisitionResult.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/core/AcquisitionResult.java
index 23cfb5aed233d841d79ab56265b8e9f0b0809fb5..5c75c65a453b0934ca493f9d5b26ea15577666de 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/core/AcquisitionResult.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/core/AcquisitionResult.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,11 +18,12 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.core;
 
-import icy.gui.viewer.Viewer;
-import icy.main.Icy;
-import icy.sequence.Sequence;
-import icy.util.StringUtil;
 import mmcorej.TaggedImage;
+import org.bioimageanalysis.icy.Icy;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+import org.bioimageanalysis.icy.gui.viewer.Viewer;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
+import org.jetbrains.annotations.NotNull;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.micromanager.api.SequenceSettings;
@@ -61,7 +62,7 @@ public class AcquisitionResult {
         return new ArrayList<>(sequences.values());
     }
 
-    public void imageReceived(final TaggedImage taggedImage) throws JSONException, MMScriptException {
+    public void imageReceived(final @NotNull TaggedImage taggedImage) throws JSONException, MMScriptException {
         final JSONObject tags = taggedImage.tags;
         final Integer position = MDUtils.getPositionIndex(tags);
 
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/AcquisitionListener.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/AcquisitionListener.java
index f1c04f5e760c48c44e8714e9856c7a039ee839c7..083ea0ff3e291de85b1323dac9081b8cb58742c6 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/AcquisitionListener.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/AcquisitionListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,8 +18,8 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.event;
 
-import icy.sequence.Sequence;
 import mmcorej.TaggedImage;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
 import org.json.JSONObject;
 import org.micromanager.api.SequenceSettings;
 import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/CoreListener.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/CoreListener.java
index f466c01d2f53d53b47173aab9e1fb775740eca7f..53936b046be3842974d18ef18dab00f8629a1047 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/CoreListener.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/CoreListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/LiveListener.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/LiveListener.java
index 8d2b2d806400e004a714155e755f7254cdc59626..585c6ad1687a1004f10bfa5f29e7d9420e92ef69 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/LiveListener.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/event/LiveListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,8 +18,8 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.event;
 
-import icy.sequence.Sequence;
 import mmcorej.TaggedImage;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
 import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
 import plugins.tprovoost.Microscopy.MicroManager.tools.MMUtils;
 
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/AboutPanel.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/AboutPanel.java
index 1067b46fe0622419118d13c867cbee8b3d51bf9c..12f9fc6111440cc85e31fd79649ec6be707d054d 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/AboutPanel.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/AboutPanel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,7 +18,7 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.network.NetworkUtil;
+import org.bioimageanalysis.icy.network.NetworkUtil;
 import org.micromanager.MMVersion;
 
 import javax.swing.*;
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/AcquisitionInfoPanel.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/AcquisitionInfoPanel.java
index c46f9ff64b7fed28d83ce9e688aa171b2ecec15e..b36d1e748c66c36631dd29b5c0672271d5677fb8 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/AcquisitionInfoPanel.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/AcquisitionInfoPanel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,9 +18,10 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.math.MathUtil;
-import icy.system.thread.ThreadUtil;
 import mmcorej.CMMCore;
+import org.bioimageanalysis.icy.common.math.MathUtil;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.bioimageanalysis.icy.system.thread.ThreadUtil;
 import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
 import plugins.tprovoost.Microscopy.MicroManager.tools.StageMover;
 
@@ -251,8 +252,7 @@ public class AcquisitionInfoPanel extends JPanel implements Runnable {
                 setPixelSize(core.getPixelSizeUm());
             }
             catch (final Throwable t) {
-                System.err.println("Warning: can't read camera informations from Micro-Manager");
-                System.err.println("Cause: " + t);
+                IcyLogger.warn(this.getClass(), t, "Cannot read camera information from Micro-Manager.");
             }
         }
     }
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ActionsPanel.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ActionsPanel.java
index f28a4e120857ef10800d3f4a55cc32c7586a6809..f41c07399b75ffb88ed37c07aef3096363ec5d63 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ActionsPanel.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ActionsPanel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,20 +18,20 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.gui.component.button.IcyButton;
-import icy.gui.component.button.IcyToggleButton;
-import icy.gui.dialog.MessageDialog;
-import icy.main.Icy;
-import icy.math.FPSMeter;
-import icy.resource.ResourceUtil;
-import icy.resource.icon.IcyIcon;
-import icy.sequence.Sequence;
-import icy.sequence.SequenceEvent;
-import icy.sequence.SequenceListener;
-import icy.system.IcyExceptionHandler;
-import icy.util.StringUtil;
 import mmcorej.CMMCore;
 import mmcorej.TaggedImage;
+import org.bioimageanalysis.icy.Icy;
+import org.bioimageanalysis.icy.common.math.FPSMeter;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+import org.bioimageanalysis.icy.gui.component.button.IcyButton;
+import org.bioimageanalysis.icy.gui.component.button.IcyToggleButton;
+import org.bioimageanalysis.icy.gui.component.icon.SVGIcon;
+import org.bioimageanalysis.icy.gui.dialog.MessageDialog;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
+import org.bioimageanalysis.icy.model.sequence.SequenceEvent;
+import org.bioimageanalysis.icy.model.sequence.SequenceListener;
+import org.bioimageanalysis.icy.system.IcyExceptionHandler;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
 import org.json.JSONObject;
 import org.micromanager.MMStudio;
 import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
@@ -116,7 +116,7 @@ public class ActionsPanel extends JPanel implements LiveListener, SequenceListen
         gridBagLayout.rowWeights = new double[]{1.0, 1.0, 1.0, 1.0, 1.0, Double.MIN_VALUE};
         setLayout(gridBagLayout);
 
-        snapBtn = new IcyButton("Snap", new IcyIcon(ResourceUtil.ICON_PHOTO));
+        snapBtn = new IcyButton("Snap", SVGIcon.PHOTO_CAMERA);
         snapBtn.setToolTipText("Snap an image");
         snapBtn.setIconTextGap(12);
         final GridBagConstraints gbc_snapBtn = new GridBagConstraints();
@@ -126,7 +126,7 @@ public class ActionsPanel extends JPanel implements LiveListener, SequenceListen
         gbc_snapBtn.gridy = 0;
         add(snapBtn, gbc_snapBtn);
 
-        liveBtn = new IcyToggleButton("Live", new IcyIcon("camera"));
+        liveBtn = new IcyToggleButton("Live", SVGIcon.VIDEOCAM);
         liveBtn.setToolTipText("Enable / Disable the live display");
         liveBtn.setIconTextGap(12);
         final GridBagConstraints gbc_liveBtn = new GridBagConstraints();
@@ -136,7 +136,7 @@ public class ActionsPanel extends JPanel implements LiveListener, SequenceListen
         gbc_liveBtn.gridy = 1;
         add(liveBtn, gbc_liveBtn);
 
-        albumBtn = new IcyButton("Album", new IcyIcon("movie"));
+        albumBtn = new IcyButton("Album", SVGIcon.CAMERA_ROLL);
         albumBtn.setToolTipText("Snap an image and store it in the album");
         albumBtn.setIconTextGap(12);
         final GridBagConstraints gbc_albumBtn = new GridBagConstraints();
@@ -146,7 +146,7 @@ public class ActionsPanel extends JPanel implements LiveListener, SequenceListen
         gbc_albumBtn.gridy = 2;
         add(albumBtn, gbc_albumBtn);
 
-        advAcqBtn = new IcyButton("Multi-D Acq.", new IcyIcon(ResourceUtil.ICON_LAYER_V1));
+        advAcqBtn = new IcyButton("Multi-D Acq.", SVGIcon.LAYERS);
         advAcqBtn.setToolTipText("Multi dimension acquisition");
         advAcqBtn.setIconTextGap(8);
         final GridBagConstraints gbc_advAcqBtn = new GridBagConstraints();
@@ -156,7 +156,7 @@ public class ActionsPanel extends JPanel implements LiveListener, SequenceListen
         gbc_advAcqBtn.gridy = 3;
         add(advAcqBtn, gbc_advAcqBtn);
 
-        refreshBtn = new IcyButton("Refresh", new IcyIcon(ResourceUtil.ICON_RELOAD));
+        refreshBtn = new IcyButton("Refresh", SVGIcon.REPLAY);
         refreshBtn.setToolTipText("Force GUI refresh");
         refreshBtn.setIconTextGap(12);
         final GridBagConstraints gbc_refreshBtn = new GridBagConstraints();
@@ -403,7 +403,7 @@ public class ActionsPanel extends JPanel implements LiveListener, SequenceListen
         liveSequence.beginUpdate();
         try {
             // format not anymore compatible --> need to clear sequence first
-            if (!MMUtils.isCompatible(liveSequence, images.get(0).tags))
+            if (!MMUtils.isCompatible(liveSequence, images.getFirst().tags))
                 liveSequence.removeAllImages();
 
             final LiveSettingsPanel livePanel = mainFrame.livePanel;
@@ -474,8 +474,7 @@ public class ActionsPanel extends JPanel implements LiveListener, SequenceListen
             }
         }
         catch (final Exception e) {
-            System.err.println("MicroManager: cannot update live image.");
-            IcyExceptionHandler.showErrorMessage(e, false, true);
+            IcyLogger.error(this.getClass(), e, "Cannot update live image.");
         }
         finally {
             liveSequence.endUpdate();
@@ -499,7 +498,6 @@ public class ActionsPanel extends JPanel implements LiveListener, SequenceListen
     @Override
     public void sequenceChanged(final SequenceEvent sequenceEvent) {
         // ignore this event
-
     }
 
     @Override
@@ -511,7 +509,7 @@ public class ActionsPanel extends JPanel implements LiveListener, SequenceListen
         if (sequence == albumSequence) {
             // album not saved ?
             //if (StringUtil.isEmpty(sequence.getFilename())) {
-            // ask user if he want to save it
+            // ask user if he wants to save it
             //}
 
             // clear it
@@ -561,7 +559,7 @@ public class ActionsPanel extends JPanel implements LiveListener, SequenceListen
                 }
             }
             catch (final Exception e) {
-                System.err.println("MicroManager: cannot process stack acquisition.");
+                //IcyLogger.error(this.getClass(), e, "Stack acquisition failed.");
                 IcyExceptionHandler.handleException(e, true);
             }
         }
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/CameraSettingsPanel.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/CameraSettingsPanel.java
index 48a128a2e966df55aed32727b8779a196a01b2f0..48183ad28075254a791c069167b4f9316da22654 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/CameraSettingsPanel.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/CameraSettingsPanel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,18 +18,17 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.gui.component.NumberTextField;
-import icy.gui.component.button.IcyButton;
-import icy.gui.component.button.IcyToggleButton;
-import icy.gui.dialog.MessageDialog;
-import icy.resource.icon.IcyIcon;
-import icy.system.IcyExceptionHandler;
-import icy.system.thread.ThreadUtil;
-import icy.util.StringUtil;
 import mmcorej.CMMCore;
 import mmcorej.DeviceType;
 import mmcorej.MMCoreJ;
 import mmcorej.StrVector;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+import org.bioimageanalysis.icy.gui.component.button.IcyButton;
+import org.bioimageanalysis.icy.gui.component.button.IcyToggleButton;
+import org.bioimageanalysis.icy.gui.component.field.NumberTextField;
+import org.bioimageanalysis.icy.gui.component.icon.SVGIcon;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.bioimageanalysis.icy.system.thread.ThreadUtil;
 import org.micromanager.MMStudio;
 import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
 
@@ -116,8 +115,7 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
                 refreshOpenShutterButton(open);
             }
             catch (final Throwable t) {
-                MessageDialog.showDialog("Cannot change shutter state: " + t, MessageDialog.ERROR_MESSAGE);
-                System.err.println("Cannot change shutter state: " + t);
+                IcyLogger.error(this.getClass(), t, "Cannot change shutter state.");
             }
         });
         lblAutoShutter.addMouseListener(new MouseAdapter() {
@@ -145,8 +143,7 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
                     shutterOpenBtn.setEnabled(!autoshutter);
             }
             catch (final Throwable t) {
-                MessageDialog.showDialog("Cannot set auto shutter: " + t, MessageDialog.ERROR_MESSAGE);
-                System.err.println("Cannot set auto shutter: " + t);
+                IcyLogger.error(this.getClass(), t, "Cannot set auto shutter.");
             }
         });
         autofocusBtn.addActionListener(e -> {
@@ -154,14 +151,14 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
             if (studio != null)
                 studio.autofocusNow();
             else
-                System.err.println("MMStudio is null, cannot autofocus");
+                IcyLogger.error(this.getClass(), "Cannot autofocus now (MMStudio is null).");
         });
         autofocusSettingBtn.addActionListener(e -> {
             final MMStudio studio = MicroManager.getMMStudio();
             if (studio != null)
                 studio.showAutofocusDialog();
             else
-                System.err.println("MMStudio is null, cannot open autofocus setting panel");
+                IcyLogger.error(this.getClass(), "Cannot show autofocus dialog (MMStudio is null).");
         });
     }
 
@@ -226,7 +223,7 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
         gbc_shuttersCombo.gridy = 2;
         add(shuttersCombo, gbc_shuttersCombo);
 
-        shutterOpenBtn = new IcyToggleButton("Open", new IcyIcon("shutter"));
+        shutterOpenBtn = new IcyToggleButton("Open", SVGIcon.CAMERA);
         shutterOpenBtn.setIconTextGap(10);
         shutterOpenBtn.setToolTipText("Open / close the shutter");
 
@@ -265,7 +262,7 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
         gbc_lblAutofocus.gridy = 4;
         add(lblAutofocus, gbc_lblAutofocus);
 
-        autofocusBtn = new IcyButton(new IcyIcon("autofocus"));
+        autofocusBtn = new IcyButton(SVGIcon.CENTER_FOCUS_STRONG);
         autofocusBtn.setToolTipText("Perform autofocus now");
         final GridBagConstraints gbc_autofocusBtn = new GridBagConstraints();
         gbc_autofocusBtn.fill = GridBagConstraints.BOTH;
@@ -274,7 +271,7 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
         gbc_autofocusBtn.gridy = 4;
         add(autofocusBtn, gbc_autofocusBtn);
 
-        autofocusSettingBtn = new IcyButton(new IcyIcon("af_setting"));
+        autofocusSettingBtn = new IcyButton(SVGIcon.SETTINGS_PHOTO_CAMERA);
         autofocusSettingBtn.setToolTipText("Autofocus settings");
         final GridBagConstraints gbc_autoFocusSettingBtn = new GridBagConstraints();
         gbc_autoFocusSettingBtn.fill = GridBagConstraints.BOTH;
@@ -299,13 +296,15 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
         mainFrame.unlock();
     }
 
+    /*@Deprecated(forRemoval = true)
     public void logError(final Exception e) {
         getMMStudio().logError(e);
-    }
+    }*/
 
+    /*@Deprecated(forRemoval = true)
     public void logError(final Exception e, final String msg) {
         getMMStudio().logError(e, msg);
-    }
+    }*/
 
     public String getCameraName() {
         return cameraName;
@@ -343,8 +342,8 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
             MicroManager.setExposure(exposure);
         }
         catch (final Exception e) {
-            logError(e, "Couldn't set exposure time.");
-            IcyExceptionHandler.showErrorMessage(e, true);
+            IcyLogger.error(this.getClass(), e, "Cannot set exposure time.");
+            //logError(e, "Couldn't set exposure time.");
         }
     }
 
@@ -360,8 +359,8 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
             MicroManager.setBinning(binning);
         }
         catch (final Exception e) {
-            logError(e, "Couldn't set camera binning.");
-            IcyExceptionHandler.showErrorMessage(e, true);
+            IcyLogger.error(this.getClass(), e, "Cannot set camera binning.");
+            //logError(e, "Couldn't set camera binning.");
         }
     }
 
@@ -420,7 +419,8 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
             }
         }
         catch (final Exception e) {
-            logError(e);
+            IcyLogger.error(this.getClass(), e);
+            //logError(e);
         }
     }
 
@@ -463,7 +463,8 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
             }
         }
         catch (final Exception e) {
-            logError(e);
+            IcyLogger.error(this.getClass(), e);
+            //logError(e);
         }
     }
 
@@ -512,7 +513,8 @@ public class CameraSettingsPanel extends JPanel implements Runnable {
             autoShutterCheckbox.setSelected(autoShutter);
         }
         catch (final Exception e) {
-            logError(e);
+            IcyLogger.error(this.getClass(), e);
+            //logError(e);
         }
     }
 
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ChannelTable.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ChannelTable.java
index bb67d21dc3c69f90755cbf3920f6c89655f8f318..62c1426e6a9fdbf17e47989b4c3d740ce8e7ba4a 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ChannelTable.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ChannelTable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,10 +18,10 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.system.IcyExceptionHandler;
 import mmcorej.CMMCore;
 import mmcorej.Configuration;
 import mmcorej.PropertySetting;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
 import org.micromanager.acquisition.AcquisitionWrapperEngine;
 import org.micromanager.dialogs.ChannelCellEditor;
 import org.micromanager.dialogs.ChannelCellRenderer;
@@ -42,7 +42,7 @@ import java.util.List;
 /**
  * Custom table representing channel definition for Micro-Manager advanced acquisition
  *
- * @author Stephane
+ * @author Stephane Dallongeville
  */
 public class ChannelTable extends JTable {
     final protected ChannelTableModel model;
@@ -118,8 +118,7 @@ public class ChannelTable extends JTable {
                 return true;
             }
             catch (final Throwable t) {
-                System.err.println("Cannot set channel group in Micro-Manager.");
-                IcyExceptionHandler.showErrorMessage(t, true);
+                IcyLogger.error(ChannelTable.class, t, "Cannot set channel group in Micro-Manager.");
             }
         }
 
@@ -135,7 +134,7 @@ public class ChannelTable extends JTable {
 
         if (!cfgs.isEmpty()) {
             try {
-                final Configuration presetData = core.getConfigData(group, cfgs.get(0));
+                final Configuration presetData = core.getConfigData(group, cfgs.getFirst());
 
                 if (presetData.size() >= 1L) {
                     final PropertySetting setting = presetData.getSetting(0L);
@@ -147,8 +146,7 @@ public class ChannelTable extends JTable {
                 }
             }
             catch (final Exception e) {
-                System.err.println("Error with Micro-Manager:");
-                IcyExceptionHandler.showErrorMessage(e, true);
+                IcyLogger.error(ChannelTable.class, e, "Error with Micro-Manager");
                 return false;
             }
         }
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ConfigurationPanel.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ConfigurationPanel.java
index d8b61bfa208db1d51ec47d962af666161e94c47e..dcc7a0c60ff709ffd41c42091f35777fb8ba6681 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ConfigurationPanel.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/ConfigurationPanel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,15 +18,14 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.gui.component.button.IcyButton;
-import icy.gui.dialog.ConfirmDialog;
-import icy.gui.dialog.MessageDialog;
-import icy.resource.ResourceUtil;
-import icy.resource.icon.IcyIcon;
-import icy.system.IcyExceptionHandler;
-import icy.system.thread.ThreadUtil;
-import icy.util.StringUtil;
 import mmcorej.CMMCore;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+import org.bioimageanalysis.icy.gui.component.button.IcyButton;
+import org.bioimageanalysis.icy.gui.component.icon.SVGIcon;
+import org.bioimageanalysis.icy.gui.dialog.ConfirmDialog;
+import org.bioimageanalysis.icy.gui.dialog.MessageDialog;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.bioimageanalysis.icy.system.thread.ThreadUtil;
 import org.micromanager.ConfigGroupPad;
 import org.micromanager.MMStudio;
 import org.micromanager.dialogs.GroupEditor;
@@ -81,7 +80,7 @@ public class ConfigurationPanel extends JPanel {
                 ThreadUtil.invokeLater(() -> refreshGroupNow(groupNameRefresh, configName));
             }
             catch (final Exception e) {
-                IcyExceptionHandler.showErrorMessage(e, true);
+                IcyLogger.error(this.getClass(), e);
             }
         };
     }
@@ -104,7 +103,7 @@ public class ConfigurationPanel extends JPanel {
         gbl_configButtonPanel.rowWeights = new double[]{0.0, Double.MIN_VALUE};
         configButtonPanel.setLayout(gbl_configButtonPanel);
 
-        final IcyButton addGroupBtn = new IcyButton(new IcyIcon("sq_plus"));
+        final IcyButton addGroupBtn = new IcyButton(SVGIcon.ADD);
         addGroupBtn.addActionListener(e -> {
             final GroupEditor ge = new GroupEditor("", "", getMMStudio(), getCore(), true);
             if (ge.getWidth() < 580)
@@ -132,10 +131,10 @@ public class ConfigurationPanel extends JPanel {
         gbc_addGroupBtn.gridx = 1;
         gbc_addGroupBtn.gridy = 0;
         configButtonPanel.add(addGroupBtn, gbc_addGroupBtn);
-        final IcyButton editGroupBtn = new IcyButton(new IcyIcon("doc_edit"));
+        final IcyButton editGroupBtn = new IcyButton(SVGIcon.EDIT);
         editGroupBtn.addActionListener(e -> {
             final String groupName = MMUtils.getSelectedGroupName(groupPad);
-            final String groupName2 = groupPad.getSelectedGroup();
+            //final String groupName2 = groupPad.getSelectedGroup();
 
             if (StringUtil.isEmpty(groupName))
                 MessageDialog.showDialog("To edit a group, please select it first then press the edit group button.");
@@ -151,7 +150,7 @@ public class ConfigurationPanel extends JPanel {
                 });
             }
         });
-        final IcyButton removeGroupBtn = new IcyButton(new IcyIcon("sq_minus"));
+        final IcyButton removeGroupBtn = new IcyButton(SVGIcon.REMOVE);
         removeGroupBtn.addActionListener(e -> {
             final String groupName = MMUtils.getSelectedGroupName(groupPad);
 
@@ -192,7 +191,7 @@ public class ConfigurationPanel extends JPanel {
         gbc_presetLabel.gridy = 0;
         configButtonPanel.add(presetLabel, gbc_presetLabel);
 
-        final IcyButton addPresetBtn = new IcyButton(new IcyIcon("sq_plus"));
+        final IcyButton addPresetBtn = new IcyButton(SVGIcon.ADD);
         addPresetBtn.addActionListener(e -> {
             final String groupName = MMUtils.getSelectedGroupName(groupPad);
 
@@ -215,7 +214,7 @@ public class ConfigurationPanel extends JPanel {
         gbc_addPresetBtn.gridx = 7;
         gbc_addPresetBtn.gridy = 0;
         configButtonPanel.add(addPresetBtn, gbc_addPresetBtn);
-        final IcyButton editPresetBtn = new IcyButton(new IcyIcon("doc_edit"));
+        final IcyButton editPresetBtn = new IcyButton(SVGIcon.EDIT);
         editPresetBtn.addActionListener(e -> {
             final String groupName = MMUtils.getSelectedGroupName(groupPad);
             final String presetName = MMUtils.getSelectedPresetName(groupPad);
@@ -232,7 +231,7 @@ public class ConfigurationPanel extends JPanel {
                 });
             }
         });
-        final IcyButton removePresetBtn = new IcyButton(new IcyIcon("sq_minus"));
+        final IcyButton removePresetBtn = new IcyButton(SVGIcon.REMOVE);
         removePresetBtn.addActionListener(e -> {
             final String groupName = MMUtils.getSelectedGroupName(groupPad);
             final String presetName = MMUtils.getSelectedPresetName(groupPad);
@@ -282,7 +281,7 @@ public class ConfigurationPanel extends JPanel {
         gbc_editPresetBtn.gridy = 0;
         configButtonPanel.add(editPresetBtn, gbc_editPresetBtn);
 
-        final IcyButton saveBtn = new IcyButton(new IcyIcon(ResourceUtil.ICON_SAVE));
+        final IcyButton saveBtn = new IcyButton(SVGIcon.SAVE);
         saveBtn.setToolTipText("Save current presets to configuration file...");
         saveBtn.addActionListener(e -> mainFrame.saveConfig());
         final GridBagConstraints gbc_saveBtn = new GridBagConstraints();
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LiveSettingsPanel.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LiveSettingsPanel.java
index 1ece6a73fc1ea47db9597c711bc1eb55760b4c8d..4372153478de248933ca843baf6d1fd25d99435d 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LiveSettingsPanel.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LiveSettingsPanel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,8 +18,8 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.gui.component.NumberTextField;
-import icy.util.StringUtil;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+import org.bioimageanalysis.icy.gui.component.field.NumberTextField;
 
 import javax.swing.*;
 import javax.swing.border.TitledBorder;
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LoadFrame.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LoadFrame.java
index b6d9e3a4c227c68e1bc67894c2a12450afe78afc..ca334be9a708afd38bdc609c543616a773d05764 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LoadFrame.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LoadFrame.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,16 +18,15 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.action.IcyAbstractAction;
-import icy.file.FileUtil;
-import icy.gui.component.button.IcyButton;
-import icy.gui.dialog.OpenDialog;
-import icy.main.Icy;
-import icy.preferences.PluginsPreferences;
-import icy.preferences.XMLPreferences;
-import icy.resource.ResourceUtil;
-import icy.resource.icon.IcyIcon;
-import icy.system.IcyExceptionHandler;
+import org.bioimageanalysis.icy.Icy;
+import org.bioimageanalysis.icy.gui.action.IcyAbstractAction;
+import org.bioimageanalysis.icy.gui.component.button.IcyButton;
+import org.bioimageanalysis.icy.gui.component.icon.SVGIcon;
+import org.bioimageanalysis.icy.gui.dialog.OpenDialog;
+import org.bioimageanalysis.icy.io.FileUtil;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.bioimageanalysis.icy.system.preferences.PluginsPreferences;
+import org.bioimageanalysis.icy.system.preferences.XMLPreferences;
 import plugins.tprovoost.Microscopy.MicroManager.tools.MMUtils;
 import plugins.tprovoost.Microscopy.MicroManagerForIcy.MicromanagerPlugin;
 
@@ -132,7 +131,7 @@ public class LoadFrame extends JDialog {
                     openButton.setEnabled(true);
                 }
                 catch (final IOException e1) {
-                    IcyExceptionHandler.showErrorMessage(e1, true);
+                    IcyLogger.error(this.getClass(), e1);
                 }
             }
             else
@@ -232,15 +231,11 @@ public class LoadFrame extends JDialog {
         lbl_devices.setFont(lbl_files.getFont().deriveFont(Font.BOLD, 12));
         lbl_config_presets.setFont(lbl_files.getFont().deriveFont(Font.BOLD, 12));
 
-        openButton = new IcyButton(openAction);
-        openButton.setIcon(new IcyIcon(ResourceUtil.ICON_OPEN));
+        openButton = new IcyButton(openAction, SVGIcon.FOLDER_OPEN);
         openButton.setEnabled(false);
-        final IcyButton cancelButton = new IcyButton(cancelAction);
-        cancelButton.setIcon(new IcyIcon(ResourceUtil.ICON_DELETE));
-        final IcyButton addButton = new IcyButton(addAction);
-        addButton.setIcon(new IcyIcon(ResourceUtil.ICON_PLUS));
-        final IcyButton removeButton = new IcyButton(removeAction);
-        removeButton.setIcon(new IcyIcon(ResourceUtil.ICON_MINUS));
+        final IcyButton cancelButton = new IcyButton(cancelAction, SVGIcon.DELETE);
+        final IcyButton addButton = new IcyButton(addAction, SVGIcon.ADD);
+        final IcyButton removeButton = new IcyButton(removeAction, SVGIcon.REMOVE);
 
         final JPanel buttonPanel = new JPanel();
         getContentPane().add(buttonPanel, BorderLayout.SOUTH);
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LoadingFrame.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LoadingFrame.java
index 800aa72e76b8206247b95ac77d324e56f3ed81ca..76032477531f32ca56f71cb7815a9a1ab099b217 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LoadingFrame.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/LoadingFrame.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,8 +18,8 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.gui.frame.IcyFrame;
-import icy.system.thread.ThreadUtil;
+import org.bioimageanalysis.icy.gui.frame.IcyFrame;
+import org.bioimageanalysis.icy.system.thread.ThreadUtil;
 
 import javax.swing.*;
 import java.awt.*;
@@ -27,7 +27,7 @@ import java.awt.*;
 /**
  * Simple static Loading Frame for Micro-Manager initialization.
  *
- * @author Stephane
+ * @author Stephane Dallongeville
  */
 public class LoadingFrame extends IcyFrame {
     JProgressBar progressBar;
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/MMMainFrame.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/MMMainFrame.java
index 4e8f9d0e07cde7d1b977eb3051f9f16af611730f..9bea7ceb885076066b0f8cc54ed9c45a05c20430 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/MMMainFrame.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/MMMainFrame.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,30 +18,28 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.common.MenuCallback;
-import icy.file.FileUtil;
-import icy.gui.dialog.ActionDialog;
-import icy.gui.dialog.ConfirmDialog;
-import icy.gui.dialog.MessageDialog;
-import icy.gui.dialog.SaveDialog;
-import icy.gui.frame.IcyFrame;
-import icy.gui.frame.IcyFrameAdapter;
-import icy.gui.frame.IcyFrameEvent;
-import icy.gui.frame.progress.FailedAnnounceFrame;
-import icy.gui.frame.progress.ToolTipFrame;
-import icy.gui.util.ComponentUtil;
-import icy.main.Icy;
-import icy.preferences.PluginPreferences;
-import icy.preferences.XMLPreferences;
-import icy.resource.ResourceUtil;
-import icy.resource.icon.IcyIcon;
-import icy.system.IcyExceptionHandler;
-import icy.system.thread.ThreadUtil;
-import icy.util.ReflectionUtil;
-import icy.util.StringUtil;
 import mmcorej.CMMCore;
 import mmcorej.MMCoreJ;
 import mmcorej.MMEventCallback;
+import org.bioimageanalysis.icy.Icy;
+import org.bioimageanalysis.icy.common.reflect.ReflectionUtil;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+import org.bioimageanalysis.icy.gui.component.ComponentUtil;
+import org.bioimageanalysis.icy.gui.component.icon.SVGIcon;
+import org.bioimageanalysis.icy.gui.component.menu.IcyMenuItem;
+import org.bioimageanalysis.icy.gui.dialog.ActionDialog;
+import org.bioimageanalysis.icy.gui.dialog.ConfirmDialog;
+import org.bioimageanalysis.icy.gui.dialog.MessageDialog;
+import org.bioimageanalysis.icy.gui.dialog.SaveDialog;
+import org.bioimageanalysis.icy.gui.frame.IcyFrame;
+import org.bioimageanalysis.icy.gui.frame.IcyFrameAdapter;
+import org.bioimageanalysis.icy.gui.frame.IcyFrameEvent;
+import org.bioimageanalysis.icy.gui.frame.progress.ToolTipFrame;
+import org.bioimageanalysis.icy.io.FileUtil;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.bioimageanalysis.icy.system.preferences.PluginPreferences;
+import org.bioimageanalysis.icy.system.preferences.XMLPreferences;
+import org.bioimageanalysis.icy.system.thread.ThreadUtil;
 import org.micromanager.MMOptions;
 import org.micromanager.MMStudio;
 import org.micromanager.MainFrame;
@@ -50,7 +48,6 @@ import org.micromanager.conf2.ConfiguratorDlg2;
 import org.micromanager.conf2.MMConfigFileException;
 import org.micromanager.conf2.MicroscopeModel;
 import org.micromanager.dialogs.CalibrationListDlg;
-import org.micromanager.utils.ReportingUtils;
 import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
 import plugins.tprovoost.Microscopy.MicroManager.core.AcquisitionHandler;
 import plugins.tprovoost.Microscopy.MicroManager.event.CoreListener;
@@ -170,7 +167,7 @@ public class MMMainFrame extends IcyFrame {
                     options.closeOnExit_ = false;
                 }
                 catch (final Exception ex) {
-                    System.err.println("Warning: cannot patch options informations from Micro-Manager.");
+                    IcyLogger.warn(MMMainFrame.this.getClass(), ex, "Cannot patch options information from Micro-Manager");
                 }
 
                 try {
@@ -181,7 +178,7 @@ public class MMMainFrame extends IcyFrame {
                     contrastPrefs = (Preferences) ReflectionUtil.getFieldObject(mmstudio, "contrastPrefs_");
                 }
                 catch (final Exception ex) {
-                    System.err.println("Warning: cannot retrieve Preferences from Micro-Manager.");
+                    IcyLogger.warn(MMMainFrame.this.getClass(), ex, "Cannot retrieve Preferences from Micro-Manager");
                 }
 
                 final MainFrame frame = MMStudio.getFrame();
@@ -363,8 +360,7 @@ public class MMMainFrame extends IcyFrame {
         final JMenuBar menuBar = new JMenuBar();
         menuBar.add(toReturn);
         setJMenuBar(menuBar);
-        final JMenuItem hconfig = new JMenuItem("Configuration Wizard");
-        hconfig.setIcon(new IcyIcon("star.png"));
+        final IcyMenuItem hconfig = new IcyMenuItem("Configuration Wizard", SVGIcon.STAR);
         hconfig.addActionListener(e -> {
             // we have some plugins running ?
             if (pluginsPanel.getRunningPluginsCount() > 0) {
@@ -394,8 +390,7 @@ public class MMMainFrame extends IcyFrame {
             refreshGUI();
         });
 
-        final JMenuItem menuPxSizeConfigItem = new JMenuItem("Pixel Size Config");
-        menuPxSizeConfigItem.setIcon(new IcyIcon(ResourceUtil.ICON_PROPERTIES));
+        final IcyMenuItem menuPxSizeConfigItem = new IcyMenuItem("Pixel Size Config", SVGIcon.SETTINGS);
         menuPxSizeConfigItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_G, InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK));
         menuPxSizeConfigItem.addActionListener(e -> {
             final CalibrationListDlg dlg = new CalibrationListDlg(mmstudio.getCore());
@@ -407,9 +402,8 @@ public class MMMainFrame extends IcyFrame {
             pixelSizeConfig.setResizable(true);
         });
 
-        final JMenuItem loadConfigItem = new JMenuItem("Load Configuration");
+        final IcyMenuItem loadConfigItem = new IcyMenuItem("Load Configuration", SVGIcon.FOLDER_OPEN);
         loadConfigItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK));
-        loadConfigItem.setIcon(new IcyIcon(ResourceUtil.ICON_OPEN));
         loadConfigItem.addActionListener(e -> {
             final LoadFrame f = new LoadFrame();
 
@@ -431,13 +425,11 @@ public class MMMainFrame extends IcyFrame {
             }
         });
 
-        final JMenuItem saveConfigItem = new JMenuItem("Save Configuration");
+        final IcyMenuItem saveConfigItem = new IcyMenuItem("Save Configuration", SVGIcon.SAVE);
         saveConfigItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.SHIFT_DOWN_MASK | InputEvent.CTRL_DOWN_MASK));
-        saveConfigItem.setIcon(new IcyIcon(ResourceUtil.ICON_SAVE));
         saveConfigItem.addActionListener(e -> saveConfig());
 
-        final JMenuItem aboutItem = new JMenuItem("About");
-        aboutItem.setIcon(new IcyIcon(ResourceUtil.ICON_INFO));
+        final IcyMenuItem aboutItem = new IcyMenuItem("About", SVGIcon.INFO);
         aboutItem.addActionListener(e -> {
             final JDialog dialog = new JDialog(Icy.getMainInterface().getMainFrame(), "About");
 
@@ -449,9 +441,8 @@ public class MMMainFrame extends IcyFrame {
             dialog.setVisible(true);
         });
 
-        final JMenuItem propertyBrowserItem = new JMenuItem("Property Browser");
+        final IcyMenuItem propertyBrowserItem = new IcyMenuItem("Property Browser", SVGIcon.DATABASE);
         propertyBrowserItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_COMMA, InputEvent.CTRL_DOWN_MASK));
-        propertyBrowserItem.setIcon(new IcyIcon(ResourceUtil.ICON_DATABASE));
         propertyBrowserItem.addActionListener(e -> {
             final PropertyEditor editor = new PropertyEditor();
             editor.setGui(mmstudio);
@@ -463,13 +454,11 @@ public class MMMainFrame extends IcyFrame {
             propertyBrowser.setResizable(true);
         });
 
-        final JMenuItem resetMMPath = new JMenuItem("Reset Micro-Manager path");
-        resetMMPath.setIcon(new IcyIcon("folder"));
+        final IcyMenuItem resetMMPath = new IcyMenuItem("Reset Micro-Manager path", SVGIcon.FOLDER);
         resetMMPath.addActionListener(e -> {
             // so user can change the defined MM folder
             MMUtils.resetLibrayPath();
-            MessageDialog.showDialog("Information", "You need to restart Icy now to change the defined Micro-Manager folder.",
-                    MessageDialog.INFORMATION_MESSAGE);
+            MessageDialog.showDialog("Information", "You need to restart Icy now to change the defined Micro-Manager folder.", MessageDialog.INFORMATION_MESSAGE);
         });
 
         // JMenuItem loadPresetConfigItem = new JMenuItem("Load Core properties from XML");
@@ -494,8 +483,7 @@ public class MMMainFrame extends IcyFrame {
         // }
         // });
         //
-        final JMenuItem mmSettingItem = new JMenuItem("Micro-Manager options");
-        mmSettingItem.setIcon(new IcyIcon(ResourceUtil.ICON_COG, true));
+        final IcyMenuItem mmSettingItem = new IcyMenuItem("Micro-Manager options", SVGIcon.SETTINGS);
         mmSettingItem.setToolTipText("Set a variety of Micro-Manager configuration options");
         mmSettingItem.addActionListener(e -> {
             if (options == null)
@@ -522,8 +510,7 @@ public class MMMainFrame extends IcyFrame {
         // }
         // });
 
-        final JMenuItem mmScriptPanel = new JMenuItem("Script panel");
-        mmScriptPanel.setIcon(new IcyIcon(ResourceUtil.getAlphaIconAsImage("text_curstor"), true));
+        final IcyMenuItem mmScriptPanel = new IcyMenuItem("Script panel", SVGIcon.EDIT);
         mmScriptPanel.setToolTipText("Open Micro-Manager script panel");
         mmScriptPanel.addActionListener(e -> mmstudio.showScriptPanel());
 
@@ -621,9 +608,8 @@ public class MMMainFrame extends IcyFrame {
                 model.saveToFile(path);
         }
         catch (final MMConfigFileException e) {
-            ReportingUtils.logError(e);
-            IcyExceptionHandler.showErrorMessage(e, false);
-            new FailedAnnounceFrame("Unable to save configuration file");
+            IcyLogger.error(this.getClass(), e, "Error while saving Micro-Manager configuration.");
+            //ReportingUtils.logError(e);
         }
     }
 
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/MainPanel.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/MainPanel.java
index a3530188a684c35f43866d2390c45a55e987fd3b..1b3327965895cbf29fd85499bf2a726c480b468c 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/MainPanel.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/MainPanel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/OptionsPanel.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/OptionsPanel.java
index cf25b0022364e82f0dd3e69b3437199f06a85f16..7f09f49586b0712dc30c4e4e38271dcdba620c1b 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/OptionsPanel.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/OptionsPanel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,8 +18,8 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.gui.dialog.ConfirmDialog;
 import mmcorej.CMMCore;
+import org.bioimageanalysis.icy.gui.dialog.ConfirmDialog;
 import org.micromanager.MMOptions;
 import org.micromanager.logging.LogFileManager;
 import org.micromanager.utils.NumberUtils;
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/PluginsToolbar.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/PluginsToolbar.java
index 079fed1733ffb8766e134951e296fe55794b35f4..7c6beacf8f91372bf1bc26824ac8ea4491f0e854 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/PluginsToolbar.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/gui/PluginsToolbar.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,10 +18,12 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.gui;
 
-import icy.plugin.PluginDescriptor;
-import icy.plugin.PluginLauncher;
-import icy.plugin.PluginLoader;
-import plugins.tprovoost.Microscopy.MicroManager.tools.FrameUtils;
+import org.bioimageanalysis.icy.extension.plugin.PluginDescriptor;
+import org.bioimageanalysis.icy.extension.plugin.PluginLauncher;
+import org.bioimageanalysis.icy.extension.plugin.PluginLoader;
+import org.bioimageanalysis.icy.gui.component.button.IcyButton;
+import org.bioimageanalysis.icy.gui.component.icon.SVGIcon;
+import org.jetbrains.annotations.NotNull;
 import plugins.tprovoost.Microscopy.MicroManagerForIcy.MicroscopePlugin;
 
 import javax.swing.*;
@@ -53,14 +55,23 @@ public class PluginsToolbar extends JPanel {
         initialize(PluginLoader.getPlugins(MicroscopePlugin.class));
     }
 
-    private void initialize(final List<PluginDescriptor> plugins) {
+    private void initialize(final @NotNull List<PluginDescriptor> plugins) {
         pluginToolbar = new JToolBar(SwingConstants.HORIZONTAL);
         pluginToolbar.setRollover(true);
         pluginToolbar.setFloatable(false);
         pluginToolbar.setToolTipText("Micro Manager plugins for Icy");
 
         for (final PluginDescriptor plugin : plugins) {
-            pluginToolbar.add(FrameUtils.createPluginButton(plugin, e -> {
+            final JButton pluginButton;
+            final SVGIcon pluginSVGIcon = plugin.getSVGIcon();
+            if (pluginSVGIcon != null)
+                pluginButton = new IcyButton(pluginSVGIcon);
+            else
+                pluginButton = new JButton(plugin.getIcon());
+
+            pluginButton.setToolTipText(plugin.getName());
+
+            pluginButton.addActionListener(e -> {
                 // create the microscope plugin
                 final MicroscopePlugin microscopePlugin = (MicroscopePlugin) PluginLauncher.start(plugin);
 
@@ -69,19 +80,10 @@ public class PluginsToolbar extends JPanel {
                     addPlugin(microscopePlugin);
                     microscopePlugin.start();
                 }
-            }));
+            });
+            pluginToolbar.add(pluginButton);
         }
 
-        // if (plugins.size() == 0)
-        // {
-        // MessageDialog.showDialog("Information",
-        // "You don't have any Micro manager plugins installed, use the search bar to install some",
-        // MessageDialog.INFORMATION_MESSAGE);
-        //
-        // // search for micro manager plugin
-        // // Icy.getMainInterface().getSearchEngine().search("micro-manager");
-        // }
-
         setLayout(new BorderLayout());
         setBorder(new TitledBorder("Plugins"));
         add(pluginToolbar, BorderLayout.CENTER);
@@ -139,7 +141,7 @@ public class PluginsToolbar extends JPanel {
     }
 
     /**
-     * Shutdown all running plugins (should automatically call removePlugin(..))
+     * Shutdown all running plugins (should automatically call removePlugin(...))
      */
     public void shutdownPlugins() {
         for (final MicroscopePlugin plugin : getRunningPlugins())
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/ClassPatcher.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/ClassPatcher.java
index c6d55b54207afb81a936c95f1bf0470245f65761..9ccf1fadf1bf4f120d42ac440e6a0141d04cca28 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/ClassPatcher.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/ClassPatcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,23 +18,16 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.patch;
 
-import java.security.ProtectionDomain;
-import java.util.ArrayList;
-
-import icy.system.IcyExceptionHandler;
-import icy.system.SystemUtil;
-import icy.util.StringUtil;
-import javassist.CannotCompileException;
-import javassist.ClassClassPath;
-import javassist.ClassPool;
-import javassist.CtClass;
-import javassist.CtField;
-import javassist.CtMethod;
-import javassist.CtNewMethod;
-import javassist.LoaderClassPath;
-import javassist.NotFoundException;
+import javassist.*;
 import javassist.bytecode.AccessFlag;
 import javassist.bytecode.FieldInfo;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+import org.bioimageanalysis.icy.system.SystemUtil;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.jetbrains.annotations.NotNull;
+
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
 
 /**
  * The code hacker provides a mechanism for altering the behavior of classes
@@ -239,8 +232,7 @@ public class ClassPatcher {
             return pool.toClass(classRef);
         }
         catch (final CannotCompileException e) {
-            IcyExceptionHandler.showErrorMessage(e, false);
-            System.err.println("Cannot load class: " + fullClass);
+            IcyLogger.error(this.getClass(), e, "Cannot load class: " + fullClass);
             return null;
         }
     }
@@ -265,8 +257,7 @@ public class ClassPatcher {
             return pool.toClass(classRef, neighbor, classLoader, protectionDomain);
         }
         catch (final CannotCompileException e) {
-            IcyExceptionHandler.showErrorMessage(e, false);
-            System.err.println("Cannot load class: " + fullClass);
+            IcyLogger.error(this.getClass(), e, "Cannot load class: " + fullClass);
             return null;
         }
     }
@@ -323,7 +314,7 @@ public class ClassPatcher {
      * Generates a new line of code calling the <code>imagej.legacy.patches</code> class and method
      * corresponding to the given method signature.
      */
-    private String newCode(final String fullClass, final String methodSig) {
+    private @NotNull String newCode(final @NotNull String fullClass, final String methodSig) {
         final int dotIndex = fullClass.lastIndexOf(".");
         final String className = fullClass.substring(dotIndex + 1);
 
@@ -360,13 +351,13 @@ public class ClassPatcher {
     /**
      * Extracts the method name from the given method signature.
      */
-    private String getMethodName(final String methodSig) {
+    private @NotNull String getMethodName(final @NotNull String methodSig) {
         final int parenIndex = methodSig.indexOf("(");
         final int spaceIndex = methodSig.lastIndexOf(" ", parenIndex);
         return methodSig.substring(spaceIndex + 1, parenIndex);
     }
 
-    private String[] getMethodArgs(final String methodSig, final boolean wantResult) {
+    private String @NotNull [] getMethodArgs(final @NotNull String methodSig, final boolean wantResult) {
         final ArrayList<String> result = new ArrayList<>();
 
         final int parenIndex = methodSig.indexOf("(");
@@ -381,14 +372,14 @@ public class ClassPatcher {
         return result.toArray(new String[0]);
     }
 
-    private String[] getMethodArgTypes(final String methodSig, final boolean wantResult) {
+    private String @NotNull [] getMethodArgTypes(final String methodSig, final boolean wantResult) {
         final String[] args = getMethodArgs(methodSig, wantResult);
         for (int i = 0; i < args.length; i++)
             args[i] = args[i].split(" ")[0];
         return args;
     }
 
-    private String[] getMethodArgNames(final String methodSig, final boolean wantResult) {
+    private String @NotNull [] getMethodArgNames(final String methodSig, final boolean wantResult) {
         final String[] args = getMethodArgs(methodSig, wantResult);
         for (int i = 0; i < args.length; i++)
             args[i] = args[i].split(" ")[1];
@@ -398,7 +389,7 @@ public class ClassPatcher {
     /**
      * Returns true if the given method signature is static.
      */
-    private boolean isStatic(final String methodSig) {
+    private boolean isStatic(final @NotNull String methodSig) {
         final int parenIndex = methodSig.indexOf("(");
         final String methodPrefix = methodSig.substring(0, parenIndex);
         for (final String token : methodPrefix.split(" ")) {
@@ -411,7 +402,7 @@ public class ClassPatcher {
     /**
      * Returns true if the given method signature returns void.
      */
-    private boolean isVoid(final String methodSig) {
+    private boolean isVoid(final @NotNull String methodSig) {
         final int parenIndex = methodSig.indexOf("(");
         final String methodPrefix = methodSig.substring(0, parenIndex);
         return methodPrefix.startsWith("void ") || methodPrefix.indexOf(" void ") > 0;
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/MMPatcher.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/MMPatcher.java
index 38cf863b6733952a277698320da258cc4c1abb74..73d993b4c02ade4ae9af7b7420cbf7cb8cd3a3e8 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/MMPatcher.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/MMPatcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,7 +18,7 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.patch;
 
-import icy.plugin.PluginLoader;
+import org.bioimageanalysis.icy.extension.plugin.PluginLoader;
 import org.micromanager.MMVersion;
 
 /**
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/MMStudioMethods.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/MMStudioMethods.java
index 2771b265f0012302994506a87dfe23831b309320..203b847bded525269a1803588d4b0c5d0cf3d513 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/MMStudioMethods.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/patch/MMStudioMethods.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -21,9 +21,8 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.patch;
 
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
 import org.micromanager.MMStudio;
-
-import icy.system.IcyExceptionHandler;
 import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
 
 /**
@@ -56,7 +55,7 @@ public class MMStudioMethods {
                 MicroManager.stopLiveMode();
         }
         catch (final Throwable t) {
-            IcyExceptionHandler.showErrorMessage(t, true);
+            IcyLogger.error(MMStudioMethods.class, t);
         }
     }
 }
\ No newline at end of file
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/FrameUtils.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/FrameUtils.java
index d0e519a70f4e4808fb2cd8948c0e7f95fd2fb854..f014470f6989a26e4bdd1339434075f1e1025007 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/FrameUtils.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/FrameUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,15 +18,13 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.tools;
 
-import icy.gui.component.button.IcyButton;
-import icy.gui.frame.IcyFrame;
-import icy.gui.util.GuiUtil;
-import icy.plugin.PluginDescriptor;
-import icy.resource.icon.IcyIcon;
+import org.bioimageanalysis.icy.gui.GuiUtil;
+import org.bioimageanalysis.icy.gui.frame.IcyFrame;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
-import java.awt.event.ActionListener;
 
 /**
  * Utilities class used for wrapping Micro-Manager Frames and Dialogs in a IcyFrame.
@@ -42,7 +40,7 @@ public class FrameUtils {
      * @param window the window to add to the main pane
      * @return the window converted as an {@link IcyFrame}
      */
-    public static IcyFrame addMMWindowToDesktopPane(final Window window) {
+    public static @NotNull IcyFrame addMMWindowToDesktopPane(final Window window) {
         final IcyFrame frame = GuiUtil.createIcyFrameFromWindow(window);
         frame.addToDesktopPane();
         frame.setVisible(true);
@@ -56,11 +54,9 @@ public class FrameUtils {
      * @param label     button label
      * @return the button searched or <code>null</code> if was not found
      */
-    public static JButton findButtonComponents(final Container container, final String label) {
+    public static @Nullable JButton findButtonComponents(final @NotNull Container container, final String label) {
         for (final Component c : container.getComponents()) {
-            if (c instanceof JButton) {
-                final JButton button = (JButton) c;
-
+            if (c instanceof final JButton button) {
                 if (button.getText().equalsIgnoreCase(label))
                     return button;
             }
@@ -68,40 +64,4 @@ public class FrameUtils {
 
         return null;
     }
-
-    /**
-     * Create an {@link IcyButton} from given information
-     *
-     * @param buttonText button text
-     * @param iconPath   the icon path. Can be null if no icon wanted
-     * @param action     the action to execute when button is clicked
-     * @return an IcyButton with buttonText and an icon on it if iconPath not null.<br>
-     * The button returned have an actionListener wich execute the runnable.
-     */
-    public static IcyButton createUIButton(final String buttonText, final String iconPath, final Runnable action) {
-        final IcyButton theButton;
-        if (iconPath != null && !iconPath.isEmpty())
-            theButton = new IcyButton(buttonText, new IcyIcon(iconPath, IcyIcon.DEFAULT_SIZE));
-        else
-            theButton = new IcyButton(buttonText);
-        theButton.addActionListener(e -> action.run());
-        return theButton;
-    }
-
-    /**
-     * Create a button to launch the specified plugin
-     *
-     * @param plugin plugin descriptor
-     * @param action the action to execute when we click on the button
-     * @return an IcyButton with text and icon describing the specified plugin.
-     */
-    public static IcyButton createPluginButton(final PluginDescriptor plugin, final ActionListener action) {
-        final IcyButton result = new IcyButton(new IcyIcon(plugin.getIconAsImage(), 32, false));
-
-        result.setToolTipText(plugin.getName());
-        if (action != null)
-            result.addActionListener(action);
-
-        return result;
-    }
 }
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/MMUtils.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/MMUtils.java
index ca4af071fe4339d8f6f668394d05d4f6ef89724b..34ba4f2d9df5318334eaea31c17ced8276b0c61f 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/MMUtils.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/MMUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,37 +18,38 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.tools;
 
-import icy.file.FileUtil;
-import icy.gui.dialog.MessageDialog;
-import icy.gui.frame.progress.FailedAnnounceFrame;
-import icy.gui.frame.progress.ProgressFrame;
-import icy.image.IcyBufferedImage;
-import icy.image.colormap.IcyColorMap;
-import icy.main.Icy;
-import icy.network.NetworkUtil;
-import icy.plugin.PluginLoader;
-import icy.plugin.PluginLoader.PluginClassLoader;
-import icy.preferences.PluginsPreferences;
-import icy.preferences.XMLPreferences;
-import icy.sequence.MetaDataUtil;
-import icy.sequence.Sequence;
-import icy.system.IcyExceptionHandler;
-import icy.system.SystemUtil;
-import icy.system.thread.ThreadUtil;
-import icy.type.DataType;
-import icy.type.collection.CollectionUtil;
-import icy.type.collection.array.Array2DUtil;
-import icy.type.collection.array.ArrayUtil;
-import icy.type.point.Point3D;
-import icy.util.DateUtil;
-import icy.util.OMEUtil;
-import icy.util.ReflectionUtil;
-import icy.util.StringUtil;
 import mmcorej.TaggedImage;
 import ome.xml.meta.OMEXMLMetadata;
 import ome.xml.model.Pixels;
 import ome.xml.model.primitives.NonNegativeInteger;
 import ome.xml.model.primitives.Timestamp;
+import org.bioimageanalysis.icy.Icy;
+import org.bioimageanalysis.icy.common.collection.CollectionUtil;
+import org.bioimageanalysis.icy.common.collection.array.Array2DUtil;
+import org.bioimageanalysis.icy.common.collection.array.ArrayUtil;
+import org.bioimageanalysis.icy.common.datetime.DateUtil;
+import org.bioimageanalysis.icy.common.geom.point.Point3D;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+import org.bioimageanalysis.icy.common.type.DataType;
+import org.bioimageanalysis.icy.extension.plugin.PluginLoader;
+import org.bioimageanalysis.icy.gui.dialog.MessageDialog;
+import org.bioimageanalysis.icy.gui.frame.progress.FailedAnnounceFrame;
+import org.bioimageanalysis.icy.gui.frame.progress.ProgressFrame;
+import org.bioimageanalysis.icy.io.FileUtil;
+import org.bioimageanalysis.icy.model.OMEUtil;
+import org.bioimageanalysis.icy.model.colormap.IcyColorMap;
+import org.bioimageanalysis.icy.model.image.IcyBufferedImage;
+import org.bioimageanalysis.icy.model.sequence.MetaDataUtil;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
+import org.bioimageanalysis.icy.network.NetworkUtil;
+import org.bioimageanalysis.icy.system.SystemUtil;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.bioimageanalysis.icy.system.preferences.PluginsPreferences;
+import org.bioimageanalysis.icy.system.preferences.XMLPreferences;
+import org.bioimageanalysis.icy.system.thread.ThreadUtil;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 import org.joda.time.DateTime;
 import org.json.JSONArray;
 import org.json.JSONException;
@@ -195,7 +196,8 @@ public class MMUtils {
      * @param images the list of {@link TaggedImage} to test
      * @return <code>true</code> if the specified list of TaggedImage contains a <code>null</code> or poison image.
      */
-    public static boolean hasNullOrPoison(final List<TaggedImage> images) {
+    @Contract(pure = true)
+    public static boolean hasNullOrPoison(final @NotNull List<TaggedImage> images) {
         for (final TaggedImage image : images)
             if ((image == null) || TaggedImageQueue.isPoison(image))
                 return true;
@@ -218,7 +220,7 @@ public class MMUtils {
      * @return the resulting {@link IcyBufferedImage} image
      * @throws JSONException if an error occurred while reading the metadata
      */
-    public static IcyBufferedImage convertToIcyImage(final List<TaggedImage> images) throws JSONException {
+    public static @Nullable IcyBufferedImage convertToIcyImage(final @NotNull List<TaggedImage> images) throws JSONException {
         final List<TaggedImage> goodImages = new ArrayList<>(images.size());
         int w, h, bpp;
 
@@ -246,7 +248,7 @@ public class MMUtils {
 
         if ((!goodImages.isEmpty()) && (w > 0) && (h > 0) && (bpp > 0)) {
             // create the data array
-            final Object[] data = Array2DUtil.createArray(ArrayUtil.getDataType(goodImages.get(0).pix),
+            final Object[] data = Array2DUtil.createArray(ArrayUtil.getDataType(goodImages.getFirst().pix),
                     goodImages.size());
 
             for (int i = 0; i < goodImages.size(); i++)
@@ -278,7 +280,7 @@ public class MMUtils {
      * @throws JSONException     if an error occurred while reading the metadata
      * @throws MMScriptException if an error occurred on MM script parsing
      */
-    public static void setMetadata(final Sequence sequence, final JSONObject tags) throws JSONException, MMScriptException {
+    public static void setMetadata(final @NotNull Sequence sequence, final JSONObject tags) throws JSONException, MMScriptException {
         final OMEXMLMetadata metadata = sequence.getOMEXMLMetadata();
         final int numComp = Math.max(1, MDUtils.getNumberOfComponents(tags));
 
@@ -420,8 +422,7 @@ public class MMUtils {
      * @param sizeC       wanted global size C (number of channel), set to <code>-1</code> to keep current value
      * @throws JSONException if an error occurred while reading the metadata
      */
-    public static void setImageMetadata(final TaggedImage taggedImage, final int t, final int z, final int c, final int sizeT, final int sizeZ, final int sizeC)
-            throws JSONException {
+    public static void setImageMetadata(final TaggedImage taggedImage, final int t, final int z, final int c, final int sizeT, final int sizeZ, final int sizeC) throws JSONException {
         if (taggedImage == null)
             return;
 
@@ -489,8 +490,8 @@ public class MMUtils {
      * @throws MMScriptException if an error occurred on MM script parsing
      * @see #setImageMetadata(TaggedImage, int, int, int, int, int, int)
      */
-    public static boolean setImage(final Sequence sequence, final TaggedImage taggedImage, final long startDate)
-            throws JSONException, MMScriptException {
+    @Contract("_, null, _ -> false")
+    public static boolean setImage(final Sequence sequence, final TaggedImage taggedImage, final long startDate) throws JSONException, MMScriptException {
         // incorrect image --> do nothing
         if ((taggedImage == null) || TaggedImageQueue.isPoison(taggedImage))
             return false;
@@ -576,7 +577,7 @@ public class MMUtils {
                 exposure = MicroManager.getExposure() / 1000d;
         }
         catch (final Throwable e) {
-            IcyExceptionHandler.showErrorMessage(e, false);
+            IcyLogger.error(MMUtils.class, e);
         }
 
         metadata.setPlanePositionX(OMEUtil.getLength(pos.getX()), 0, planeIndex);
@@ -599,6 +600,7 @@ public class MMUtils {
      * @throws JSONException     if an error occurred while reading the metadata
      * @throws MMScriptException if an error occurred on MM script parsing
      */
+    @Contract("_, null -> false")
     public static boolean setImage(final Sequence sequence, final TaggedImage taggedImage) throws JSONException, MMScriptException {
         return setImage(sequence, taggedImage, 0L);
     }
@@ -611,7 +613,7 @@ public class MMUtils {
      * @throws JSONException     if an error occurred while reading the metadata
      * @throws MMScriptException if an error occurred on MM script parsing
      */
-    public static boolean isCompatible(final Sequence sequence, final JSONObject metadata) throws JSONException, MMScriptException {
+    public static boolean isCompatible(final @NotNull Sequence sequence, final JSONObject metadata) throws JSONException, MMScriptException {
         if (sequence.isEmpty())
             return true;
 
@@ -619,7 +621,7 @@ public class MMUtils {
                 && (sequence.getSizeY() == MDUtils.getHeight(metadata))
                 && (sequence.getSizeC() == (MDUtils.getNumChannels(metadata)
                 * Math.max(1, MDUtils.getNumberOfComponents(metadata))))
-                && (sequence.getDataType_().getSize() == ((MDUtils.getBitDepth(metadata) + 7) / 8));
+                && (sequence.getDataType().getSize() == ((MDUtils.getBitDepth(metadata) + 7) / 8));
     }
 
     /**
@@ -629,35 +631,27 @@ public class MMUtils {
      * @throws JSONException     if an error occurred while reading the metadata
      * @throws MMScriptException if an error occurred on MM script parsing
      */
-    public static IcyBufferedImage createEmptyImage(final JSONObject metadata) throws JSONException, MMScriptException {
+    @Contract("_ -> new")
+    public static @NotNull IcyBufferedImage createEmptyImage(final JSONObject metadata) throws JSONException, MMScriptException {
         final int width = MDUtils.getWidth(metadata);
         final int height = MDUtils.getHeight(metadata);
         final int numChannels = MDUtils.getNumChannels(metadata) * Math.max(1, MDUtils.getNumberOfComponents(metadata));
         final int bpp = MDUtils.getBitDepth(metadata);
         final int bytespp = (bpp + 7) / 8;
 
-        switch (bytespp) {
-            default:
-            case 1:
-                return new IcyBufferedImage(width, height, numChannels, DataType.UBYTE);
-            case 2:
-                return new IcyBufferedImage(width, height, numChannels, DataType.USHORT);
-            case 3:
-            case 4:
-                return new IcyBufferedImage(width, height, numChannels, DataType.UINT);
-            case 5:
-            case 6:
-            case 7:
-            case 8:
-                return new IcyBufferedImage(width, height, numChannels, DataType.DOUBLE);
-        }
+        return switch (bytespp) {
+            default -> new IcyBufferedImage(width, height, numChannels, DataType.UBYTE);
+            case 2 -> new IcyBufferedImage(width, height, numChannels, DataType.USHORT);
+            case 3, 4 -> new IcyBufferedImage(width, height, numChannels, DataType.UINT);
+            case 5, 6, 7, 8 -> new IcyBufferedImage(width, height, numChannels, DataType.DOUBLE);
+        };
     }
 
     /**
      * @param group the {@link ConfigGroupPad} name
      * @return the selected group name from specified ConfigGroupPad
      */
-    public static String getSelectedGroupName(final ConfigGroupPad group) {
+    public static String getSelectedGroupName(final @NotNull ConfigGroupPad group) {
         /*try {
             return (String) ReflectionUtil.invokeMethod(group, "getGroup", true, new Object[]{});
         }
@@ -677,7 +671,7 @@ public class MMUtils {
      * @param group the {@link ConfigGroupPad} name
      * @return the selected preset name from specified ConfigGroupPad
      */
-    public static String getSelectedPresetName(final ConfigGroupPad group) {
+    public static String getSelectedPresetName(final @NotNull ConfigGroupPad group) {
         /*try {
             return (String) ReflectionUtil.invokeMethod(group, "getPreset", true, new Object[]{});
         }
@@ -734,7 +728,7 @@ public class MMUtils {
             return false;
 
         final ClassLoader cl = PluginLoader.getLoader();
-        if (cl instanceof PluginClassLoader) {
+        if (cl instanceof PluginLoader.PluginClassLoader) {
             for (final File f : files) {
                 final String path = f.getAbsolutePath();
                 final String ext = FileUtil.getFileExtension(path, false).toLowerCase();
@@ -757,7 +751,7 @@ public class MMUtils {
                         continue;
 
                     // we can add it
-                    ((PluginClassLoader) cl).add(path);
+                    ((PluginLoader.PluginClassLoader) cl).add(path);
                 }
             }
         }
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/StageMover.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/StageMover.java
index b6c45ee3dcf78f654fae4957fbe3ad12fee4db96..17dacf044114c2432ced1c54be8eeef32c48f463 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/StageMover.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManager/tools/StageMover.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,13 +18,15 @@
 
 package plugins.tprovoost.Microscopy.MicroManager.tools;
 
-import icy.preferences.XMLPreferences;
-import icy.roi.ROI2D;
-import icy.sequence.Sequence;
-import icy.system.thread.ThreadUtil;
-import icy.type.point.Point3D;
-import icy.util.StringUtil;
 import mmcorej.CMMCore;
+import org.bioimageanalysis.icy.common.geom.point.Point3D;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+import org.bioimageanalysis.icy.model.roi.ROI2D;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
+import org.bioimageanalysis.icy.system.preferences.XMLPreferences;
+import org.bioimageanalysis.icy.system.thread.ThreadUtil;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
 import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
 
 import java.awt.geom.Point2D;
@@ -143,6 +145,7 @@ public class StageMover {
     /**
      * @return state of X inverted axis.
      */
+    @Contract(pure = true)
     public static boolean isInvertX() {
         return invertX;
     }
@@ -150,6 +153,7 @@ public class StageMover {
     /**
      * @return state of Y inverted axis.
      */
+    @Contract(pure = true)
     public static boolean isInvertY() {
         return invertY;
     }
@@ -157,6 +161,7 @@ public class StageMover {
     /**
      * @return state of Y inverted axis.
      */
+    @Contract(pure = true)
     public static boolean isInvertZ() {
         return invertZ;
     }
@@ -174,6 +179,7 @@ public class StageMover {
     /**
      * @return state of X and Y axis inversion.
      */
+    @Contract(pure = true)
     public static boolean isSwitchXY() {
         return switchXY;
     }
@@ -181,7 +187,7 @@ public class StageMover {
     /**
      * Fire Z stage position change event
      *
-     * @param s stage devicce name
+     * @param s stage device name
      * @param z Z position
      */
     public static void onStagePositionChanged(final String s, final double z) {
@@ -322,7 +328,7 @@ public class StageMover {
      * @return the X, Y and Z coordinates of the current stage/focus device(s).
      * @throws Exception if an error occurs
      */
-    public static Point3D.Double getXYZ() throws Exception {
+    public static Point3D.@NotNull Double getXYZ() throws Exception {
         final Point2D.Double pt2d = getXY();
         return new Point3D.Double(pt2d.x, pt2d.y, getZ());
     }
@@ -333,7 +339,7 @@ public class StageMover {
      * @return the X, Y and Z coordinates of the current stage/focus device(s) in double[3] format
      * @throws Exception if an error occurs
      */
-    public static double[] getXYZAsDoubleArray() throws Exception {
+    public static double @NotNull [] getXYZAsDoubleArray() throws Exception {
         final Point3D.Double pt = getXYZ();
         return new double[]{pt.x, pt.y, pt.z};
     }
@@ -642,7 +648,7 @@ public class StageMover {
      * @param y y value of the point we want to go to.
      * @throws Exception if an error occurs
      */
-    public static void moveToPoint(final Sequence s, final double x, final double y) throws Exception {
+    public static void moveToPoint(final @NotNull Sequence s, final double x, final double y) throws Exception {
         final double pxsize;
         final double vectx = x - s.getBounds2D().getCenterX();
         // Y coordinates are inverted in the sequence
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManagerForIcy/MicromanagerPlugin.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManagerForIcy/MicromanagerPlugin.java
index 737b8609262c28b2eb711b3c0f7adfbb613e21eb..0d954c929f28fbb7db9c3f8d6a25424c4fcde574 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManagerForIcy/MicromanagerPlugin.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManagerForIcy/MicromanagerPlugin.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,11 +18,15 @@
 
 package plugins.tprovoost.Microscopy.MicroManagerForIcy;
 
-import icy.plugin.abstract_.PluginActionable;
-import icy.plugin.interface_.PluginThreaded;
+import org.bioimageanalysis.icy.extension.plugin.abstract_.PluginActionable;
+import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginIcon;
+import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginName;
+import org.bioimageanalysis.icy.extension.plugin.interface_.PluginThreaded;
 import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
 import plugins.tprovoost.Microscopy.MicroManager.tools.MMUtils;
 
+@IcyPluginName("Micro-Manager")
+@IcyPluginIcon(path = "/mmj.png")
 public final class MicromanagerPlugin extends PluginActionable implements PluginThreaded {
     /**
      * Initialize Micro-Manager sub system.
diff --git a/src/main/java/plugins/tprovoost/Microscopy/MicroManagerForIcy/MicroscopePlugin.java b/src/main/java/plugins/tprovoost/Microscopy/MicroManagerForIcy/MicroscopePlugin.java
index 2f7603e34af72f626e042a1e771889846f774725..291e932bd077fa094e9a9708bead13cf129742bc 100644
--- a/src/main/java/plugins/tprovoost/Microscopy/MicroManagerForIcy/MicroscopePlugin.java
+++ b/src/main/java/plugins/tprovoost/Microscopy/MicroManagerForIcy/MicroscopePlugin.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010-2023. Institut Pasteur.
+ * Copyright (c) 2010-2024. Institut Pasteur.
  *
  * This file is part of Icy.
  * Icy is free software: you can redistribute it and/or modify
@@ -18,7 +18,7 @@
 
 package plugins.tprovoost.Microscopy.MicroManagerForIcy;
 
-import icy.plugin.abstract_.Plugin;
+import org.bioimageanalysis.icy.extension.plugin.abstract_.Plugin;
 import plugins.tprovoost.Microscopy.MicroManager.MicroManager;
 
 /**
diff --git a/src/main/resources/mmj.png b/src/main/resources/mmj.png
new file mode 100644
index 0000000000000000000000000000000000000000..9a64c58c2537a9f82c3e99f8f8ec2bc82c754549
Binary files /dev/null and b/src/main/resources/mmj.png differ