diff --git a/pom.xml b/pom.xml
index 406aa07435e93cd3a95229a7ef356a0c9f2e0b2d..99854e10bc5e81318d17c9de71e87fdf85c74c80 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
 	<parent>
 		<groupId>org.scijava</groupId>
 		<artifactId>pom-scijava</artifactId>
-		<version>17.1.1</version>
+		<version>22.2.0</version>
 		<relativePath />
 	</parent>
 
@@ -93,11 +93,6 @@
 		<license.licenseName>gpl_v3</license.licenseName>
 		<license.copyrightOwners>BigDataViewer developers.</license.copyrightOwners>
 
-		<imglib2.version>4.2.1</imglib2.version>
-		<imglib2-ui.version>2.0.0-beta-32</imglib2-ui.version>
-		<bigdataviewer-core.version>4.1.0</bigdataviewer-core.version>
-		<SPIM_Registration.version>5.0.13</SPIM_Registration.version>
-
 		<!-- NB: Deploy releases to the ImageJ Maven repository. -->
 		<releaseProfiles>deploy-to-imagej</releaseProfiles>
 	</properties>
diff --git a/src/main/java/bdv/ij/OpenImagePlusPlugIn.java b/src/main/java/bdv/ij/OpenImagePlusPlugIn.java
index eb1cd985175bd3f59de2adef70aa6ea5d58c2b2c..c62b681a012a63ce6e85aa63fe1c733ebeab1853 100644
--- a/src/main/java/bdv/ij/OpenImagePlusPlugIn.java
+++ b/src/main/java/bdv/ij/OpenImagePlusPlugIn.java
@@ -51,8 +51,8 @@ public class OpenImagePlusPlugIn implements Command
 	{
 		System.setProperty( "apple.laf.useScreenMenuBar", "true" );
 		new ImageJ();
-		IJ.run("Confocal Series (2.2MB)");
-//		IJ.run("Fly Brain (1MB)");
+		IJ.run( "Confocal Series (2.2MB)" );
+//		IJ.run( "Fly Brain (1MB)" );
 		new OpenImagePlusPlugIn().run();
 	}
 
diff --git a/src/main/java/bdv/img/imagestack/ImageStackImageLoader.java b/src/main/java/bdv/img/imagestack/ImageStackImageLoader.java
index 43affc871fe4d5f5ccc9f5a8e1b521d32dad44e4..d3f3eeda0ac51fa5fb73ef05003d98d9c1f39e4f 100644
--- a/src/main/java/bdv/img/imagestack/ImageStackImageLoader.java
+++ b/src/main/java/bdv/img/imagestack/ImageStackImageLoader.java
@@ -1,12 +1,8 @@
 package bdv.img.imagestack;
 
 import java.util.ArrayList;
+import java.util.function.Function;
 
-import ij.ImagePlus;
-import mpicbg.spim.data.generic.sequence.BasicImgLoader;
-import mpicbg.spim.data.generic.sequence.BasicSetupImgLoader;
-import mpicbg.spim.data.generic.sequence.ImgLoaderHint;
-import mpicbg.spim.data.generic.sequence.TypedBasicImgLoader;
 import net.imglib2.RandomAccessibleInterval;
 import net.imglib2.img.basictypeaccess.array.ArrayDataAccess;
 import net.imglib2.img.basictypeaccess.array.ByteArray;
@@ -15,84 +11,39 @@ import net.imglib2.img.basictypeaccess.array.IntArray;
 import net.imglib2.img.basictypeaccess.array.ShortArray;
 import net.imglib2.img.planar.PlanarImg;
 import net.imglib2.type.NativeType;
+import net.imglib2.type.NativeTypeFactory;
 import net.imglib2.type.numeric.ARGBType;
 import net.imglib2.type.numeric.NumericType;
 import net.imglib2.type.numeric.integer.UnsignedByteType;
 import net.imglib2.type.numeric.integer.UnsignedShortType;
 import net.imglib2.type.numeric.real.FloatType;
 
-public abstract class ImageStackImageLoader< T extends NumericType< T > & NativeType< T >, A extends ArrayDataAccess< A > > implements BasicImgLoader, TypedBasicImgLoader< T >
+import ij.ImagePlus;
+import mpicbg.spim.data.generic.sequence.BasicImgLoader;
+import mpicbg.spim.data.generic.sequence.BasicSetupImgLoader;
+import mpicbg.spim.data.generic.sequence.ImgLoaderHint;
+import mpicbg.spim.data.generic.sequence.TypedBasicImgLoader;
+
+public class ImageStackImageLoader< T extends NumericType< T > & NativeType< T >, A extends ArrayDataAccess< A > > implements BasicImgLoader, TypedBasicImgLoader< T >
 {
 	public static ImageStackImageLoader< UnsignedByteType, ByteArray > createUnsignedByteInstance( final ImagePlus imp )
 	{
-		return new ImageStackImageLoader< UnsignedByteType, ByteArray >( new UnsignedByteType(), imp )
-		{
-			@Override
-			protected ByteArray wrapPixels( final Object array )
-			{
-				return new ByteArray( ( byte[] ) array );
-			}
-
-			@Override
-			protected void linkType( final PlanarImg< UnsignedByteType, ByteArray > img )
-			{
-				img.setLinkedType( new UnsignedByteType( img ) );
-			}
-		};
+		return new ImageStackImageLoader<>( new UnsignedByteType(), imp, array -> new ByteArray( ( byte[] ) array ) );
 	}
 
 	public static ImageStackImageLoader< UnsignedShortType, ShortArray > createUnsignedShortInstance( final ImagePlus imp )
 	{
-		return new ImageStackImageLoader< UnsignedShortType, ShortArray >( new UnsignedShortType(), imp )
-		{
-			@Override
-			protected ShortArray wrapPixels( final Object array )
-			{
-				return new ShortArray( ( short[] ) array );
-			}
-
-			@Override
-			protected void linkType( final PlanarImg< UnsignedShortType, ShortArray > img )
-			{
-				img.setLinkedType( new UnsignedShortType( img ) );
-			}
-		};
+		return new ImageStackImageLoader<>( new UnsignedShortType(), imp, array -> new ShortArray( ( short[] ) array ) );
 	}
 
 	public static ImageStackImageLoader< FloatType, FloatArray > createFloatInstance( final ImagePlus imp )
 	{
-		return new ImageStackImageLoader< FloatType, FloatArray >( new FloatType(), imp )
-		{
-			@Override
-			protected FloatArray wrapPixels( final Object array )
-			{
-				return new FloatArray( ( float[] ) array );
-			}
-
-			@Override
-			protected void linkType( final PlanarImg< FloatType, FloatArray > img )
-			{
-				img.setLinkedType( new FloatType( img ) );
-			}
-		};
+		return new ImageStackImageLoader<>( new FloatType(), imp, array -> new FloatArray( ( float[] ) array ) );
 	}
 
 	public static ImageStackImageLoader< ARGBType, IntArray > createARGBInstance( final ImagePlus imp )
 	{
-		return new ImageStackImageLoader< ARGBType, IntArray >( new ARGBType(), imp )
-		{
-			@Override
-			protected IntArray wrapPixels( final Object array )
-			{
-				return new IntArray( ( int[] ) array );
-			}
-
-			@Override
-			protected void linkType( final PlanarImg< ARGBType, IntArray > img )
-			{
-				img.setLinkedType( new ARGBType( img ) );
-			}
-		};
+		return new ImageStackImageLoader<>( new ARGBType(), imp, array -> new IntArray( ( int[] ) array ) );
 	}
 
 	private final T type;
@@ -103,10 +54,13 @@ public abstract class ImageStackImageLoader< T extends NumericType< T > & Native
 
 	private final ArrayList< SetupImgLoader > setupImgLoaders;
 
-	public ImageStackImageLoader( final T type, final ImagePlus imp )
+	private final Function< Object, A > wrapPixels;
+
+	public ImageStackImageLoader( final T type, final ImagePlus imp, final Function< Object, A > wrapPixels )
 	{
 		this.type = type;
 		this.imp = imp;
+		this.wrapPixels = wrapPixels;
 		this.dim = new long[] { imp.getWidth(), imp.getHeight(), imp.getNSlices() };
 		final int numSetups = imp.getNChannels();
 		setupImgLoaders = new ArrayList<>();
@@ -114,10 +68,6 @@ public abstract class ImageStackImageLoader< T extends NumericType< T > & Native
 			setupImgLoaders.add( new SetupImgLoader( setupId ) );
 	}
 
-	protected abstract A wrapPixels( Object array );
-
-	protected abstract void linkType( PlanarImg< T, A > img );
-
 	public class SetupImgLoader implements BasicSetupImgLoader< T >
 	{
 		private final int setupId;
@@ -130,18 +80,16 @@ public abstract class ImageStackImageLoader< T extends NumericType< T > & Native
 		@Override
 		public RandomAccessibleInterval< T > getImage( final int timepointId, final ImgLoaderHint... hints )
 		{
-			return new PlanarImg< T, A >( dim, type.getEntitiesPerPixel() )
-			{
-				private PlanarImg< T, A > init()
-				{
-					final int channel = setupId + 1;
-					final int frame = timepointId + 1;
-					for ( int slice = 1; slice <= dim[ 2 ]; ++slice )
-						mirror.set( slice - 1, wrapPixels( imp.getStack().getPixels( imp.getStackIndex( channel, slice, frame ) ) ) );
-					linkType( this );
-					return this;
-				}
-			}.init();
+			final int channel = setupId + 1;
+			final int frame = timepointId + 1;
+			final ArrayList< A > slices = new ArrayList<>();
+			for ( int slice = 1; slice <= dim[ 2 ]; ++slice )
+				slices.add( wrapPixels.apply( imp.getStack().getPixels( imp.getStackIndex( channel, slice, frame ) ) ) );
+			final PlanarImg< T, A > img = new PlanarImg<>( slices, dim, type.getEntitiesPerPixel() );
+			@SuppressWarnings( "unchecked" )
+			final NativeTypeFactory< T, ? super A > typeFactory = ( NativeTypeFactory< T, ? super A > ) type.getNativeTypeFactory();
+			img.setLinkedType( typeFactory.createLinkedType( img ) );
+			return img;
 		}
 
 		@Override