diff --git a/screening/source/core-plugins/microscopy/1/as/webapps/image-viewer/html/image-viewer.js b/screening/source/core-plugins/microscopy/1/as/webapps/image-viewer/html/image-viewer.js
index 2b11eba53e1d74eb5131f3dc4a6a3d2eab493005..30fd6eaea077372e2ca5211bbf4bd1e1f15721a1 100644
--- a/screening/source/core-plugins/microscopy/1/as/webapps/image-viewer/html/image-viewer.js
+++ b/screening/source/core-plugins/microscopy/1/as/webapps/image-viewer/html/image-viewer.js
@@ -456,24 +456,10 @@ $.extend(ImageViewerWidget.prototype, AbstractWidget.prototype, {
 	},
 
 	getChannelStacks : function() {
-		return this.imageInfo.channelStacks.sort(function(o1, o2) {
-			var t1 = o1.timePointOrNull;
-			var t2 = o2.timePointOrNull;
-			var d1 = o1.depthOrNull;
-			var d2 = o2.depthOrNull;
-
-			var compare = function(v1, v2) {
-				if (v1 > v2) {
-					return 1;
-				} else if (v1 < v2) {
-					return -1;
-				} else {
-					return 0;
-				}
-			}
-
-			return compare(t1, t2) * 10 + compare(d1, d2);
-		});
+		if (this.channelStackManager == null) {
+			this.channelStackManager = new ChannelStackManager(this.imageInfo.channelStacks);
+		}
+		return this.channelStackManager.getChannelStacks();
 	},
 
 	getResolutions : function() {
@@ -785,7 +771,7 @@ $.extend(ChannelStackChooserWidget.prototype, {
 		if (manager.isMatrix()) {
 			this.widget = new ChannelStackMatrixChooserWidget(channelStacks);
 		} else {
-			this.widget = new ChannelStackDefaultChooserWidget(channelStacks);
+			this.widget = new ChannelStackSeriesChooserWidget(channelStacks);
 		}
 	},
 
@@ -893,9 +879,11 @@ $.extend(ChannelStackMatrixChooserView.prototype, AbstractView.prototype, {
 			"step" : 1,
 			"tooltip" : "hide"
 		}).on("slide", function(event) {
-			var timeIndex = parseInt(event.value);
-			var time = thisView.controller.getTimePoints()[timeIndex];
-			thisView.controller.setSelectedTimePoint(time);
+			if (!$.isArray(event.value) && !isNaN(event.value)) {
+				var timeIndex = parseInt(event.value);
+				var time = thisView.controller.getTimePoints()[timeIndex];
+				thisView.controller.setSelectedTimePoint(time);
+			}
 		});
 
 		return widget;
@@ -917,9 +905,11 @@ $.extend(ChannelStackMatrixChooserView.prototype, AbstractView.prototype, {
 			"step" : 1,
 			"tooltip" : "hide"
 		}).on("slide", function(event) {
-			var depthIndex = parseInt(event.value);
-			var depth = thisView.controller.getDepths()[depthIndex];
-			thisView.controller.setSelectedDepth(depth);
+			if (!$.isArray(event.value) && !isNaN(event.value)) {
+				var depthIndex = parseInt(event.value);
+				var depth = thisView.controller.getDepths()[depthIndex];
+				thisView.controller.setSelectedDepth(depth);
+			}
 		});
 
 		return widget;
@@ -1070,41 +1060,146 @@ $.extend(ChannelStackMatrixChooserWidget.prototype, AbstractWidget.prototype, {
 });
 
 //
-// CHANNEL STACK DEFAULT CHOOSER VIEW
+// CHANNEL STACK SERIES CHOOSER VIEW
 //
 
-function ChannelStackDefaultChooserView(controller) {
+function ChannelStackSeriesChooserView(controller) {
 	this.init(controller);
 }
 
-$.extend(ChannelStackDefaultChooserView.prototype, AbstractView.prototype, {
+$.extend(ChannelStackSeriesChooserView.prototype, AbstractView.prototype, {
 
 	init : function(controller) {
 		AbstractView.prototype.init.call(this, controller);
+		this.panel = $("<div>").addClass("channelStackChooserWidget").addClass("form-group");
+	},
+
+	render : function() {
+		var thisView = this;
+
+		this.panel.append(this.createSliderWidget());
+		this.panel.append(this.createButtonsWidget());
+
+		this.refresh();
+
+		return this.panel;
+	},
+
+	refresh : function() {
+		var channelStackId = this.controller.getSelectedChannelStackId();
+
+		if (channelStackId != null) {
+			var count = this.controller.getChannelStacks().length;
+			var index = this.controller.getChannelStackIndex(channelStackId);
+
+			var sliderLabel = this.panel.find(".sliderWidget label");
+			sliderLabel.text("Channel Stack: " + index + " (" + (index + 1) + "/" + count + ")");
+
+			var sliderInput = this.panel.find(".sliderWidget input");
+			sliderInput.slider("setValue", index);
+
+			this.buttons.setSelectedFrame(index);
+		}
+	},
+
+	createSliderWidget : function() {
+		var thisView = this;
+		var widget = $("<div>").addClass("sliderWidget").addClass("form-group");
+
+		$("<label>").attr("for", "sliderInput").appendTo(widget);
+
+		var sliderInput = $("<input>").attr("id", "sliderInput").attr("type", "text").addClass("form-control");
+
+		$("<div>").append(sliderInput).appendTo(widget);
+
+		sliderInput.slider({
+			"min" : 0,
+			"max" : this.controller.getChannelStacks().length - 1,
+			"step" : 1,
+			"tooltip" : "hide"
+		}).on("slide", function(event) {
+			if (!$.isArray(event.value) && !isNaN(event.value)) {
+				var index = parseInt(event.value);
+				var channelStack = thisView.controller.getChannelStacks()[index];
+				thisView.controller.setSelectedChannelStackId(channelStack.id);
+			}
+		});
+
+		return widget;
+	},
+
+	createButtonsWidget : function() {
+		var thisView = this;
+
+		var buttons = new MovieButtonsWidget(this.controller.getChannelStacks().length);
+
+		buttons.setFrameContentLoader(function(frameIndex, callback) {
+			var channelStack = thisView.controller.getChannelStacks()[frameIndex];
+			thisView.controller.loadChannelStackContent(channelStack, callback);
+		});
+
+		buttons.addChangeListener(function() {
+			var channelStack = thisView.controller.getChannelStacks()[buttons.getSelectedFrame()];
+			thisView.controller.setSelectedChannelStackId(channelStack.id);
+		});
+
+		this.buttons = buttons;
+		return buttons.render();
 	}
 
 });
 
 //
-// CHANNEL STACK DEFAULT CHOOSER
+// CHANNEL STACK SERIES CHOOSER
 //
 
-function ChannelStackDefaultChooserWidget(channelStacks) {
+function ChannelStackSeriesChooserWidget(channelStacks) {
 	this.init(channelStacks);
 }
 
-$.extend(ChannelStackDefaultChooserWidget.prototype, AbstractWidget.prototype, {
+$.extend(ChannelStackSeriesChooserWidget.prototype, AbstractWidget.prototype, {
 
 	init : function(channelStacks) {
-		AbstractWidget.prototype.init.call(this, new ChannelStackDefaultChooserView(this));
+		AbstractWidget.prototype.init.call(this, new ChannelStackSeriesChooserView(this));
 		this.channelStackManager = new ChannelStackManager(channelStacks);
 	},
 
+	getChannelStacks : function() {
+		return this.channelStackManager.getChannelStacks();
+	},
+
+	getChannelStackIndex : function(channelStackId) {
+		return this.channelStackManager.getChannelStackIndex(channelStackId);
+	},
+
+	loadChannelStackContent : function(channelStack, callback) {
+		this.getChannelStackContentLoader()(channelStack, callback);
+	},
+
+	getChannelStackContentLoader : function() {
+		if (this.channelStackContentLoader) {
+			return this.channelStackContentLoader;
+		} else {
+			return function(channelStack, callback) {
+				callback();
+			}
+		}
+	},
+
+	setChannelStackContentLoader : function(channelStackContentLoader) {
+		this.channelStackContentLoader = channelStackContentLoader;
+	},
+
 	getSelectedChannelStackId : function() {
-		return null;
+		return this.selectedChannelStackId;
 	},
 
 	setSelectedChannelStackId : function(channelStackId) {
+		if (this.selectedChannelStackId != channelStackId) {
+			this.selectedChannelStackId = channelStackId;
+			this.refresh();
+			this.notifyChangeListeners();
+		}
 	}
 
 });
@@ -1449,9 +1544,44 @@ $.extend(ChannelStackManager.prototype, {
 
 	init : function(channelStacks) {
 		this.channelStacks = channelStacks;
+		this.channelStacks.sort(function(o1, o2) {
+			var s1 = o1.seriesNumberOrNull;
+			var s2 = o2.seriesNumberOrNull;
+			var t1 = o1.timePointOrNull;
+			var t2 = o2.timePointOrNull;
+			var d1 = o1.depthOrNull;
+			var d2 = o2.depthOrNull;
+
+			var compare = function(v1, v2) {
+				if (v1 == null) {
+					if (v2 == null) {
+						return 0;
+					} else {
+						return -1;
+					}
+				} else if (v2 == null) {
+					return 1;
+				} else {
+					if (v1 > v2) {
+						return 1;
+					} else if (v1 < v2) {
+						return -1;
+					} else {
+						return 0;
+					}
+				}
+			}
+
+			return compare(s1, s2) * 100 + compare(t1, t2) * 10 + compare(d1, d2);
+		});
 	},
 
 	isMatrix : function() {
+		/*
+		 * TODO return (!this.isSeriesNumberPresent() ||
+		 * this.getSeriesNumbers().length == 1) && !this.isTimePointMissing() &&
+		 * !this.isDepthMissing() && this.isDepthConsistent();
+		 */
 		return !this.isSeriesNumberPresent() && !this.isTimePointMissing() && !this.isDepthMissing() && this.isDepthConsistent();
 	},
 
@@ -1486,6 +1616,27 @@ $.extend(ChannelStackManager.prototype, {
 		return Object.keys(depthCounts).length == 1;
 	},
 
+	getSeriesNumbers : function() {
+		if (!this.seriesNumbers) {
+			var seriesNumbers = {};
+
+			this.channelStacks.forEach(function(channelStack) {
+				if (channelStack.seriesNumberOrNull != null) {
+					seriesNumbers[channelStack.seriesNumberOrNull] = true;
+				}
+			});
+
+			this.seriesNumbers = Object.keys(seriesNumbers).map(function(seriesNumber) {
+				return parseInt(seriesNumber);
+			}).sort();
+		}
+		return this.seriesNumbers;
+	},
+
+	getSeriesNumber : function(index) {
+		return this.getSeriesNumbers()[index];
+	},
+
 	getTimePoints : function() {
 		if (!this.timePoints) {
 			var timePoints = {};
@@ -1498,7 +1649,7 @@ $.extend(ChannelStackManager.prototype, {
 
 			this.timePoints = Object.keys(timePoints).map(function(timePoint) {
 				return parseInt(timePoint);
-			});
+			}).sort();
 		}
 		return this.timePoints;
 	},
@@ -1533,7 +1684,7 @@ $.extend(ChannelStackManager.prototype, {
 
 			this.depths = Object.keys(depths).map(function(depth) {
 				return parseInt(depth);
-			});
+			}).sort();
 		}
 		return this.depths;
 	},
@@ -1556,15 +1707,18 @@ $.extend(ChannelStackManager.prototype, {
 		return this.depthsMap[depth];
 	},
 
-	getChannelStackByTimePointAndDepth : function(timePoint, depth) {
-		var map = this.getChannelStackByTimePointAndDepthMap();
-		var entry = map[timePoint];
+	getChannelStackIndex : function(channelStackId) {
+		if (!this.channelStackMap) {
+			var map = {};
 
-		if (entry) {
-			return entry[depth];
-		} else {
-			return null;
+			this.getChannelStacks().forEach(function(channelStack, index) {
+				map[channelStack.id] = index;
+			});
+
+			this.channelStackMap = map;
 		}
+
+		return this.channelStackMap[channelStackId];
 	},
 
 	getChannelStackById : function(channelStackId) {
@@ -1578,12 +1732,19 @@ $.extend(ChannelStackManager.prototype, {
 		return this.channelStackByIdMap[channelStackId];
 	},
 
-	getChannelStacks : function() {
-		return this.channelStacks;
+	getChannelStackByTimePointAndDepth : function(timePoint, depth) {
+		var map = this.getChannelStackByTimePointAndDepthMap();
+		var entry = map[timePoint];
+
+		if (entry) {
+			return entry[depth];
+		} else {
+			return null;
+		}
 	},
 
 	getChannelStackByTimePointAndDepthMap : function() {
-		if (!this.channelStackMap) {
+		if (!this.channelStackByTimePointAndDepthMap) {
 			var map = {};
 			this.channelStacks.forEach(function(channelStack) {
 				if (channelStack.timePointOrNull != null && channelStack.depthOrNull != null) {
@@ -1595,10 +1756,15 @@ $.extend(ChannelStackManager.prototype, {
 					entry[channelStack.depthOrNull] = channelStack;
 				}
 			});
-			this.channelStackMap = map;
+			this.channelStackByTimePointAndDepthMap = map;
 		}
-		return this.channelStackMap;
+		return this.channelStackByTimePointAndDepthMap;
+	},
+
+	getChannelStacks : function() {
+		return this.channelStacks;
 	}
+
 });
 
 //
diff --git a/screening/source/core-plugins/microscopy/1/as/webapps/image-viewer/html/index.html b/screening/source/core-plugins/microscopy/1/as/webapps/image-viewer/html/index.html
index 66c1c265cfa45f7c59b790f2051b4ef48bcbf363..0778636fe34d039c996a65d8c09228ec20c35100 100644
--- a/screening/source/core-plugins/microscopy/1/as/webapps/image-viewer/html/index.html
+++ b/screening/source/core-plugins/microscopy/1/as/webapps/image-viewer/html/index.html
@@ -24,13 +24,13 @@
 			var facade = new openbis();
 
 			facade.login("admin", "password", function(response) {
-				var widget = new ImageViewerChooserWidget(facade, [ "20140415140347875-53", "20140429125231346-56", "20140429125614418-59" ]);
+				var widget = new ImageViewerChooserWidget(facade, [ "20140415140347875-53", "20140506132344798-146" ]);
 				$("#container").append(widget.render());
 			});
 		});
 	</script>
 
-	<div id="container" class="container" style="width: 800px"></div>
+	<div id="container" style="width: 600px; padding: 20px;"></div>
 
 </body>
 </html>