From cc4dea9b291f32af42e8588ff705bec2b8ca1686 Mon Sep 17 00:00:00 2001
From: Thomas <thomas.musset@pasteur.fr>
Date: Thu, 4 Jul 2024 16:06:10 +0200
Subject: [PATCH] added annotations, fixed NullPointerException on MenuItem
 generation

---
 .../java/plugins/fab/trackmanager/Link.java   |  3 +-
 .../PluginTrackManagerProcessor.java          | 16 ++++-
 .../fab/trackmanager/TrackDetection.java      |  4 +-
 .../plugins/fab/trackmanager/TrackGroup.java  | 11 ++--
 .../fab/trackmanager/TrackLengthDialog.java   | 13 +---
 .../fab/trackmanager/TrackManager.java        | 59 +++++++++----------
 .../fab/trackmanager/TrackManagerPainter.java | 12 ++--
 .../plugins/fab/trackmanager/TrackPanel.java  | 46 ++++++---------
 .../plugins/fab/trackmanager/TrackPool.java   | 56 +++++++-----------
 .../fab/trackmanager/TrackSegment.java        | 13 ++--
 .../blocks/LoadTracksFromXML.java             | 18 ++----
 .../trackmanager/blocks/SaveTracksToXML.java  | 16 ++---
 12 files changed, 116 insertions(+), 151 deletions(-)

diff --git a/src/main/java/plugins/fab/trackmanager/Link.java b/src/main/java/plugins/fab/trackmanager/Link.java
index 8145eb3..a2fc342 100644
--- a/src/main/java/plugins/fab/trackmanager/Link.java
+++ b/src/main/java/plugins/fab/trackmanager/Link.java
@@ -18,12 +18,14 @@
 
 package plugins.fab.trackmanager;
 
+import org.jetbrains.annotations.Contract;
 import plugins.nchenouard.spot.Detection;
 
 public class Link {
     TrackSegment start;
     TrackSegment end;
 
+    @Contract(pure = true)
     public Link(final TrackSegment start, final TrackSegment end) {
         this.start = start;
         this.end = end;
@@ -49,5 +51,4 @@ public class Link {
     public String toString() {
         return "link start:" + getStartDetection() + " end:" + getEndDetection();
     }
-
 }
diff --git a/src/main/java/plugins/fab/trackmanager/PluginTrackManagerProcessor.java b/src/main/java/plugins/fab/trackmanager/PluginTrackManagerProcessor.java
index 1276a8b..3468c73 100644
--- a/src/main/java/plugins/fab/trackmanager/PluginTrackManagerProcessor.java
+++ b/src/main/java/plugins/fab/trackmanager/PluginTrackManagerProcessor.java
@@ -21,6 +21,8 @@ package plugins.fab.trackmanager;
 import org.bioimageanalysis.icy.extension.plugin.abstract_.Plugin;
 import org.bioimageanalysis.icy.gui.GuiUtil;
 import org.bioimageanalysis.icy.gui.component.panel.PopupPanel;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 import java.awt.event.ActionEvent;
@@ -47,8 +49,14 @@ public abstract class PluginTrackManagerProcessor extends Plugin {
         enabledCheckBox.setSelected(true);
         enabledCheckBox.addActionListener(actionButton);
 
-        final JPanel commandPanel = GuiUtil.createLineBoxPanel(enabledCheckBox, Box.createHorizontalGlue(), performanceLabel,
-                moveUpButton, moveDownButton, closeButton);
+        final JPanel commandPanel = GuiUtil.createLineBoxPanel(
+                enabledCheckBox,
+                Box.createHorizontalGlue(),
+                performanceLabel,
+                moveUpButton,
+                moveDownButton,
+                closeButton
+        );
 
         closeButton.addActionListener(actionButton);
         closeButton.setToolTipText("Close processor");
@@ -75,7 +83,7 @@ public abstract class PluginTrackManagerProcessor extends Plugin {
 
     class ActionButton implements ActionListener {
         @Override
-        public void actionPerformed(final ActionEvent e) {
+        public void actionPerformed(final @NotNull ActionEvent e) {
 
             if (e.getSource() == closeButton) {
                 Close();
@@ -128,6 +136,8 @@ public abstract class PluginTrackManagerProcessor extends Plugin {
         super.finalize();
     }*/
 
+    @SuppressWarnings("UnstableApiUsage")
+    @Contract(mutates = "this")
     public final void setTrackPool(final TrackPool trackPool) {
         this.trackPool = trackPool;
     }
diff --git a/src/main/java/plugins/fab/trackmanager/TrackDetection.java b/src/main/java/plugins/fab/trackmanager/TrackDetection.java
index 0876f46..2fb2b13 100644
--- a/src/main/java/plugins/fab/trackmanager/TrackDetection.java
+++ b/src/main/java/plugins/fab/trackmanager/TrackDetection.java
@@ -28,7 +28,7 @@ import java.awt.geom.Rectangle2D;
 /**
  * Display a single detection of a track. Used by TrackPanel / TrackEditor
  *
- * @author fab
+ * @author Fabrice de Chaumont
  */
 public class TrackDetection extends JPanel {
     private boolean Selected = false;
@@ -103,7 +103,5 @@ public class TrackDetection extends JPanel {
             g2.drawLine(0, 0, getWidth(), getHeight());
             g2.setStroke(new BasicStroke(1));
         }
-
     }
-
 }
diff --git a/src/main/java/plugins/fab/trackmanager/TrackGroup.java b/src/main/java/plugins/fab/trackmanager/TrackGroup.java
index e600bab..597e931 100644
--- a/src/main/java/plugins/fab/trackmanager/TrackGroup.java
+++ b/src/main/java/plugins/fab/trackmanager/TrackGroup.java
@@ -19,6 +19,9 @@
 package plugins.fab.trackmanager;
 
 import org.bioimageanalysis.icy.model.sequence.Sequence;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
 import plugins.nchenouard.spot.Detection;
 
 import java.util.ArrayList;
@@ -30,6 +33,7 @@ public class TrackGroup {
      */
     private final ArrayList<TrackSegment> trackSegmentList;
 
+    @Contract(pure = true)
     public TrackGroup(final Sequence sequence) {
         this.sequence = sequence;
         trackSegmentList = new ArrayList<>();
@@ -46,9 +50,9 @@ public class TrackGroup {
         return trackSegmentList;
     }
 
-    public void addTrackSegment(final TrackSegment ts) {
+    public void addTrackSegment(final @NotNull TrackSegment ts) {
         if (ts.getOwnerTrackGroup() != null) {
-            System.err.println("The trackSegment is already owned by another TrackGroup.");
+            IcyLogger.warn(this.getClass(), "The trackSegment is already owned by another TrackGroup.");
             return;
         }
 
@@ -77,7 +81,7 @@ public class TrackGroup {
         }
     }
 
-    public void removeTrackSegment(final TrackSegment ts) {
+    public void removeTrackSegment(final @NotNull TrackSegment ts) {
         // should remove links
         ts.setOwnerTrackGroup(null);
         ts.removeAllLinks();
@@ -98,5 +102,4 @@ public class TrackGroup {
     public String toString() {
         return description;
     }
-
 }
diff --git a/src/main/java/plugins/fab/trackmanager/TrackLengthDialog.java b/src/main/java/plugins/fab/trackmanager/TrackLengthDialog.java
index aeb940e..702fe65 100644
--- a/src/main/java/plugins/fab/trackmanager/TrackLengthDialog.java
+++ b/src/main/java/plugins/fab/trackmanager/TrackLengthDialog.java
@@ -20,21 +20,20 @@ package plugins.fab.trackmanager;
 
 import org.bioimageanalysis.icy.gui.GuiUtil;
 import org.bioimageanalysis.icy.gui.dialog.ActionDialog;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
 
 import javax.swing.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 
 public class TrackLengthDialog implements ActionListener {
-
     JTextField textField = new JTextField("3-10");
     TrackPool trackPool;
 
     public TrackLengthDialog(final TrackPool trackPool) {
         this.trackPool = trackPool;
         final ActionDialog actionDialog = new ActionDialog("Select by length");
-        actionDialog.getContentPane().setLayout(
-                new BoxLayout(actionDialog.getContentPane(), BoxLayout.PAGE_AXIS));
+        actionDialog.getContentPane().setLayout(new BoxLayout(actionDialog.getContentPane(), BoxLayout.PAGE_AXIS));
 
         actionDialog.getContentPane().add(GuiUtil.createLineBoxPanel(new JLabel("Use the syntax: from-to (in number of frame):")));
         actionDialog.getContentPane().add(GuiUtil.createLineBoxPanel(textField));
@@ -44,13 +43,10 @@ public class TrackLengthDialog implements ActionListener {
 
         actionDialog.setOkAction(this);
         actionDialog.setVisible(true);
-
-
     }
 
     @Override
     public void actionPerformed(final ActionEvent e) {
-
         final String text = textField.getText();
 
         final String[] values = text.split("-");
@@ -69,11 +65,8 @@ public class TrackLengthDialog implements ActionListener {
             highVal = Integer.MAX_VALUE;
         }
 
-        System.out.println("low val : " + lowVal);
-        System.out.println("high val : " + highVal);
+        IcyLogger.debug(this.getClass(), "low val : " + lowVal, "high val : " + highVal);
 
         trackPool.selectTracksByLength(lowVal, highVal);
-
-
     }
 }
diff --git a/src/main/java/plugins/fab/trackmanager/TrackManager.java b/src/main/java/plugins/fab/trackmanager/TrackManager.java
index 29e10d7..9adf815 100644
--- a/src/main/java/plugins/fab/trackmanager/TrackManager.java
+++ b/src/main/java/plugins/fab/trackmanager/TrackManager.java
@@ -26,6 +26,7 @@ import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginIcon;
 import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginName;
 import org.bioimageanalysis.icy.gui.GuiUtil;
 import org.bioimageanalysis.icy.gui.component.ComponentUtil;
+import org.bioimageanalysis.icy.gui.component.menu.IcyPluginMenuItem;
 import org.bioimageanalysis.icy.gui.component.panel.PopupPanel;
 import org.bioimageanalysis.icy.gui.dialog.MessageDialog;
 import org.bioimageanalysis.icy.gui.frame.IcyFrame;
@@ -42,7 +43,9 @@ import org.bioimageanalysis.icy.model.swimmingPool.SwimmingPoolEvent;
 import org.bioimageanalysis.icy.model.swimmingPool.SwimmingPoolEventType;
 import org.bioimageanalysis.icy.model.swimmingPool.SwimmingPoolListener;
 import org.bioimageanalysis.icy.network.NetworkUtil;
-import org.bioimageanalysis.icy.system.IcyExceptionHandler;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import plugins.nchenouard.spot.Detection;
@@ -84,6 +87,7 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
         Class<? extends PluginTrackManagerProcessor> pluginTrackManagerProcessor;
         PluginDescriptor pluginDescriptor;
 
+        @Contract(pure = true)
         public MenuItemActionListener(final PluginDescriptor pluginDescriptor,
                                       final Class<? extends PluginTrackManagerProcessor> pluginTrackEditorProcessor) {
             this.pluginTrackManagerProcessor = pluginTrackEditorProcessor;
@@ -98,9 +102,8 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
     }
 
     void loadTrackProcessor(final PluginDescriptor pluginDescriptor) {
-
         if (pluginDescriptor == null || pluginDescriptor.getPluginClass() == null) {
-            System.err.println("Can't load processor (plugin not found)");
+            IcyLogger.error(this.getClass(), "Can't load processor (plugin not found)");
             return;
         }
 
@@ -109,11 +112,11 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
             ptep = (PluginTrackManagerProcessor) pluginDescriptor.getPluginClass().getDeclaredConstructor().newInstance();
         }
         catch (final Exception e) {
-            IcyExceptionHandler.showErrorMessage(e, true);
+            IcyLogger.error(this.getClass(), e, "Can't instantiate plugin class " + pluginDescriptor.getPluginClass());
         }
 
         if (ptep == null) {
-            System.err.println("Can't load processor.");
+            IcyLogger.error(this.getClass(), "Can't load processor.");
             return;
         }
 
@@ -157,8 +160,7 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
      * Preferences preferences = Preferences.userRoot().node( node );
      * preferences.put( "path", chooser.getCurrentDirectory().getAbsolutePath() );
      */
-    JCheckBoxMenuItem displayTrackPanelCheckBoxMenuItem = new JCheckBoxMenuItem("Display Track Panel",
-            displayTrackManagerBoolean);
+    JCheckBoxMenuItem displayTrackPanelCheckBoxMenuItem = new JCheckBoxMenuItem("Display Track Panel", displayTrackManagerBoolean);
 
     /*
      * void
@@ -223,7 +225,6 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
     JMenuItem onlineHelpMenuItem;
 
     public TrackManager() {
-
         mainFrame.addFrameListener(this);
 
         trackPool = new TrackPool();
@@ -414,7 +415,7 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
      * another trackeditor, the trackgroup checkbox is disabled.
      */
     @Override
-    public void swimmingPoolChangeEvent(final SwimmingPoolEvent swimmingPoolEvent) {
+    public void swimmingPoolChangeEvent(final @NotNull SwimmingPoolEvent swimmingPoolEvent) {
         if (swimmingPoolEvent.getType() == SwimmingPoolEventType.ELEMENT_ADDED) {
             // System.out.println("TrackManager : swimming pool element added.");
             // System.out.println("object: " +
@@ -439,9 +440,7 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
 
             for (int i = 0; i < trackingGroupSourceMenu.getItemCount(); i++) {
                 final JMenuItem mi = trackingGroupSourceMenu.getItem(i);
-                if (mi instanceof CheckBoxResultSource) {
-                    final CheckBoxResultSource cbrs = (CheckBoxResultSource) mi;
-
+                if (mi instanceof final CheckBoxResultSource cbrs) {
                     if (cbrs.result == swimmingPoolEvent.getResult()) {
                         cbrs.destroy();
                         return;
@@ -588,13 +587,12 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
         // JToggleButton trackTimeOnSequenceButton = new JToggleButton("T");
         SwimmingObject result;
 
-        public CheckBoxResultSource(final SwimmingObject result, final boolean enabled) {
-            if (!(result.getObject() instanceof TrackGroup)) {
-                System.out.println("Result object type not supported.");
+        public CheckBoxResultSource(final @NotNull SwimmingObject result, final boolean enabled) {
+            if (!(result.getObject() instanceof final TrackGroup trackGroup)) {
+                IcyLogger.error(this.getClass(), "Result object type not supported.");
                 return;
             }
 
-            final TrackGroup trackGroup = (TrackGroup) result.getObject();
             final int nbTracks = trackGroup.getTrackSegmentList().size();
 
             final String label = result.getObject().toString() + " (" + nbTracks + " Tracks)";
@@ -653,7 +651,7 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
         }
 
         @Override
-        public void actionPerformed(final ActionEvent e) {
+        public void actionPerformed(final @NotNull ActionEvent e) {
 
             // if (e.getSource() == trackTimeOnSequenceButton)
             // {
@@ -749,12 +747,13 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
         }
     }
 
-    public static List<TrackGroup> loadTracks(final String path) throws IllegalArgumentException {
+    public static @NotNull List<TrackGroup> loadTracks(final String path) throws IllegalArgumentException {
         final Document document = XMLUtil.loadDocument(path, false);
         return loadTracks(document);
     }
 
-    public static List<TrackGroup> loadTracks(final Document document) throws IllegalArgumentException {
+    @Contract("null -> fail")
+    public static @NotNull List<TrackGroup> loadTracks(final Document document) throws IllegalArgumentException {
         if (document == null)
             throw new IllegalArgumentException("Invalid track file !");
 
@@ -850,12 +849,13 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
         }
     }
 
-    public static List<TrackGroup> loadTracksFromTrackMate(final String path) {
+    public static @NotNull List<TrackGroup> loadTracksFromTrackMate(final String path) {
         final Document document = XMLUtil.loadDocument(path, false);
         return loadTracksFromTrackMate(document);
     }
 
-    public static List<TrackGroup> loadTracksFromTrackMate(final Document document) throws IllegalArgumentException {
+    @Contract("null -> fail")
+    public static @NotNull List<TrackGroup> loadTracksFromTrackMate(final Document document) throws IllegalArgumentException {
         if (document == null)
             throw new IllegalArgumentException("Invalid track file !");
 
@@ -907,8 +907,7 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
     }
 
     private void debug() {
-
-        System.out.println("--- debug");
+        IcyLogger.debug(this.getClass(), "--- debug");
         // for ( Link link : trackPool.getLinks() )
         // {
         // System.out.println( link );
@@ -917,7 +916,6 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
         // System.out.println( "Track segment idHashMapSize = " + TrackSegment.idHashMapList.size()
         // );
         // TrackSegment.idHashMapList.clear();
-
     }
 
     private void saveTracks() {
@@ -949,7 +947,7 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
         XMLUtil.saveDocument(document, file);
     }
 
-    public static Document saveTracks(final List<TrackGroup> groups) {
+    public static @NotNull Document saveTracks(final @NotNull List<TrackGroup> groups) {
         final Document result = XMLUtil.createDocument(true);
         final Element rootElement = result.getDocumentElement();
 
@@ -1025,7 +1023,7 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
     }
 
     @Override
-    public void actionPerformed(final ActionEvent e) {
+    public void actionPerformed(final @NotNull ActionEvent e) {
         if (e.getSource() == onlineHelpMenuItem) {
             NetworkUtil.openBrowser("https://icy.bioimageanalysis.org/plugin/track-manager/");
         }
@@ -1135,8 +1133,7 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
             trackPool.fireTrackEditorProcessorChange();
         }
         if (e.getSource() == zoomMoreButton) {
-            trackPanel.setDetectDim(new Dimension((int) trackPanel.getDetectDim().getWidth() + 5,
-                    (int) trackPanel.getDetectDim().getHeight() + 5));
+            trackPanel.setDetectDim(new Dimension((int) trackPanel.getDetectDim().getWidth() + 5, (int) trackPanel.getDetectDim().getHeight() + 5));
             trackPool.fireTrackEditorProcessorChange();
         }
         // if (e.getSource() == zoomYLessButton)
@@ -1163,9 +1160,7 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
     }
 
     private void buildPluginMenu() {
-
         pluginPopupMenu.removeAll();
-
         {
             final JMenuItem menuItem = new JMenuItem("Add Track Processor Plugin...");
             menuItem.setEnabled(false);
@@ -1176,12 +1171,12 @@ public class TrackManager extends PluginActionable implements AdjustmentListener
         for (final PluginDescriptor plugin : PluginLoader.getPlugins()) {
             if (plugin.isInstanceOf(PluginTrackManagerProcessor.class))
                 if (!plugin.isAbstract()) {
-                    final JMenuItem menuItem = new JMenuItem(plugin.getName(), new ImageIcon(plugin.getIcon().getImage().getScaledInstance(24, 24, Image.SCALE_SMOOTH)));
+                    //final JMenuItem menuItem = new JMenuItem(plugin.getName(), new ImageIcon(plugin.getIcon().getImage().getScaledInstance(24, 24, Image.SCALE_SMOOTH)));
+                    final IcyPluginMenuItem menuItem = new IcyPluginMenuItem(plugin);
 
                     pluginPopupMenu.add(menuItem);
 
                     menuItem.addActionListener(new MenuItemActionListener(plugin, PluginTrackManagerProcessor.class));
-
                 }
         }
 
diff --git a/src/main/java/plugins/fab/trackmanager/TrackManagerPainter.java b/src/main/java/plugins/fab/trackmanager/TrackManagerPainter.java
index 16e38f3..6a6687b 100644
--- a/src/main/java/plugins/fab/trackmanager/TrackManagerPainter.java
+++ b/src/main/java/plugins/fab/trackmanager/TrackManagerPainter.java
@@ -26,6 +26,8 @@ import org.bioimageanalysis.icy.gui.canvas.IcyCanvas;
 import org.bioimageanalysis.icy.model.overlay.Overlay;
 import org.bioimageanalysis.icy.model.sequence.Sequence;
 import org.bioimageanalysis.icy.model.swimmingPool.SwimmingObject;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
 import plugins.nchenouard.spot.Detection;
 
 import java.awt.*;
@@ -68,7 +70,7 @@ public class TrackManagerPainter extends Overlay {
     }
 
     @Override
-    public void mouseClick(final MouseEvent e, /*Point2D p*/ final Point5D.Double imagePoint, final IcyCanvas icyCanvas) {
+    public void mouseClick(final @NotNull MouseEvent e, final Point5D.Double imagePoint, final IcyCanvas icyCanvas) {
         if (e.isConsumed())
             return;
 
@@ -309,7 +311,6 @@ public class TrackManagerPainter extends Overlay {
 
     @Override
     public void paint(final Graphics2D g, final Sequence sequence, final IcyCanvas canvas) {
-
         // System.out.println("TP");
 
         if (trackPool != null) {
@@ -511,6 +512,7 @@ public class TrackManagerPainter extends Overlay {
         final Detection start;
         final Detection end;
 
+        @Contract(pure = true)
         public TrackLineSection(final Detection start, final Detection end) {
             super();
 
@@ -518,7 +520,8 @@ public class TrackManagerPainter extends Overlay {
             this.end = end;
         }
 
-        public Line2D getLine2D(final Line2D line) {
+        @Contract("_ -> param1")
+        public @NotNull Line2D getLine2D(final @NotNull Line2D line) {
             line.setLine(start.getX(), start.getY(), end.getX(), end.getY());
             return line;
         }
@@ -527,7 +530,8 @@ public class TrackManagerPainter extends Overlay {
             return start.getColor();
         }
 
-        public Rectangle2D getBounds(final Rectangle2D bounds, final float stroke) {
+        @Contract("_, _ -> param1")
+        public @NotNull Rectangle2D getBounds(final @NotNull Rectangle2D bounds, final float stroke) {
             bounds.setFrameFromDiagonal(start.getX(), start.getY(), end.getX(), end.getY());
             ShapeUtil.enlarge(bounds, stroke, stroke, true);
             return bounds;
diff --git a/src/main/java/plugins/fab/trackmanager/TrackPanel.java b/src/main/java/plugins/fab/trackmanager/TrackPanel.java
index 40c0702..9a3436b 100644
--- a/src/main/java/plugins/fab/trackmanager/TrackPanel.java
+++ b/src/main/java/plugins/fab/trackmanager/TrackPanel.java
@@ -27,7 +27,10 @@ import org.bioimageanalysis.icy.gui.viewer.ViewerListener;
 import org.bioimageanalysis.icy.model.overlay.Overlay;
 import org.bioimageanalysis.icy.model.sequence.DimensionId;
 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.jetbrains.annotations.Nullable;
 import plugins.nchenouard.spot.Detection;
 
 import javax.swing.*;
@@ -48,7 +51,6 @@ import java.util.HashMap;
  * @author Fabrice de Chaumont
  */
 public class TrackPanel extends JPanel implements MouseListener, MouseMotionListener, TrackPainterListener, TrackManagerProcessorListener, ViewerListener, GlobalSequenceListener, GlobalViewerListener, Runnable {
-
     TimeCursor timeCursor = new TimeCursor();
 
     /**
@@ -58,8 +60,7 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
 
     private TrackPool trackPool;
 
-    public TrackPanel(final TrackPool trackPool, final boolean enableLeftPanelTrackDisplay) {
-
+    public TrackPanel(final @NotNull TrackPool trackPool, final boolean enableLeftPanelTrackDisplay) {
         super();
         this.enableLeftPanelTrackDisplay = enableLeftPanelTrackDisplay;
         this.trackPool = trackPool;
@@ -76,7 +77,6 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
         Icy.getMainInterface().addGlobalViewerListener(this);
 
         // System.out.println("TEST trackpanel");
-
     }
 
     void setupViewerListener() {
@@ -127,7 +127,6 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
     }
 
     private TrackSegment getTrackSegmentAt(int y) {
-
         TrackSegment tsResult = null;
 
         y = y / getDetectDim().height;
@@ -147,7 +146,7 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
         return tsResult;
     }
 
-    private Detection getDetectionAt(final int x, final int y) {
+    private @Nullable Detection getDetectionAt(final int x, final int y) {
         final TrackSegment ts = getTrackSegmentAt(y);
 
         if (ts == null)
@@ -226,7 +225,7 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
                 // look if at least one track exists.
                 boolean oneAtLeast = false;
                 for (final TrackGroup trackGroup : trackPool.getTrackGroupList()) {
-                    if (trackGroup.getTrackSegmentList().size() != 0) {
+                    if (!trackGroup.getTrackSegmentList().isEmpty()) {
                         oneAtLeast = true;
                         break;
                     }
@@ -285,13 +284,12 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
      * class use to record Track Drag states.
      */
     private static class TrackDrag {
-
         static boolean dragging = false;
         static TrackSegment ts = null;
     }
 
     @Override
-    public void mouseReleased(final MouseEvent e) {
+    public void mouseReleased(final @NotNull MouseEvent e) {
         MouseLink.xEnd = e.getX();
         MouseLink.yEnd = e.getY();
 
@@ -344,7 +342,6 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
             timeCursor.dragging = false;
             repaint();
         }
-
     }
 
     @Override
@@ -633,7 +630,6 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
     public void setTrackPool(final TrackPool trackPool) {
         this.trackPool = trackPool;
         clearDetectionsAndReDisplay();
-
     }
 
     /**
@@ -695,8 +691,7 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
 
         if (width * height > maxSize) {
             height = maxSize / width;
-            System.out.println(
-                    "too much track to display them all in trackManager left panel. Still, they all appear on the sequence.");
+            IcyLogger.warn(this.getClass(), "too much track to display them all in trackManager left panel.", "Still, they all appear on the sequence.");
         }
 
         // if ( trackingPanelSize.width * trackingPanelSize.height > maxSize )
@@ -723,9 +718,12 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
                             BufferedImage.TYPE_INT_RGB);
                 }
                 catch (final OutOfMemoryError e) {
-                    System.out.println("can't create " + trackingPanelSize.width + "x" + trackingPanelSize.height
-                            + " bitmap for track representation in trackPanel");
-                    System.out.println("left panel disabled");
+                    IcyLogger.error(
+                            this.getClass(),
+                            e,
+                            "can't create " + trackingPanelSize.width + "x" + trackingPanelSize.height + " bitmap for track representation in trackPanel.",
+                            "left panel disabled"
+                    );
                     enableLeftPanelTrackDisplay = false;
                     return;
                 }
@@ -883,8 +881,7 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
         repaint();
     }
 
-    private void drawDetection(final Graphics2D g, final Detection d, final Rectangle2D bounds) {
-
+    private void drawDetection(final @NotNull Graphics2D g, final @NotNull Detection d, final Rectangle2D bounds) {
         g.setColor(d.getColor());
         g.fill(bounds);
         g.setColor(d.getColor().darker());
@@ -903,7 +900,6 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
             g.drawLine((int) bounds.getMinX(), (int) bounds.getMinY(), (int) bounds.getMaxX(), (int) bounds.getMaxY());
             g.setStroke(new BasicStroke(1));
         }
-
     }
 
     BufferedImage bufferedImage;
@@ -947,10 +943,8 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
         // draw current Time Cursor.
         g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f));
         g.setColor(Color.red);
-        g.fillRect(getDetectDim().width * timeCursor.currentT, getVisibleRect().y, getDetectDim().width,
-                getVisibleRect().height);
+        g.fillRect(getDetectDim().width * timeCursor.currentT, getVisibleRect().y, getDetectDim().width, getVisibleRect().height);
         g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
-
     }
 
     /**
@@ -996,7 +990,6 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
         }
         clearDetectionsAndReDisplay();
         updateUI();
-
     }
 
     /**
@@ -1036,7 +1029,7 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
     }
 
     @Override
-    public void viewerChanged(final ViewerEvent event) {
+    public void viewerChanged(final @NotNull ViewerEvent event) {
         if (event.getDim() == DimensionId.T) {
             timeCursor.currentT = event.getSource().getPositionT();
             // trackPool.fireTrackEditorProcessorChange();
@@ -1049,13 +1042,11 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
 
     public void displaySequenceChanged() {
         setupViewerListener();
-
     }
 
     public void setEnableLeftPanelTrackDisplay(final boolean selected) {
         this.enableLeftPanelTrackDisplay = selected;
         redrawDetection3();
-
     }
 
     @Override
@@ -1066,18 +1057,15 @@ public class TrackPanel extends JPanel implements MouseListener, MouseMotionList
     @Override
     public void viewerOpened(final Viewer viewer) {
         setupViewerListener();
-
     }
 
     @Override
     public void sequenceOpened(final Sequence sequence) {
         setupViewerListener();
-
     }
 
     @Override
     public void sequenceClosed(final Sequence sequence) {
         setupViewerListener();
     }
-
 }
diff --git a/src/main/java/plugins/fab/trackmanager/TrackPool.java b/src/main/java/plugins/fab/trackmanager/TrackPool.java
index 879d3fd..6771976 100644
--- a/src/main/java/plugins/fab/trackmanager/TrackPool.java
+++ b/src/main/java/plugins/fab/trackmanager/TrackPool.java
@@ -23,6 +23,9 @@ import org.bioimageanalysis.icy.gui.dialog.MessageDialog;
 import org.bioimageanalysis.icy.gui.frame.progress.AnnounceFrame;
 import org.bioimageanalysis.icy.model.sequence.Sequence;
 import org.bioimageanalysis.icy.model.swimmingPool.SwimmingObject;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
 import plugins.nchenouard.spot.Detection;
 
 import javax.swing.event.ChangeEvent;
@@ -35,9 +38,7 @@ import java.util.List;
  *
  * @author Fabrice de Chaumont
  */
-
 public class TrackPool {
-
     private final TrackManagerPainter tePainter;
 
     private final ArrayList<PluginTrackManagerProcessor> trackManagerProcessorList = new ArrayList<>();
@@ -79,7 +80,8 @@ public class TrackPool {
         fireTrackEditorProcessorChange();
     }
 
-    public static boolean linkExists(final List<Link> links, final TrackSegment start, final TrackSegment end) {
+    @Contract(pure = true)
+    public static boolean linkExists(final @NotNull List<Link> links, final TrackSegment start, final TrackSegment end) {
         // check if the link already exists
         for (final Link link : links)
             if ((link.start == start) && (link.end == end))
@@ -144,7 +146,7 @@ public class TrackPool {
                 final ArrayList<TrackSegment> returnList = splitTrackSegment(segmentStart,
                         segmentStart.getDetectionIndex(detectionStart), true);
                 // should render 2 segments. The first is the one we want. We take the last detection of the first tracksegment.
-                detectionStart = returnList.get(0).getLastDetection();
+                detectionStart = returnList.getFirst().getLastDetection();
                 segmentStart = getTrackSegmentWithDetection(detectionStart);
             }
 
@@ -257,7 +259,6 @@ public class TrackPool {
      * Creates a virtual track
      */
     public void createVirtualTrackWith2TrackDetection(final Detection detectionStart, final Detection detectionEnd) {
-
         // check if both sides of the link are TrackDetectionComponents.
         if (detectionStart == null)
             return;
@@ -333,7 +334,7 @@ public class TrackPool {
     /**
      * @return null if no trackgroup contains the tracksegment
      */
-    public TrackGroup getTrackGroupContainingSegment(final TrackSegment ts) {
+    public TrackGroup getTrackGroupContainingSegment(final @NotNull TrackSegment ts) {
         return ts.getOwnerTrackGroup();
 
     }
@@ -345,8 +346,7 @@ public class TrackPool {
 
         final TrackGroup trackGroup = getTrackGroupContainingSegment(ts);
         if (trackGroup == null) {
-            System.out.println(
-                    "Can't delete The track segment " + ts + " Reason: it is not in any trackGroup");
+            IcyLogger.warn(this.getClass(), "Can't delete The track segment " + ts + " Reason: it is not in any trackGroup.");
             return;
         }
         trackGroup.getTrackSegmentList().remove(ts);
@@ -407,10 +407,10 @@ public class TrackPool {
             for (final TrackSegment ts : trackSegmentListClone) {
                 // System.out.println("Computing trackSegment # " + trackSegmentListClone.indexOf( ts ) );
                 if (ts.nextList.size() == 1) // if the track has only one successor.
-                    if (ts.nextList.get(0).previousList.size() == 1) // If successor has only one predecessor.
+                    if (ts.nextList.getFirst().previousList.size() == 1) // If successor has only one predecessor.
                     {
                         // System.out.println("Fusing...");
-                        fuseTrack(ts, ts.nextList.get(0)); // fuse tracks.
+                        fuseTrack(ts, ts.nextList.getFirst()); // fuse tracks.
                         fuseOperationPerformed = true;
                         break;
                     }
@@ -423,7 +423,7 @@ public class TrackPool {
     /**
      * Fusing 2 tracks ts1 is one step before ts2.
      */
-    public void fuseTrack(final TrackSegment ts1, final TrackSegment ts2) {
+    public void fuseTrack(final TrackSegment ts1, final @NotNull TrackSegment ts2) {
         // System.out.println("debug fuse track: fusing ");
         // System.out.println("ts1 = " + ts1);
         // System.out.println("ts2 = " + ts2);
@@ -438,7 +438,7 @@ public class TrackPool {
 
         // ts1.getDetectionList().addAll(ts2.getDetectionList());
 
-        while (ts2.getDetectionList().size() > 0) {
+        while (!ts2.getDetectionList().isEmpty()) {
             final Detection detection = ts2.getFirstDetection();
             ts2.removeDetection(detection);
             // System.out.println("Remove 1 detection to ts2. t=" + detection.getT() );
@@ -461,7 +461,7 @@ public class TrackPool {
     /**
      * return distance between 2 detections
      */
-    public double getDistance(final Detection d1, final Detection d2) {
+    public double getDistance(final @NotNull Detection d1, final @NotNull Detection d2) {
         return getDistance(d1.getX(), d1.getY(), d1.getZ(), d2.getX(), d2.getY(), d2.getZ());
     }
 
@@ -493,7 +493,7 @@ public class TrackPool {
         return linkarray;
     }
 
-    public static List<Link> getLinks(final List<TrackGroup> groups) {
+    public static @NotNull List<Link> getLinks(final List<TrackGroup> groups) {
         final List<Link> result = new ArrayList<>();
         final List<TrackSegment> segments = getTrackSegmentList(groups);
 
@@ -551,7 +551,7 @@ public class TrackPool {
     /**
      * @return the pool of tracksegment of all the trackgroup
      */
-    public static List<TrackSegment> getTrackSegmentList(final List<TrackGroup> groups) {
+    public static @NotNull List<TrackSegment> getTrackSegmentList(final @NotNull List<TrackGroup> groups) {
         final List<TrackSegment> result = new ArrayList<>();
 
         for (final TrackGroup group : groups)
@@ -564,7 +564,6 @@ public class TrackPool {
      * @return the pool of tracksegment of all the trackgroup
      */
     public ArrayList<TrackSegment> getTrackSegmentList() {
-
         final ArrayList<TrackSegment> trackSegmentList = new ArrayList<>();
         for (final TrackGroup group : getTrackGroupList()) {
             trackSegmentList.addAll(group.getTrackSegmentList());
@@ -577,7 +576,6 @@ public class TrackPool {
      * find the tracksegment containing the given detection
      */
     public TrackSegment getTrackSegmentWithDetection(final Detection detection) {
-
         final ArrayList<TrackSegment> trackSegmentList = getTrackSegmentList();
 
         for (final TrackSegment ts : trackSegmentList) {
@@ -589,14 +587,13 @@ public class TrackPool {
     }
 
     // FIXME: 05/04/2023 does nothing
-    public static ArrayList<TrackSegment> loadTracks(final File f) {
-
+    public static @NotNull ArrayList<TrackSegment> loadTracks(final File f) {
         final ArrayList<TrackSegment> inputTrackSegmentList = new ArrayList<>();
         final ArrayList<TrackSegment> targetTrackSegmentList = new ArrayList<>();
 
         for (final TrackSegment ts : inputTrackSegmentList) {
             if (ts.getFirstDetection() == null || ts.getLastDetection() == null) {
-                System.out.println("Warning, found and removed empty track segment");
+                IcyLogger.warn(TrackPool.class, "Warning, found and removed empty track segment");
                 continue;
             }
 
@@ -610,7 +607,7 @@ public class TrackPool {
             }
 
             if (skipTrackSegment) {
-                System.out.println("Warning, found and removed empty track segment");
+                IcyLogger.warn(TrackPool.class, "Warning, found and removed empty track segment");
                 continue;
             }
 
@@ -628,7 +625,7 @@ public class TrackPool {
     /**
      * remove a link between 2 track segment.
      */
-    public void removeLink(final TrackSegment start, final TrackSegment end) {
+    public void removeLink(final @NotNull TrackSegment start, final TrackSegment end) {
         // int nb = 0;
         // while ( start.nextList.contains( end ) )
         // {
@@ -668,14 +665,12 @@ public class TrackPool {
     }
 
     public void selectTracksByLength(final int lowVal, final int highVal) {
-
         for (final TrackSegment ts : getTrackSegmentList()) {
             if (ts.getDetectionList().size() >= lowVal && ts.getDetectionList().size() <= highVal) {
                 ts.setAllDetectionSelected(true);
             }
         }
         fireTrackEditorProcessorChange();
-
     }
 
     public void unselectAllTracks() {
@@ -773,11 +768,9 @@ public class TrackPool {
         trackSegmentReturnList.add(ts1);
         trackSegmentReturnList.add(ts2);
         return trackSegmentReturnList;
-
     }
 
     public ArrayList<TrackGroup> getTrackGroupList() {
-
         final ArrayList<TrackGroup> trackGroupList = new ArrayList<>();
 
         for (final SwimmingObject result : resultList)
@@ -791,7 +784,7 @@ public class TrackPool {
      */
     ArrayList<SwimmingObject> resultList = new ArrayList<>();
 
-    public void addResult(final SwimmingObject result) {
+    public void addResult(final @NotNull SwimmingObject result) {
         if (!(result.getObject() instanceof TrackGroup)) {
             // System.out.println("Object " + result + " is not recognized as a TrackGroup.");
             return;
@@ -807,9 +800,7 @@ public class TrackPool {
 
         resultList.remove(result);
 
-        if (result.getObject() instanceof TrackGroup) {
-            final TrackGroup tg = (TrackGroup) result.getObject();
-
+        if (result.getObject() instanceof final TrackGroup tg) {
             // remove track segment from hash map
             for (final TrackSegment ts : tg.getTrackSegmentList())
                 ts.removeId();
@@ -820,27 +811,22 @@ public class TrackPool {
      * removes the painter from all sequences.
      */
     public void removePainter() {
-
         // System.out.println("remove painter");
 
         final List<Sequence> sequenceList = Icy.getMainInterface().getSequencesContaining(tePainter);
         for (final Sequence sequence : sequenceList) {
             sequence.removeOverlay(tePainter);
         }
-
     }
 
     public int getTrackIndex(final TrackSegment ts) {
-
         return getTrackSegmentList().indexOf(ts);
-
     }
 
     /**
      * @return the timepoint corresponding to the last detection of all the trackgroup.
      */
     public int getLastDetectionTimePoint() {
-
         int maxT = 0;
         for (final TrackGroup tg : getTrackGroupList()) {
             for (final TrackSegment ts : tg.getTrackSegmentList()) {
diff --git a/src/main/java/plugins/fab/trackmanager/TrackSegment.java b/src/main/java/plugins/fab/trackmanager/TrackSegment.java
index 4afa588..7a76dc6 100644
--- a/src/main/java/plugins/fab/trackmanager/TrackSegment.java
+++ b/src/main/java/plugins/fab/trackmanager/TrackSegment.java
@@ -19,6 +19,7 @@
 package plugins.fab.trackmanager;
 
 import org.bioimageanalysis.icy.common.math.Random;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
 import plugins.nchenouard.spot.Detection;
 
 import java.lang.ref.Reference;
@@ -32,9 +33,8 @@ import java.util.Map;
  * TrackSegment is a pool of consecutive detection.
  *
  * @author Fabrice de Chaumont
- * @author Stephane
+ * @author Stephane Dallongeville
  */
-
 public class TrackSegment implements Cloneable {
     // better to use weak reference in the map 
     protected final static Map<Integer, Reference<TrackSegment>> idKeyHashMapList = new HashMap<>(); // 1-1 hashmap.
@@ -145,7 +145,7 @@ public class TrackSegment implements Cloneable {
                 this.id = key;
             }
             else
-                System.out.println("track id already loaded");
+                IcyLogger.warn(this.getClass(), "Track ID already loaded.");
         }
     }
 
@@ -209,8 +209,7 @@ public class TrackSegment implements Cloneable {
         if (!detectionList.isEmpty()) {
             final Detection detectionPrevious = getLastDetection();
             if (detection.getT() != detectionPrevious.getT() + 1) {
-                System.err.println(
-                        "TrackSegment : The detection must be added with consecutive T value. Detection was not added");
+                IcyLogger.warn(this.getClass(), "TrackSegment : The detection must be added with consecutive T value. Detection was not added.");
                 // throw new IllegalArgumentException();
                 return;
             }
@@ -275,10 +274,10 @@ public class TrackSegment implements Cloneable {
      * return first detection ( should be first in time too )
      */
     public Detection getFirstDetection() {
-        if (detectionList.size() == 0)
+        if (detectionList.isEmpty())
             return null;
 
-        return detectionList.get(0);
+        return detectionList.getFirst();
     }
 
     /**
diff --git a/src/main/java/plugins/fab/trackmanager/blocks/LoadTracksFromXML.java b/src/main/java/plugins/fab/trackmanager/blocks/LoadTracksFromXML.java
index 9487a08..e0b91c2 100644
--- a/src/main/java/plugins/fab/trackmanager/blocks/LoadTracksFromXML.java
+++ b/src/main/java/plugins/fab/trackmanager/blocks/LoadTracksFromXML.java
@@ -21,8 +21,7 @@ package plugins.fab.trackmanager.blocks;
 import org.bioimageanalysis.icy.extension.plugin.abstract_.Plugin;
 import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginIcon;
 import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginName;
-import org.bioimageanalysis.icy.extension.plugin.interface_.PluginBundled;
-import org.bioimageanalysis.icy.extension.plugin.interface_.PluginLibrary;
+import org.jetbrains.annotations.NotNull;
 import plugins.adufour.blocks.tools.roi.ROIBlock;
 import plugins.adufour.blocks.util.VarList;
 import plugins.adufour.vars.lang.Var;
@@ -37,14 +36,14 @@ import java.util.List;
 /**
  * Block to load a set of ROI from a file
  *
- * @author Stephane
+ * @author Stephane Dallongeville
  */
 @IcyPluginName("Load Tracks From XML")
 @IcyPluginIcon(path = "/track-manager.png")
-public class LoadTracksFromXML extends Plugin implements ROIBlock, PluginLibrary, PluginBundled {
+public class LoadTracksFromXML extends Plugin implements ROIBlock {
     final VarMutable file = new VarMutable("XML file", null) {
         @Override
-        public boolean isAssignableFrom(final Var source) {
+        public boolean isAssignableFrom(final @NotNull Var source) {
             return (String.class == source.getType()) || (File.class == source.getType());
         }
     };
@@ -71,19 +70,14 @@ public class LoadTracksFromXML extends Plugin implements ROIBlock, PluginLibrary
     }
 
     @Override
-    public void declareInput(final VarList inputMap) {
+    public void declareInput(final @NotNull VarList inputMap) {
         inputMap.add("file", file);
         inputMap.add("groupIndex", groupIndex);
     }
 
     @Override
-    public void declareOutput(final VarList outputMap) {
+    public void declareOutput(final @NotNull VarList outputMap) {
         outputMap.add("tracks", tracks);
 
     }
-
-    @Override
-    public String getMainPluginClassName() {
-        return TrackManager.class.getName();
-    }
 }
diff --git a/src/main/java/plugins/fab/trackmanager/blocks/SaveTracksToXML.java b/src/main/java/plugins/fab/trackmanager/blocks/SaveTracksToXML.java
index 72cffb4..e8c88a1 100644
--- a/src/main/java/plugins/fab/trackmanager/blocks/SaveTracksToXML.java
+++ b/src/main/java/plugins/fab/trackmanager/blocks/SaveTracksToXML.java
@@ -22,8 +22,7 @@ import org.bioimageanalysis.icy.common.collection.CollectionUtil;
 import org.bioimageanalysis.icy.extension.plugin.abstract_.Plugin;
 import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginIcon;
 import org.bioimageanalysis.icy.extension.plugin.annotation_.IcyPluginName;
-import org.bioimageanalysis.icy.extension.plugin.interface_.PluginBundled;
-import org.bioimageanalysis.icy.extension.plugin.interface_.PluginLibrary;
+import org.jetbrains.annotations.NotNull;
 import plugins.adufour.blocks.tools.roi.ROIBlock;
 import plugins.adufour.blocks.util.VarList;
 import plugins.adufour.vars.lang.Var;
@@ -36,15 +35,15 @@ import java.io.File;
 /**
  * Block to save a set of ROI to a file
  *
- * @author Stephane
+ * @author Stephane Dallongeville
  */
 @IcyPluginName("Save Tracks To XML")
 @IcyPluginIcon(path = "/track-manager.png")
-public class SaveTracksToXML extends Plugin implements ROIBlock, PluginLibrary, PluginBundled {
+public class SaveTracksToXML extends Plugin implements ROIBlock {
     final Var<TrackGroup> tracks = new Var<>("Track group", new TrackGroup(null));
     final VarMutable file = new VarMutable("XML file", null) {
         @Override
-        public boolean isAssignableFrom(final Var source) {
+        public boolean isAssignableFrom(final @NotNull Var source) {
             return (String.class == source.getType()) || (File.class == source.getType());
         }
     };
@@ -72,7 +71,7 @@ public class SaveTracksToXML extends Plugin implements ROIBlock, PluginLibrary,
     }
 
     @Override
-    public void declareInput(final VarList inputMap) {
+    public void declareInput(final @NotNull VarList inputMap) {
         inputMap.add("tracks", tracks);
         inputMap.add("file", file);
     }
@@ -81,9 +80,4 @@ public class SaveTracksToXML extends Plugin implements ROIBlock, PluginLibrary,
     public void declareOutput(final VarList outputMap) {
         //
     }
-
-    @Override
-    public String getMainPluginClassName() {
-        return TrackManager.class.getName();
-    }
 }
-- 
GitLab