diff --git a/.gitignore b/.gitignore
index 3d47f986c41db29ec6dc0d5036bf760b3a1cf366..57f16fb67c1b1589981416b323d7a9debc728665 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,41 @@
-.idea/
+/build*
+/workspace
+setting.xml
+release/
 target/
-.settings/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+icy.log
+
+### IntelliJ IDEA ###
+.idea/
+*.iws
 *.iml
+*.ipr
+
+### Eclipse ###
+.apt_generated
+.classpath
+.factorypath
 .project
-.classpath
\ No newline at end of file
+.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 1f12d2d6e7f7957625c0aea07e2ed3ee4d53333b..ddb0adaae907a4be27a49400509f735d23121dab 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,15 +7,13 @@
     <!-- Inherited Icy Parent POM -->
     <parent>
         <groupId>org.bioimageanalysis.icy</groupId>
-        <artifactId>parent-pom-plugin</artifactId>
-        <version>1.0.3</version>
+        <artifactId>pom-icy</artifactId>
+        <version>3.0.0-a.1</version>
     </parent>
 
     <!-- Project Information -->
     <artifactId>roi-tooltip</artifactId>
-    <version>1.1.4</version>
-
-    <packaging>jar</packaging>
+    <version>2.0.0-a.1</version>
 
     <name>ROI Tooltip</name>
     <description>
@@ -23,7 +21,7 @@
         position and size. - number of interior points and contour points. - perimeter, area, surface area, volume. - min, max, mean
         intensity. This plugin is a daemon plugin, that means plugin is automatically loaded when Icy starts.
     </description>
-    <url>http://icy.bioimageanalysis.org/plugin/roi-tooltip/</url>
+    <url>https://icy.bioimageanalysis.org/plugin/roi-tooltip/</url>
     <inceptionYear>2020</inceptionYear>
 
     <organization>
@@ -57,31 +55,11 @@
         </developer>
     </developers>
 
-    <!-- Project properties -->
-    <properties>
-
-    </properties>
-
-    <!-- Project build configuration -->
-    <build>
-
-    </build>
-
-    <!-- List of project's dependencies -->
-    <dependencies>
-        <!-- The core of Icy -->
-        <dependency>
-            <groupId>org.bioimageanalysis.icy</groupId>
-            <artifactId>icy-kernel</artifactId>
-        </dependency>
-    </dependencies>
-
     <!-- Icy Maven repository (to find parent POM) -->
     <repositories>
         <repository>
             <id>icy</id>
-            <name>Icy's Nexus</name>
-            <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/stef/roi/ROIToolTip.java b/src/main/java/plugins/stef/roi/ROIToolTip.java
index 808c80c06974ce0555ad7cc50306b667f7be7a15..aa405f4e4eec44922fe077f4a29a17aec1d54c62 100644
--- a/src/main/java/plugins/stef/roi/ROIToolTip.java
+++ b/src/main/java/plugins/stef/roi/ROIToolTip.java
@@ -1,36 +1,51 @@
+/*
+ * Copyright (c) 2010-2024. Institut Pasteur.
+ *
+ * This file is part of Icy.
+ * Icy is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Icy is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Icy. If not, see <https://www.gnu.org/licenses/>.
+ */
+
 package plugins.stef.roi;
 
-import icy.canvas.IcyCanvas;
-import icy.canvas.IcyCanvas2D;
-import icy.canvas.Layer;
-import icy.gui.main.ActiveViewerListener;
-import icy.gui.viewer.Viewer;
-import icy.gui.viewer.ViewerEvent;
-import icy.image.IntensityInfo;
-import icy.main.Icy;
-import icy.math.MathUtil;
-import icy.painter.Overlay;
-import icy.plugin.abstract_.Plugin;
-import icy.plugin.interface_.PluginDaemon;
-import icy.roi.ROI;
-import icy.roi.ROI2D;
-import icy.roi.ROI3D;
-import icy.roi.ROIEvent;
-import icy.roi.ROIEvent.ROIEventType;
-import icy.roi.ROIListener;
-import icy.roi.ROIUtil;
-import icy.sequence.Sequence;
-import icy.system.thread.SingleProcessor;
-import icy.util.GraphicsUtil;
-import icy.util.StringUtil;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
+import org.bioimageanalysis.extension.kernel.roi.descriptor.measure.ROIAreaDescriptor;
+import org.bioimageanalysis.extension.kernel.roi.descriptor.measure.ROIPerimeterDescriptor;
+import org.bioimageanalysis.extension.kernel.roi.descriptor.measure.ROISurfaceAreaDescriptor;
+import org.bioimageanalysis.extension.kernel.roi.descriptor.measure.ROIVolumeDescriptor;
+import org.bioimageanalysis.icy.Icy;
+import org.bioimageanalysis.icy.common.math.MathUtil;
+import org.bioimageanalysis.icy.common.string.StringUtil;
+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_.PluginDaemon;
+import org.bioimageanalysis.icy.gui.GraphicsUtil;
+import org.bioimageanalysis.icy.gui.canvas.IcyCanvas;
+import org.bioimageanalysis.icy.gui.canvas.IcyCanvas2D;
+import org.bioimageanalysis.icy.gui.canvas.Layer;
+import org.bioimageanalysis.icy.gui.listener.ActiveViewerListener;
+import org.bioimageanalysis.icy.gui.viewer.Viewer;
+import org.bioimageanalysis.icy.gui.viewer.ViewerEvent;
+import org.bioimageanalysis.icy.model.overlay.Overlay;
+import org.bioimageanalysis.icy.model.roi.*;
+import org.bioimageanalysis.icy.model.roi.descriptor.IntensityDescriptorInfos;
+import org.bioimageanalysis.icy.model.sequence.Sequence;
+import org.bioimageanalysis.icy.system.logging.IcyLogger;
+import org.bioimageanalysis.icy.system.thread.SingleProcessor;
+import org.jetbrains.annotations.Contract;
+import org.jetbrains.annotations.NotNull;
+
+import java.awt.*;
 import java.awt.geom.Rectangle2D;
 import java.util.ArrayList;
 import java.util.List;
@@ -38,39 +53,40 @@ import java.util.List;
 /**
  * ROI Tooltip plugin.<br>
  * Display a tool tip with extras informations on focused ROI in Canvas2D.
- * 
- * @author Stephane
+ *
+ * @author Stephane Dallongeville
  */
-public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerListener, ROIListener
-{
-    private class ROICalculator implements Runnable
-    {
-        public ROICalculator()
-        {
+@IcyPluginName("ROI Tooltip")
+@IcyPluginIcon(path = "/roi-tooltip.png")
+public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerListener, ROIListener {
+    private class ROICalculator implements Runnable {
+        @Contract(pure = true)
+        public ROICalculator() {
             super();
         }
 
         @Override
-        public void run()
-        {
+        public void run() {
             final Sequence seq = activeSequence;
             final ROI roi = focusedROI;
 
-            try
-            {
-                if ((seq != null) && (roi != null))
-                {
-                    intensityInfo = ROIUtil.getIntensityInfo(activeSequence, focusedROI);
+            try {
+                if ((seq != null) && (roi != null)) {
+                    //intensityInfo = ROIUtil.getIntensityInfo(activeSequence, focusedROI);
+                    intensityInfo = ROIUtil.computeIntensityDescriptors(focusedROI, activeSequence, true);
                     points = MathUtil.roundSignificant(roi.getNumberOfPoints(), 2, true);
                     contourPoints = MathUtil.roundSignificant(roi.getNumberOfContourPoints(), 2, true);
-                    perimeter = ROIUtil.getPerimeter(activeSequence, roi);
-                    area = ROIUtil.getArea(activeSequence, roi);
-                    surfaceArea = ROIUtil.getSurfaceArea(activeSequence, roi);
-                    volume = ROIUtil.getVolume(activeSequence, roi);
+                    //perimeter = ROIUtil.getPerimeter(activeSequence, roi);
+                    perimeter = (Double) ROIUtil.computeDescriptor(ROIPerimeterDescriptor.ID, roi, activeSequence);
+                    //area = ROIUtil.getArea(activeSequence, roi);
+                    area = (Double) ROIUtil.computeDescriptor(ROIAreaDescriptor.ID, roi, activeSequence);
+                    //surfaceArea = ROIUtil.getSurfaceArea(activeSequence, roi);
+                    surfaceArea = (Double) ROIUtil.computeDescriptor(ROISurfaceAreaDescriptor.ID, roi, activeSequence);
+                    //volume = ROIUtil.getVolume(activeSequence, roi);
+                    volume = (Double) ROIUtil.computeDescriptor(ROIVolumeDescriptor.ID, roi, activeSequence);
                 }
             }
-            catch (Exception e)
-            {
+            catch (final Exception e) {
                 // async process, ROI can change in the meantime
             }
 
@@ -78,31 +94,25 @@ public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerList
         }
     }
 
-    private class HintOverlay extends Overlay
-    {
-        public HintOverlay()
-        {
+    private class HintOverlay extends Overlay {
+        public HintOverlay() {
             super("ROI tip", OverlayPriority.TOOLTIP_LOW);
         }
 
-        private String enlarge(String text, int len)
-        {
-            String result = text;
+        @Contract(pure = true)
+        private @NotNull String enlarge(final String text, final int len) {
+            final StringBuilder result = new StringBuilder(text);
             while (result.length() < len)
-                result += ' ';
-            return result;
+                result.append(' ');
+            return result.toString();
         }
 
         @Override
-        public void paint(Graphics2D g, Sequence sequence, IcyCanvas canvas)
-        {
-            if (canvas instanceof IcyCanvas2D)
-            {
-                final IcyCanvas2D cnv2d = (IcyCanvas2D) canvas;
+        public void paint(final Graphics2D g, final Sequence sequence, final IcyCanvas canvas) {
+            if (canvas instanceof final IcyCanvas2D cnv2d) {
                 ROI roi = sequence.getFocusedROI();
 
-                if (roi == null)
-                {
+                if (roi == null) {
                     // search in selected ROI
                     final ROI2D selectedRoi = sequence.getSelectedROI2D();
 
@@ -111,16 +121,16 @@ public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerList
                         roi = selectedRoi;
                 }
 
-                if (roi != null)
-                {
+                if (roi != null) {
                     roiFocused(roi);
 
-                    if (roi instanceof ROI2D)
-                    {
+                    if (roi instanceof ROI2D) {
                         final Rectangle2D bounds = ((ROI2D) roi).getBounds2D();
-                        final List<String> text = new ArrayList<String>();
-                        final String perim = perimeter;
-                        final String surfArea = surfaceArea;
+                        final List<String> text = new ArrayList<>();
+                        //final String perim = perimeter;
+                        final double perim = perimeter;
+                        //final String surfArea = surfaceArea;
+                        final double surfArea = surfaceArea;
 
                         // if (processor.isProcessing())
                         // updatingMark = "*";
@@ -131,17 +141,19 @@ public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerList
                         text.add("Position X " + StringUtil.toString(bounds.getX(), 1));
                         text.add("Size X     " + StringUtil.toString(bounds.getWidth(), 1));
                         text.add("Interior   " + StringUtil.toString(points) + " px");
-                        if (!StringUtil.isEmpty(perim))
-                            text.add("Perimeter  " + perim);
-                        if (!StringUtil.isEmpty(surfArea))
-                            text.add("Surf. area " + surfArea);
+                        //if (!StringUtil.isEmpty(perim))
+                        if (perim > 0)
+                            text.add("Perimeter  " + String.format("%.2f", perim));
+                        //if (!StringUtil.isEmpty(surfArea))
+                        if (surfArea > 0)
+                            text.add("Surf. area " + String.format("%.2f", surfArea));
 
                         int maxLength = 0;
-                        for (String t : text)
+                        for (final String t : text)
                             maxLength = Math.max(maxLength, t.length());
                         maxLength += 2;
 
-                        String tooltipText = "";
+                        String tooltipText; // = "";
                         int ind = 0;
 
                         tooltipText = enlarge(text.get(ind++), maxLength);
@@ -151,23 +163,22 @@ public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerList
                         tooltipText += enlarge(text.get(ind++), maxLength);
                         tooltipText += "Contour    " + StringUtil.toString(contourPoints) + " px" + "\n";
 
-                        if (!StringUtil.isEmpty(perim))
-                        {
+                        //if (!StringUtil.isEmpty(perim)) {
+                        if (perim > 0) {
                             tooltipText += enlarge(text.get(ind++), maxLength);
-                            tooltipText += "Area       " + area + "\n";
+                            tooltipText += "Area       " + String.format("%.2f", area) + "\n";
                         }
-                        if (!StringUtil.isEmpty(surfArea))
-                        {
+                        //if (!StringUtil.isEmpty(surfArea)) {
+                        if (surfArea > 0) {
                             tooltipText += enlarge(text.get(ind++), maxLength);
-                            tooltipText += "Volume     " + volume + "\n";
+                            tooltipText += "Volume     " + String.format("%.2f", volume) + "\n";
                         }
 
-                        if (intensityInfo != null)
-                        {
+                        if (intensityInfo != null) {
                             tooltipText += "Intensity  ";
-                            tooltipText += "min: " + StringUtil.toString(intensityInfo.minIntensity, 1) + "  ";
-                            tooltipText += "max: " + StringUtil.toString(intensityInfo.maxIntensity, 1) + "  ";
-                            tooltipText += "mean: " + StringUtil.toString(intensityInfo.meanIntensity, 1);
+                            tooltipText += "min: " + StringUtil.toString(intensityInfo.min, 1) + "  ";
+                            tooltipText += "max: " + StringUtil.toString(intensityInfo.max, 1) + "  ";
+                            tooltipText += "mean: " + StringUtil.toString(intensityInfo.mean, 1);
                         }
 
                         final Graphics2D g2 = (Graphics2D) g.create();
@@ -194,10 +205,9 @@ public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerList
 
                         g2.dispose();
                     }
-                    else if (roi instanceof ROI3D)
-                    {
+                    else if (roi instanceof ROI3D) {
                         // not yet supported
-
+                        IcyLogger.warn(this.getClass(), "ROI3D not supported yet.");
                     }
                 }
             }
@@ -214,31 +224,33 @@ public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerList
     /**
      * ROI calculated infos
      */
-    IntensityInfo intensityInfo;
+    //IntensityInfo intensityInfo;
+    IntensityDescriptorInfos intensityInfo;
     double points;
     double contourPoints;
-    String perimeter;
-    String area;
-    String surfaceArea;
-    String volume;
-
-    public ROIToolTip()
-    {
+    //String perimeter;
+    double perimeter;
+    //String area;
+    double area;
+    //String surfaceArea;
+    double surfaceArea;
+    //String volume;
+    double volume;
+
+    public ROIToolTip() {
         super();
 
         overlay = new HintOverlay();
-        intensityInfo = new IntensityInfo();
+        intensityInfo = new IntensityDescriptorInfos();
         processor = new SingleProcessor(true);
     }
 
-    void updateInfos()
-    {
+    void updateInfos() {
         processor.submit(new ROICalculator());
     }
 
     @Override
-    public void init()
-    {
+    public void init() {
         activeViewer = null;
         activeSequence = null;
         focusedROI = null;
@@ -250,24 +262,20 @@ public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerList
     }
 
     @Override
-    public void run()
-    {
+    public void run() {
         // nothing to do here
     }
 
     @Override
-    public void stop()
-    {
+    public void stop() {
         Icy.getMainInterface().removeActiveViewerListener(this);
 
         viewerActivated(null);
         roiFocused(null);
     }
 
-    public void sequenceActivated(Sequence sequence)
-    {
-        if (activeSequence != sequence)
-        {
+    public void sequenceActivated(final Sequence sequence) {
+        if (activeSequence != sequence) {
             if (activeSequence != null)
                 activeSequence.removeOverlay(overlay);
 
@@ -279,10 +287,8 @@ public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerList
         }
     }
 
-    public void roiFocused(ROI roi)
-    {
-        if (focusedROI != roi)
-        {
+    public void roiFocused(final ROI roi) {
+        if (focusedROI != roi) {
             if (focusedROI != null)
                 focusedROI.removeListener(this);
 
@@ -296,27 +302,22 @@ public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerList
     }
 
     @Override
-    public void roiChanged(ROIEvent event)
-    {
-        if (event.getType() == ROIEventType.ROI_CHANGED)
+    public void roiChanged(final @NotNull ROIEvent event) {
+        if (event.getType() == ROIEvent.ROIEventType.ROI_CHANGED)
             updateInfos();
     }
 
     @Override
-    public void viewerActivated(Viewer viewer)
-    {
-        if (activeViewer != viewer)
-        {
+    public void viewerActivated(final Viewer viewer) {
+        if (activeViewer != viewer) {
             float alpha = 1f;
 
-            if (activeViewer != null)
-            {
+            if (activeViewer != null) {
                 final IcyCanvas canvas = activeViewer.getCanvas();
-                if (canvas != null)
-                {
+                if (canvas != null) {
                     final Layer layer = canvas.getLayer(overlay);
                     if (layer != null)
-                        alpha = layer.getAlpha();
+                        alpha = layer.getOpacity();
                 }
             }
 
@@ -330,28 +331,24 @@ public class ROIToolTip extends Plugin implements PluginDaemon, ActiveViewerList
 
             sequenceActivated(sequence);
 
-            if (activeViewer != null)
-            {
+            if (activeViewer != null) {
                 final IcyCanvas canvas = activeViewer.getCanvas();
-                if (canvas != null)
-                {
+                if (canvas != null) {
                     final Layer layer = canvas.getLayer(overlay);
                     if (layer != null)
-                        layer.setAlpha(alpha);
+                        layer.setOpacity(alpha);
                 }
             }
         }
     }
 
     @Override
-    public void viewerDeactivated(Viewer viewer)
-    {
+    public void viewerDeactivated(final Viewer viewer) {
         // nothing here
     }
 
     @Override
-    public void activeViewerChanged(ViewerEvent event)
-    {
+    public void activeViewerChanged(final ViewerEvent event) {
         // nothing here
     }
 }
\ No newline at end of file
diff --git a/src/main/resources/icon.png b/src/main/resources/roi-tooltip.png
similarity index 100%
rename from src/main/resources/icon.png
rename to src/main/resources/roi-tooltip.png