diff --git a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/FlowCytometryTechnology.js b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/FlowCytometryTechnology.js
index bd6a377e9d0a6ad004ad133e75c57b232bd3b8bd..8e3f6127ab873e2249b0ba9349bda6934f1ea1cc 100644
--- a/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/FlowCytometryTechnology.js
+++ b/openbis_standard_technologies/dist/core-plugins/eln-lims/1/as/webapps/eln-lims/html/js/plugins/FlowCytometryTechnology.js
@@ -1,744 +1,748 @@
 function FlowCytometryTechnology() {
-	this.init();
+    this.init();
 }
 
 $.extend(FlowCytometryTechnology.prototype, ELNLIMSPlugin.prototype, {
-	init: function () {
-
-		// Store a reference to the "retrieve FCS events" service
-		this.retrieveFCSEventsService = null;
-
-		// Data cache
-		this.dataCache = {};
-	},
-	forcedDisableRTF: [],
-	forceMonospaceFont: [],
-	sampleTypeDefinitionsExtension: {
-		"FACS_ARIA_EXPERIMENT": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SAMPLE_PARENTS_HINT": [{
-				"LABEL": "Organization Units",
-				"TYPE": "ORGANIZATION_UNIT",
-				"ANNOTATION_PROPERTIES": []
-			}]
-		},
-		"INFLUX_EXPERIMENT": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SAMPLE_PARENTS_HINT": [{
-				"LABEL": "Organization Units",
-				"TYPE": "ORGANIZATION_UNIT",
-				"ANNOTATION_PROPERTIES": []
-			}]
-		},
-		"LSR_FORTESSA_EXPERIMENT": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SAMPLE_PARENTS_HINT": [{
-				"LABEL": "Organization Units",
-				"TYPE": "ORGANIZATION_UNIT",
-				"ANNOTATION_PROPERTIES": []
-			}]
-		},
-		"MOFLO_XDP_EXPERIMENT": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SAMPLE_PARENTS_HINT": [{
-				"LABEL": "Organization Units",
-				"TYPE": "ORGANIZATION_UNIT",
-				"ANNOTATION_PROPERTIES": []
-			}]
-		},
-		"S3E_EXPERIMENT": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SAMPLE_PARENTS_HINT": [{
-				"LABEL": "Organization Units",
-				"TYPE": "ORGANIZATION_UNIT",
-				"ANNOTATION_PROPERTIES": []
-			}]
-		},
-		"FACS_ARIA_SPECIMEN": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"FACS_ARIA_TUBE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"FACS_ARIA_TUBESET": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"INFLUX_SPECIMEN": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"INFLUX_TUBE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"INFLUX_TUBESET": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"LSR_FORTESSA_PLATE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"LSR_FORTESSA_SPECIMEN": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"LSR_FORTESSA_TUBE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"LSR_FORTESSA_TUBESET": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"LSR_FORTESSA_WELL": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"MOFLO_XDP_SPECIMEN": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"MOFLO_XDP_TUBE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"MOFLO_XDP_TUBESET": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"S3E_TUBE": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"S3E_TUBESET": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		},
-		"S3E_SPECIMEN": {
-			"TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
-			"SHOW_ON_NAV": true
-		}
-	},
-	dataSetTypeDefinitionsExtension: {
-		"FACS_ARIA_FCSFILE": {
-			"DATASET_PARENTS_DISABLED": true,
-			"TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
-		},
-		"INFLUX_FCSFILE": {
-			"DATASET_PARENTS_DISABLED": true,
-			"TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
-		},
-		"LSR_FORTESSA_FCSFILE": {
-			"DATASET_PARENTS_DISABLED": true,
-			"TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
-		},
-		"MOFLO_XDP_FCSFILE": {
-			"DATASET_PARENTS_DISABLED": true,
-			"TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
-		},
-		"S3E_ARIA_FCSFILE": {
-			"DATASET_PARENTS_DISABLED": true,
-			"TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
-		}
-	},
-	sampleFormTop: function ($container, model) {
-
-	},
-	sampleFormBottom: function ($container, model) {
-
-	},
-	dataSetFormTop: function ($container, model) {
-
-		// Render the paremeter options
-		this.renderParameterSelectionWidget($container, model);
-
-		// Add a div for reporting status
-		$container.append($('<div>')
-			.css("margin-bottom", "5px")
-			.attr("id", "status_div"));
-
-		// Append the div where the data will be plotted
-		$container.append($('<div>')
-			.css("width", "580px")
-			.attr("id", "plot_canvas_div"));
-
-	},
-	dataSetFormBottom: function ($container, model) {
-
-	},
-
-	// Additional functionality
-	renderParameterSelectionWidget: function ($container, model) {
-
-		// Check that we ave the correct dataset type
-		if (!model.dataSetV3.type.code.endsWith("_FCSFILE")) {
-			return;
-		}
-
-		// Clear the container
-		$container.empty();
-
-		//
-		// Retrieve the parameter info
-		//
-		var parameterInfo = this.retrieveParameterInfo(model);
-
-		// Add legend
-		var legend = $("<legend>")
-			.text("Data viewer")
-		$container.append(legend);
-
-		// Create a div for all plotting options
-		var plot_params_div = $('<div>')
-			.css("text-align", "left")
-			.css("margin", "5px 0 15px 0")
-			.attr("id", "plot_params_div");
-
-		//
-		// Lay out the widget
-		//
-
-		// Create a form for the plot parameters
-		var form = $("<form>")
-			.attr("id", "parameter_form");
-		plot_params_div.append(form);
-
-		// Create divs to spatially organize the groups of parameters
-		var xAxisDiv = $("<div>")
-			.css("display", "inline-block")
-			.css("text-align", "right")
-			.attr("id", "xAxisDiv")
-		var yAxisDiv = $("<div>")
-			.css("display", "inline-block")
-			.css("text-align", "right")
-			.attr("id", "yAxisDiv")
-		var eventsDiv = $("<div>")
-			.css("display", "inline-block")
-			.css("text-align", "right")
-			.attr("id", "eventsDiv")
-		var plotDiv = $("<div>")
-			.css("display", "inline-block")
-			.css("vertical-align", "top")
-			.css("padding-left", "10px")
-			.attr("id", "plotDiv")
-
-		// Add them to the form
-		form.append(xAxisDiv);
-		form.append(yAxisDiv);
-		form.append(eventsDiv);
-		form.append(plotDiv);
-
-		// X axis parameters
-		xAxisDiv.append($("<label>")
-			.attr("for", "parameter_form_select_X_axis")
-			.html("X axis"));
-		var selectXAxis = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_X_axis");
-		xAxisDiv.append(selectXAxis);
-
-		// Y axis parameters
-		yAxisDiv.append($("<label>")
-			.attr("for", "parameter_form_select_Y_axis")
-			.html("Y axis"));
-		var selectYAxis = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_Y_axis");
-		yAxisDiv.append(selectYAxis);
-
-		// Add all options
-		for (var i = 0; i < parameterInfo.numParameters; i++) {
-			var name = parameterInfo["names"][i];
-			var compositeName = parameterInfo["compositeNames"][i];
-			selectXAxis.append($("<option>")
-				.attr("value", name)
-				.text(compositeName));
-			selectYAxis.append($("<option>")
-				.attr("value", name)
-				.text(compositeName));
-		}
-
-		// // Pre-select some parameters
-		selectXAxis.val(parameterInfo["names"][0]);
-		selectYAxis.val(parameterInfo["names"][1]);
-
-		// Add a selector with the number of events to plot
-		eventsDiv.append($("<label>")
-			.attr("for", "parameter_form_select_num_events")
-			.html("Events to plot"));
-		var selectNumEvents = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_num_events");
-		eventsDiv.append(selectNumEvents);
-
-		// Add the options
-		var possibleOptions = [500, 1000, 2500, 5000, 10000, 20000, 50000, 100000];
-		var numEventsInFile = parseInt(parameterInfo.numEvents);
-		for (var i = 0; i < possibleOptions.length; i++) {
-			if (possibleOptions[i] < numEventsInFile) {
-				selectNumEvents.append($("<option>")
-					.attr("value", possibleOptions[i])
-					.text(possibleOptions[i].toString()));
-			}
-		}
-		selectNumEvents.append($("<option>")
-			.attr("value", parameterInfo.numEvents)
-			.text(parseInt(parameterInfo.numEvents)));
-
-		// Pre-select something reasonable
-		if (parameterInfo.numEvents > possibleOptions[4]) {
-			selectNumEvents.val(parseInt(possibleOptions[4]));
-		} else {
-			selectNumEvents.val(parseInt(parameterInfo.numEvents));
-		}
-
-		// Add "Plot" button
-		var thisObj = this;
-		var plotButton = $("<input>")
-			.attr("type", "button")
-			.attr("value", "Plot")
-			.click(function () {
-
-				// Get the selected parameters and their display scaling
-				var paramX = selectXAxis.find(":selected").val();
-				var paramY = selectYAxis.find(":selected").val();
-				var displayX = selectScaleX.find(":selected").val();
-				var displayY = selectScaleY.find(":selected").val();
-
-				// How many events to plot?
-				var numEventsToPlot = selectNumEvents.val();
-
-				// Sampling method
-				var samplingMethod = selectSamplingMethod.find(":selected").val();
-
-				// Call the retrieving and plotting method
-				thisObj.callServerSidePluginGenerateFCSPlot(
-					model,
-					paramX,
-					paramY,
-					displayX,
-					displayY,
-					numEventsToPlot,
-					parameterInfo.numEvents,
-					samplingMethod);
-			});
-		plotDiv.append(plotButton);
-
-		// Add a selector with the scaling for axis X
-		var xAxisScalingDiv = xAxisDiv.append($("<div>")
-			.css("display", "block")
-			.attr("id", "xAxisScalingDiv"));
-		xAxisScalingDiv.append($("<label>")
-			.attr("for", "parameter_form_select_scaleX")
-			.html("Scale for X axis"));
-		var selectScaleX = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_scaleX");
-		xAxisScalingDiv.append(selectScaleX);
-
-		// Add the options
-		possibleOptions = ["Linear", "Hyperlog"];
-		for (var i = 0; i < possibleOptions.length; i++) {
-			selectScaleX.append($("<option>")
-				.attr("name", possibleOptions[i])
-				.attr("value", possibleOptions[i])
-				.text(possibleOptions[i]));
-		}
-
-		// Pre-select "Linear"
-		$("parameter_form_select_scaleX").val(0);
-
-		// Add a selector with the scaling for axis Y
-		var yAxisScalingDiv = yAxisDiv.append($("<div>")
-			.css("display", "block")
-			.attr("id", "yAxisScalingDiv"));
-		yAxisScalingDiv.append($("<label>")
-			.attr("for", "parameter_form_select_scaleY")
-			.html("Scale for Y axis"));
-		var selectScaleY = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_scaleY");
-		yAxisScalingDiv.append(selectScaleY);
-
-		// Add the options
-		possibleOptions = ["Linear", "Hyperlog"];
-		for (var i = 0; i < possibleOptions.length; i++) {
-			selectScaleY.append($("<option>")
-				.attr("name", possibleOptions[i])
-				.attr("value", possibleOptions[i])
-				.text(possibleOptions[i]));
-		}
-
-		// Pre-select "Linear"
-		$("parameter_form_select_scaleY").val(0);
-
-		// Add a selector with the sampling method
-		var eventSamplingDiv = eventsDiv.append($("<div>")
-			.css("display", "block")
-			.attr("id", "eventSamplingDiv"));
-		eventSamplingDiv.append($("<label>")
-			.attr("for", "parameter_form_select_sampling_method")
-			.html("Sampling"));
-		var selectSamplingMethod = $("<select>")
-			.css("margin", "0 3px 0 3px")
-			.attr("id", "parameter_form_select_sampling_method");
-		eventSamplingDiv.append(selectSamplingMethod);
-
-		// Add the options
-		possibleOptions = ["Regular", "First rows"];
-		for (var i = 0; i < possibleOptions.length; i++) {
-			selectSamplingMethod.append($("<option>")
-				.attr("name", "" + (i + 1))
-				.attr("value", (i + 1))
-				.text(possibleOptions[i]));
-		}
-
-		// Pre-select "Linear"
-		$("parameter_form_select_sampling_method").val(0);
-
-		//
-		// End of widget
-		//
-
-		// Append the created div to the container
-		$container.append(plot_params_div);
-
-	},
-
-	retrieveParameterInfo: function (model) {
-
-		// Retrieve parameter information
-		var key = model.dataSetV3.type.code.substring(
-			0, model.dataSetV3.type.code.indexOf("_FCSFILE")) +
-			"_FCSFILE_PARAMETERS";
-
-		var parametersXML = $.parseXML(model.dataSetV3.properties[key]);
-		var parameters = parametersXML.childNodes[0];
-
-		var numParameters = parameters.getAttribute("numParameters");
-		var numEvents = parameters.getAttribute("numEvents");
-
-		var names = [];
-		var compositeNames = [];
-		var display = [];
-
-		// Parameter numbering starts at 1
-		var parametersToDisplay = 0;
-		for (var i = 1; i <= numParameters; i++) {
-
-			// If the parameter contains the PnCHANNELTYPE attribute (BD Influx Cell Sorter),
-			// we only add it if the channel type is 6.
-			var channelType = parameters.getAttribute("P" + i + "CHANNELTYPE");
-			if (channelType != null && channelType !== 6) {
-				continue;
-			}
-
-			// Store the parameter name
-			var name = parameters.getAttribute("P" + i + "N");
-			names.push(name);
-
-			// Store the composite name
-			var pStr = parameters.getAttribute("P" + i + "S");
-			var composite = name;
-			if (pStr !== "") {
-				composite = name + " (" + pStr + ")";
-			}
-			compositeNames.push(composite);
-
-			// Store the display scale
-			var displ = parameters.getAttribute("P" + i + "DISPLAY");
-			display.push(displ);
-
-			// Update the count of parameters to display
-			parametersToDisplay++;
-		}
-
-		// Store the parameter info
-		parameterInfo = {
-			"numParameters": parametersToDisplay,
-			"numEvents": numEvents,
-			"names": names,
-			"compositeNames": compositeNames,
-			"display": display
-		}
-
-		// Return it
-		return parameterInfo;
-	},
-
-	callServerSidePluginGenerateFCSPlot: function (model, paramX, paramY, displayX, displayY, numEventsToPlot, totalNumEvents, samplingMethod) {
-
-		// Check whether the data for the plot is already cached
-		var key = model.dataSetV3.code + "_" + paramX + "_" + paramY + "_" + numEventsToPlot.toString() +
-			"_" + displayX + "_" + displayY + "_" + samplingMethod.toString();
-
-		if (model.dataSetV3.code in this.dataCache &&
-			key in this.dataCache[model.dataSetV3.code]) {
-
-			// Plot the cached data
-			this.plotFCSData(
-				this.dataCache[model.dataSetV3.code][key],
-				paramX,
-				paramY,
-				displayX,
-				displayY);
-
-			// Return immediately
-			return;
-		}
-
-		// Inform the user that we are about to process the request
-		this.displayStatus("Please wait while processing your request. This might take a while...",
-			"info");
-	
-		var thisObj = this;
-		require(["openbis",
-			"as/dto/service/search/AggregationServiceSearchCriteria",
-			"as/dto/service/fetchoptions/AggregationServiceFetchOptions",
-			"as/dto/service/execute/AggregationServiceExecutionOptions"],
-			function (openbis,
-				AggregationServiceSearchCriteria,
-				AggregationServiceFetchOptions,
-				AggregationServiceExecutionOptions) {
-
-				// Parameters for the aggregation service
-				var options = new AggregationServiceExecutionOptions();
-				options.withParameter("code", model.dataSetV3.code);
-				options.withParameter("paramX", paramX);
-				options.withParameter("paramY", paramY);
-				options.withParameter("displayX", displayX);
-				options.withParameter("displayY", displayY);
-				options.withParameter("numEvents", totalNumEvents);
-				options.withParameter("maxNumEvents", numEventsToPlot);
-				options.withParameter("samplingMethod", samplingMethod);
-				options.withParameter("nodeKey", model.dataSetV3.code);
-
-				// Call service
-				if (null === thisObj.retrieveFCSEventsService) {
-					var criteria = new AggregationServiceSearchCriteria();
-					criteria.withName().thatEquals("retrieve_fcs_events");
-					var fetchOptions = new AggregationServiceFetchOptions();
-					mainController.openbisV3.searchAggregationServices(criteria, fetchOptions).then(function (result) {
-
-						// Check that we got our service
-						if (undefined === result.objects) {
-							console.log("Could not retrieve the server-side aggregation service!");
-							return;
-						}
-						thisObj.retrieveFCSEventsService = result.getObjects()[0];
-
-						// Now call the service
-						mainController.openbisV3.executeAggregationService(
-							thisObj.retrieveFCSEventsService.getPermId(),
-							options).then(function (result) {
-								thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
-							});
-					});
-				} else {
-					// Call the service
-					mainController.openbisV3.executeAggregationService(
-						thisObj.retrieveFCSEventsService.getPermId(),
-						options).then(function (result) {
-							thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
-						});
-				}
-			});
-	},
-
-	plotFCSData: function (data, xLabel, yLabel, xDisplay, yDisplay) {
-
-		// Make sure to have a proper array
-		var parsed_data = JSON.parse(data);
-
-		// Prepend data names to be compatible with C3.js
-		parsed_data[0].unshift("x_values");
-		parsed_data[1].unshift("y_values");
-
-		// Plot the data
-		c3.generate({
-			bindto: '#plot_canvas_div',
-			title: {
-				text: yLabel + " vs. " + xLabel
-			},
-			data: {
-				xs: {
-					y_values: "x_values"
-				},
-				columns: [
-					parsed_data[0],
-					parsed_data[1],
-				],
-				names: {
-					y_values: yLabel
-				},
-				type: 'scatter'
-			},
-			axis: {
-				x: {
-					label: xLabel,
-					tick: {
-						fit: false
-					}
-				},
-				y: {
-					label: yLabel,
-					tick: {
-						fit: false
-					}
-				}
-			},
-			legend: {
-				show: false
-			},
-			tooltip: {
-				format: {
-					title: function (d) {
-						const format = d3.format(',');
-						return xLabel + " | " + format(d);
-					},
-					value: function (value, ratio, id) {
-						const format = d3.format(',');
-						return format(value);
-					}
-				}
-			},
-			zoom: {
-				enabled: true,
-				rescale: true
-			},
-		});
-	},
-
-	processResultsFromRetrieveFCSEventsServerSidePlugin: function (table) {
-
-		// Did we get the expected result?
-		if (!table.rows || table.rows.length !== 1) {
-			DATAVIEWER.displayStatus(
-				"There was an error retrieving the data to plot!",
-				"danger");
-			return;
-		}
-
-		// Get the row of results
-		var row = table.rows[0];
-
-		// Retrieve the uid
-		var r_UID = row[0].value;
-
-		// Is the process completed?
-		var r_Completed = row[1].value;
-
-		var thisObj = this;
-		if (r_Completed === 0) {
-
-			require(["as/dto/service/execute/AggregationServiceExecutionOptions"],
-				function (AggregationServiceExecutionOptions) {
-
-					// Call the plug-in
-					setTimeout(function () {
-
-						// Now call the service again:
-						// we only need the UID of the job
-						var options = new AggregationServiceExecutionOptions();
-						options.withParameter("uid", r_UID);
-
-						mainController.openbisV3.executeAggregationService(
-							thisObj.retrieveFCSEventsService.getPermId(),
-							options).then(function (result) {
-								thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
-							})
-					}, 2000);
-				});
-
-			// Return here
-			return;
-
-		}
-
-		// We completed the call and we can process the result
-
-		// Returned parameters
-		var r_Success = row[2].value;
-		var r_ErrorMessage = row[3].value;
-		var r_Data = row[4].value;
-		var r_Code = row[5].value;
-		var r_ParamX = row[6].value;
-		var r_ParamY = row[7].value;
-		var r_DisplayX = row[8].value;
-		var r_DisplayY = row[9].value;
-		var r_NumEvents = row[10].value;   // Currently not used
-		var r_MaxNumEvents = row[11].value;
-		var r_SamplingMethod = row[12].value;
-		var r_NodeKey = row[13].value;
-
-		var level;
-		if (r_Success === 1) {
-
-			// Error message and level
-			status = r_ErrorMessage;
-			level = "success";
-
-			// Plot the data
-			thisObj.plotFCSData(r_Data, r_ParamX, r_ParamY, r_DisplayX, r_DisplayY);
-
-			// Cache the plotted data
-			var dataKey = r_Code + "_" + r_ParamX + "_" + r_ParamY + "_" + r_MaxNumEvents.toString() +
-				"_" + r_DisplayX + "_" + r_DisplayY + "_" + r_SamplingMethod.toString();
-			thisObj.cacheFCSData(r_NodeKey, dataKey, r_Data);
-
-		} else {
-			status = "Sorry, there was an error: \"" + r_ErrorMessage + "\".";
-			level = "danger";
-		}
-
-		// We only display errors
-		if (r_Success === 0) {
-			thisObj.displayStatus(status, level);
-		} else {
-			thisObj.hideStatus();
-		}
-
-		return table;
-
-	},
-
-	cacheFCSData: function (nodeKey, dataKey, fcsData) {
-
-		// Cache the data
-		if (! (nodeKey in this.dataCache)) {
-			this.dataCache[nodeKey] = {};
-		}
-		this.dataCache[nodeKey][dataKey] = fcsData;
-	},
-
-	displayStatus: function(status, level) {
-		switch (level) {
-			case "info":
-				color = "black";
-				break;
-			case "success":
-				color = "cyan";
-				break;
-			case "danger":
-				color = "red";
-				break;
-			default:
-				color = "black";
-				break;
-		}
-		var status_div = $("#status_div");
-		status_div
-			.css("color", color)
-			.text(status);
-		status_div.show();
-	},
-
-	hideStatus: function() {
-		$("#status_div").hide();
-	}
+    init: function () {
+
+        // Store a reference to the "retrieve FCS events" service
+        this.retrieveFCSEventsService = null;
+
+        // Data cache
+        this.dataCache = {};
+    },
+    forcedDisableRTF: [],
+    forceMonospaceFont: [],
+    sampleTypeDefinitionsExtension: {
+        "FACS_ARIA_EXPERIMENT": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SAMPLE_PARENTS_HINT": [{
+                "LABEL": "Organization Units",
+                "TYPE": "ORGANIZATION_UNIT",
+                "ANNOTATION_PROPERTIES": []
+            }]
+        },
+        "INFLUX_EXPERIMENT": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SAMPLE_PARENTS_HINT": [{
+                "LABEL": "Organization Units",
+                "TYPE": "ORGANIZATION_UNIT",
+                "ANNOTATION_PROPERTIES": []
+            }]
+        },
+        "LSR_FORTESSA_EXPERIMENT": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SAMPLE_PARENTS_HINT": [{
+                "LABEL": "Organization Units",
+                "TYPE": "ORGANIZATION_UNIT",
+                "ANNOTATION_PROPERTIES": []
+            }]
+        },
+        "MOFLO_XDP_EXPERIMENT": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SAMPLE_PARENTS_HINT": [{
+                "LABEL": "Organization Units",
+                "TYPE": "ORGANIZATION_UNIT",
+                "ANNOTATION_PROPERTIES": []
+            }]
+        },
+        "S3E_EXPERIMENT": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SAMPLE_PARENTS_HINT": [{
+                "LABEL": "Organization Units",
+                "TYPE": "ORGANIZATION_UNIT",
+                "ANNOTATION_PROPERTIES": []
+            }]
+        },
+        "FACS_ARIA_SPECIMEN": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "FACS_ARIA_TUBE": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "FACS_ARIA_TUBESET": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "INFLUX_SPECIMEN": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "INFLUX_TUBE": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "INFLUX_TUBESET": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "LSR_FORTESSA_PLATE": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "LSR_FORTESSA_SPECIMEN": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "LSR_FORTESSA_TUBE": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "LSR_FORTESSA_TUBESET": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "LSR_FORTESSA_WELL": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "MOFLO_XDP_SPECIMEN": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "MOFLO_XDP_TUBE": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "MOFLO_XDP_TUBESET": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "S3E_TUBE": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "S3E_TUBESET": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        },
+        "S3E_SPECIMEN": {
+            "TOOLBAR": { CREATE: false, EDIT: false, MOVE: false, COPY: false, DELETE: false, PRINT: true, HIERARCHY_GRAPH: true, HIERARCHY_TABLE: true, UPLOAD_DATASET: false, UPLOAD_DATASET_HELPER: false, EXPORT_ALL: true, EXPORT_METADATA: true },
+            "SHOW_ON_NAV": true
+        }
+    },
+    dataSetTypeDefinitionsExtension: {
+        "FACS_ARIA_FCSFILE": {
+            "DATASET_PARENTS_DISABLED": true,
+            "TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+        },
+        "INFLUX_FCSFILE": {
+            "DATASET_PARENTS_DISABLED": true,
+            "TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+        },
+        "LSR_FORTESSA_FCSFILE": {
+            "DATASET_PARENTS_DISABLED": true,
+            "TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+        },
+        "MOFLO_XDP_FCSFILE": {
+            "DATASET_PARENTS_DISABLED": true,
+            "TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+        },
+        "S3E_ARIA_FCSFILE": {
+            "DATASET_PARENTS_DISABLED": true,
+            "TOOLBAR": { EDIT: false, MOVE: false, ARCHIVE: true, DELETE: false, HIERARCHY_TABLE: true, EXPORT_ALL: true, EXPORT_METADATA: true }
+        }
+    },
+    sampleFormTop: function ($container, model) {
+
+    },
+    sampleFormBottom: function ($container, model) {
+
+    },
+    dataSetFormTop: function ($container, model) {
+
+        // Render the paremeter options
+        this.renderParameterSelectionWidget($container, model);
+
+        // Add a div for reporting status
+        $container.append($('<div>')
+            .css("margin-bottom", "5px")
+            .attr("id", "status_div"));
+
+        // Append the div where the data will be plotted
+        $container.append($('<div>')
+            .css("width", "580px")
+            .attr("id", "plot_canvas_div"));
+
+    },
+    dataSetFormBottom: function ($container, model) {
+
+    },
+
+    // Additional functionality
+    renderParameterSelectionWidget: function ($container, model) {
+
+        // Check that we ave the correct dataset type
+        if (!model.dataSetV3) {
+            return;
+        }
+
+        if (!model.dataSetV3.type.code.endsWith("_FCSFILE")) {
+            return;
+        }
+
+        // Clear the container
+        $container.empty();
+
+        //
+        // Retrieve the parameter info
+        //
+        var parameterInfo = this.retrieveParameterInfo(model);
+
+        // Add legend
+        var legend = $("<legend>")
+            .text("Data viewer");
+        $container.append(legend);
+
+        // Create a div for all plotting options
+        var plot_params_div = $('<div>')
+            .css("text-align", "left")
+            .css("margin", "5px 0 15px 0")
+            .attr("id", "plot_params_div");
+
+        //
+        // Lay out the widget
+        //
+
+        // Create a form for the plot parameters
+        var form = $("<form>")
+            .attr("id", "parameter_form");
+        plot_params_div.append(form);
+
+        // Create divs to spatially organize the groups of parameters
+        var xAxisDiv = $("<div>")
+            .css("display", "inline-block")
+            .css("text-align", "right")
+            .attr("id", "xAxisDiv");
+        var yAxisDiv = $("<div>")
+            .css("display", "inline-block")
+            .css("text-align", "right")
+            .attr("id", "yAxisDiv");
+        var eventsDiv = $("<div>")
+            .css("display", "inline-block")
+            .css("text-align", "right")
+            .attr("id", "eventsDiv");
+        var plotDiv = $("<div>")
+            .css("display", "inline-block")
+            .css("vertical-align", "top")
+            .css("padding-left", "10px")
+            .attr("id", "plotDiv");
+
+        // Add them to the form
+        form.append(xAxisDiv);
+        form.append(yAxisDiv);
+        form.append(eventsDiv);
+        form.append(plotDiv);
+
+        // X axis parameters
+        xAxisDiv.append($("<label>")
+            .attr("for", "parameter_form_select_X_axis")
+            .html("X axis"));
+        var selectXAxis = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_X_axis");
+        xAxisDiv.append(selectXAxis);
+
+        // Y axis parameters
+        yAxisDiv.append($("<label>")
+            .attr("for", "parameter_form_select_Y_axis")
+            .html("Y axis"));
+        var selectYAxis = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_Y_axis");
+        yAxisDiv.append(selectYAxis);
+
+        // Add all options
+        for (var i = 0; i < parameterInfo.numParameters; i++) {
+            var name = parameterInfo["names"][i];
+            var compositeName = parameterInfo["compositeNames"][i];
+            selectXAxis.append($("<option>")
+                .attr("value", name)
+                .text(compositeName));
+            selectYAxis.append($("<option>")
+                .attr("value", name)
+                .text(compositeName));
+        }
+
+        // // Pre-select some parameters
+        selectXAxis.val(parameterInfo["names"][0]);
+        selectYAxis.val(parameterInfo["names"][1]);
+
+        // Add a selector with the number of events to plot
+        eventsDiv.append($("<label>")
+            .attr("for", "parameter_form_select_num_events")
+            .html("Events to plot"));
+        var selectNumEvents = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_num_events");
+        eventsDiv.append(selectNumEvents);
+
+        // Add the options
+        var possibleOptions = [500, 1000, 2500, 5000, 10000, 20000, 50000, 100000];
+        var numEventsInFile = parseInt(parameterInfo.numEvents);
+        for (i = 0; i < possibleOptions.length; i++) {
+            if (possibleOptions[i] < numEventsInFile) {
+                selectNumEvents.append($("<option>")
+                    .attr("value", possibleOptions[i])
+                    .text(possibleOptions[i].toString()));
+            }
+        }
+        selectNumEvents.append($("<option>")
+            .attr("value", parameterInfo.numEvents)
+            .text(parseInt(parameterInfo.numEvents)));
+
+        // Pre-select something reasonable
+        if (parameterInfo.numEvents > possibleOptions[4]) {
+            selectNumEvents.val(possibleOptions[4]);
+        } else {
+            selectNumEvents.val(parameterInfo.numEvents);
+        }
+
+        // Add "Plot" button
+        var thisObj = this;
+        var plotButton = $("<input>")
+            .attr("type", "button")
+            .attr("value", "Plot")
+            .click(function () {
+
+                // Get the selected parameters and their display scaling
+                var paramX = selectXAxis.find(":selected").val();
+                var paramY = selectYAxis.find(":selected").val();
+                var displayX = selectScaleX.find(":selected").val();
+                var displayY = selectScaleY.find(":selected").val();
+
+                // How many events to plot?
+                var numEventsToPlot = selectNumEvents.val();
+
+                // Sampling method
+                var samplingMethod = selectSamplingMethod.find(":selected").val();
+
+                // Call the retrieving and plotting method
+                thisObj.callServerSidePluginGenerateFCSPlot(
+                    model,
+                    paramX,
+                    paramY,
+                    displayX,
+                    displayY,
+                    numEventsToPlot,
+                    parameterInfo.numEvents,
+                    samplingMethod);
+            });
+        plotDiv.append(plotButton);
+
+        // Add a selector with the scaling for axis X
+        var xAxisScalingDiv = xAxisDiv.append($("<div>")
+            .css("display", "block")
+            .attr("id", "xAxisScalingDiv"));
+        xAxisScalingDiv.append($("<label>")
+            .attr("for", "parameter_form_select_scaleX")
+            .html("Scale for X axis"));
+        var selectScaleX = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_scaleX");
+        xAxisScalingDiv.append(selectScaleX);
+
+        // Add the options
+        possibleOptions = ["Linear", "Hyperlog"];
+        for (i = 0; i < possibleOptions.length; i++) {
+            selectScaleX.append($("<option>")
+                .attr("name", possibleOptions[i])
+                .attr("value", possibleOptions[i])
+                .text(possibleOptions[i]));
+        }
+
+        // Pre-select "Linear"
+        $("parameter_form_select_scaleX").val(0);
+
+        // Add a selector with the scaling for axis Y
+        var yAxisScalingDiv = yAxisDiv.append($("<div>")
+            .css("display", "block")
+            .attr("id", "yAxisScalingDiv"));
+        yAxisScalingDiv.append($("<label>")
+            .attr("for", "parameter_form_select_scaleY")
+            .html("Scale for Y axis"));
+        var selectScaleY = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_scaleY");
+        yAxisScalingDiv.append(selectScaleY);
+
+        // Add the options
+        possibleOptions = ["Linear", "Hyperlog"];
+        for (i = 0; i < possibleOptions.length; i++) {
+            selectScaleY.append($("<option>")
+                .attr("name", possibleOptions[i])
+                .attr("value", possibleOptions[i])
+                .text(possibleOptions[i]));
+        }
+
+        // Pre-select "Linear"
+        $("parameter_form_select_scaleY").val(0);
+
+        // Add a selector with the sampling method
+        var eventSamplingDiv = eventsDiv.append($("<div>")
+            .css("display", "block")
+            .attr("id", "eventSamplingDiv"));
+        eventSamplingDiv.append($("<label>")
+            .attr("for", "parameter_form_select_sampling_method")
+            .html("Sampling"));
+        var selectSamplingMethod = $("<select>")
+            .css("margin", "0 3px 0 3px")
+            .attr("id", "parameter_form_select_sampling_method");
+        eventSamplingDiv.append(selectSamplingMethod);
+
+        // Add the options
+        possibleOptions = ["Regular", "First rows"];
+        for (i = 0; i < possibleOptions.length; i++) {
+            selectSamplingMethod.append($("<option>")
+                .attr("name", "" + (i + 1))
+                .attr("value", (i + 1))
+                .text(possibleOptions[i]));
+        }
+
+        // Pre-select "Linear"
+        $("parameter_form_select_sampling_method").val(0);
+
+        //
+        // End of widget
+        //
+
+        // Append the created div to the container
+        $container.append(plot_params_div);
+
+    },
+
+    retrieveParameterInfo: function (model) {
+
+        // Retrieve parameter information
+        var key = model.dataSetV3.type.code.substring(
+            0, model.dataSetV3.type.code.indexOf("_FCSFILE")) +
+            "_FCSFILE_PARAMETERS";
+
+        var parametersXML = $.parseXML(model.dataSetV3.properties[key]);
+        var parameters = parametersXML.childNodes[0];
+
+        var numParameters = parameters.getAttribute("numParameters");
+        var numEvents = parameters.getAttribute("numEvents");
+
+        var names = [];
+        var compositeNames = [];
+        var display = [];
+
+        // Parameter numbering starts at 1
+        var parametersToDisplay = 0;
+        for (var i = 1; i <= numParameters; i++) {
+
+            // If the parameter contains the PnCHANNELTYPE attribute (BD Influx Cell Sorter),
+            // we only add it if the channel type is 6.
+            var channelType = parameters.getAttribute("P" + i + "CHANNELTYPE");
+            if (channelType != null && channelType !== 6) {
+                continue;
+            }
+
+            // Store the parameter name
+            var name = parameters.getAttribute("P" + i + "N");
+            names.push(name);
+
+            // Store the composite name
+            var pStr = parameters.getAttribute("P" + i + "S");
+            var composite = name;
+            if (pStr !== "") {
+                composite = name + " (" + pStr + ")";
+            }
+            compositeNames.push(composite);
+
+            // Store the display scale
+            var displ = parameters.getAttribute("P" + i + "DISPLAY");
+            display.push(displ);
+
+            // Update the count of parameters to display
+            parametersToDisplay++;
+        }
+
+        // Store the parameter info
+        parameterInfo = {
+            "numParameters": parametersToDisplay,
+            "numEvents": numEvents,
+            "names": names,
+            "compositeNames": compositeNames,
+            "display": display
+        };
+
+        // Return it
+        return parameterInfo;
+    },
+
+    callServerSidePluginGenerateFCSPlot: function (model, paramX, paramY, displayX, displayY, numEventsToPlot, totalNumEvents, samplingMethod) {
+
+        // Check whether the data for the plot is already cached
+        var key = model.dataSetV3.code + "_" + paramX + "_" + paramY + "_" + numEventsToPlot.toString() +
+            "_" + displayX + "_" + displayY + "_" + samplingMethod.toString();
+
+        if (model.dataSetV3.code in this.dataCache &&
+            key in this.dataCache[model.dataSetV3.code]) {
+
+            // Plot the cached data
+            this.plotFCSData(
+                this.dataCache[model.dataSetV3.code][key],
+                paramX,
+                paramY,
+                displayX,
+                displayY);
+
+            // Return immediately
+            return;
+        }
+
+        // Inform the user that we are about to process the request
+        this.displayStatus("Please wait while processing your request. This might take a while...",
+            "info");
+
+        var thisObj = this;
+        require(["openbis",
+                "as/dto/service/search/AggregationServiceSearchCriteria",
+                "as/dto/service/fetchoptions/AggregationServiceFetchOptions",
+                "as/dto/service/execute/AggregationServiceExecutionOptions"],
+            function (openbis,
+                      AggregationServiceSearchCriteria,
+                      AggregationServiceFetchOptions,
+                      AggregationServiceExecutionOptions) {
+
+                // Parameters for the aggregation service
+                var options = new AggregationServiceExecutionOptions();
+                options.withParameter("code", model.dataSetV3.code);
+                options.withParameter("paramX", paramX);
+                options.withParameter("paramY", paramY);
+                options.withParameter("displayX", displayX);
+                options.withParameter("displayY", displayY);
+                options.withParameter("numEvents", totalNumEvents);
+                options.withParameter("maxNumEvents", numEventsToPlot);
+                options.withParameter("samplingMethod", samplingMethod);
+                options.withParameter("nodeKey", model.dataSetV3.code);
+
+                // Call service
+                if (null === thisObj.retrieveFCSEventsService) {
+                    var criteria = new AggregationServiceSearchCriteria();
+                    criteria.withName().thatEquals("retrieve_fcs_events");
+                    var fetchOptions = new AggregationServiceFetchOptions();
+                    mainController.openbisV3.searchAggregationServices(criteria, fetchOptions).then(function (result) {
+
+                        // Check that we got our service
+                        if (undefined === result.objects) {
+                            console.log("Could not retrieve the server-side aggregation service!");
+                            return;
+                        }
+                        thisObj.retrieveFCSEventsService = result.getObjects()[0];
+
+                        // Now call the service
+                        mainController.openbisV3.executeAggregationService(
+                            thisObj.retrieveFCSEventsService.getPermId(),
+                            options).then(function (result) {
+                            thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
+                        });
+                    });
+                } else {
+                    // Call the service
+                    mainController.openbisV3.executeAggregationService(
+                        thisObj.retrieveFCSEventsService.getPermId(),
+                        options).then(function (result) {
+                        thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
+                    });
+                }
+            });
+    },
+
+    plotFCSData: function (data, xLabel, yLabel, xDisplay, yDisplay) {
+
+        // Make sure to have a proper array
+        var parsed_data = JSON.parse(data);
+
+        // Prepend data names to be compatible with C3.js
+        parsed_data[0].unshift("x_values");
+        parsed_data[1].unshift("y_values");
+
+        // Plot the data
+        c3.generate({
+            bindto: '#plot_canvas_div',
+            title: {
+                text: yLabel + " vs. " + xLabel
+            },
+            data: {
+                xs: {
+                    y_values: "x_values"
+                },
+                columns: [
+                    parsed_data[0],
+                    parsed_data[1],
+                ],
+                names: {
+                    y_values: yLabel
+                },
+                type: 'scatter'
+            },
+            axis: {
+                x: {
+                    label: xLabel,
+                    tick: {
+                        fit: false
+                    }
+                },
+                y: {
+                    label: yLabel,
+                    tick: {
+                        fit: false
+                    }
+                }
+            },
+            legend: {
+                show: false
+            },
+            tooltip: {
+                format: {
+                    title: function (d) {
+                        const format = d3.format(',');
+                        return xLabel + " | " + format(d);
+                    },
+                    value: function (value, ratio, id) {
+                        const format = d3.format(',');
+                        return format(value);
+                    }
+                }
+            },
+            zoom: {
+                enabled: true,
+                rescale: true
+            },
+        });
+    },
+
+    processResultsFromRetrieveFCSEventsServerSidePlugin: function (table) {
+
+        // Did we get the expected result?
+        if (!table.rows || table.rows.length !== 1) {
+            DATAVIEWER.displayStatus(
+                "There was an error retrieving the data to plot!",
+                "danger");
+            return;
+        }
+
+        // Get the row of results
+        var row = table.rows[0];
+
+        // Retrieve the uid
+        var r_UID = row[0].value;
+
+        // Is the process completed?
+        var r_Completed = row[1].value;
+
+        var thisObj = this;
+        if (r_Completed === 0) {
+
+            require(["as/dto/service/execute/AggregationServiceExecutionOptions"],
+                function (AggregationServiceExecutionOptions) {
+
+                    // Call the plug-in
+                    setTimeout(function () {
+
+                        // Now call the service again:
+                        // we only need the UID of the job
+                        var options = new AggregationServiceExecutionOptions();
+                        options.withParameter("uid", r_UID);
+
+                        mainController.openbisV3.executeAggregationService(
+                            thisObj.retrieveFCSEventsService.getPermId(),
+                            options).then(function (result) {
+                            thisObj.processResultsFromRetrieveFCSEventsServerSidePlugin(result);
+                        })
+                    }, 2000);
+                });
+
+            // Return here
+            return;
+
+        }
+
+        // We completed the call and we can process the result
+
+        // Returned parameters
+        var r_Success = row[2].value;
+        var r_ErrorMessage = row[3].value;
+        var r_Data = row[4].value;
+        var r_Code = row[5].value;
+        var r_ParamX = row[6].value;
+        var r_ParamY = row[7].value;
+        var r_DisplayX = row[8].value;
+        var r_DisplayY = row[9].value;
+        var r_NumEvents = row[10].value;   // Currently not used
+        var r_MaxNumEvents = row[11].value;
+        var r_SamplingMethod = row[12].value;
+        var r_NodeKey = row[13].value;
+
+        var level;
+        if (r_Success === 1) {
+
+            // Error message and level
+            status = r_ErrorMessage;
+            level = "success";
+
+            // Plot the data
+            thisObj.plotFCSData(r_Data, r_ParamX, r_ParamY, r_DisplayX, r_DisplayY);
+
+            // Cache the plotted data
+            var dataKey = r_Code + "_" + r_ParamX + "_" + r_ParamY + "_" + r_MaxNumEvents.toString() +
+                "_" + r_DisplayX + "_" + r_DisplayY + "_" + r_SamplingMethod.toString();
+            thisObj.cacheFCSData(r_NodeKey, dataKey, r_Data);
+
+        } else {
+            status = "Sorry, there was an error: \"" + r_ErrorMessage + "\".";
+            level = "danger";
+        }
+
+        // We only display errors
+        if (r_Success === 0) {
+            thisObj.displayStatus(status, level);
+        } else {
+            thisObj.hideStatus();
+        }
+
+        return table;
+
+    },
+
+    cacheFCSData: function (nodeKey, dataKey, fcsData) {
+
+        // Cache the data
+        if (! (nodeKey in this.dataCache)) {
+            this.dataCache[nodeKey] = {};
+        }
+        this.dataCache[nodeKey][dataKey] = fcsData;
+    },
+
+    displayStatus: function(status, level) {
+        switch (level) {
+            case "info":
+                color = "black";
+                break;
+            case "success":
+                color = "cyan";
+                break;
+            case "danger":
+                color = "red";
+                break;
+            default:
+                color = "black";
+                break;
+        }
+        var status_div = $("#status_div");
+        status_div
+            .css("color", color)
+            .text(status);
+        status_div.show();
+    },
+
+    hideStatus: function() {
+        $("#status_div").hide();
+    }
 
 });