diff --git a/.gitignore b/.gitignore
index 9eee571d0dd8122e8838586c3eea8145168466f4..40bbaf46a7d36d07b6073c8a6e901299bfbfbcc9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,5 @@ target/
 *.iml
 *.class
 .project
-.classpath
\ No newline at end of file
+.classpath
+**/.DS_Store
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index ab4d3722f651d4a832b8a8df3357b9a4345c58ae..c0643018cb9882f40de4ad698e4bebf26bf2aa13 100644
--- a/pom.xml
+++ b/pom.xml
@@ -7,19 +7,19 @@
     <!-- Inherited Icy Parent POM -->
     <parent>
         <groupId>org.bioimageanalysis.icy</groupId>
-        <artifactId>parent-pom-plugin</artifactId>
-        <version>1.0.8</version>
+        <artifactId>pom-icy</artifactId>
+        <version>2.2.0</version>
     </parent>
 
     <!-- Project Information -->
     <artifactId>angle-helper</artifactId>
-    <version>1.1.0</version>
+    <version>1.1.1</version>
 
     <packaging>jar</packaging>
 
     <name>Angle Helper</name>
     <description>This repo serves as a template for you to implement new Icy plugins.</description>
-    <url>http://icy.bioimageanalysis.org/plugin/angle-helper/</url>
+    <url>https://icy.bioimageanalysis.org/plugin/angle-helper/</url>
     <inceptionYear>2020</inceptionYear>
 
     <organization>
@@ -53,34 +53,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>
-
-        <dependency>
-            <groupId>org.bioimageanalysis.icy</groupId>
-            <artifactId>xuggler</artifactId>
-            <version>5.5.2</version>
-        </dependency>
-
         <dependency>
             <groupId>org.bioimageanalysis.icy</groupId>
             <artifactId>ruler-helper</artifactId>
-            <version>1.2.1</version>
         </dependency>
     </dependencies>
 
diff --git a/src/main/java/plugins/fab/anglehelper/AngleHelper.java b/src/main/java/plugins/fab/anglehelper/AngleHelper.java
index 58f19050f4d66183e261b9b8aff033b5a71653db..cbd3287ee383396f714981571875ecd4716e3379 100644
--- a/src/main/java/plugins/fab/anglehelper/AngleHelper.java
+++ b/src/main/java/plugins/fab/anglehelper/AngleHelper.java
@@ -1,28 +1,22 @@
 package plugins.fab.anglehelper;
 
 import icy.gui.dialog.MessageDialog;
-import icy.plugin.abstract_.Plugin;
-import icy.plugin.interface_.PluginImageAnalysis;
+import icy.plugin.abstract_.PluginActionable;
 import icy.sequence.Sequence;
 
 /**
  * @author Fabrice de Chaumont
  */
-public class AngleHelper extends Plugin implements PluginImageAnalysis {
-
+public class AngleHelper extends PluginActionable {
 	@Override
-	public void compute() {
+	public void run() {
+		Sequence sequence = getActiveSequence();
 
-		Sequence sequence = getFocusedSequence();
-		
-		if ( sequence!=null )
-		{
-			new AnglePainter( getFocusedSequence() );
-		}else
-		{
+		if (sequence != null) {
+			new AnglePainter(sequence);
+		}
+		else {
 			MessageDialog.showDialog("Please open an image first.", MessageDialog.INFORMATION_MESSAGE );
 		}
-		
 	}
-
 }
diff --git a/src/main/java/plugins/fab/anglehelper/AnglePainter.java b/src/main/java/plugins/fab/anglehelper/AnglePainter.java
index b6714ed2ae3a5979369700e5d96d76fddf8aac36..3cb9eb6288afa1dca31ab47efa4efdcfa017eea3 100644
--- a/src/main/java/plugins/fab/anglehelper/AnglePainter.java
+++ b/src/main/java/plugins/fab/anglehelper/AnglePainter.java
@@ -2,14 +2,9 @@ package plugins.fab.anglehelper;
 
 import icy.canvas.IcyCanvas;
 import icy.canvas.IcyCanvas2D;
-import icy.gui.util.GuiUtil;
 import icy.main.Icy;
 import icy.math.Scaler;
-import icy.painter.Anchor2D;
-import icy.painter.Anchor2D.Anchor2DListener;
-import icy.painter.Painter;
-import icy.painter.PainterEvent;
-import icy.roi.ROI2D;
+import icy.painter.*;
 import icy.sequence.Sequence;
 
 import java.awt.AlphaComposite;
@@ -22,315 +17,295 @@ import java.awt.event.MouseEvent;
 import java.awt.geom.AffineTransform;
 import java.awt.geom.Arc2D;
 import java.awt.geom.Line2D;
-import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
 import java.util.ArrayList;
 
+import icy.type.point.Point5D;
+import icy.util.GraphicsUtil;
 import plugins.fab.Ruler.Anchor2DTarget;
 import plugins.fab.Ruler.ShapeDefinition;
 
 /**
  * @author Fabrice de Chaumont
  */
-public class AnglePainter implements Painter, Anchor2DListener {
-
-	Anchor2DTarget a1 = new Anchor2DTarget( 0 , 0 );
-	Anchor2DTarget a2 = new Anchor2DTarget( 0 , 0 );
-	Anchor2DTarget a3 = new Anchor2DTarget( 0 , 0 );
-	
-	ArrayList<ShapeDefinition> shapeDefinitionList = new ArrayList<ShapeDefinition>();
-	ArrayList<AffineTransform> affineTransformList = new ArrayList<AffineTransform>();
-	
-	public AnglePainter(Sequence sequence) {
-	
-		if ( sequence == null ) return;
-		
-		a1.setPosition( sequence.getWidth() / 2 , sequence.getHeight() / 2 );
-		a2.setPosition( 3 * sequence.getWidth() / 4 , sequence.getHeight() / 2 );
-		a3.setPosition( 3 * sequence.getWidth() / 4 , sequence.getHeight() / 3 );
-
-		sequence.addPainter( this );
-		a1.addListener( this );
-		a2.addListener( this );
-		a3.addListener( this );
-		
-	}
-	
-	// Listener of Anchor
-	
-	@Override
-	public void painterChanged(PainterEvent event) {
-		
-		for ( Sequence sequence : Icy.getMainInterface().getSequencesContaining( this ) )
-		{
-			sequence.painterChanged( this );
-		}
-		
-	}
-
-	@Override
-	public void positionChanged(Anchor2D source) {
-		
-		
-	}
-	
-	void pushTransform( Graphics2D g )
-	{
-		affineTransformList.add( g.getTransform() );
-	}
-
-	void popTransform( Graphics2D g )
-	{
-		g.setTransform( affineTransformList.get( affineTransformList.size() -1 ) );
-		affineTransformList.remove( affineTransformList.size() -1 );
-	}
-	
-	public double CleanAngle( double angle )
-	{
-		double a = Math.abs( angle );
-		a = Math.round(a*10)/10.;
-		return a;
-	}
-	
-	// Painter Section:
-
-	@Override
-	public void paint(Graphics2D g, Sequence sequence, IcyCanvas canvas) {
-		
-		if ( ! ( canvas instanceof IcyCanvas2D ) ) return;
-		
-		g= (Graphics2D) g.create();
-		
-		BasicStroke[] stroke = new BasicStroke[4];
-		
-		stroke[0] = new BasicStroke((float) ROI2D.canvasToImageLogDeltaX(canvas, 2 ) ); 
-		stroke[1] = new BasicStroke((float) ROI2D.canvasToImageLogDeltaX(canvas, 3 ) ); 
-		stroke[2] = new BasicStroke((float) ROI2D.canvasToImageLogDeltaX(canvas, 4 ) ); 
-		stroke[3] = new BasicStroke((float) ROI2D.canvasToImageLogDeltaX(canvas, 5 ) ); 
-				
-		// transform and display ticks
-
-		shapeDefinitionList.clear();
-	
-		pushTransform( g );
-		
-		double vx12 = ( a2.getX() - a1.getX() ) ;
-		double vy12 = ( a2.getY() - a1.getY() ) ;
-		double angle12 = Math.atan2( vy12 , vx12 ) * ( 180d / Math.PI ) ;
-
-		double vx13 = ( a3.getX() - a1.getX() ) ;
-		double vy13 = ( a3.getY() - a1.getY() ) ;
-		double angle13 = Math.atan2( vy13 , vx13 ) * ( 180d / Math.PI );
-
-		double angle1 = angle12-angle13;
-
-		if ( angle1 < 0 ) angle1+=360;
-		
-		double angle2 = 360-angle1;
-		
-		double dis1 = a1.getPosition().distance( a2.getPosition() );
-		double dis2 = a1.getPosition().distance( a3.getPosition() );
-		
-		double minDistance = Math.min( dis1 , dis2 );		
-
-		double distanceAngle1 = minDistance ;
-		double distanceAngle2 = minDistance / 2;
-
-		double distanceTextAngle1 = minDistance;
-		double distanceTextAngle2 = minDistance/2;
-		
-		// Lines
-		
-		shapeDefinitionList.add( new ShapeDefinition( 2 , new Line2D.Double( a1.getPosition() , a2.getPosition() ) ) );
-		shapeDefinitionList.add( new ShapeDefinition( 2 , new Line2D.Double( a1.getPosition() , a3.getPosition() ) ) );
-
-		// angle 1
-		{
-			double arcSize = distanceAngle1;
-			Arc2D arc = new Arc2D.Double( 
-					a1.getX() - arcSize/2d,
-					a1.getY() - arcSize/2d,
-					arcSize,
-					arcSize,
-					-angle12 ,
-					angle1,//angle13,
-					Arc2D.OPEN
-					);
-
-			shapeDefinitionList.add( new ShapeDefinition( 2 , arc ) );
-		}
-		
-		// angle 2
-		{
-			double arcSize = distanceAngle2;
-			Arc2D arc = new Arc2D.Double( 
-					a1.getX() - arcSize/2d,
-					a1.getY() - arcSize/2d,
-					arcSize,
-					arcSize,
-					-angle13 ,
-					angle2,//angle13,
-					Arc2D.OPEN
-					);
-
-			shapeDefinitionList.add( new ShapeDefinition( 2 , arc ) );
-		}
-
-		// draw lines ( black background, then white )
-		
-		float oldAlpha= -1;
-		g.setColor( Color.black );
-		for ( ShapeDefinition ld : shapeDefinitionList )
-		{
-			if (oldAlpha!=ld.alpha)
-			{
-				g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, ld.alpha ) );
-				oldAlpha = ld.alpha;
-			}
-			g.setStroke( stroke[ld.stroke] );
-			g.draw( ld.shape );
-		}
-
-		g.setColor( Color.white );
-		for ( ShapeDefinition ld : shapeDefinitionList )
-		{
-			if (oldAlpha!=ld.alpha)
-			{
-				g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, ld.alpha ) );
-				oldAlpha = ld.alpha;
-			}
-			g.setStroke( stroke[ld.stroke-1] );
-			g.draw( ld.shape );
-		}
-		
-		// Display angle text
-		
-		{
-			int fontSize =  (int)convertScale(canvas, 15 );
-			Font font =  new Font( "Arial" , Font.PLAIN , fontSize ); 
-
-			pushTransform( g );
-			String pixelString = " "+ (int)( Math.round( angle1 ) ) + "° ";
-			Rectangle2D pixelBounds = GuiUtil.getStringBounds( g , font, pixelString );
-			g.translate( a1.getX() , a1.getY() );
-			
-			double angleText = Math.toRadians( angle12 - angle1 / 2d );			
-			g.translate( Math.cos( angleText  ) * distanceTextAngle1 /2 , Math.sin( angleText ) * distanceTextAngle1 /2 );
-			g.translate( -pixelBounds.getWidth() / 2 , 0 );
-			
-			g.setFont( font );
-			g.setColor( Color.white );
-			g.fill( pixelBounds );
-			g.setColor( Color.black );
-			g.drawString( pixelString , 0, 0 );
-			popTransform( g );
-		}
-
-		{
-			int fontSize =  (int)convertScale(canvas, 15 );
-			Font font =  new Font( "Arial" , Font.PLAIN , fontSize ); 
-
-			pushTransform( g );
-			String pixelString = " "+ (int)(Math.round( angle2 ) ) + "� ";
-			Rectangle2D pixelBounds = GuiUtil.getStringBounds( g , font, pixelString );
-			g.translate( a1.getX() , a1.getY() );
-			
-			double angleText = Math.toRadians( 180 + angle12 - angle1 / 2d );			
-			g.translate( Math.cos( angleText  ) * distanceTextAngle2 / 2d , Math.sin( angleText ) * distanceTextAngle2 / 2d );
-			g.translate( -pixelBounds.getWidth() / 2 , 0 );
-
-			float alpha = 1 ;
-			double distance = canvas.getScaleX() * distanceTextAngle2 / 2d ;
-			
-			Scaler scaler = new Scaler( 0 , 10 , 0, 1 , false );
-			alpha = (float)scaler.scale( distance - pixelBounds.getWidth() / 10d );
-					
-			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha ) );
-
-			g.setFont( font );
-			g.setColor( Color.white );
-			g.fill( pixelBounds );
-			g.setColor( Color.black );
-			g.drawString( pixelString , 0, 0 );
-			
-			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1 ) );
-			popTransform( g );
-		}
-		
-		// get back to original transform
-				
-		popTransform( g );
-
-		// display anchors
-		g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1 ) );
-		a1.paint( g, sequence, canvas);
-		a2.paint( g, sequence, canvas);
-		a3.paint( g, sequence, canvas);
-	}
-		
-	double convertScale( IcyCanvas canvas , double value )
-	{
-		return ROI2D.canvasToImageLogDeltaX(canvas, value ); 
-	}
-
-	@Override
-	public void mousePressed(MouseEvent e, Point2D imagePoint, IcyCanvas canvas) {
-		a1.mousePressed(e, imagePoint, canvas);		
-		a2.mousePressed(e, imagePoint, canvas);
-		a3.mousePressed(e, imagePoint, canvas);
-	}
-
-	@Override
-	public void mouseReleased(MouseEvent e, Point2D imagePoint, IcyCanvas canvas) {
-		a1.mouseReleased(e, imagePoint, canvas);
-		a2.mouseReleased(e, imagePoint, canvas);
-		a3.mouseReleased(e, imagePoint, canvas);
-	}
-
-	@Override
-	public void mouseClick(MouseEvent e, Point2D imagePoint, IcyCanvas canvas) {
-		a1.mouseClick(e, imagePoint, canvas);
-		a2.mouseClick(e, imagePoint, canvas);
-		a3.mouseClick(e, imagePoint, canvas);
-		
-	}
-
-	@Override
-	public void mouseMove(MouseEvent e, Point2D imagePoint, IcyCanvas canvas) {
-		a1.mouseMove(e, imagePoint, canvas);
-		a2.mouseMove(e, imagePoint, canvas);
-		a3.mouseMove(e, imagePoint, canvas);
-	}
-
-	@Override
-	public void mouseDrag(MouseEvent e, Point2D imagePoint, IcyCanvas canvas) {
-		a1.mouseDrag(e, imagePoint, canvas);
-		a2.mouseDrag(e, imagePoint, canvas);
-		a3.mouseDrag(e, imagePoint, canvas);
-	}
-
-	@Override
-	public void keyPressed(KeyEvent e, Point2D imagePoint, IcyCanvas canvas) {
-				
-		if ( ( e.getKeyCode() == KeyEvent.VK_DELETE && a1.isSelected() ) || ( e.getKeyCode() == KeyEvent.VK_DELETE && a2.isSelected() ) )
-		{			
-			for ( Sequence sequence : Icy.getMainInterface().getSequencesContaining( this ) )
-			{
-				sequence.removePainter( this );
-			}
-			
-		}
-			
-		a1.keyPressed(e, imagePoint, canvas);
-		a2.keyPressed(e, imagePoint, canvas);
-		a3.keyPressed(e, imagePoint, canvas);
-	}
-
-	@Override
-	public void keyReleased(KeyEvent e, Point2D imagePoint, IcyCanvas canvas) {
-		a1.keyReleased(e, imagePoint, canvas);
-		a2.keyReleased(e, imagePoint, canvas);
-		a3.keyReleased(e, imagePoint, canvas);
-	}	
-	
+public class AnglePainter extends Overlay implements OverlayListener {
+
+    Anchor2DTarget a1 = new Anchor2DTarget(0, 0);
+    Anchor2DTarget a2 = new Anchor2DTarget(0, 0);
+    Anchor2DTarget a3 = new Anchor2DTarget(0, 0);
+
+    ArrayList<ShapeDefinition> shapeDefinitionList = new ArrayList<>();
+    ArrayList<AffineTransform> affineTransformList = new ArrayList<>();
+
+    public AnglePainter(Sequence sequence) {
+        super("Angle painter", OverlayPriority.SHAPE_NORMAL);
+
+        if (sequence == null) return;
+
+        a1.setPosition(sequence.getWidth() / 2f, sequence.getHeight() / 2f);
+        a2.setPosition(3 * sequence.getWidth() / 4f, sequence.getHeight() / 2f);
+        a3.setPosition(3 * sequence.getWidth() / 4f, sequence.getHeight() / 3f);
+
+        sequence.addOverlay(this);
+        a1.addOverlayListener(this);
+        a2.addOverlayListener(this);
+        a3.addOverlayListener(this);
+
+    }
+
+    // Listener of Anchor
+    @Override
+    public void overlayChanged(OverlayEvent overlayEvent) {
+        for (Sequence sequence : Icy.getMainInterface().getSequencesContaining(this)) {
+            sequence.overlayChanged(this);
+        }
+    }
+
+    void pushTransform(Graphics2D g) {
+        affineTransformList.add(g.getTransform());
+    }
+
+    void popTransform(Graphics2D g) {
+        g.setTransform(affineTransformList.get(affineTransformList.size() - 1));
+        affineTransformList.remove(affineTransformList.size() - 1);
+    }
+
+    public double CleanAngle(double angle) {
+        double a = Math.abs(angle);
+        a = Math.round(a * 10) / 10.;
+        return a;
+    }
+
+    // Painter Section:
+
+    @Override
+    public void paint(Graphics2D g, Sequence sequence, IcyCanvas canvas) {
+
+        if (!(canvas instanceof IcyCanvas2D)) return;
+
+        g = (Graphics2D) g.create();
+
+        BasicStroke[] stroke = new BasicStroke[4];
+
+        stroke[0] = new BasicStroke((float) canvas.canvasToImageLogDeltaX(2));
+        stroke[1] = new BasicStroke((float) canvas.canvasToImageLogDeltaX(3));
+        stroke[2] = new BasicStroke((float) canvas.canvasToImageLogDeltaX(4));
+        stroke[3] = new BasicStroke((float) canvas.canvasToImageLogDeltaX(5));
+
+        // transform and display ticks
+
+        shapeDefinitionList.clear();
+
+        pushTransform(g);
+
+        double vx12 = (a2.getX() - a1.getX());
+        double vy12 = (a2.getY() - a1.getY());
+        double angle12 = Math.atan2(vy12, vx12) * (180d / Math.PI);
+
+        double vx13 = (a3.getX() - a1.getX());
+        double vy13 = (a3.getY() - a1.getY());
+        double angle13 = Math.atan2(vy13, vx13) * (180d / Math.PI);
+
+        double angle1 = angle12 - angle13;
+
+        if (angle1 < 0) angle1 += 360;
+
+        double angle2 = 360 - angle1;
+
+        double dis1 = a1.getPosition().distance(a2.getPosition());
+        double dis2 = a1.getPosition().distance(a3.getPosition());
+
+        double minDistance = Math.min(dis1, dis2);
+
+        double distanceAngle1 = minDistance;
+        double distanceAngle2 = minDistance / 2;
+
+        double distanceTextAngle1 = minDistance;
+        double distanceTextAngle2 = minDistance / 2;
+
+        // Lines
+
+        shapeDefinitionList.add(new ShapeDefinition(2, new Line2D.Double(a1.getPosition(), a2.getPosition())));
+        shapeDefinitionList.add(new ShapeDefinition(2, new Line2D.Double(a1.getPosition(), a3.getPosition())));
+
+        // angle 1
+        {
+            double arcSize = distanceAngle1;
+            Arc2D arc = new Arc2D.Double(
+                    a1.getX() - arcSize / 2d,
+                    a1.getY() - arcSize / 2d,
+                    arcSize,
+                    arcSize,
+                    -angle12,
+                    angle1,//angle13,
+                    Arc2D.OPEN
+            );
+
+            shapeDefinitionList.add(new ShapeDefinition(2, arc));
+        }
+
+        // angle 2
+        {
+            double arcSize = distanceAngle2;
+            Arc2D arc = new Arc2D.Double(
+                    a1.getX() - arcSize / 2d,
+                    a1.getY() - arcSize / 2d,
+                    arcSize,
+                    arcSize,
+                    -angle13,
+                    angle2,//angle13,
+                    Arc2D.OPEN
+            );
+
+            shapeDefinitionList.add(new ShapeDefinition(2, arc));
+        }
+
+        // draw lines ( black background, then white )
+
+        float oldAlpha = -1;
+        g.setColor(Color.black);
+        for (ShapeDefinition ld : shapeDefinitionList) {
+            if (oldAlpha != ld.alpha) {
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, ld.alpha));
+                oldAlpha = ld.alpha;
+            }
+            g.setStroke(stroke[ld.stroke]);
+            g.draw(ld.shape);
+        }
+
+        g.setColor(Color.white);
+        for (ShapeDefinition ld : shapeDefinitionList) {
+            if (oldAlpha != ld.alpha) {
+                g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, ld.alpha));
+                oldAlpha = ld.alpha;
+            }
+            g.setStroke(stroke[ld.stroke - 1]);
+            g.draw(ld.shape);
+        }
+
+        // Display angle text
+
+        {
+            int fontSize = (int) convertScale(canvas, 15);
+            Font font = new Font("Arial", Font.PLAIN, fontSize);
+
+            pushTransform(g);
+            String pixelString = " " + (int) (Math.round(angle1)) + "° ";
+            Rectangle2D pixelBounds = GraphicsUtil.getStringBounds(g, font, pixelString);
+            g.translate(a1.getX(), a1.getY());
+
+            double angleText = Math.toRadians(angle12 - angle1 / 2d);
+            g.translate(Math.cos(angleText) * distanceTextAngle1 / 2, Math.sin(angleText) * distanceTextAngle1 / 2);
+            g.translate(-pixelBounds.getWidth() / 2, 0);
+
+            g.setFont(font);
+            g.setColor(Color.white);
+            g.fill(pixelBounds);
+            g.setColor(Color.black);
+            g.drawString(pixelString, 0, 0);
+            popTransform(g);
+        }
+
+        {
+            int fontSize = (int) convertScale(canvas, 15);
+            Font font = new Font("Arial", Font.PLAIN, fontSize);
+
+            pushTransform(g);
+            String pixelString = " " + (int) (Math.round(angle2)) + "� ";
+            Rectangle2D pixelBounds = GraphicsUtil.getStringBounds(g, font, pixelString);
+            g.translate(a1.getX(), a1.getY());
+
+            double angleText = Math.toRadians(180 + angle12 - angle1 / 2d);
+            g.translate(Math.cos(angleText) * distanceTextAngle2 / 2d, Math.sin(angleText) * distanceTextAngle2 / 2d);
+            g.translate(-pixelBounds.getWidth() / 2, 0);
+
+            float alpha = 1;
+            double distance = canvas.getScaleX() * distanceTextAngle2 / 2d;
+
+            Scaler scaler = new Scaler(0, 10, 0, 1, false);
+            alpha = (float) scaler.scale(distance - pixelBounds.getWidth() / 10d);
+
+            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
+
+            g.setFont(font);
+            g.setColor(Color.white);
+            g.fill(pixelBounds);
+            g.setColor(Color.black);
+            g.drawString(pixelString, 0, 0);
+
+            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1));
+            popTransform(g);
+        }
+
+        // get back to original transform
+
+        popTransform(g);
+
+        // display anchors
+        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1));
+        a1.paint(g, sequence, canvas);
+        a2.paint(g, sequence, canvas);
+        a3.paint(g, sequence, canvas);
+    }
+
+    double convertScale(IcyCanvas canvas, int value) {
+        return canvas.canvasToImageLogDeltaX(value);
+    }
+
+    @Override
+    public void mousePressed(MouseEvent e, Point5D.Double imagePoint, IcyCanvas canvas) {
+        a1.mousePressed(e, imagePoint, canvas);
+        a2.mousePressed(e, imagePoint, canvas);
+        a3.mousePressed(e, imagePoint, canvas);
+    }
+
+    @Override
+    public void mouseReleased(MouseEvent e, Point5D.Double imagePoint, IcyCanvas canvas) {
+        a1.mouseReleased(e, imagePoint, canvas);
+        a2.mouseReleased(e, imagePoint, canvas);
+        a3.mouseReleased(e, imagePoint, canvas);
+    }
+
+    @Override
+    public void mouseClick(MouseEvent e, Point5D.Double imagePoint, IcyCanvas canvas) {
+        a1.mouseClick(e, imagePoint, canvas);
+        a2.mouseClick(e, imagePoint, canvas);
+        a3.mouseClick(e, imagePoint, canvas);
+
+    }
+
+    @Override
+    public void mouseMove(MouseEvent e, Point5D.Double imagePoint, IcyCanvas canvas) {
+        a1.mouseMove(e, imagePoint, canvas);
+        a2.mouseMove(e, imagePoint, canvas);
+        a3.mouseMove(e, imagePoint, canvas);
+    }
+
+    @Override
+    public void mouseDrag(MouseEvent e, Point5D.Double imagePoint, IcyCanvas canvas) {
+        a1.mouseDrag(e, imagePoint, canvas);
+        a2.mouseDrag(e, imagePoint, canvas);
+        a3.mouseDrag(e, imagePoint, canvas);
+    }
+
+    @Override
+    public void keyPressed(KeyEvent e, Point5D.Double imagePoint, IcyCanvas canvas) {
+
+        if ((e.getKeyCode() == KeyEvent.VK_DELETE && a1.isSelected()) || (e.getKeyCode() == KeyEvent.VK_DELETE && a2.isSelected())) {
+            for (Sequence sequence : Icy.getMainInterface().getSequencesContaining(this)) {
+                sequence.removeOverlay(this);
+            }
+        }
+
+        a1.keyPressed(e, imagePoint, canvas);
+        a2.keyPressed(e, imagePoint, canvas);
+        a3.keyPressed(e, imagePoint, canvas);
+    }
+
+    @Override
+    public void keyReleased(KeyEvent e, Point5D.Double imagePoint, IcyCanvas canvas) {
+        a1.keyReleased(e, imagePoint, canvas);
+        a2.keyReleased(e, imagePoint, canvas);
+        a3.keyReleased(e, imagePoint, canvas);
+    }
 }