diff --git a/pom.xml b/pom.xml
index a46ee15faad93b93668b9d0c18b72d03ba4c8454..e437b06707a7d74f8b8ecb591dc3fa376dac47c5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,41 +5,47 @@
 	<parent>
 		<groupId>sc.fiji</groupId>
 		<artifactId>pom-bigdataviewer</artifactId>
-		<version>2.1.6</version>
+		<version>4.0.1</version>
 	</parent>
 
 	<artifactId>bigdataviewer-server</artifactId>
-	<version>1.0.5-SNAPSHOT</version>
+	<version>2.1.1-SNAPSHOT</version>
 
 	<name>BigDataServer</name>
 	<description>A web server for BigDataViewer datasets</description>
 
+	<scm>
+		<connection>scm:git:git://github.com/bigdataviewer/bigdataviewer-server</connection>
+		<developerConnection>scm:git:git@github.com:bigdataviewer/bigdataviewer-server</developerConnection>
+		<tag>HEAD</tag>
+		<url>https://github.com/bigdataviewer/bigdataviewer-server</url>
+	</scm>
+	<issueManagement>
+		<system>GitHub Issues</system>
+		<url>https://github.com/bigdataviewer/bigdataviewer-server/issues</url>
+	</issueManagement>
+	<ciManagement>
+		<system>Jenkins</system>
+		<url>http://jenkins.imagej.net/job/bigdataviewer-server/</url>
+	</ciManagement>
+
 	<properties>
-		<scijava.jvm.version>1.7</scijava.jvm.version>
-		<jetty.version>9.2.10.v20150310</jetty.version>
+		<enforcer.skip>true</enforcer.skip>
+		<!-- <jetty.version>9.2.10.v20150310</jetty.version> -->
 	</properties>
 
-	<build>
-		<plugins>
-			<plugin>
-				<artifactId>maven-compiler-plugin</artifactId>
-				<configuration>
-					<source>1.7</source>
-					<target>1.7</target>
-				</configuration>
-			</plugin>
-		</plugins>
-	</build>
+	<repositories>
+		<repository>
+			<id>imagej.public</id>
+			<url>http://maven.imagej.net/content/groups/public</url>
+		</repository>
+	</repositories>
 
 	<dependencies>
 		<dependency>
 			<groupId>sc.fiji</groupId>
 			<artifactId>bigdataviewer-core</artifactId>
 		</dependency>
-		<dependency>
-			<groupId>sc.fiji</groupId>
-			<artifactId>spim_data</artifactId>
-		</dependency>
 		<dependency>
 			<groupId>org.eclipse.jetty</groupId>
 			<artifactId>jetty-server</artifactId>
@@ -73,15 +79,16 @@
 		<developer>
 			<id>tpietzsch</id>
 			<name>Tobias Pietzsch</name>
-			<email>pietzsch@mpi-cbg.de</email>
-			<url/>
-			<organization>MPI-CBG</organization>
-			<organizationUrl>http://www.mpi-cbg.de/</organizationUrl>
+			<url>http://imagej.net/User:Pietzsch</url>
 			<roles>
-				<role>architect</role>
+				<role>founder</role>
+				<role>lead</role>
 				<role>developer</role>
+				<role>debugger</role>
+				<role>reviewer</role>
+				<role>support</role>
+				<role>maintainer</role>
 			</roles>
-			<timezone>+1</timezone>
 		</developer>
 		<developer>
 			<id>hkmoon</id>
@@ -94,21 +101,6 @@
 				<role>architect</role>
 				<role>developer</role>
 			</roles>
-			<timezone>+1</timezone>
 		</developer>
 	</developers>
-
-	<repositories>
-		<repository>
-			<id>imagej.public</id>
-			<url>http://maven.imagej.net/content/groups/public</url>
-		</repository>
-	</repositories>
-
-	<scm>
-		<connection>scm:git:git://github.com/bigdataviewer/bigdataviewer-server</connection>
-		<developerConnection>scm:git:git@github.com:bigdataviewer/bigdataviewer-server</developerConnection>
-		<tag>HEAD</tag>
-		<url>https://github.com/bigdataviewer/bigdataviewer-server</url>
-	</scm>
 </project>
diff --git a/src/main/java/bdv/server/CellHandler.java b/src/main/java/bdv/server/CellHandler.java
index e9024c67fcd25671f262097b5c5ec09b26ce577a..e432f9c77bb702f45c890a433db2095edbf6e50f 100644
--- a/src/main/java/bdv/server/CellHandler.java
+++ b/src/main/java/bdv/server/CellHandler.java
@@ -1,11 +1,40 @@
 package bdv.server;
 
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+import javax.imageio.ImageIO;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.util.log.Log;
+import org.jdom2.Document;
+import org.jdom2.JDOMException;
+import org.jdom2.input.SAXBuilder;
+import org.jdom2.output.Format;
+import org.jdom2.output.XMLOutputter;
+
+import com.google.gson.GsonBuilder;
+import com.google.gson.stream.JsonWriter;
+
 import bdv.BigDataViewer;
-import bdv.img.cache.CacheHints;
-import bdv.img.cache.LoadingStrategy;
+import bdv.cache.CacheHints;
+import bdv.cache.LoadingStrategy;
 import bdv.img.cache.VolatileCell;
 import bdv.img.cache.VolatileGlobalCellCache;
+import bdv.img.cache.VolatileGlobalCellCache.Key;
+import bdv.img.cache.VolatileGlobalCellCache.VolatileCellLoader;
 import bdv.img.hdf5.Hdf5ImageLoader;
+import bdv.img.hdf5.Hdf5VolatileShortArrayLoader;
 import bdv.img.hdf5.Partition;
 import bdv.img.remote.AffineTransform3DJsonSerializer;
 import bdv.img.remote.RemoteImageLoader;
@@ -15,39 +44,17 @@ import bdv.spimdata.SequenceDescriptionMinimal;
 import bdv.spimdata.SpimDataMinimal;
 import bdv.spimdata.XmlIoSpimDataMinimal;
 import bdv.util.ThumbnailGenerator;
-
-import com.google.gson.GsonBuilder;
-
-import com.google.gson.stream.JsonWriter;
 import mpicbg.spim.data.SpimDataException;
 import net.imglib2.img.basictypeaccess.volatiles.array.VolatileShortArray;
 import net.imglib2.realtransform.AffineTransform3D;
 
-import org.eclipse.jetty.server.Handler;
-import org.eclipse.jetty.server.Request;
-import org.eclipse.jetty.server.handler.ContextHandler;
-import org.eclipse.jetty.util.log.Log;
-import org.jdom2.Document;
-import org.jdom2.JDOMException;
-import org.jdom2.input.SAXBuilder;
-import org.jdom2.output.Format;
-import org.jdom2.output.XMLOutputter;
-
-import javax.imageio.ImageIO;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import java.awt.image.BufferedImage;
-import java.io.*;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
-
 public class CellHandler extends ContextHandler
 {
 	private static final org.eclipse.jetty.util.log.Logger LOG = Log.getLogger( CellHandler.class );
 
-	private VolatileGlobalCellCache< VolatileShortArray > cache;
+	private VolatileGlobalCellCache cache;
+
+	private final Hdf5VolatileShortArrayLoader loader;
 
 	private final CacheHints cacheHints;
 
@@ -82,11 +89,11 @@ public class CellHandler extends ContextHandler
 
 	private boolean active = false;
 
-	private SequenceDescriptionMinimal seq;
+	private final SequenceDescriptionMinimal seq;
 
 	private Hdf5ImageLoader imgLoader;
 
-	private String baseUrl;
+	private final String baseUrl;
 
 	/**
 	 * DataSet information holder
@@ -104,7 +111,8 @@ public class CellHandler extends ContextHandler
 		seq = spimData.getSequenceDescription();
 		imgLoader = ( Hdf5ImageLoader ) seq.getImgLoader();
 
-		cache = imgLoader.getCache();
+		cache = imgLoader.getCacheControl();
+		loader = imgLoader.getShortArrayLoader();
 		cacheHints = new CacheHints( LoadingStrategy.BLOCKING, 0, false );
 
 		// dataSetURL property is used for providing the XML file by replace
@@ -122,7 +130,7 @@ public class CellHandler extends ContextHandler
 		long size = new File( xmlFilename.replace( ".xml", ".h5" ) ).length();
 
 		if ( imgLoader.getPartitions().size() > 0 )
-			for ( Partition partition : imgLoader.getPartitions() )
+			for ( final Partition partition : imgLoader.getPartitions() )
 			{
 				size += new File( partition.getPath() ).length();
 			}
@@ -170,7 +178,8 @@ public class CellHandler extends ContextHandler
 			final int timepoint = Integer.parseInt( parts[ 2 ] );
 			final int setup = Integer.parseInt( parts[ 3 ] );
 			final int level = Integer.parseInt( parts[ 4 ] );
-			VolatileCell< VolatileShortArray > cell = cache.getGlobalIfCached( timepoint, setup, level, index, cacheHints );
+			final Key key = new VolatileGlobalCellCache.Key( timepoint, setup, level, index );
+			VolatileCell< ? > cell = cache.getLoadingVolatileCache().getIfPresent( key, cacheHints );
 			if ( cell == null )
 			{
 				final int[] cellDims = new int[] {
@@ -181,10 +190,11 @@ public class CellHandler extends ContextHandler
 						Long.parseLong( parts[ 8 ] ),
 						Long.parseLong( parts[ 9 ] ),
 						Long.parseLong( parts[ 10 ] ) };
-				cell = cache.createGlobal( cellDims, cellMin, timepoint, setup, level, index, cacheHints );
+				cell = cache.getLoadingVolatileCache().get( key, cacheHints, new VolatileCellLoader<>( loader, timepoint, setup, level, cellDims, cellMin ) );
 			}
 
-			final short[] data = cell.getData().getCurrentStorageArray();
+			@SuppressWarnings( "unchecked" )
+			final short[] data = ( ( VolatileCell< VolatileShortArray > ) cell ).getData().getCurrentStorageArray();
 			final byte[] buf = new byte[ 2 * data.length ];
 			for ( int i = 0, j = 0; i < data.length; i++ )
 			{
@@ -227,17 +237,17 @@ public class CellHandler extends ContextHandler
 		}
 	}
 
-	public void setDescription(String desc)
+	public void setDescription(final String desc)
 	{
 		dataSet.setDescription( desc );
 	}
 
-	public void setCategory(String cate)
+	public void setCategory(final String cate)
 	{
 		dataSet.setCategory( cate );
 	}
 
-	public void setIndex(String idx)
+	public void setIndex(final String idx)
 	{
 		dataSet.setIndex( idx );
 	}
@@ -358,14 +368,14 @@ public class CellHandler extends ContextHandler
 	 * Set the active status
 	 * @param active
 	 */
-	public void setActive( boolean active ) throws SpimDataException
+	public void setActive( final boolean active ) throws SpimDataException
 	{
 		this.active = active;
 
 		if ( active )
 		{
 			imgLoader = ( Hdf5ImageLoader ) seq.getImgLoader();
-			cache = imgLoader.getCache();
+			cache = imgLoader.getCacheControl();
 		}
 		else
 		{
diff --git a/src/main/java/bdv/server/JsonDatasetListHandler.java b/src/main/java/bdv/server/JsonDatasetListHandler.java
index e540466b1df3fc84e0c22b62d462efde8640f6d0..59599bb48dd3a31b852ed1cbc3fc5781ad4efbe0 100644
--- a/src/main/java/bdv/server/JsonDatasetListHandler.java
+++ b/src/main/java/bdv/server/JsonDatasetListHandler.java
@@ -21,7 +21,7 @@ import java.util.Comparator;
 /**
  * Provides a list of available datasets on this {@link BigDataServer}
  *
- * @author HongKee Moon <moon@mpi-cbg.de>
+ * @author HongKee Moon &lt;moon@mpi-cbg.de&gt;
  */
 public class JsonDatasetListHandler extends ContextHandler
 {
diff --git a/src/main/java/bdv/util/ThumbnailGenerator.java b/src/main/java/bdv/util/ThumbnailGenerator.java
index 8f824c63de2d6f27da76bb94cd5cc02d38812fcf..92c0f322bce7e29f9406fd1d063dba49b65e25f5 100644
--- a/src/main/java/bdv/util/ThumbnailGenerator.java
+++ b/src/main/java/bdv/util/ThumbnailGenerator.java
@@ -7,16 +7,12 @@ import java.util.List;
 
 import javax.imageio.ImageIO;
 
-import net.imglib2.realtransform.AffineTransform3D;
-import net.imglib2.ui.PainterThread;
-import net.imglib2.ui.RenderTarget;
-
 import org.jdom2.Document;
 import org.jdom2.Element;
 import org.jdom2.input.SAXBuilder;
 
 import bdv.BigDataViewer;
-import bdv.img.cache.Cache;
+import bdv.cache.CacheControl;
 import bdv.spimdata.SpimDataMinimal;
 import bdv.spimdata.XmlIoSpimDataMinimal;
 import bdv.tools.InitializeViewerState;
@@ -26,11 +22,15 @@ import bdv.tools.transformation.TransformedSource;
 import bdv.tools.transformation.XmlIoTransformedSources;
 import bdv.viewer.Source;
 import bdv.viewer.SourceAndConverter;
+import bdv.viewer.render.AccumulateProjectorARGB;
 import bdv.viewer.render.MultiResolutionRenderer;
 import bdv.viewer.state.SourceGroup;
 import bdv.viewer.state.SourceState;
 import bdv.viewer.state.ViewerState;
 import bdv.viewer.state.XmlIoViewerState;
+import net.imglib2.realtransform.AffineTransform3D;
+import net.imglib2.ui.PainterThread;
+import net.imglib2.ui.RenderTarget;
 
 /**
  * Created by moon on 2/5/15.
@@ -93,7 +93,7 @@ public class ThumbnailGenerator
 			}
 		}
 		final ThumbnailTarget renderTarget = new ThumbnailTarget();
-		new MultiResolutionRenderer( renderTarget, new PainterThread( null ), new double[] { 1 }, 0, false, 1, null, false, new Cache.Dummy() ).paint( state );
+		new MultiResolutionRenderer( renderTarget, new PainterThread( null ), new double[] { 1 }, 0, false, 1, null, false, AccumulateProjectorARGB.factory, new CacheControl.Dummy() ).paint( state );
 		return renderTarget.bi;
 	}