diff --git a/.gitignore b/.gitignore
index 4d6d26eb5c996073a0b63007cf16faee399b26cd..22af9746b07a854159ce190cf70f35b692fe6fdc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,4 +5,5 @@ target/
 *.iml
 *.eml
 .classpath
-.project
\ No newline at end of file
+.project
+**/.DS_Store
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index e90eddbff19a9c94c1dad306f05b5f5a52e8db6b..1be905bb3178056b842ca267fcaa88dc2747cf96 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,54 +5,18 @@
     <modelVersion>4.0.0</modelVersion>
 
     <parent>
-		<artifactId>pom-icy</artifactId>
         <groupId>org.bioimageanalysis.icy</groupId>
-        <version>2.0.0</version>
+		<artifactId>pom-icy</artifactId>
+        <version>2.2.0</version>
     </parent>
 
     <artifactId>spot-detection-utilities</artifactId>
-    <version>1.1.6</version>
+    <version>1.1.7</version>
 
     <packaging>jar</packaging>
 
     <name>Detection Utilities</name>
 	
-	<profiles>
-		<profile>
-			<id>icy-plugin</id>
-			<activation>
-				<activeByDefault>true</activeByDefault>
-			</activation>
-		</profile>
-	</profiles>
-	
-	<build>
-		<plugins>
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-javadoc-plugin</artifactId>
-				<configuration>
-					<overview>${basedir}/src/main/javadoc/overview.html</overview>
-					<stylesheetfile>${basedir}/src/main/javadoc/java7doc.css</stylesheetfile>
-					<!-- disable javadoc errors for substance library (too many, and we don't care really) -->
-					<additionalOptions>
-						<additionalOption>-Xdoclint:none</additionalOption>
-					</additionalOptions>
-				</configuration>
-			</plugin>
-		</plugins>
-	</build>
-    
-	<!-- List of project's dependencies -->
-    <dependencies>
-        <!-- The core of Icy -->
-        <dependency>
-            <groupId>org.bioimageanalysis.icy</groupId>
-            <artifactId>icy-kernel</artifactId>
-			<version>${icy-kernel.version}</version>
-        </dependency>
-	</dependencies>
-	
     <repositories>
         <repository>
             <id>icy</id>
diff --git a/src/main/java/plugins/nchenouard/spot/Detection.java b/src/main/java/plugins/nchenouard/spot/Detection.java
index df6a1853b69f3947a1427baf72d1bda8f205b6e6..dfbfbdca018220da2d715ee8629f680ec70d8dc6 100644
--- a/src/main/java/plugins/nchenouard/spot/Detection.java
+++ b/src/main/java/plugins/nchenouard/spot/Detection.java
@@ -1,39 +1,30 @@
 /*
- * Copyright 2010, 2011 Institut Pasteur.
- * 
+ * Copyright 2010-2023 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 <http://www.gnu.org/licenses/>.
+ * along with ICY. If not, see <https://www.gnu.org/licenses/>.
  */
 package plugins.nchenouard.spot;
 
-import icy.canvas.Canvas2D;
-import icy.canvas.IcyCanvas;
 import icy.file.xml.XMLPersistent;
-import icy.painter.Painter;
-import icy.sequence.Sequence;
+import icy.painter.Overlay;
 import icy.system.IcyExceptionHandler;
 import icy.util.ClassUtil;
 import icy.util.XMLUtil;
 
-import java.awt.BasicStroke;
 import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseEvent;
-import java.awt.geom.Line2D;
-import java.awt.geom.Point2D;
 import java.lang.reflect.Constructor;
 
 import org.w3c.dom.Element;
@@ -41,16 +32,14 @@ import org.w3c.dom.Node;
 
 /**
  * Detection is the basic detection class. Extends Detection to create more complete Detection.
- * 
+ *
  * @author Fabrice de Chaumont
  */
 
-public class Detection implements Painter, Cloneable , XMLPersistent
-{
+public class Detection extends Overlay implements Cloneable, XMLPersistent {
 
     @Override
-	public Object clone() throws CloneNotSupportedException
-    {
+    public Object clone() throws CloneNotSupportedException {
 
         Detection clone = (Detection) super.clone();
 
@@ -63,23 +52,35 @@ public class Detection implements Painter, Cloneable , XMLPersistent
         clone.detectionEditor = detectionEditor;
         clone.enabled = enabled;
         clone.color = new Color(color.getRed(), color.getGreen(), color.getBlue());
-        clone.originalColor = new Color( originalColor.getRGB() );
+        clone.originalColor = new Color(originalColor.getRGB());
 
         return clone;
 
     }
 
-    /** x position of detection. */
+    /**
+     * x position of detection.
+     */
     protected double x;
-    /** y position of detection. */
+    /**
+     * y position of detection.
+     */
     protected double y;
-    /** z position of detection. */
+    /**
+     * z position of detection.
+     */
     protected double z;
-    /** t position of detection. */
+    /**
+     * t position of detection.
+     */
     protected int t;
-    /** default detection type */
+    /**
+     * Default detection type
+     */
     protected int detectionType = DETECTIONTYPE_REAL_DETECTION;
-    /** Selected */
+    /**
+     * Selected
+     */
     protected boolean selected = false;
     /**
      * Detection enabled/disable is the internal mechanism to filter track with TrackProcessor. At
@@ -91,183 +92,123 @@ public class Detection implements Painter, Cloneable , XMLPersistent
     /**
      * This color is used each time the TrackProcessor start, as it call the detection.reset() function.
      * This color is loaded when using an XML file.
-     * While saving, the current color of the track ( color propertie ) is used. So at load it will become the new originalColor.
+     * While saving, the current color of the track ( color property ) is used. So at load it will become the new originalColor.
      */
     protected Color originalColor = Color.blue;
-    
+
     public final static int DETECTIONTYPE_REAL_DETECTION = 1;
     public final static int DETECTIONTYPE_VIRTUAL_DETECTION = 2;
 
-    public Detection(double x, double y, double z, int t)
-    {
+    public Detection(double x, double y, double z, int t) {
+        super("Detection", OverlayPriority.SHAPE_NORMAL);
         this.x = x;
         this.y = y;
         this.z = z;
         this.t = t;
         reset();
     }
-    
-    public Detection()
-    {
-    	reset();
+
+    public Detection() {
+        super("Detection", OverlayPriority.SHAPE_NORMAL);
+        reset();
     }
-    
-    public int getT()
-    {
+
+    public int getT() {
         return t;
     }
 
-    public void setT(int t)
-    {
+    public void setT(int t) {
         this.t = t;
     }
 
-    public double getX()
-    {
+    public double getX() {
         return x;
     }
 
-    public void setX(double x)
-    {
+    public void setX(double x) {
         this.x = x;
     }
 
-    public double getY()
-    {
+    public double getY() {
         return y;
     }
 
-    public void setY(double y)
-    {
+    public void setY(double y) {
         this.y = y;
     }
 
-    public double getZ()
-    {
+    public double getZ() {
         return z;
     }
 
-    public void setZ(double z)
-    {
+    public void setZ(double z) {
         this.z = z;
     }
 
     @Override
-    public String toString()
-    {
+    public String toString() {
         return "Detection [x:" + x + " y:" + y + " z:" + z + " t:" + t + "]";
     }
 
     Color color;
 
-    public int getDetectionType()
-    {
+    public int getDetectionType() {
         return detectionType;
     }
 
-    public void setDetectionType(int detectionType)
-    {
+    public void setDetectionType(int detectionType) {
         this.detectionType = detectionType;
     }
 
-    public boolean isSelected()
-    {
+    public boolean isSelected() {
         return selected;
     }
 
-    public void setSelected(boolean selected)
-    {
+    public void setSelected(boolean selected) {
         this.selected = selected;
     }
 
-    public Color getColor()
-    {
+    public Color getColor() {
         return color;
     }
 
-    public void setColor(Color color)
-    {
+    public void setColor(Color color) {
         this.color = color;
     }
 
-    public boolean isEnabled()
-    {
+    public boolean isEnabled() {
         return enabled;
     }
 
-    public void setEnabled(boolean enabled)
-    {
+    public void setEnabled(boolean enabled) {
         this.enabled = enabled;
     }
 
+    @Deprecated
     private DetectionEditor detectionEditor = null;
 
-    public void setExternalDetectionTools(DetectionEditor detectionEditor)
-    {
+    @Deprecated
+    public void setExternalDetectionTools(DetectionEditor detectionEditor) {
         this.detectionEditor = detectionEditor;
     }
 
-    public void reset()
-    {
-    	this.color = originalColor;
+    public void reset() {
+        this.color = originalColor;
         this.setEnabled(true);
     }
 
-    public DetectionEditor getDetectionEditor()
-    {
+    @Deprecated
+    public DetectionEditor getDetectionEditor() {
         return detectionEditor;
     }
 
-    public void setDeet(DetectionEditor detectionEditor)
-    {
+    @Deprecated
+    public void setDeet(DetectionEditor detectionEditor) {
         this.detectionEditor = detectionEditor;
     }
 
-    @Override
-    public void keyPressed(KeyEvent e, Point2D imagePoint, IcyCanvas icyCanvas)
-    {
-
-    }
-
-    @Override
-    public void mouseClick(MouseEvent e, Point2D p, IcyCanvas icyCanvas)
-    {
-
-    }
-
-    @Override
-    public void mouseDrag(MouseEvent e, Point2D p, IcyCanvas icyCanvas)
-    {
-
-    }
-
-    @Override
-    public void mouseMove(MouseEvent e, Point2D p, IcyCanvas icyCanvas)
-    {
-
-    }
-
-    @Override
-    public void keyReleased(KeyEvent e, Point2D imagePoint, IcyCanvas canvas)
-    {
-
-    }
-
-    @Override
-    public void mousePressed(MouseEvent e, Point2D imagePoint, IcyCanvas canvas)
-    {
-
-    }
-
-    @Override
-    public void mouseReleased(MouseEvent e, Point2D imagePoint, IcyCanvas canvas)
-    {
-
-    }
-
-    @Override
-    public void paint(Graphics2D g, Sequence sequence, IcyCanvas canvas)
-    {
+//    @Override
+//    public void paint(Graphics2D g, Sequence sequence, IcyCanvas canvas) {
 //        if (enabled)
 //        {
 //            if (canvas instanceof Canvas2D)
@@ -280,83 +221,77 @@ public class Detection implements Painter, Cloneable , XMLPersistent
 //                g.setStroke(new BasicStroke(1f));
 //            }
 //        }
+//    }
+
+    /**
+     * @return true if load is successful.
+     */
+    @Override
+    public boolean loadFromXML(Node node) {
+
+        Element detectionElement = (Element) node;
+
+        x = XMLUtil.getAttributeDoubleValue(detectionElement, "x", 0);
+        y = XMLUtil.getAttributeDoubleValue(detectionElement, "y", 0);
+        z = XMLUtil.getAttributeDoubleValue(detectionElement, "z", 0);
+        t = XMLUtil.getAttributeIntValue(detectionElement, "t", 0);
+        detectionType = XMLUtil.getAttributeIntValue(detectionElement, "type", DETECTIONTYPE_REAL_DETECTION);
+        selected = XMLUtil.getAttributeBooleanValue(detectionElement, "selected", false);
+        originalColor = new Color(XMLUtil.getAttributeIntValue(detectionElement, "color", Color.blue.getRGB()));
+
+        return true;
     }
 
     /**
-     * return true if load is successful.
+     * @return true if save is successful.
      */
-	@Override
-	public boolean loadFromXML(Node node) {
-		
-		Element detectionElement = (Element) node;
-		
-		x = XMLUtil.getAttributeDoubleValue( detectionElement , "x" ,  0 );
-		y = XMLUtil.getAttributeDoubleValue( detectionElement , "y" ,  0 );
-		z = XMLUtil.getAttributeDoubleValue( detectionElement , "z" ,  0 );
-		t = XMLUtil.getAttributeIntValue( detectionElement , "t" ,  0 );
-		detectionType = XMLUtil.getAttributeIntValue( detectionElement , "type" ,  DETECTIONTYPE_REAL_DETECTION );
-		selected = XMLUtil.getAttributeBooleanValue( detectionElement , "selected" ,  false );
-		originalColor = new Color ( XMLUtil.getAttributeIntValue( detectionElement , "color" ,  Color.blue.getRGB() ) );
-		
-		return true;
-	}
-	
-	/**
-	 * return true if save is successful.
-	 */
-	@Override
-	public boolean saveToXML(Node node) {
-
-		Element detectionElement = (Element) node;
-		
-		XMLUtil.setAttributeDoubleValue(detectionElement, "x", x );
-		XMLUtil.setAttributeDoubleValue(detectionElement, "y", y );
-		XMLUtil.setAttributeDoubleValue(detectionElement, "z", z );
-		XMLUtil.setAttributeIntValue(detectionElement, "t", t );
-		XMLUtil.setAttributeIntValue(detectionElement, "type", detectionType );
-		XMLUtil.setAttributeIntValue(detectionElement, "color", color.getRGB() );
-		
-		if ( selected )
-		{
-			XMLUtil.setAttributeBooleanValue(detectionElement, "selected", true );
-		}
-		
-		return true;
-	}
-	
-	// Inpired form the ROI Persistance mechanism
-    public static Detection createDetection( String className )
-    {
+    @Override
+    public boolean saveToXML(Node node) {
+
+        Element detectionElement = (Element) node;
+
+        XMLUtil.setAttributeDoubleValue(detectionElement, "x", x);
+        XMLUtil.setAttributeDoubleValue(detectionElement, "y", y);
+        XMLUtil.setAttributeDoubleValue(detectionElement, "z", z);
+        XMLUtil.setAttributeIntValue(detectionElement, "t", t);
+        XMLUtil.setAttributeIntValue(detectionElement, "type", detectionType);
+        XMLUtil.setAttributeIntValue(detectionElement, "color", color.getRGB());
+
+        if (selected) {
+            XMLUtil.setAttributeBooleanValue(detectionElement, "selected", true);
+        }
+
+        return true;
+    }
+
+    // Inspired from the ROI Persistance mechanism
+    public static Detection createDetection(String className) {
         Detection result = null;
 
-        try
-        {
+        try {
             // search for the specified className
             final Class<?> clazz = ClassUtil.findClass(className);
-            
+
             // class found
-            if (clazz != null)
-            {
-                    final Class<? extends Detection> detectionClazz = clazz.asSubclass(Detection.class);                    
-                    
-                    final Constructor<? extends Detection> constructor = detectionClazz.getConstructor(new Class[] {});
-                    result = constructor.newInstance(new Object[] {});
-            
+            if (clazz != null) {
+                final Class<? extends Detection> detectionClazz = clazz.asSubclass(Detection.class);
+
+                final Constructor<? extends Detection> constructor = detectionClazz.getConstructor();
+                result = constructor.newInstance();
+
             }
-        }
-        catch (Exception e)
-        {
+        } catch (Exception e) {
             System.err.println("********* TrackManager.createDetection('" + className + "', ...) error :");
             IcyExceptionHandler.showErrorMessage(e, false);
             System.err.println("The object is maybe not compatible (should have a default constructor with no arguments and extends Detection)");
             System.err.println("Loading as a the default Detection object.");
 
             // Load as a default detection.
-            
-            result = new Detection();            
-            
-        }        
-        
+
+            result = new Detection();
+
+        }
+
         return result;
     }
 
diff --git a/src/main/java/plugins/nchenouard/spot/DetectionEditor.java b/src/main/java/plugins/nchenouard/spot/DetectionEditor.java
index 08e94d70724ed1a1450205d86bd4fa82e8080b7c..2d3f82bd0f0b15887027704578a11c2f1e3a0935 100644
--- a/src/main/java/plugins/nchenouard/spot/DetectionEditor.java
+++ b/src/main/java/plugins/nchenouard/spot/DetectionEditor.java
@@ -1,44 +1,41 @@
 /*
- * Copyright 2010, 2011 Institut Pasteur.
- * 
+ * Copyright 2010-2023 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 <http://www.gnu.org/licenses/>.
+ * along with ICY. If not, see <https://www.gnu.org/licenses/>.
  */
 package plugins.nchenouard.spot;
 
 import javax.swing.JPanel;
 
 /**
- * @deprecated detection editor not ready yet
  * @author Fabrice de Chaumont
- *
+ * @deprecated detection editor not ready yet
  */
-public abstract class DetectionEditor
-{
+@Deprecated
+public abstract class DetectionEditor {
 
-    private JPanel panel;
+    private final JPanel panel;
     //protected TrackPool trackPool = null;
     protected Detection currentDetection = null;
 
-    public DetectionEditor()
-    {
+    public DetectionEditor() {
         panel = new JPanel();
     }
 
-    public JPanel getPanel()
-    {
+    public JPanel getPanel() {
         return panel;
     }
 
@@ -46,22 +43,20 @@ public abstract class DetectionEditor
 
     /**
      * called by the trackManager to set a new detection when the user select a detection
-     * 
-     * @param detection
      */
-    public final void setDetection(Detection detection)
-    {
+    public final void setDetection(Detection detection) {
         currentDetection = detection;
         currentDetectionAsChanged();
     }
 
     /**
-     * Send the detection to the heriting class. Should display data about it. Then use
-     * trackPool.fire to update TrackEditor Interface.
+     * Send the detection to the inheriting class. Should display data about it. Then use
+     * trackPool.<br>
+     * Fire to update TrackEditor Interface.
      */
     protected abstract void currentDetectionAsChanged();
 
-    /** The trackPool is set by the trackEditor constructor */
+    /* The trackPool is set by the trackEditor constructor */
 //    public final void setTrackPool(TrackPool trackPool)
 //    {
 //        this.trackPool = trackPool;
diff --git a/src/main/java/plugins/nchenouard/spot/DetectionResult.java b/src/main/java/plugins/nchenouard/spot/DetectionResult.java
index b5ff1b14d176e566e1ba5d72fbf8584cdcce15a9..75ebf84ee1b8ec8ab000ab8a0f1c416fb55ea0a7 100644
--- a/src/main/java/plugins/nchenouard/spot/DetectionResult.java
+++ b/src/main/java/plugins/nchenouard/spot/DetectionResult.java
@@ -7,154 +7,132 @@ import java.util.TreeMap;
 import java.util.Vector;
 
 
-/** A class to manage detection results
- * 
- * @author nicolas chenouard and Fabrice de Chaumont
+/**
+ * A class to manage detection results
  *
- * */
-
-public class DetectionResult extends Plugin
-{
-	private TreeMap<Integer, Vector<Spot>> results;
-	private Sequence sourceSequence;
-	private boolean numberOfDetectionShouldBeRecomputed = true;
-	private int detectionNumber = 0;
-	private String name = null;
-	
-	@Override
-	public String toString() {
-		if (name == null)
-		{
-			if (!results.isEmpty())
-				return "Detection set from t:" + getFirstFrameTime() + " to t:" + getLastFrameTime() + " #detection(s): " + getNumberOfDetection();
-			else
-				return  "Detection set (empty)";
-		}
-		else
-			return name;
-	}
-	
-	public int getNumberOfDetection()
-	{
-		if ( numberOfDetectionShouldBeRecomputed )
-		{
-			computeNumberOfDetection();
-		}
-		return detectionNumber;
-	}
-	
-	private void computeNumberOfDetection() {
-		
-		detectionNumber = 0;
-		for ( int index : results.keySet() )
-		{
-			detectionNumber+=results.get( index ).size();
-		}
-		numberOfDetectionShouldBeRecomputed = false;
-
-	}
-
-	public Sequence getSequence()
-	{
-		return sourceSequence;
-	}
-	
-	public void setSequence(Sequence seq)
-	{
-		this.sourceSequence = seq;
-	}
-	
-	protected void finalize() throws Throwable {
-		results.clear();
-		super.finalize();
-	}
-	
-	public DetectionResult()
-	{
-		results = new TreeMap<Integer, Vector<Spot>>();
-		numberOfDetectionShouldBeRecomputed = true;
-	}
-	
-	public DetectionResult(TreeMap<Integer, Vector<Spot>> results)
-	{
-		this.results = results;
-		numberOfDetectionShouldBeRecomputed = true;
-	}
-	
-	public void addDetection(int t, Spot s)
-	{
-		Vector<Spot> spots;
-		if (results.containsKey(Integer.valueOf(t)))
-			spots = results.get(Integer.valueOf(t));
-		else
-		{
-			spots = new Vector<Spot>(1);
-			results.put(Integer.valueOf(t), spots);
-		}
-		spots.add(s);
-		numberOfDetectionShouldBeRecomputed = true;
-	}
-	
-	public void setResult(int t, Vector<Spot> detections)
-	{
-		results.put(Integer.valueOf(t), new Vector<Spot>(detections) );
-		numberOfDetectionShouldBeRecomputed = true;
-	}
-	
-	/**
-	 * 
-	 * @return a COPY of the detection vector at time t
-	 */
-	public Vector<Spot> getDetectionsAtT(int t)
-	{
-		Vector<Spot> spots = results.get(t);
-		if (spots == null){
-			spots = new Vector<Spot>();
-			results.put(Integer.valueOf(t), spots);
-		}
-		return spots;
-	}
-	
-	/**
-	 * 
-	 * @return a Copy of the TreeMap.
-	 */
-	public TreeMap<Integer, Vector<Spot>> getResults()
-	{
-		return new TreeMap<Integer, Vector<Spot>>(results);
-	}
-
-	public DetectionResult copy()
-	{
-		TreeMap<Integer, Vector<Spot>> copy = new TreeMap<Integer, Vector<Spot>>();
-		for ( int key : results.keySet() )
-		{
-			Vector<Spot> spotVectorClone = (Vector<Spot>) results.get( key ).clone();
-			copy.put( key , spotVectorClone );
-		}		
-		DetectionResult dr = new DetectionResult(copy);
-		dr.setName(name);
-		return dr;
-	}
-
-	public String getName()
-	{
-		return name;
-	}
-	
-	public void setName(String name)
-	{
-		this.name = name;
-	}
-	
-	public int getFirstFrameTime()
-	{
-		return results.firstKey();
-	}
-	
-	public int getLastFrameTime()
-	{
-		return results.lastKey();
-
-	}
+ * @author nicolas chenouard and Fabrice de Chaumont
+ */
+
+public class DetectionResult extends Plugin {
+    private final TreeMap<Integer, Vector<Spot>> results;
+    private Sequence sourceSequence;
+    private boolean numberOfDetectionShouldBeRecomputed;
+    private int detectionNumber = 0;
+    private String name = null;
+
+    @Override
+    public String toString() {
+        if (name == null) {
+            if (!results.isEmpty())
+                return "Detection set from t:" + getFirstFrameTime() + " to t:" + getLastFrameTime() + " #detection(s): " + getNumberOfDetection();
+            else
+                return "Detection set (empty)";
+        }
+        else
+            return name;
+    }
+
+    public int getNumberOfDetection() {
+        if (numberOfDetectionShouldBeRecomputed) {
+            computeNumberOfDetection();
+        }
+        return detectionNumber;
+    }
+
+    private void computeNumberOfDetection() {
+
+        detectionNumber = 0;
+        for (int index : results.keySet()) {
+            detectionNumber += results.get(index).size();
+        }
+        numberOfDetectionShouldBeRecomputed = false;
+
+    }
+
+    public Sequence getSequence() {
+        return sourceSequence;
+    }
+
+    public void setSequence(Sequence seq) {
+        this.sourceSequence = seq;
+    }
+
+    protected void finalize() throws Throwable {
+        results.clear();
+        super.finalize();
+    }
+
+    public DetectionResult() {
+        results = new TreeMap<>();
+        numberOfDetectionShouldBeRecomputed = true;
+    }
+
+    public DetectionResult(TreeMap<Integer, Vector<Spot>> results) {
+        this.results = results;
+        numberOfDetectionShouldBeRecomputed = true;
+    }
+
+    public void addDetection(int t, Spot s) {
+        Vector<Spot> spots;
+        if (results.containsKey(Integer.valueOf(t)))
+            spots = results.get(Integer.valueOf(t));
+        else {
+            spots = new Vector<>(1);
+            results.put(Integer.valueOf(t), spots);
+        }
+        spots.add(s);
+        numberOfDetectionShouldBeRecomputed = true;
+    }
+
+    public void setResult(int t, Vector<Spot> detections) {
+        results.put(Integer.valueOf(t), new Vector<>(detections));
+        numberOfDetectionShouldBeRecomputed = true;
+    }
+
+    /**
+     * @return a COPY of the detection vector at time t
+     */
+    public Vector<Spot> getDetectionsAtT(int t) {
+        Vector<Spot> spots = results.get(t);
+        if (spots == null) {
+            spots = new Vector<>();
+            results.put(Integer.valueOf(t), spots);
+        }
+        return spots;
+    }
+
+    /**
+     * @return a Copy of the TreeMap.
+     */
+    public TreeMap<Integer, Vector<Spot>> getResults() {
+        return new TreeMap<>(results);
+    }
+
+    public DetectionResult copy() {
+        TreeMap<Integer, Vector<Spot>> copy = new TreeMap<>();
+        for (int key : results.keySet()) {
+            @SuppressWarnings("unchecked")
+            Vector<Spot> spotVectorClone = (Vector<Spot>) results.get(key).clone();
+            copy.put(key, spotVectorClone);
+        }
+        DetectionResult dr = new DetectionResult(copy);
+        dr.setName(name);
+        return dr;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getFirstFrameTime() {
+        return results.firstKey();
+    }
+
+    public int getLastFrameTime() {
+        return results.lastKey();
+    }
 }
diff --git a/src/main/java/plugins/nchenouard/spot/Point3D.java b/src/main/java/plugins/nchenouard/spot/Point3D.java
index 96582224807ec8bca519de418e1bc345038ebaed..c34b27b9b9ec81ed945d56b263ff96e7ab4364eb 100644
--- a/src/main/java/plugins/nchenouard/spot/Point3D.java
+++ b/src/main/java/plugins/nchenouard/spot/Point3D.java
@@ -5,43 +5,38 @@ import java.awt.geom.Point2D;
 
 public class Point3D {
 
-	@Override
-	public String toString() {
-
-		return "Point3D["+x+","+y+","+z+"]";
-	}
-
-	public double x,y,z;
-	
-	public Point3D(){}
-	
-	public Point3D( double x, double y , double z )
-	{
-		this.x = x;
-		this.y = y;
-		this.z = z;
-	}
-	
-	public Point3D( double x, double y)
-	{
-		this.x = x;
-		this.y = y;
-		this.z = 0;
-	}
-	
-	public Point3D( double[] coord)
-	{
-		this.x = coord[0];
-		this.y = coord[1];
-		if (coord.length>2)
-			this.z = coord[2];
-		else this.z = 0;
-	}
-	
-	public Point2D asPoint2D()
-	{
-		return new Point2D.Double( x , y );
-	}
-	
+    @Override
+    public String toString() {
 
+        return "Point3D[" + x + "," + y + "," + z + "]";
+    }
+
+    public double x, y, z;
+
+    public Point3D() {
+    }
+
+    public Point3D(double x, double y, double z) {
+        this.x = x;
+        this.y = y;
+        this.z = z;
+    }
+
+    public Point3D(double x, double y) {
+        this.x = x;
+        this.y = y;
+        this.z = 0;
+    }
+
+    public Point3D(double[] coord) {
+        this.x = coord[0];
+        this.y = coord[1];
+        if (coord.length > 2)
+            this.z = coord[2];
+        else this.z = 0;
+    }
+
+    public Point2D asPoint2D() {
+        return new Point2D.Double(x, y);
+    }
 }
diff --git a/src/main/java/plugins/nchenouard/spot/Spot.java b/src/main/java/plugins/nchenouard/spot/Spot.java
index 3fc34317d16335db8dc1f4b132ca3b2078558153..f807fdd179d1a76a43b10e251c03a50bd78a5235 100644
--- a/src/main/java/plugins/nchenouard/spot/Spot.java
+++ b/src/main/java/plugins/nchenouard/spot/Spot.java
@@ -6,81 +6,67 @@ import java.text.ParseException;
 import java.util.ArrayList;
 
 public class Spot {
-	
-	public Point3D mass_center;
-	public double minIntensity;
-	public double maxIntensity;
-	public double meanIntensity;
-	
-	/** List of point of the detection */
-	public ArrayList<Point3D> point3DList = new ArrayList<Point3D>();
-	
-	public Spot()
-	{
-		mass_center = new Point3D();
-	}
 
-	public Spot( double x , double y , double z )
-	{
-		mass_center = new Point3D( x , y , z );
-	}
+    public Point3D mass_center;
+    public double minIntensity;
+    public double maxIntensity;
+    public double meanIntensity;
 
-	public Spot( double x , double y , double z , double minIntensity , double maxIntensity, double meanIntensity )
-	{
-		mass_center = new Point3D( x , y , z );
-		this.minIntensity = minIntensity;
-		this.maxIntensity = maxIntensity;
-		this.meanIntensity = meanIntensity;
-	}
+    /**
+     * List of point of the detection
+     */
+    public ArrayList<Point3D> point3DList = new ArrayList<>();
 
-	public Spot( double x , double y , double z , double minIntensity , double maxIntensity, double meanIntensity , ArrayList<Point3D> point3DList )
-	{
-		mass_center = new Point3D( x , y , z );
-		this.minIntensity = minIntensity;
-		this.maxIntensity = maxIntensity;
-		this.meanIntensity = meanIntensity;
-		this.point3DList = new ArrayList<Point3D>( point3DList );
-	}
-	
-	@Override
-	protected void finalize() throws Throwable
-	{		
-		mass_center = null;
-		super.finalize();
-	}
-		
-	public static Spot load(String line)
-	{
-		if (line.startsWith("detection"))
-		{
-			String[] tmpTab = line.split("\\[");
-			tmpTab = tmpTab[1].split("]");
-			line = tmpTab[0];
-			String[] coordinates = line.split(",",3);
-			if (coordinates.length>2)
-			{
-				NumberFormat nf = NumberFormat.getInstance();
-				Spot s = new Spot();
-				try {
-					s.mass_center.x = nf.parse(coordinates[0]).intValue();
-					s.mass_center.y = nf.parse(coordinates[1]).intValue();
-					s.mass_center.z = nf.parse(coordinates[2]).intValue();
-				} catch (ParseException e) {
-					e.printStackTrace();
-					return null;
-				}
-				return s;
-			}
-			return null;
-		}
-		else return null;
-	}
-	
-	public void save(PrintStream printOut, int num)
-	{
-		printOut.print("detection{"+num+"} = [");
-		printOut.print ( mass_center.x +"," );
-		printOut.print ( mass_center.y +"," );
-		printOut.print ( mass_center.z +"];" );
-	}
+    public Spot() {
+        mass_center = new Point3D();
+    }
+
+    public Spot(double x, double y, double z) {
+        mass_center = new Point3D(x, y, z);
+    }
+
+    public Spot(double x, double y, double z, double minIntensity, double maxIntensity, double meanIntensity) {
+        mass_center = new Point3D(x, y, z);
+        this.minIntensity = minIntensity;
+        this.maxIntensity = maxIntensity;
+        this.meanIntensity = meanIntensity;
+    }
+
+    public Spot(double x, double y, double z, double minIntensity, double maxIntensity, double meanIntensity, ArrayList<Point3D> point3DList) {
+        mass_center = new Point3D(x, y, z);
+        this.minIntensity = minIntensity;
+        this.maxIntensity = maxIntensity;
+        this.meanIntensity = meanIntensity;
+        this.point3DList = new ArrayList<>(point3DList);
+    }
+
+    public static Spot load(String line) {
+        if (line.startsWith("detection")) {
+            String[] tmpTab = line.split("\\[");
+            tmpTab = tmpTab[1].split("]");
+            line = tmpTab[0];
+            String[] coordinates = line.split(",", 3);
+            if (coordinates.length > 2) {
+                NumberFormat nf = NumberFormat.getInstance();
+                Spot s = new Spot();
+                try {
+                    s.mass_center.x = nf.parse(coordinates[0]).intValue();
+                    s.mass_center.y = nf.parse(coordinates[1]).intValue();
+                    s.mass_center.z = nf.parse(coordinates[2]).intValue();
+                } catch (ParseException e) {
+                    e.printStackTrace();
+                    return null;
+                }
+                return s;
+            }
+        }
+        return null;
+    }
+
+    public void save(PrintStream printOut, int num) {
+        printOut.print("detection{" + num + "} = [");
+        printOut.print(mass_center.x + ",");
+        printOut.print(mass_center.y + ",");
+        printOut.print(mass_center.z + "];");
+    }
 }