diff --git a/pom.xml b/pom.xml
index 8d1935148ba274f44b6b915e5d99725dff65d83d..50f16a9020b6df3044be50d4dfe6283208ab4c4a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -79,6 +79,16 @@
 			<artifactId>vecmath</artifactId>
 			<version>1.3.1</version>
 		</dependency>
+		<dependency>
+			<groupId>org.eclipse.jetty</groupId>
+			<artifactId>jetty-server</artifactId>
+			<version>9.1.3.v20140225</version>
+		</dependency>
+		<dependency>
+			<groupId>com.google.code.gson</groupId>
+			<artifactId>gson</artifactId>
+			<version>2.2.4</version>
+		</dependency>
 	</dependencies>
 
 	<developers>
diff --git a/src/main/java/bdv/server/BigDataServer.java b/src/main/java/bdv/server/BigDataServer.java
new file mode 100644
index 0000000000000000000000000000000000000000..afe3a4cb4a6f32b86609c79fbee7d431769b5bbd
--- /dev/null
+++ b/src/main/java/bdv/server/BigDataServer.java
@@ -0,0 +1,135 @@
+package server;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.parsers.ParserConfigurationException;
+
+import mpicbg.spim.data.SequenceDescription;
+import net.imglib2.img.basictypeaccess.array.ShortArray;
+
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+import org.xml.sax.SAXException;
+
+import viewer.SequenceViewsLoader;
+import viewer.hdf5.Hdf5ImageLoader;
+import viewer.hdf5.Hdf5ImageLoader.DimensionsInfo;
+import viewer.hdf5.img.Hdf5Cell;
+import viewer.hdf5.img.Hdf5GlobalCellCache;
+
+public class CellServer
+{
+	public static void main( final String[] args ) throws Exception
+	{
+		final String fn = args.length > 0 ? args[ 0 ] : "/Users/pietzsch/Desktop/Valia/valia.xml";
+		final Server server = new Server( 8080 );
+		server.setHandler( new CellHandler( fn ) );
+		server.start();
+		server.join();
+	}
+
+	static class CellHandler extends AbstractHandler
+	{
+		final Hdf5ImageLoader imgLoader;
+
+		final Hdf5GlobalCellCache< ShortArray > cache;
+
+		final byte[] initObjects;
+
+		public CellHandler( final String xmlFilename ) throws ParserConfigurationException, SAXException, IOException, InstantiationException, IllegalAccessException, ClassNotFoundException
+		{
+			final SequenceViewsLoader loader = new SequenceViewsLoader( xmlFilename );
+			final SequenceDescription seq = loader.getSequenceDescription();
+			imgLoader = ( Hdf5ImageLoader ) seq.imgLoader;
+			cache = imgLoader.getCache();
+
+			final ArrayList< double[][] > perSetupResolutions = new ArrayList< double[][] >();
+			for ( int setup = 0; setup < seq.numViewSetups(); ++setup )
+				perSetupResolutions.add( imgLoader.getMipmapResolutions( setup ) );
+			final ByteArrayOutputStream bs = new ByteArrayOutputStream();
+			final ObjectOutputStream os = new ObjectOutputStream( bs );
+			os.writeInt( seq.numTimepoints() );
+			os.writeObject( perSetupResolutions );
+			os.close();
+			initObjects = bs.toByteArray();
+		}
+
+		@Override
+		public void handle( final String target, final Request baseRequest, final HttpServletRequest request, final HttpServletResponse response ) throws IOException, ServletException
+		{
+			final String cellString = request.getParameter( "p" );
+			if ( cellString == null )
+				return;
+			final String[] parts = cellString.split( "/" );
+			if ( parts[ 0 ].equals( "cell" ) )
+			{
+				final int index = Integer.parseInt( parts[ 1 ] );
+				final int timepoint = Integer.parseInt( parts[ 2 ] );
+				final int setup = Integer.parseInt( parts[ 3 ] );
+				final int level = Integer.parseInt( parts[ 4 ] );
+				Hdf5Cell< ShortArray > cell = cache.getGlobalIfCached( timepoint, setup, level, index );
+				if ( cell == null )
+				{
+					final int[] cellDims = new int[] { Integer.parseInt( parts[ 5 ] ), Integer.parseInt( parts[ 6 ] ), Integer.parseInt( parts[ 7 ] ) };
+					final long[] cellMin = new long[] { Long.parseLong( parts[ 8 ] ), Long.parseLong( parts[ 9 ] ), Long.parseLong( parts[ 10 ] ) };
+					cell = cache.loadGlobal( cellDims, cellMin, timepoint, setup, level, index );
+				}
+				final short[] data = cell.getData().getCurrentStorageArray();
+				final byte[] buf = new byte[ 2 * data.length ];
+				for ( int i = 0, j = 0; i < data.length; i++ )
+				{
+					final short s = data[ i ];
+					buf[ j++ ] = ( byte ) ( ( s >> 8 ) & 0xff );
+					buf[ j++ ] = ( byte ) ( s & 0xff );
+				}
+
+				response.setContentType( "application/octet-stream" );
+				response.setContentLength( buf.length );
+				response.setStatus( HttpServletResponse.SC_OK );
+				baseRequest.setHandled( true );
+				final OutputStream os = response.getOutputStream();
+				os.write( buf );
+				os.close();
+
+//				final byte[] buf = new byte[ 4096 ];
+//				for ( int i = 0, l = Math.min( buf.length / 2, data.length - i ); i < data.length; i += l )
+//				{
+//					ByteBuffer.wrap( buf ).asShortBuffer().put( data, i, l );
+//					os.write( buf, 0, 2 * l );
+//				}
+//				os.close();
+			}
+			else if ( parts[ 0 ].equals( "dim" ) )
+			{
+				final int timepoint = Integer.parseInt( parts[ 1 ] );
+				final int setup = Integer.parseInt( parts[ 2 ] );
+				final int level = Integer.parseInt( parts[ 3 ] );
+				final DimensionsInfo info = imgLoader.getDimensionsInfo( timepoint, setup, level );
+
+				response.setContentType( "application/octet-stream" );
+				response.setStatus( HttpServletResponse.SC_OK );
+				baseRequest.setHandled( true );
+				final ObjectOutputStream os = new ObjectOutputStream( response.getOutputStream() );
+				os.writeObject( info );
+				os.close();
+			}
+			else if ( parts[ 0 ].equals( "init" ) )
+			{
+				response.setContentType( "application/octet-stream" );
+				response.setStatus( HttpServletResponse.SC_OK );
+				baseRequest.setHandled( true );
+				final OutputStream os = response.getOutputStream();
+				os.write( initObjects );
+				os.close();
+			}
+		}
+	}
+}