Index: /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs	(revision 9324)
@@ -162,4 +162,26 @@
     }
 
+    public bool Delete(string username, string experimentId) {
+      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
+      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
+      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
+                    where e.ExperimentId == experimentId
+                    select e).FirstOrDefault();
+
+      if (entity == null)
+        return false;
+
+      if (entity.ExperimentJsonUrl != null) {
+        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
+        container.CreateIfNotExist();
+        var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
+        blob.DeleteIfExists();
+      }
+
+      serviceContext.DeleteObject(entity);
+      serviceContext.SaveChangesWithRetries();
+      return true;
+    }
+
     public bool DeleteByName(string username, string experiment) {
       TableServiceContext serviceContext = TableClient.GetDataServiceContext();
@@ -209,5 +231,5 @@
     //}
 
-    public IEnumerable<Model.Experiment> GetExperiments(string user) {
+    public IEnumerable<Model.Experiment> GetExperiments(string user, bool namesOnly=false) {
       TableServiceContext serviceContext = TableClient.GetDataServiceContext();
       TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
@@ -216,11 +238,16 @@
                     select e).ToList();
       var experiments = new List<Experiment>();
-      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
-      container.CreateIfNotExist();
-      foreach (var entity in entites) {
-        var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
-        experiments.Add(AlgorithmConverter.ConvertJsonToExperiment(blob.DownloadText()));
-      }
-      return experiments;
+      if (namesOnly) {
+        return (from e in entites select new Model.Experiment() { Id = e.ExperimentId, Name = e.RowKey.Split('_')[1] });
+      }
+      else {
+        CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
+        container.CreateIfNotExist();
+        foreach (var entity in entites) {
+          var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
+          experiments.Add(AlgorithmConverter.ConvertJsonToExperiment(blob.DownloadText()));
+        }
+        return experiments;
+      }
     }
 
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs	(revision 9324)
@@ -336,5 +336,5 @@
       else if (item is DoubleMatrix) {
         var matrix = item as DoubleMatrix;
-        double[][] matrixValue = new double[matrix.Rows][];
+        /*double[][] matrixValue = new double[matrix.Rows][];
         for (int i = 0; i < matrixValue.Length; ++i) {
           matrixValue[i] = new double[matrix.Columns];
@@ -342,6 +342,13 @@
             matrixValue[i][j] = matrix[i, j];
           }
-        }
-        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.DecimalMatrix() { Name = name, Value = matrixValue };
+        } */
+        double[][] matrixValue = new double[matrix.Columns][];
+        for (int i = 0; i < matrix.Columns; ++i) {
+          matrixValue[i] = new double[matrix.Rows];
+          for (int j = 0; j < matrix.Rows; ++j) {
+            matrixValue[i][j] = matrix[j, i];
+          }
+        }        
+        result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.DecimalMatrix() { Name = name, Value = matrixValue, RowNames = (matrix.ColumnNames.Count() > 0 ? matrix.ColumnNames.ToArray() : null) };
       }
       else if (item is IStringConvertibleArray) {
@@ -369,9 +376,10 @@
           var columns = table.Rows.ToList()[i];
           names[i] = columns.Name;
-          results[i] = new double[columns.Values.Count];
+          results[i] = new double[columns.Values.Count];          
           for (int j=0; j < columns.Values.Count; j++) {
             results[i][j] = columns.Values[j];
           }
         }
+        results = transpose(results);
         result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.DecimalMatrix() { Name = name, Value = results, RowNames = names };
       }
@@ -437,4 +445,20 @@
     }
 
+    private double[][] transpose(double[][] arr) {
+      var width = arr.Length;
+      var height = arr[0].Length;
+
+      var res = new double[height][];
+      for (var i = 0; i < height; i++) 
+        res[i] = new double[width];
+
+      for (var i = 0; i < width; i++) {
+        for (var j = 0; j < height; j++) {
+          res[j][i] = arr[i][j];
+        }
+      }
+      return res;
+    }
+
     private string GetMapperFromBlobStore(string scenarioName) {
       var scenarioDao = dal.ScenarioDao;
@@ -482,5 +506,5 @@
 
     public bool DeleteExperiment(User user, string experiment) {
-      return dal.ExperimentDao.DeleteByName(user.Username, experiment);
+      return dal.ExperimentDao.Delete(user.Username, experiment);
     }
 
@@ -564,6 +588,6 @@
     }
 
-    public IEnumerable<Model.Experiment> GetExperiments(User user) {
-      return dal.ExperimentDao.GetExperiments(user.Username);
+    public IEnumerable<Model.Experiment> GetExperiments(User user, bool namesOnly=false) {
+      return dal.ExperimentDao.GetExperiments(user.Username, namesOnly);
     }
 
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/DAL.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/DAL.cs	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/DAL.cs	(revision 9324)
@@ -22,6 +22,7 @@
     bool Update(string username, Experiment experiment);
     bool DeleteByName(string username, string experiment);
+    bool Delete(string username, string experimentId);
     Experiment FindByName(string username, string experiment);
-    IEnumerable<Experiment> GetExperiments(string user);
+    IEnumerable<Experiment> GetExperiments(string user, bool namesOnly = false);
     Experiment GetExperimentByName(string username, string scenario);
 
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IControllerService.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IControllerService.cs	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IControllerService.cs	(revision 9324)
@@ -50,5 +50,5 @@
 
     [OperationContract]
-    IEnumerable<Experiment> GetExperiments(User user);
+    IEnumerable<Experiment> GetExperiments(User user, bool namesOnly = false);
 
     [OperationContract]
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IScenarioManager.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IScenarioManager.cs	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IScenarioManager.cs	(revision 9324)
@@ -17,5 +17,5 @@
     string SaveExperiment(User user, Experiment experiment);
     IEnumerable<string> GetExperimentNames(User user);
-    IEnumerable<Model.Experiment> GetExperiments(User user);
+    IEnumerable<Model.Experiment> GetExperiments(User user, bool namesOnly = false);
     Experiment GetExperimentByName(User user, string scenario);
     Experiment GetExperimentById(User user, string nodeId);
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Mockup/MockupScenarioManager.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Mockup/MockupScenarioManager.cs	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Mockup/MockupScenarioManager.cs	(revision 9324)
@@ -279,5 +279,5 @@
     }
 
-    public IEnumerable<Model.Experiment> GetExperiments(User user) {
+    public IEnumerable<Model.Experiment> GetExperiments(User user, bool namesOnly = false) {
       throw new NotImplementedException();
     }
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Parsers/AlgorithmConverter.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Parsers/AlgorithmConverter.cs	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Controller/Parsers/AlgorithmConverter.cs	(revision 9324)
@@ -184,4 +184,19 @@
     }
 
+    public static JObject ConvertRunToJson(Run run) {
+      var jrun = new JObject();
+      jrun["id"] = run.Id;
+      jrun["name"] = run.Name;
+      jrun["results"] = ConvertParametersToJson(run.Results);
+      return jrun;
+    }
+
+    public static JArray ConvertRunsToJson(IList<Run> runs) {
+       var jarray = new JArray();
+      foreach (var run in runs)
+        jarray.Add(ConvertRunToJson(run));
+      return jarray;
+    }
+
     public static Experiment ConvertJsonToExperiment(string json) {
       var experiment = new Experiment();
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Controller/PlaceholderControllerService.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Controller/PlaceholderControllerService.cs	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Controller/PlaceholderControllerService.cs	(revision 9324)
@@ -185,6 +185,6 @@
 
 
-    public IEnumerable<Experiment> GetExperiments(User user) {
-      return hiveManager.GetExperiments(user);
+    public IEnumerable<Experiment> GetExperiments(User user, bool namesOnly=false) {
+      return hiveManager.GetExperiments(user, namesOnly);
     }
 
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/Datatypemapping.js
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/Datatypemapping.js	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/Datatypemapping.js	(revision 9324)
@@ -1,159 +1,169 @@
-function DatatypeMapper() {
-}
+var OAAS_VIEW = (function (my, _, $, Backbone) {
+    my.DatatypeMapper = function () {
+        this.cb = {};
+        _.extend(this.cb, Backbone.Events);
 
-DatatypeMapper.prototype.mapHtml = function (property) {
-    var parameter = property.Value;
-    var key = property.Name;
-    if (property.Options) {
-        return DatatypeMapper_mapStrings(property.Name, property.Options, property.Value);
-    }
-    else if (parameter instanceof Array) {
-        // parameter is a vector of strings
-        if (parameter[0] instanceof String || typeof (parameter[0]) == 'string') {
-            return DatatypeMapper_mapStrings(key, parameter);
+        this.mapHtml = function (property, el) {
+            var parameter = property.Value;
+            var key = property.Name;
+            if (property.Options) {
+                var osv = new OAAS_VIEW.SelectionView({ model: property, el: el });
+                this.cb.listenTo(osv, 'selected', function (model) {
+                    property.Value = model.value;
+                });
+                osv.render();
+                return osv;
+            }
+            else if (parameter instanceof Array) {
+                // parameter is a matrix or vector of numbers
+                var tev = new OAAS_VIEW.TableEditView({ model: parameter, el: el, editable: true });
+                tev.render();
+                return tev;
+            }
+            else if (typeof (parameter) == 'boolean') {
+                var osv = new OAAS_VIEW.OptionSelectionView({ model: parameter, el: el, hideText: true });
+                this.cb.listenTo(osv, 'changed', function (model) {
+                    property.Value = model.checked;
+                });
+                osv.render();
+                return osv;
+            }
+            // parameter is a number
+            else if (!isNaN(parameter)) {
+                var nev = new OAAS_VIEW.NumberEditableView({ model: property, el: el });
+                nev.render();
+                return nev;
+            }
+            return 'No mapping for ' + typeof (parameter) + ' (Key: ' + key + ')';
+        };
 
-        }
-        // parameter is a vector of numbers
-        else if (!isNaN(parameter[0])) {
-            return DatatypeMapper_mapNumbers(key, parameter);
-        }
-        // parameter is a matrix of numbers
-        else {
-            return DatatypeMapper_mapMatrix(key, parameter);
-        }
 
     }
-    else if (typeof (parameter) == 'boolean') {
-        return DatatypeMapper_mapBoolean(key, parameter);
-    }
-    // parameter is a number
-    else if (!isNaN(parameter)) {
-        return DatatypeMapper_mapNumber(key, parameter);
-    }
-    return 'No mapping for ' + typeof (parameter) + ' (Key: ' + key + ')';
-}
 
 
-function DatatypeMapper_mapStrings(key, param, selected) {
-  // http://stackoverflow.com/questions/4814512/how-to-create-dropdown-list-dynamically-using-jquery
-  var s = $('<select name="' + key + '"/>');
-  for (var i = 0; i < param.length; i++) {
-    $('<option />', { value: param[i], text: param[i] }).appendTo(s);
-  }
-  s.val(selected);
-  return s;
-}
+    function DatatypeMapper_mapStrings(key, param, selected) {
+        // http://stackoverflow.com/questions/4814512/how-to-create-dropdown-list-dynamically-using-jquery
+        var s = $('<select name="' + key + '"/>');
+        for (var i = 0; i < param.length; i++) {
+            $('<option />', { value: param[i], text: param[i] }).appendTo(s);
+        }
+        s.val(selected);
+        return s;
+    }
 
-function DatatypeMapper_mapNumber(key, param) {
-  return $('<input type="text" name="' + key + '" />').val(param);
-}
+    function DatatypeMapper_mapNumber(key, param) {
+        return $('<input type="text" name="' + key + '" />').val(param);
+    }
 
-function DatatypeMapper_mapBoolean(key, param) {
-  var s = $('<select name="' + key + '"/>');
-  $('<option />', { value: 'true', text: 'true' }).appendTo(s);
-  $('<option />', { value: 'false', text: 'false' }).appendTo(s);
-  return s;
-}
+    function DatatypeMapper_mapBoolean(key, param) {
+        var s = $('<select name="' + key + '"/>');
+        $('<option />', { value: 'true', text: 'true' }).appendTo(s);
+        $('<option />', { value: 'false', text: 'false' }).appendTo(s);
+        return s;
+    }
 
-function DatatypeMapper_mapNumbers(key, param) {
-  // http: //stackoverflow.com/questions/8749236/create-table-with-jquery-append
-  var table = $('<table></table>').addClass('editableTable');
-  var head = $('<thead></thead>');
-  // create head elements
-  var headerRow = $('<tr></tr>');
-  $('<td />').text(key + ' Column').appendTo(headerRow);  
-  headerRow.appendTo(head);
-  head.appendTo(table);
-  var body = $('<tbody></tbody>');
-  for (var i = 0; i < param.length; i++) {
-    var row = $('<tr></tr>');
-    var td = $('<td />').appendTo(row);
-    $('<input type="text" name="' + key + '_' + i + '" />').val(param[i]).appendTo(td);    
-    row.appendTo(body);
-  }
-  body.appendTo(table);
-  return table;
-}
+    function DatatypeMapper_mapNumbers(key, param) {
+        // http: //stackoverflow.com/questions/8749236/create-table-with-jquery-append
+        var table = $('<table></table>').addClass('editableTable');
+        var head = $('<thead></thead>');
+        // create head elements
+        var headerRow = $('<tr></tr>');
+        $('<td />').text(key + ' Column').appendTo(headerRow);
+        headerRow.appendTo(head);
+        head.appendTo(table);
+        var body = $('<tbody></tbody>');
+        for (var i = 0; i < param.length; i++) {
+            var row = $('<tr></tr>');
+            var td = $('<td />').appendTo(row);
+            $('<input type="text" name="' + key + '_' + i + '" />').val(param[i]).appendTo(td);
+            row.appendTo(body);
+        }
+        body.appendTo(table);
+        return table;
+    }
 
-function DatatypeMapper_mapMatrix(key, param) {
-  // http: //stackoverflow.com/questions/8749236/create-table-with-jquery-append
-  var table = $('<table></table>').addClass('editableTable');
-  var head = $('<thead></thead>');
-  // create head elements
-  var headerRow = $('<tr></tr>');
-  for (var i = 0; i < param[0].length; i++) {
-    $('<td />').text(key + ' Column ' + i).appendTo(headerRow);
-  }
-  headerRow.appendTo(head);
-  head.appendTo(table);
-  var body = $('<tbody></tbody>');
-  for (var i = 0; i < param.length; i++) {
-    var row = $('<tr></tr>');
-    for (var j = 0; j < param[i].length; j++) {
-      var td = $('<td />').appendTo(row);      
-      $('<input type="text" name="' + key + '_' + i + '_' + j + '" />').val(param[i][j]).appendTo(td);      
+    function DatatypeMapper_mapMatrix(key, param) {
+        // http: //stackoverflow.com/questions/8749236/create-table-with-jquery-append
+        var table = $('<table></table>').addClass('editableTable');
+        var head = $('<thead></thead>');
+        // create head elements
+        var headerRow = $('<tr></tr>');
+        for (var i = 0; i < param[0].length; i++) {
+            $('<td />').text(key + ' Column ' + i).appendTo(headerRow);
+        }
+        headerRow.appendTo(head);
+        head.appendTo(table);
+        var body = $('<tbody></tbody>');
+        for (var i = 0; i < param.length; i++) {
+            var row = $('<tr></tr>');
+            for (var j = 0; j < param[i].length; j++) {
+                var td = $('<td />').appendTo(row);
+                $('<input type="text" name="' + key + '_' + i + '_' + j + '" />').val(param[i][j]).appendTo(td);
+            }
+            row.appendTo(body);
+        }
+        body.appendTo(table);
+        return table;
+
+        /*var table = '<table class="editableTable"><thead><tr>';
+        for (var i = 0; i < param[0].length; i++) {
+        table += '<th>' + key + ' Column ' + (i + 1) + '</th>';
+        }
+        table += '</tr>';
+        // foreach value entry (2d entry)
+        for (var i = 0; i < param.length; i++) {
+        table += '<tr>';
+        for (var j = 0; j < param[i].length; j++) {
+        table += '<td><input type="text" name="' + key + '_' + i + '_' + j + '" /></td>';
+        }
+        table += '</tr>';
+        }
+        return $*/
     }
-    row.appendTo(body);
-  }
-  body.appendTo(table);
-  return table;
 
-  /*var table = '<table class="editableTable"><thead><tr>';
-  for (var i = 0; i < param[0].length; i++) {
-    table += '<th>' + key + ' Column ' + (i + 1) + '</th>';
-  }
-  table += '</tr>';
-  // foreach value entry (2d entry)
-  for (var i = 0; i < param.length; i++) {
-    table += '<tr>';
-    for (var j = 0; j < param[i].length; j++) {
-      table += '<td><input type="text" name="' + key + '_' + i + '_' + j + '" /></td>';
+    /*
+    DatatypeMapper.prototype.mapString = function (value) {
+    if (value == "true") return true;
+    else if (value == "false") return false;
+    else if (!isNaN(value)) return parseFloat(value.replace(',', '.'));
+    return value;
     }
-    table += '</tr>';
-  }
-  return $*/
-}
 
-DatatypeMapper.prototype.mapString = function (value) {
-  if (value == "true") return true;
-  else if (value == "false") return false;
-  else if (!isNaN(value)) return parseFloat(value.replace(',', '.'));
-  return value;
-}
-
-DatatypeMapper.prototype.aggregateTables = function (data) {
+    DatatypeMapper.prototype.aggregateTables = function (data) {
     // aggregate tables:
     for (var dataKey in data) {
-        var entry = data[dataKey];
-        var tableEntries = {};
-        var toRemove = [];
-        for (var key in entry) {
-            if (key.indexOf('_') != -1) {
-                var splitted = key.split('_');
-                var name = splitted[0];
-                var row = parseInt(splitted[1]);
-                if (!(name in tableEntries)) {
-                    tableEntries[name] = []
-                }
+    var entry = data[dataKey];
+    var tableEntries = {};
+    var toRemove = [];
+    for (var key in entry) {
+    if (key.indexOf('_') != -1) {
+    var splitted = key.split('_');
+    var name = splitted[0];
+    var row = parseInt(splitted[1]);
+    if (!(name in tableEntries)) {
+    tableEntries[name] = []
+    }
 
-                if (splitted.length == 2) { // its a vector of elements
-                    tableEntries[name].push(entry[key])
-                } else if (splitted.length == 3) { // its a matrix of elements
-                    column = parseInt(splitted[2]);
-                    if (tableEntries[name].length < row + 1)
-                        tableEntries[name].push([]);
-                    tableEntries[name][row][column] = entry[key];
-                }
-                toRemove.push(key);
-            }
-        }
+    if (splitted.length == 2) { // its a vector of elements
+    tableEntries[name].push(entry[key])
+    } else if (splitted.length == 3) { // its a matrix of elements
+    column = parseInt(splitted[2]);
+    if (tableEntries[name].length < row + 1)
+    tableEntries[name].push([]);
+    tableEntries[name][row][column] = entry[key];
+    }
+    toRemove.push(key);
+    }
+    }
 
-        for (var i = 0; i < toRemove.length; i++) {
-            delete entry[toRemove[i]];
-        }
+    for (var i = 0; i < toRemove.length; i++) {
+    delete entry[toRemove[i]];
+    }
 
-        for (var key in tableEntries) {
-            entry[key] = tableEntries[key];
-        }
+    for (var key in tableEntries) {
+    entry[key] = tableEntries[key];
     }
-}
+    }
+    }*/
+    return my;
+} (OAAS_VIEW || {}, _, $, Backbone));
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/experiment.controller.js
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/experiment.controller.js	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/experiment.controller.js	(revision 9324)
@@ -1,112 +1,35 @@
-﻿function GeneralController() {
-    this.variationRequestHandler = function (evt) {
-        var self = this;
-        var dialog = new VariationDialog({ model: evt.model });
-        var dialogController = {};
-        _.extend(dialogController, Backbone.Events);
-        dialogController.listenTo(dialog, 'variations-generated', function (variations) {
-            var parent = evt.model.get('parent');
-            for (var i = 0; i < variations.length; i++) {
-                var title = evt.model.get('title');
-                var offset = title.indexOf('(')
-                if (offset != -1) {
-                    title = title.substring(0, offset);
-                }
-                title += '(';
-                for (var j = 0; j < variations[i].length; j++) {
-                    title += variations[i][j].Name + " = " + variations[i][j].Value + "; ";
-                }
-                title += ')';
-                var data = { AlgorithmParameters: variations[i] };
-                if (evt.model.attributes.data.ProblemParameters) {
-                    data.ProblemParameters = evt.model.attributes.data.ProblemParameters;
-                }
-                parent.addNode({ title: title, nodeId: evt.model.get('nodeId'), data: data });
-            }
-            self.model.trigger('change');
-        });
-        dialog.render();
-    },
-    this.experimentFinishedHandler = function (experimentModel, availableExperiments, selectableGroup) {
-        var loadingDialog = new LoadingDialog({ el: $('#loadingDialog') });
-        // start the loading dialog
-        loadingDialog.setLoading(true);
-        loadingDialog.text('Saving experiment ' + experimentModel.get('title') + '...');
-        loadingDialog.render();
-        // send experiment to server
-        experimentModel.save({}, { success: function () {
-            loadingDialog.setLoading(false);
-            loadingDialog.text('Experiment successfully saved!');
-            loadingDialog.render();
-            if (availableExperiments)
-                availableExperiments.fetch({ cache: false, success: function (itm) {
-                    selectableGroup.render();
-                }
-                });
-        }
-        });
-        //loadingDialog.close();
-    }
-}
-
-function ExperimentPageController() {
-    this.refreshExperiments = function () {
-        var availableExperiments = new ExperimentList();
-        availableExperiments.fetch({ cache: false, success: function (itm) {
-            $('#experiments').empty();
-            for (var i = 0; i < availableExperiments.length; i++) {
-                new DraggableView({ model: availableExperiments.models[i], el: $('#experiments') }).render();
-            }
-        }
-        });
-    },
-    this.refreshScenarios = function () {
-        var availableScenarios = new ScenarioList();
-        availableScenarios.fetch({ cache: false, success: function (itm) {
-            var group = new DraggableGroup({ model: availableScenarios, el: $('#algorithms') });
-            group.render();
-        }
-        });
-    },
-    this.create = function () {
-        var self = this;
-        var generalController = new GeneralController();
-        // create all models + required view for the experiment page
-        var model = new ExperimentNode({
-            title: 'Experiment',
-            key: 0,
-            isExperiment: true
-        }, { parse: true });
-        generalController.model = model;
-        var experimentModel = new Experiment({ experiment: model });
-
-        var view = new ExperimentTreeView({ model: model, el: $('#container') });
-        view.render();
-
-        this.refreshScenarios();
-
-        this.refreshExperiments();
-
-        var wizard = new StepWizardView({ el: $('#stepWizard') });
-        wizard.render();
-
-        var detailsView = new ExperimentDetailsTreeView({ model: model, el: $('#container2') });
-        var validationView = new ValidationHintsView({ model: { header: "Validation failed!", text: ""} });
-        var parameterDialog = new ParameterDialog({ model: model, el: $('#parameterDialog') });
-
-        var wizardController = {};
-        _.extend(wizardController, Backbone.Events);
-
-        wizardController.listenTo(model, 'change', function () {
-            // update the details view, when the model changes
-            view.render();
-            detailsView.render();
-        });
-
-
-        wizardController.listenTo(wizard, 'experiment-finished', function () {
-            generalController.experimentFinishedHandler(experimentModel, null, null);
-            self.refreshExperiments();
-            /*// start the loading dialog
+﻿var OAAS_CONTROLLER = (function (my, Backbone, OAAS_VIEW, OAAS_MODEL, _, $) {
+    my.GeneralController = function () {
+        this.variationRequestHandler = function (evt) {
+            var self = this;
+            var dialog = new OAAS_VIEW.VariationDialog({ model: evt.model });
+            var dialogController = {};
+            _.extend(dialogController, Backbone.Events);
+            dialogController.listenTo(dialog, 'variations-generated', function (variations) {
+                var parent = evt.model.get('parent');
+                for (var i = 0; i < variations.length; i++) {
+                    var title = evt.model.get('title');
+                    var offset = title.indexOf('(')
+                    if (offset != -1) {
+                        title = title.substring(0, offset);
+                    }
+                    title += '(';
+                    for (var j = 0; j < variations[i].length; j++) {
+                        title += variations[i][j].Name + " = " + variations[i][j].Value + "; ";
+                    }
+                    title += ')';
+                    var data = { AlgorithmParameters: variations[i] };
+                    if (evt.model.attributes.data.ProblemParameters) {
+                        data.ProblemParameters = evt.model.attributes.data.ProblemParameters;
+                    }
+                    parent.addNode({ title: title, nodeId: evt.model.get('nodeId'), data: data });
+                }
+                self.model.trigger('change');
+            });
+            dialog.render();
+        },
+        this.experimentFinishedHandler = function (experimentModel, availableExperiments, selectableGroup) {
+            var loadingDialog = new OAAS_VIEW.LoadingDialog({ el: $('#loadingDialog') });
+            // start the loading dialog
             loadingDialog.setLoading(true);
             loadingDialog.text('Saving experiment ' + experimentModel.get('title') + '...');
@@ -114,185 +37,263 @@
             // send experiment to server
             experimentModel.save({}, { success: function () {
-            loadingDialog.setLoading(false);
-            loadingDialog.text('Experiment successfully saved!');
-            loadingDialog.render();
-            self.refreshExperiments();
-            }
-            });*/
+                loadingDialog.setLoading(false);
+                loadingDialog.text('Experiment successfully saved!');
+                loadingDialog.render();
+                if (availableExperiments)
+                    availableExperiments.fetch({ cache: false, success: function (itm) {
+                        selectableGroup.render();
+                    }
+                    });
+            }
+            });
             //loadingDialog.close();
-        });
-
-        wizardController.listenTo(view, 'structure-changed', function (node) {
+        }
+    }
+
+    my.ExperimentPageController = function () {
+        this.refreshExperiments = function () {
+            var availableExperiments = new OAAS_MODEL.ExperimentList();
+            availableExperiments.fetch({ cache: false, success: function (itm) {
+                var group = new OAAS_VIEW.DraggableGroup({ collection: availableExperiments, el: $('#experiments') });
+                group.render();
+            }
+            });
+        },
+        this.refreshScenarios = function () {
+            var availableScenarios = new OAAS_MODEL.ScenarioList();
+            availableScenarios.fetch({ cache: false, success: function (itm) {
+                var group = new OAAS_VIEW.DraggableGroup({ collection: availableScenarios, el: $('#algorithms') });
+                group.render();
+            }
+            });
+        },
+        this.create = function () {
+            var self = this;
+            var generalController = new my.GeneralController();
+            // create all models + required view for the experiment page
+            var model = new OAAS_MODEL.ExperimentNode({
+                title: 'Experiment',
+                key: 0,
+                isExperiment: true
+            }, { parse: true });
+            generalController.model = model;
+            var experimentModel = new OAAS_MODEL.Experiment({ experiment: model });
+
+            var view = new OAAS_VIEW.ExperimentTreeView({ model: model, el: $('#container') });
             view.render();
-            detailsView.render();
-        });
-
-        wizardController.listenTo(view, 'node-added', function (node) {
-            // get details about the node
-            node.fetch({ success: function (itm) {
-                model.trigger('change', {});
-            }
-            });
-        });
-
-        wizardController.listenTo(detailsView, 'node-clicked', function (node) {
-            // get details about the node
-            var modelNode = ExperimentNode.lookup(node.data.key);
-            if (!modelNode.get('isExperiment')) {
-                parameterDialog.model = modelNode;
-                parameterDialog.render();
-            }
-        });
-
-        wizardController.listenTo(parameterDialog, 'parameters-finished', function (node) {
-            parameterDialog.close();
-        });
-
-        wizardController.listenTo(view, 'variation-request', function (evt) {
-            generalController.variationRequestHandler(evt);
-        });
-
-        var experimentDetailsView = new ExperimentDetailsView({ el: $('#step3'), model: experimentModel });
+
+            this.refreshScenarios();
+
+            this.refreshExperiments();
+
+            var wizard = new OAAS_VIEW.StepWizardView({ el: $('#stepWizard') });
+            wizard.render();
+
+            var detailsView = new OAAS_VIEW.ExperimentDetailsTreeView({ model: model, el: $('#container2') });
+            var validationView = new OAAS_VIEW.ValidationHintsView({ model: { header: "Validation failed!", text: ""} });
+            var parameterDialog = new OAAS_VIEW.ParameterDialog({ model: model, el: $('#parameterDialog') });
+
+            var wizardController = {};
+            _.extend(wizardController, Backbone.Events);
+
+            wizardController.listenTo(model, 'change', function () {
+                // update the details view, when the model changes
+                view.render();
+                detailsView.render();
+            });
+
+
+            wizardController.listenTo(wizard, 'experiment-finished', function () {
+                generalController.experimentFinishedHandler(experimentModel, null, null);
+                self.refreshExperiments();
+            });
+
+            wizardController.listenTo(view, 'structure-changed', function (node) {
+                view.render();
+                detailsView.render();
+            });
+
+            wizardController.listenTo(view, 'node-added', function (node) {
+                // get details about the node
+                node.fetch({ success: function (itm) {
+                    model.trigger('change', {});
+                }
+                });
+            });
+
+            wizardController.listenTo(detailsView, 'node-clicked', function (node) {
+                // get details about the node
+                var modelNode = OAAS_MODEL.ExperimentNode.lookup(node.data.key);
+                if (!modelNode.get('isExperiment')) {
+                    parameterDialog.model = modelNode;
+                    parameterDialog.render();
+                }
+            });
+
+            wizardController.listenTo(parameterDialog, 'parameters-finished', function (node) {
+                parameterDialog.close();
+            });
+
+            wizardController.listenTo(view, 'variation-request', function (evt) {
+                generalController.variationRequestHandler(evt);
+            });
+
+            var experimentDetailsView = new OAAS_VIEW.ExperimentDetailsView({ el: $('#step3'), model: experimentModel });
+
+
+        }
     }
-}
-
-
-
-/// ==================== EDIT PAGE =========================
-/// ==================== EDIT PAGE =========================
-/// ==================== EDIT PAGE =========================
-
-function ExperimentEditPageController() {
-    this.refreshScenarios = function () {
-        var availableScenarios = new ScenarioList();
-        availableScenarios.fetch({ cache: false, success: function (itm) {
-            var group = new DraggableGroup({ model: availableScenarios, el: $('#draggableAlgorithms') });
-            group.render();
-            /*$('#algorithms').empty();
-            for (var i = 0; i < availableScenarios.length; i++) {
-            new DraggableView({ model: availableScenarios.models[i], el: $('#algorithms') }).render();
-            }*/
+
+
+
+    /// ==================== EDIT PAGE =========================
+    /// ==================== EDIT PAGE =========================
+    /// ==================== EDIT PAGE =========================
+
+    my.ExperimentEditPageController = function () {
+        this.refreshScenarios = function () {
+            var availableScenarios = new OAAS_MODEL.ScenarioList();
+            availableScenarios.fetch({ cache: false, success: function (itm) {
+                var group = new OAAS_VIEW.DraggableGroup({ collection: availableScenarios, el: $('#draggableAlgorithms') });
+                group.render();
+            }
+            });
+        },
+        this.create = function () {
+            var generalController = new my.GeneralController();
+
+            var self = this;
+            // create all models + required view for the experiment page
+            var controllerModel = new OAAS_MODEL.ControllerModel();
+            var model = new OAAS_MODEL.ExperimentNode({
+                title: 'Experiment',
+                key: 0,
+                isExperiment: true
+            }, { parse: true });
+
+            generalController.model = model;
+            var experimentModel = new OAAS_MODEL.Experiment({ experiment: model });
+            var experimentDetailsView = new OAAS_VIEW.ExperimentDetailsView({ el: $('#step4'), model: experimentModel });
+            experimentDetailsView.render();
+
+            var availableExperiments = new OAAS_MODEL.ExperimentList();
+
+            var wizardController = {};
+            _.extend(wizardController, Backbone.Events);
+
+            this.refreshScenarios();
+
+            var selectableGroup = new OAAS_VIEW.SelectableGroup({ collection: availableExperiments, el: $('#experiments') });
+            //selectableGroup.render();
+            var draggableExperiments = new OAAS_VIEW.DraggableGroup({ collection: availableExperiments, el: $('#draggableExperiments') });
+            availableExperiments.fetch({ cache: false, success: function (itm) {
+                // selectableGroup = new OAAS_VIEW.SelectableGroup({ collection: availableExperiments, el: $('#experiments') });
+                selectableGroup.render();
+
+                wizardController.listenTo(selectableGroup, 'node-selected', function (nodeId) {
+                    var node = availableExperiments.find(function (itm) { return itm.get('nodeId') == nodeId; });
+
+                    var newNode = new OAAS_MODEL.ExperimentNode(node.attributes);
+                    newNode.fetch({ success: function () {
+                        experimentModel.set({
+                            experiment: newNode,
+                            title: node.get('title'),
+                            nodeId: node.get('nodeId'),
+                            run: node.get('run'),
+                            repititions: node.get('repititions'),
+                            group: node.get('group')
+                        });
+                        controllerModel.set({ selectedNode: newNode });
+                        $('#deleteExperimentButton').removeAttr('disabled');
+                        detailsView.model = newNode;
+                        detailsView.render();
+                        view.model = newNode;
+                        view.render();
+                        experimentDetailsView.render();
+                    }
+                    });
+                }
+                );
+            }
+            });
+
+            // create wizard with 4 steps
+            var wizard = new OAAS_VIEW.StepWizardView({ el: $('#stepWizard') });
+            wizard.render();
+
+            var view = new OAAS_VIEW.ExperimentTreeView({ model: model, el: $('#container') });
+            view.render();
+            var validationView = new OAAS_VIEW.ValidationHintsView({ model: { header: "Validation failed!", text: ""} });
+
+            var detailsView = new OAAS_VIEW.ExperimentDetailsTreeView({ model: model, el: $('#container2') });
+
+            var parameterDialog = new OAAS_VIEW.ParameterDialog({ model: model, el: $('#parameterDialog') });
+            var loadingDialog = new OAAS_VIEW.LoadingDialog({ el: $('#loadingDialog') });
+
+            wizardController.listenTo(wizard, 'step-validated', function (validationModel) {
+                // update the details view
+                if (validationModel.stepNumber == 1) {
+                    if (controllerModel.get('selectedNode') == null) {
+                        validationView.model["text"] = 'Please select an experiment to continue!';
+                        validationView.render();
+                        validationModel.succeeded = false;
+                    }
+                }
+                detailsView.render();
+            });
+
+            wizardController.listenTo(model, 'change', function () {
+                // update the details view, when the model changes
+                view.render();
+                detailsView.render();
+            });
+
+            wizardController.listenTo(view, 'structure-changed', function (node) {
+                view.render();
+            });
+
+            wizardController.listenTo(view, 'node-added', function (node) {
+                // get details about the node
+                //if (!node.get('isExperiment'))
+                node.fetch({ success: function (itm) {
+                    model.trigger('change', {});
+                }
+                });
+            });
+
+            wizardController.listenTo(wizard, 'experiment-finished', function () {
+                generalController.experimentFinishedHandler(experimentModel, availableExperiments, selectableGroup);
+            });
+
+            wizardController.listenTo(detailsView, 'node-clicked', function (node) {
+                // get details about the node
+                var modelNode = OAAS_MODEL.ExperimentNode.lookup(node.data.key);
+                if (!modelNode.get('isExperiment')) {
+                    parameterDialog.model = modelNode;
+                    parameterDialog.render();
+                }
+            });
+
+            wizardController.listenTo(view, 'variation-request', function (evt) {
+                generalController.variationRequestHandler(evt);
+            });
+
+            wizardController.listenTo(parameterDialog, 'parameters-finished', function (node) {
+                parameterDialog.close();
+            });
+
+            $('#deleteExperimentButton').click(function (evt) {
+                var node = controllerModel.get('selectedNode');
+                var nodes = availableExperiments.where({ nodeId: node.get('nodeId') });
+                if (nodes.length == 1) {
+                    nodes[0].destroy();
+                    $('#deleteExperimentButton').attr('disabled', 'disabled');
+                    controllerModel.set('selectedNode', null);
+                }
+            });
         }
-        });
-    },
-    this.create = function () {
-        var generalController = new GeneralController();
-
-        var self = this;
-        // create all models + required view for the experiment page
-        var controllerModel = new ControllerModel();
-        var model = new ExperimentNode({
-            title: 'Experiment',
-            key: 0,
-            isExperiment: true
-        }, { parse: true });
-
-        generalController.model = model;
-        var experimentModel = new Experiment({ experiment: model });
-        var experimentDetailsView = new ExperimentDetailsView({ el: $('#step4'), model: experimentModel });
-        experimentDetailsView.render();
-
-        var availableExperiments = new ExperimentList();
-        var selectableGroup = null;
-        var wizardController = {};
-        _.extend(wizardController, Backbone.Events);
-
-        this.refreshScenarios();
-
-        availableExperiments.fetch({ cache: false, success: function (itm) {
-            selectableGroup = new SelectableGroup({ model: availableExperiments, el: $('#experiments') });
-            selectableGroup.render();
-            var draggableExperiments = new DraggableGroup({ model: availableExperiments, el: $('#draggableExperiments') });
-            draggableExperiments.render();
-
-            wizardController.listenTo(selectableGroup, 'node-selected', function (nodeId) {
-                var node = availableExperiments.find(function (itm) { return itm.get('nodeId') == nodeId; });
-                var newNode = new ExperimentNode(node.attributes);
-                experimentModel.set({
-                    experiment: newNode,
-                    title: node.get('title'),
-                    nodeId: node.get('nodeId'),
-                    run: node.get('run'),
-                    repititions: node.get('repititions'),
-                    group: node.get('group')
-                });
-                controllerModel.set({ selectedNode: newNode });
-                detailsView.model = newNode;
-                detailsView.render();
-                view.model = newNode;
-                view.render();
-                experimentDetailsView.render();
-            }
-            );
-        }
-        });
-
-        // create wizard with 4 steps
-        var wizard = new StepWizardView({ el: $('#stepWizard') });
-        wizard.render();
-
-        var view = new ExperimentTreeView({ model: model, el: $('#container') });
-        view.render();
-        var validationView = new ValidationHintsView({ model: { header: "Validation failed!", text: ""} });
-
-        var detailsView = new ExperimentDetailsTreeView({ model: model, el: $('#container2') });
-
-        var parameterDialog = new ParameterDialog({ model: model, el: $('#parameterDialog') });
-        var loadingDialog = new LoadingDialog({ el: $('#loadingDialog') });
-
-        wizardController.listenTo(wizard, 'step-validated', function (validationModel) {
-            // update the details view
-            if (validationModel.stepNumber == 1) {
-                if (controllerModel.get('selectedNode') == null) {
-                    validationView.model["text"] = 'Please select an experiment to continue!';
-                    validationView.render();
-                    validationModel.succeeded = false;
-                }
-            }
-            detailsView.render();
-        });
-
-        wizardController.listenTo(model, 'change', function () {
-            // update the details view, when the model changes
-            view.render();
-            detailsView.render();
-        });
-
-        wizardController.listenTo(view, 'structure-changed', function (node) {
-            view.render();
-        });
-
-        wizardController.listenTo(view, 'node-added', function (node) {
-            // get details about the node
-            //if (!node.get('isExperiment'))
-            node.fetch({ success: function (itm) {
-                model.trigger('change', {});
-            }
-            });
-        });
-
-        wizardController.listenTo(wizard, 'experiment-finished', function () {
-            generalController.experimentFinishedHandler(experimentModel, availableExperiments, selectableGroup);          
-        });
-
-        wizardController.listenTo(detailsView, 'node-clicked', function (node) {
-            // get details about the node
-            var modelNode = ExperimentNode.lookup(node.data.key);
-            if (!modelNode.get('isExperiment')) {
-                parameterDialog.model = modelNode;
-                parameterDialog.render();
-            }
-        });
-
-        wizardController.listenTo(view, 'variation-request', function (evt) {
-            generalController.variationRequestHandler(evt);
-        });
-
-        wizardController.listenTo(parameterDialog, 'parameters-finished', function (node) {
-            parameterDialog.close();
-        });
     }
-}
-
+    return my;
+} (OAAS_CONTROLLER || {}, Backbone, OAAS_VIEW, OAAS_MODEL, _, $));
 
  
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/experiment.model.js
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/experiment.model.js	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/experiment.model.js	(revision 9324)
@@ -1,119 +1,130 @@
 ﻿//================== MODELS =====================
-var ControllerModel = Backbone.Model.extend({
-  defaults: {
-    selectedNode: null  
+var OAAS_MODEL = (function (my, Backbone) {
+    Backbone.Relational.store.addModelScope(my);
+
+    my.ControllerModel = Backbone.Model.extend({
+        defaults: {
+            selectedNode: null
+        }
+    });
+
+    my.Experiment = Backbone.RelationalModel.extend({
+        url: function () {
+            return '/Experiment/Experiment?nodeId=' + this.get('nodeId');
+        },
+        isNew: function () { return false; },
+        defaults: {
+            title: 'My Experiment',
+            isExperiment: true,
+            run: false,
+            nodeId: null,
+            repititions: 1,
+            group: 'TESTAZURE'
+        },
+        relations: [{
+            key: 'experiment',
+            relatedModel: 'ExperimentNode'
+        }]
+    });
+
+    my.ExperimentNode = Backbone.RelationalModel.extend({
+        defaults: {
+            title: 'Experiment',
+            key: -1,
+            data: {},
+            parent: null,
+            isExperiment: false,
+            nodeId: null
+        },        
+        relations: [{
+            type: Backbone.HasMany,
+            key: 'children',
+            relatedModel: 'ExperimentNode',
+            collectionType: 'AlgorithmList',
+            reverseRelation: {
+                key: 'parent'
+            }
+        }],
+        url: function () {
+            return this.get('isExperiment') ? '/Experiment/Experiment?nodeId=' + this.get('nodeId') : '/Experiment/Scenario?nodeId=' + this.get('nodeId');
+        },
+        initialize: function (spec) {
+            if (typeof spec.key === 'undefined' || spec.key == -1) {
+                spec.key = my.ExperimentNode.globalKeyCount;
+                this.set({ key: spec.key });
+                my.ExperimentNode.globalKeyCount++;
+            }
+            else if (spec.key >= my.ExperimentNode.globalKeyCount)
+                my.ExperimentNode.globalKeyCount = spec.key + 1;
+
+            my.ExperimentNode.globalNodeMap[spec.key] = this;
+        },
+        // adds a new experimentNode to this node
+        addNode: function (experimentNode) {
+            if (!(experimentNode instanceof my.ExperimentNode)) {
+                experimentNode = new my.ExperimentNode(experimentNode);
+            }
+            this.get('children').add(experimentNode);
+            experimentNode.set({ parent: this });
+            this.trigger('node-added', experimentNode);
+            return experimentNode;
+        },
+        // moves an experimentNode into this node
+        moveNode: function (experimentNode) {
+            var parent = experimentNode.get('parent');
+            if (parent != null) {
+                // remove from parent
+                parent.get('children').remove(experimentNode);
+            }
+            this.addNode(experimentNode);
+        },
+        // delete this node
+        remove: function () {
+            var parent = this.get('parent');
+            if (parent != null) {
+                parent.get('children').remove(this);
+                this.set({ parent: null });
+                // simply replace it with 'undefined'
+                delete my.ExperimentNode.globalNodeMap[this.get('key')];
+            }
+        },
+        lookup: function (key) {
+            return my.ExperimentNode.globalNodeMap[key];
+        }
+    },
+  {
+      globalKeyCount: 0,
+      globalNodeMap: {},
+      lookup: function (key) {
+          return my.ExperimentNode.globalNodeMap[key];
+      },
+      nextGlobalKey: function () {
+          var key = my.ExperimentNode.globalKeyCount;
+          my.ExperimentNode.globalKeyCount++;
+          return key;
+      }
   }
-});
+  );
 
-var Experiment = Backbone.RelationalModel.extend({   
-  url: function () {
-    return '/Experiment/Experiment?nodeId=' + this.get('nodeId');
-  },
-  defaults: {
-    title: 'My Experiment',
-    isExperiment: true,
-    run: false,
-    nodeId: null,
-    repititions: 1,
-    group: 'TESTAZURE'
-  },
-  isNew: function() { return this.get('nodeId') == null; },
-  relations: [{
-    key: 'experiment',
-    relatedModel: 'ExperimentNode'
-  }]
-});
+    my.ExperimentList = Backbone.Collection.extend({
+        url: function () {
+            return "/Experiment/ExperimentList";
+        },
+        model: my.Experiment
+    });
 
-var ExperimentNode = Backbone.RelationalModel.extend({
-    defaults: {
-        title: 'Experiment',
-        key: -1,
-        data: {},
-        parent: null,
-        isExperiment: false,
-        nodeId: null
-    },
-    relations: [{
-        type: Backbone.HasMany,
-        key: 'children',
-        relatedModel: 'ExperimentNode',
-        collectionType: 'ScenarioList',
-        reverseRelation: {
-            key: 'parent'
-        }
-    }],
-    url: function () {
-        return this.get('isExperiment') ? '/Experiment/Experiment?nodeId=' + this.get('nodeId') : '/Experiment/Scenario?nodeId=' + this.get('nodeId');
-    },
-    initialize: function (spec) {
-        if (typeof spec.key === 'undefined' || spec.key == -1) {
-            spec.key = ExperimentNode.globalKeyCount;
-            this.set({ key: spec.key });
-            ExperimentNode.globalKeyCount++;
-        }
-        else if (spec.key >= ExperimentNode.globalKeyCount)
-            ExperimentNode.globalKeyCount = spec.key + 1;
+    my.AlgorithmList = Backbone.Collection.extend({
+        url: function () {
+            return "/Experiment/AlgorithmList";
+        },
+        model: my.ExperimentNode
+    });
 
-        ExperimentNode.globalNodeMap[spec.key] = this;
-    },
-    // adds a new experimentNode to this node
-    addNode: function (experimentNode) {
-        if (!(experimentNode instanceof ExperimentNode)) {
-            experimentNode = new ExperimentNode(experimentNode);
-        }
-        this.get('children').add(experimentNode);
-        experimentNode.set({ parent: this });
-        this.trigger('node-added', experimentNode);
-        return experimentNode;
-    },
-    // moves an experimentNode into this node
-    moveNode: function (experimentNode) {
-        var parent = experimentNode.get('parent');
-        if (parent != null) {
-            // remove from parent
-            parent.get('children').remove(experimentNode);
-        }
-        this.addNode(experimentNode);
-    },
-    // delete this node
-    remove: function () {
-        var parent = this.get('parent');
-        if (parent != null) {
-            parent.get('children').remove(this);
-            this.set({ parent: null });
-            // simply replace it with 'undefined'
-            delete ExperimentNode.globalNodeMap[this.get('key')];
-        }
-        this.trigger('node-removed', this);
-    },
-    lookup: function (key) {
-        return ExperimentNode.globalNodeMap[key];
-    }
-},
-{
-    globalKeyCount: 0,
-    globalNodeMap: {},
-    lookup: function (key) {
-        return ExperimentNode.globalNodeMap[key];
-    },
-    nextGlobalKey: function () {
-        var key = ExperimentNode.globalKeyCount;
-        ExperimentNode.globalKeyCount++;
-        return key;
-    }
-}
-);
-
-var ExperimentList = Backbone.Collection.extend({
-  url: function () {
-    return "/Experiment/ExperimentList";
-  },
-  model: Experiment
-});
-
-var ScenarioList = Backbone.Collection.extend({
-  url: function () {
-    return "/Experiment/ScenarioList";
-  },
-  model: ExperimentNode
-});
+    my.ScenarioList = Backbone.Collection.extend({
+        url: function () {
+            return "/Experiment/ScenarioList";
+        },
+        model: my.ExperimentNode
+    });
+    return my;
+} (OAAS_MODEL || {}, Backbone));
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/experiment.view.js
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/experiment.view.js	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/experiment.view.js	(revision 9324)
@@ -1,499 +1,537 @@
-﻿// ================ VIEWS =======================
-var ExperimentTreeView = Backbone.View.extend({
-    renderTree: function (model) {
-        var jsonModel = model.toJSON();
-        var self = this;
-        this.tree = $('<div />').dynatree({
-            children: [jsonModel],
-            autoExpandMS: 750,
-            onActivate: function (node) {
-                // if we are able to remove this node from the tree, enable the remove button.
-                if (node && node.parent.parent != null) {
-                    $('.remove-button', this.$el).removeAttr("disabled");
-                } else if (node) {
-                    $('.remove-button', this.$el).attr("disabled", "disabled");
-                }
-
-                var modelNode = ExperimentNode.lookup(node.data.key);
-                if (modelNode && !modelNode.get('isExperiment')) {
-                    $('.variate-button', this.$el).removeAttr("disabled");
-                } else {
-                    $('.variate-button', this.$el).attr("disabled", "disabled");
-                }
-            },
-            dnd: {
-                onDragStart: function (node) {
-                    return node.parent.parent != null;
+﻿var OAAS_VIEW = (function (my, Backbone, _, $, OAAS_MODEL) {
+    // ================ VIEWS =======================
+    my.ExperimentTreeView = Backbone.View.extend({
+        renderTree: function (model) {
+            var jsonModel = model.toJSON();
+            var self = this;
+            this.tree = $('<div />').dynatree({
+                children: [jsonModel],
+                autoExpandMS: 750,
+                onActivate: function (node) {
+                    // if we are able to remove this node from the tree, enable the remove button.
+                    if (node && node.parent.parent != null) {
+                        $('.remove-button', this.$el).removeAttr("disabled");
+                    } else if (node) {
+                        $('.remove-button', this.$el).attr("disabled", "disabled");
+                    }
+
+                    var modelNode = OAAS_MODEL.ExperimentNode.lookup(node.data.key);
+                    if (modelNode && !modelNode.get('isExperiment')) {
+                        $('.variate-button', this.$el).removeAttr("disabled");
+                    } else {
+                        $('.variate-button', this.$el).attr("disabled", "disabled");
+                    }
                 },
-                onDragEnter: function (node, sourceNode) {
-                    return true;
+                dnd: {
+                    onDragStart: function (node) {
+                        return node.parent.parent != null;
+                    },
+                    onDragEnter: function (node, sourceNode) {
+                        return true;
+                    },
+                    onDragOver: function (node, sourceNode, hitMode) {
+                        return node.data.title !== "Experiment" || hitMode === "over";
+                    },
+                    onDrop: function (node, sourceNode, hitMode, ui, draggable) {
+                        if (hitMode !== 'over')
+                            return;
+                        var modelNode = OAAS_MODEL.ExperimentNode.lookup(node.data.key);
+                        if (sourceNode) {
+                            var sourceModelNode = OAAS_MODEL.ExperimentNode.lookup(sourceNode.data.key);
+                            sourceNode.move(node, hitMode);
+                            // move node into the modelNode
+                            sourceModelNode.moveNode(modelNode);
+                        }
+                        else {
+                            var elem = $(draggable.element[0]);
+                            var newNode = { nodeId: elem.attr('id'), isExperiment: elem.attr('data-isExperiment') === 'true', title: elem.attr('data-name'), key: OAAS_MODEL.ExperimentNode.nextGlobalKey() };
+                            if (hitMode == "over") {
+                                node.addChild(newNode);
+                                node.expand(true);
+                                // update the data model
+                                newNode = modelNode.addNode(newNode);
+                                self.trigger('node-added', newNode);
+                            }
+                        }
+                        self.trigger('structure-changed', modelNode);
+                    }
+                }
+            });
+            this.tree.dynatree("getRoot").visit(function (node) {
+                node.expand(true);
+            });
+        },
+        initialize: function (spec) {
+            this.renderTree(spec.model);
+        },
+        events: {
+            'click .remove-button': 'doRemove',
+            'click .variate-button': 'doVariate'
+        },
+        render: function () {
+            this.$el.empty();
+            this.renderTree(this.model);
+            var content = $(_.template($('#stepwizard_template').html(), {}));
+            this.tree.appendTo(this.$el);
+            content.appendTo(this.$el);
+        },
+        doRemove: function () {
+            var node = this.tree.dynatree('getActiveNode');
+            if (node && node.parent.parent != null) {
+                var nxt = node.getNextSibling();
+                if (nxt == null)
+                    nxt = node.getPrevSibling();
+                if (nxt == null)
+                    nxt = node.getParent();
+                node.remove();
+                OAAS_MODEL.ExperimentNode.lookup(node.data.key).remove();
+                if (nxt) {
+                    this.tree.dynatree("getTree").activateKey(nxt.data.key);
+                }
+            }
+            this.trigger('structure-changed', node);
+        },
+        doVariate: function () {
+            var node = this.tree.dynatree('getActiveNode');
+            var modelNode = OAAS_MODEL.ExperimentNode.lookup(node.data.key);
+            this.trigger('variation-request', {
+                parentNode: node.parent,
+                model: modelNode
+            });
+        }
+    });
+
+    my.ExperimentDetailsTreeView = Backbone.View.extend({
+        render: function () {
+            var jsonModel = this.model.toJSON();
+            var self = this;
+            var tree = $('<div />').dynatree({
+                children: [jsonModel],
+                autoExpandMS: 750,
+                onActivate: function (node) {
+                    // if we click a node, simply open a dialog to enter it's parameters
+                    self.trigger('node-clicked', node);
+                }
+            });
+
+            this.$el.empty();
+            tree.appendTo(this.$el);
+            tree.dynatree("getRoot").visit(function (node) {
+                node.expand(true);
+            });
+        }
+    });
+
+    my.DraggableGroup = Backbone.View.extend({
+        initialize: function () {
+            this.collection.bind('remove', this.render, this);
+            this.collection.bind('add', this.render, this);
+        },
+        render: function () {
+            var self = this;
+            var div = $('<div />');
+            if (this.collection.length == 0) {
+                $('<p></p>').text("No items found!").appendTo(div);
+            }
+            for (var i = 0; i < this.collection.length; i++) {
+                new my.DraggableView({ model: this.collection.models[i], el: div }).render();
+            }
+
+            this.$el.empty();
+            div.appendTo(this.$el);
+        }
+    });
+
+
+    my.DraggableView = Backbone.View.extend({
+        render: function () {
+            var late = _.template($("#draggable_template").html(), this.model.attributes);
+            $(late).draggable({
+                revert: true,
+                connectToDynatree: true,
+                cursorAt: { top: -5, left: -5 },
+                helper: "clone"
+            }).appendTo(this.$el);
+        }
+    });
+
+    my.SelectableGroup = Backbone.View.extend({
+        initialize: function () {
+            this.collection.bind('remove', this.render, this);
+            this.collection.bind('add', this.render, this);
+            this.collection.bind('change', this.render, this);
+        },
+        render: function () {
+            var self = this;
+            var div = $('<div />');
+            if (this.collection.length == 0) {
+                $('<p></p>').text("No experiments found!").appendTo(div);
+            }
+
+            for (var i = 0; i < this.collection.length; i++) {
+                new my.SelectableView({ model: this.collection.models[i], el: div }).render();
+            }
+            this.$el.empty();
+            div.selectable({
+                filter: 'div',
+                selected: function (event, ui) {
+                    self.selected(event, ui);
+                }
+            }).appendTo(this.$el);
+        },
+        selected: function (event, ui) {
+            var nodeId = $(ui.selected).attr('id');
+            this.trigger('node-selected', nodeId);
+        }
+    });
+
+    my.SelectableView = Backbone.View.extend({
+        render: function () {
+            var late = _.template($("#draggable_template").html(), this.model.attributes);
+            $(late).appendTo(this.$el);
+        }
+    });
+
+    my.StepWizardView = Backbone.View.extend({
+        render: function () {
+            var self = this;
+            this.$el.smartWizard({
+                onLeaveStep: function (step) {
+                    var stepNum = parseInt(step.attr("rel"));
+                    return self.validateStep(stepNum);
                 },
-                onDragOver: function (node, sourceNode, hitMode) {
-                    return node.data.title !== "Experiment" || hitMode === "over";
+                onShowStep: function (step) {
+                    var stepNum = parseInt(step.attr("rel"));
+                    return self.showStep(stepNum);
                 },
-                onDrop: function (node, sourceNode, hitMode, ui, draggable) {
-                    if (hitMode !== 'over')
-                        return;
-                    var modelNode = ExperimentNode.lookup(node.data.key);
-                    if (sourceNode) {
-                        var sourceModelNode = ExperimentNode.lookup(sourceNode.data.key);
-                        sourceNode.move(node, hitMode);
-                        // move node into the modelNode
-                        sourceModelNode.moveNode(modelNode);
-                    }
-                    else {
-                        var elem = $(draggable.element[0]);
-                        var newNode = { nodeId: elem.attr('id'), isExperiment: elem.attr('data-isExperiment') === 'true', title: elem.attr('data-name'), key: ExperimentNode.nextGlobalKey() };
-                        if (hitMode == "over") {
-                            node.addChild(newNode);
-                            node.expand(true);
-                            // update the data model
-                            newNode = modelNode.addNode(newNode);
-                            self.trigger('node-added', newNode);
-                        }
-                    }
-                    self.trigger('structure-changed', modelNode);
-                }
-            }
-        });
-        this.tree.dynatree("getRoot").visit(function (node) {
-            node.expand(true);
-        });
-    },
-    initialize: function (spec) {
-        this.renderTree(spec.model);
-    },
-    events: {
-        'click .remove-button': 'doRemove',
-        'click .variate-button': 'doVariate'
-    },
-    render: function () {
-        this.$el.empty();
-        this.renderTree(this.model);
-        var content = $(_.template($('#stepwizard_template').html(), {}));
-        this.tree.appendTo(this.$el);
-        content.appendTo(this.$el);
-    },
-    doRemove: function () {
-        var node = this.tree.dynatree('getActiveNode');
-        if (node && node.parent.parent != null) {
-            var nxt = node.getNextSibling();
-            if (nxt == null)
-                nxt = node.getPrevSibling();
-            if (nxt == null)
-                nxt = node.getParent();
-            node.remove();
-            ExperimentNode.lookup(node.data.key).remove();
-            if (nxt) {
-                this.tree.dynatree("getTree").activateKey(nxt.data.key);
-            }
-        }
-        this.trigger('structure-changed', node);
-    },
-    doVariate: function () {
-        var node = this.tree.dynatree('getActiveNode');
-        var modelNode = ExperimentNode.lookup(node.data.key);
-        this.trigger('variation-request', {
-            parentNode: node.parent,
-            model: modelNode
-        });
-    }
-});
-
-var ExperimentDetailsTreeView = Backbone.View.extend({
-  render: function () {
-    var jsonModel = this.model.toJSON();
-    var self = this;
-    var tree = $('<div />').dynatree({
-      children: [jsonModel],
-      autoExpandMS: 750,
-      onActivate: function (node) {
-        // if we click a node, simply open a dialog to enter it's parameters
-        self.trigger('node-clicked', node);
-      }
-    });
-
-    this.$el.empty();
-    tree.appendTo(this.$el);
-    tree.dynatree("getRoot").visit(function (node) {
-        node.expand(true);
-    });
-  }
-});
-
-var DraggableGroup = Backbone.View.extend({
-    render: function () {
-        var self = this;
-        var div = $('<div />');
-
-        for (var i = 0; i < this.model.length; i++) {
-            new DraggableView({ model: this.model.models[i], el: div }).render();
-        }
-
-        this.$el.empty();
-        div.appendTo(this.$el);
-    }
-});
-
-
-var DraggableView = Backbone.View.extend({
-  render: function () {
-    var late = _.template($("#draggable_template").html(), this.model.attributes);    
-    $(late).draggable({
-      revert: true,
-      connectToDynatree: true,
-      cursorAt: { top: -5, left: -5 },
-      helper: "clone"
-    }).appendTo(this.$el);
-  }
-});
-
-var SelectableGroup = Backbone.View.extend({
-    render: function () {
-        var self = this;
-        var div = $('<div />');
-        for (var i = 0; i < this.model.length; i++) {
-            new SelectableView({ model: this.model.models[i], el: div }).render();
-        }
-        this.$el.empty();
-        div.selectable({
-            filter: 'div',
-            selected: function (event, ui) {
-                self.selected(event, ui);
-            }
-        }).appendTo(this.$el);
-    },
-    selected: function (event, ui) {
-        var nodeId = $(ui.selected).attr('id');
-        this.trigger('node-selected', nodeId);
-    }
-});
-
-var SelectableView = Backbone.View.extend({
-    render: function () {
-        var late = _.template($("#draggable_template").html(), this.model.attributes);
-        $(late).appendTo(this.$el);
-    }
-});
-
-var StepWizardView = Backbone.View.extend({
-    render: function () {
-        var self = this;
-        this.$el.smartWizard({
-            onLeaveStep: function (step) {
-                var stepNum = parseInt(step.attr("rel"));
-                return self.validateStep(stepNum);
-            },
-            onShowStep: function (step) {
-                var stepNum = parseInt(step.attr("rel"));
-                return self.showStep(stepNum);
-            },
-            onFinish: function () {
-                self.trigger('experiment-finished');
-            }
-        });
-    },
-    validateStep: function (stepNumber) {
-        var validationModel = {
-            stepNumber: stepNumber,
-            succeeded: true
-        };
-        this.trigger('step-validated', validationModel);
-        return validationModel.succeeded;
-    },
-    showStep: function (stepNumber) {
-        this.trigger('step-shown', stepNumber);
-        return true;
-    }
-});
-
-var ParameterWizard = Backbone.View.extend({
-  createWizard: function (steps) {
-    // use template instead of jquery?!
-    var newWizard = $('<div />').addClass('wizard swMain');
-    var stepMenu = $('<ul />');
-    var prefix = name + '_';
-    for (var i = 0; i < steps.length; i++) {
-      var step = steps[i];
-      var a = $('<a></a>', { href: '#' + prefix + (i + 1) });
-      $('<label />').addClass("stepNumber").text((i + 1)).appendTo(a);
-      $('<span />').addClass("stepDesc").html(step.heading + '<br /><small>' + step.description + '</small>').appendTo(a);
-      var li = $('<li />').append(a);
-      li.appendTo(stepMenu);
-    }
-    stepMenu.appendTo(newWizard);
-    for (var i = 0; i < steps.length; i++) {
-      var div = $('<div />', { id: prefix + (i + 1) });
-      if (steps[i].content && steps[i].content != null)
-        div.append(steps[i].content);
-      div.appendTo(newWizard);
-    }
-    return newWizard;
-  },
-  render: function () {
-    var self = this;
-    this.$el.empty();
-    var data = this.model.get('data');
-
-    var hasProblemParameters = typeof data.ProblemParameters !== 'undefined';
-    var dialog = $('<div />');
-    var algoDiv = $('<div />');
-    var problemDiv = $('<div />');
-
-    for (var i = 0; i < data.AlgorithmParameters.length; i++) {
-      var parameterView = new ParameterEditableView({ model: data.AlgorithmParameters[i] });
-      // render to dialog
-      parameterView.render();
-      parameterView.$el.appendTo(algoDiv);
-    }
-
-    if (hasProblemParameters) {
-      var problemParameters = data.ProblemParameters;
-      for (var i = 0; i < problemParameters.length; i++) {
-        var parameterView = new ParameterEditableView({ model: problemParameters[i] });
-        // render to dialog
-        parameterView.render();
-        parameterView.$el.appendTo(problemDiv);
-      }
-    }
-
-    var newWizard =
-        hasProblemParameters ?
-          this.createWizard([
-            { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoDiv },
-            { heading: "Problem Parameters", description: "Adjust problem parameters", content: problemDiv }
-          ]) :
-          this.createWizard([
-            { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoDiv }
-          ]);
-
-    newWizard.appendTo(this.$el);
-    newWizard.smartWizard({
-      onFinish: function () {
-        self.trigger('parameters-finished');
-      }
-    });
-  }
-});
-
-var ParameterEditableView = Backbone.View.extend({
-    events: {
+                onFinish: function () {
+                    self.trigger('experiment-finished');
+                }
+            });
+        },
+        validateStep: function (stepNumber) {
+            var validationModel = {
+                stepNumber: stepNumber,
+                succeeded: true
+            };
+            this.trigger('step-validated', validationModel);
+            return validationModel.succeeded;
+        },
+        showStep: function (stepNumber) {
+            this.trigger('step-shown', stepNumber);
+            return true;
+        }
+    });
+
+    my.ParameterWizard = Backbone.View.extend({
+        createWizard: function (steps) {
+            // use template instead of jquery?!
+            var newWizard = $('<div />').addClass('wizard swMain');
+            var stepMenu = $('<ul />');
+            var prefix = name + '_';
+            for (var i = 0; i < steps.length; i++) {
+                var step = steps[i];
+                var a = $('<a></a>', { href: '#' + prefix + (i + 1) });
+                $('<label />').addClass("stepNumber").text((i + 1)).appendTo(a);
+                $('<span />').addClass("stepDesc").html(step.heading + '<br /><small>' + step.description + '</small>').appendTo(a);
+                var li = $('<li />').append(a);
+                li.appendTo(stepMenu);
+            }
+            stepMenu.appendTo(newWizard);
+            for (var i = 0; i < steps.length; i++) {
+                var div = $('<div />', { id: prefix + (i + 1) });
+                if (steps[i].content && steps[i].content != null)
+                    div.append(steps[i].content);
+                div.appendTo(newWizard);
+            }
+            return newWizard;
+        },
+        render: function () {
+            var self = this;
+            this.$el.empty();
+            var data = this.model.get('data');
+
+            var hasProblemParameters = typeof data.ProblemParameters !== 'undefined';
+            var dialog = $('<div />');
+            var algoDiv = $('<div />');
+            var problemDiv = $('<div />');
+
+            for (var i = 0; i < data.AlgorithmParameters.length; i++) {
+                var parameterView = new my.ParameterEditableView({ model: data.AlgorithmParameters[i] });
+                // render to dialog
+                parameterView.render();
+                parameterView.$el.appendTo(algoDiv);
+            }
+
+            if (hasProblemParameters) {
+                var problemParameters = data.ProblemParameters;
+                for (var i = 0; i < problemParameters.length; i++) {
+                    var parameterView = new my.ParameterEditableView({ model: problemParameters[i] });
+                    // render to dialog
+                    parameterView.render();
+                    parameterView.$el.appendTo(problemDiv);
+                }
+            }
+
+            var newWizard =
+          hasProblemParameters ?
+            this.createWizard([
+              { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoDiv },
+              { heading: "Problem Parameters", description: "Adjust problem parameters", content: problemDiv }
+            ]) :
+            this.createWizard([
+              { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoDiv }
+            ]);
+
+            newWizard.appendTo(this.$el);
+            newWizard.smartWizard({
+                onFinish: function () {
+                    self.trigger('parameters-finished');
+                }
+            });
+        }
+    });
+
+    my.ParameterEditableView = Backbone.View.extend({
+        /*events: {
         'change': 'valueChanged'
-    },
-    render: function () {
-        var mapper = new DatatypeMapper();
-        var content = $(_.template($('#parameter_template').html(), this.model));
-        mapper.mapHtml(this.model).appendTo($('.rightEntry', content));
-        content.appendTo(this.$el);
-    },
-    valueChanged: function (param) {
-        var value = $(param.target).val();
-        if (!isNaN(value))
-            value = parseFloat(value);
-        var name = $(param.target).attr("name");
-        // normally a controller would do this, just for once, let the view update the model
-        var splitted = name.split("_");
-        if (splitted.length == 1) {
-            this.model.Value = value;
-        } else if (splitted.length == 2) {
-            this.model.Value[parseInt(splitted[1])] = value;
-        } else if (splitted.length == 3) {
-            this.model.Value[parseInt(splitted[1])][parseInt(splitted[2])] = value;
-        }
-    }
-});
-
-
-var LoadingDialog = Backbone.View.extend({
-    initialize: function () {
-        this.reset();
-    },
-    render: function () {
-        var self = this;
-        this.$el.empty();
-        var dialog = $('<div />');
-        this.content.appendTo(dialog);
-        dialog.appendTo(this.$el);
-        this.$el.dialog({
-            autoOpen: true
-        });
-    },
-    text: function (txt) {
-        $('p', this.$el).text(txt);
-    },
-    setLoading: function(isLoading) {
-      if (isLoading)
-        $('img', this.$el).show();
-      else
-        $('img', this.$el).hide();
-    },
-    reset: function () {
-        this.content = $(_.template($('#loading_template').html(), {}));
-    },
-    setContent: function (el) {
-        this.content = el;
-    },
-    close: function () {
-        this.$el.dialog("close");
-    }
-});
-
-
-var ParameterDialog = Backbone.View.extend({
-  render: function () {
-    var self = this;
-
-    this.$el.empty();
-    var data = this.model.get('data');
-
-    var hasProblemParameters = typeof data.ProblemParameters !== 'undefined';
-    var dialog = $('<div />');
-
-    var parameterWizard = new ParameterWizard({ model: this.model, el: dialog });
-    parameterWizard.render();
-    this.listenTo(parameterWizard, 'parameters-finished', function () {
-      self.trigger('parameters-finished');
-    });
-    dialog.appendTo(this.$el);
-    this.$el.dialog({
-      autoOpen: true,
-      width: 1024,
-      height: 768
-    });
-  },
-  close: function () {
-    this.$el.dialog("close");
-  }
-});
-
-var ExperimentDetailsView = Backbone.View.extend({
-    events: {
-        'change': 'valueChanged'
-    },
-    valueChanged: function (param) {
-        var value = $(param.target).val();
-        if (!isNaN(value))
-            value = parseFloat(value);
-        var name = $(param.target).attr("name");
-        if (name == 'Name')
-            this.model.set({ title: value });
-        else if (name == 'RunImmediately')
-            this.model.set({ run: $(param.target).is(':checked') });
-        else if (name == 'Repititions')
-            this.model.set({ repititions: value });
-        else if (name == 'Group')
-            this.model.set({ group: value });
-
-        if (this.model.get('run')) {
-            $('input[name="Repititions"]', this.$el).removeAttr('disabled');
-            $('input[name="Group"]', this.$el).removeAttr('disabled');
-        } else {
-            $('input[name="Repititions"]', this.$el).attr('disabled', 'disabled');
-            $('input[name="Group"]', this.$el).attr('disabled', 'disabled');
-        }
-    },
-    render: function () {
-        $('input[name="Name"]', this.$el).val(this.model.get('title'));
-        $('input[name="RunImmediately"]', this.$el).attr('checked', this.model.get('run'));
-        $('input[name="Repititions"]', this.$el).val(this.model.get('repititions'));
-        $('input[name="Group"]', this.$el).val(this.model.get('group'));
-    }
-});
-
-var ValidationHintsView = Backbone.View.extend({
-    render: function () {
-        var template = _.template($('#validationhints_template').html(), this.model);
-        $(template).dialog({
-            resizable: false,
-            modal: true,
-            buttons: {
-                "OK": function () {
-                    $(this).dialog("close");
-                }
-            }
-        });
-    }
-});
-
-// ========== Variation Dialog Views ============
-
-var VariationDialog = Backbone.View.extend({
-    initialize: function (spec) {
-
-    },
-    events: {
-        'change': 'entrySelected'
-    },
-    render: function () {
-        var self = this;
-        var dialog = $(_.template($('#variationdialog_template').html(), {}));
-
-        var content = $('select[class="variationDialogContent"]', dialog);
-        var data = this.model.get('data');
-        for (var i = 0; i < data.AlgorithmParameters.length; i++) {
-            data.AlgorithmParameters[i].Index = i;
-            var entry = new VariationEntryView({ model: data.AlgorithmParameters[i], el: content });
-            entry.render();
-        }
-
-        this.details = $('div[class="variationDetails"]', dialog);
-        this.activateButton = $('input[name="active"]', dialog);
-        this.activateButton.change(function (evt) {
-            var checked = $(evt.target).is(':checked');
-            if (self.selectedModel && self.selectedModel != null) {
-                self.selectedModel.Active = checked;
-            }
-        });
-        dialog.dialog({
-            height: 300,
-            buttons: {
-                "Abort": function () {
-                    $(this).dialog("close");
-                },
-                "OK": function () {
-                    self.generateVariations();
-                    $(this).dialog("close");
-                }
-            }
-        });
-
-        content.change(function (evt) {
-            var optionSelected = $("option:selected", this);
-            var model = self.model.get('data').AlgorithmParameters[parseInt($(optionSelected).attr('data-index'))]
-            self.entrySelected(model);
-        });
-
-        this.variationDetails = new VariationContentView({ el: this.details });
-        var model = this.model.get('data').AlgorithmParameters[0];
-        this.entrySelected(model);
-    },
-    entrySelected: function (model) {
-        this.selectedModel = model;
-        if (model.Active)
-            this.activateButton.attr('checked', 'checked');
-        else
-            this.activateButton.removeAttr('checked');
-        this.variationDetails.model = model;
-        this.details.empty();
-        this.variationDetails.render();
-    },
-    generateVariations: function () {
-        this.solutions = [];
-        this.exhaust(0, []);
-        this.trigger('variations-generated', this.solutions);
-    },
-    exhaust: function (index, element) {
-        if (index == this.model.get('data').AlgorithmParameters.length) {
-            // we found a solution! store it by creating a deep copy
-            this.solutions.push($.extend(true, [], element));
-            return;
-        }
-
-        var currentParameter = this.model.get('data').AlgorithmParameters[index];
-        if (currentParameter.Active && currentParameter.Generated) {
-            for (var i = 0; i < currentParameter.Generated.length; i++) {
+        },*/
+        render: function () {
+            var mapper = new my.DatatypeMapper();
+            var content = $(_.template($('#parameter_template').html(), this.model));
+            mapper.mapHtml(this.model, $('.rightEntry', content));
+            content.appendTo(this.$el);
+        } /*,
+        valueChanged: function (param) {
+            var value = $(param.target).val();
+            if (!isNaN(value))
+                value = parseFloat(value);
+            var name = $(param.target).attr("name");
+            // normally a controller would do this, just for once, let the view update the model
+            var splitted = name.split("_");
+            if (splitted.length == 1) {
+                this.model.Value = value;
+            } else if (splitted.length == 2) {
+                this.model.Value[parseInt(splitted[1])] = value;
+            } else if (splitted.length == 3) {
+                this.model.Value[parseInt(splitted[1])][parseInt(splitted[2])] = value;
+            }
+        }*/
+    });
+
+
+    my.LoadingDialog = Backbone.View.extend({
+        initialize: function () {
+            this.reset();
+        },
+        render: function () {
+            var self = this;
+            this.$el.empty();
+            var dialog = $('<div />');
+            this.content.appendTo(dialog);
+            dialog.appendTo(this.$el);
+            this.$el.dialog({
+                autoOpen: true
+            });
+        },
+        text: function (txt) {
+            $('p', this.$el).text(txt);
+        },
+        setLoading: function (isLoading) {
+            if (isLoading)
+                $('img', this.$el).show();
+            else
+                $('img', this.$el).hide();
+        },
+        reset: function () {
+            this.content = $(_.template($('#loading_template').html(), {}));
+        },
+        setContent: function (el) {
+            this.content = el;
+        },
+        close: function () {
+            this.$el.dialog("close");
+        }
+    });
+
+
+    my.ParameterDialog = Backbone.View.extend({
+        render: function () {
+            var self = this;
+
+            this.$el.empty();
+            var data = this.model.get('data');
+
+            var hasProblemParameters = typeof data.ProblemParameters !== 'undefined';
+            var dialog = $('<div />');
+
+            var parameterWizard = new my.ParameterWizard({ model: this.model, el: dialog });
+            parameterWizard.render();
+            this.listenTo(parameterWizard, 'parameters-finished', function () {
+                self.trigger('parameters-finished');
+            });
+            dialog.appendTo(this.$el);
+            this.$el.dialog({
+                autoOpen: true,
+                width: 1024,
+                height: 768
+            });
+        },
+        close: function () {
+            this.$el.dialog("close");
+        }
+    });
+
+    my.ExperimentDetailsView = Backbone.View.extend({
+        events: {
+            'change': 'valueChanged'
+        },
+        valueChanged: function (param) {
+            var value = $(param.target).val();
+            if (!isNaN(value))
+                value = parseFloat(value);
+            var name = $(param.target).attr("name");
+            if (name == 'Name')
+                this.model.set({ title: value });
+            else if (name == 'RunImmediately')
+                this.model.set({ run: $(param.target).is(':checked') });
+            else if (name == 'Repititions')
+                this.model.set({ repititions: value });
+            else if (name == 'Group')
+                this.model.set({ group: value });
+
+            if (this.model.get('run')) {
+                $('input[name="Repititions"]', this.$el).removeAttr('disabled');
+                $('input[name="Group"]', this.$el).removeAttr('disabled');
+            } else {
+                $('input[name="Repititions"]', this.$el).attr('disabled', 'disabled');
+                $('input[name="Group"]', this.$el).attr('disabled', 'disabled');
+            }
+        },
+        render: function () {
+            $('input[name="Name"]', this.$el).val(this.model.get('title'));
+            $('input[name="RunImmediately"]', this.$el).attr('checked', this.model.get('run'));
+            $('input[name="Repititions"]', this.$el).val(this.model.get('repititions'));
+            $('input[name="Group"]', this.$el).val(this.model.get('group'));
+        }
+    });
+
+    my.ValidationHintsView = Backbone.View.extend({
+        render: function () {
+            var template = _.template($('#validationhints_template').html(), this.model);
+            $(template).dialog({
+                resizable: false,
+                modal: true,
+                buttons: {
+                    "OK": function () {
+                        $(this).dialog("close");
+                    }
+                }
+            });
+        }
+    });
+
+    // ========== Variation Dialog Views ============
+
+    my.VariationDialog = Backbone.View.extend({
+        initialize: function (spec) {
+
+        },
+        events: {
+            'change': 'entrySelected'
+        },
+        render: function () {
+            var self = this;
+            var dialog = $(_.template($('#variationdialog_template').html(), {}));
+
+            var content = $('select[class="variationDialogContent"]', dialog);
+            var data = this.model.get('data');
+            for (var i = 0; i < data.AlgorithmParameters.length; i++) {
+                data.AlgorithmParameters[i].Index = i;
+                var entry = new my.VariationEntryView({ model: data.AlgorithmParameters[i], el: content });
+                entry.render();
+            }
+
+            this.details = $('div[class="variationDetails"]', dialog);
+            this.activateButton = $('input[name="active"]', dialog);
+            this.activateButton.change(function (evt) {
+                var checked = $(evt.target).is(':checked');
+                if (self.selectedModel && self.selectedModel != null) {
+                    self.selectedModel.Active = checked;
+                }
+
+                if (self.selectedModel.Active) {
+                    $('*', self.details).removeAttr('disabled');
+                }
+                else {
+                    //$('input,button,select', self.details).attr('disabled', 'disabled');
+                    $('*', self.details).attr('disabled', 'disabled');
+                }
+            });
+            dialog.dialog({
+                height: 300,
+                buttons: {
+                    "Abort": function () {
+                        $(this).dialog("close");
+                    },
+                    "OK": function () {
+                        self.generateVariations();
+                        $(this).dialog("close");
+                    }
+                }
+            });
+
+            content.change(function (evt) {
+                var optionSelected = $("option:selected", this);
+                var model = self.model.get('data').AlgorithmParameters[parseInt($(optionSelected).attr('data-index'))]
+                self.entrySelected(model);
+            });
+
+            this.variationDetails = new my.VariationContentView({ el: this.details });
+            var model = this.model.get('data').AlgorithmParameters[0];
+            this.entrySelected(model);
+        },
+        entrySelected: function (model) {
+            this.selectedModel = model;
+            this.variationDetails.model = model;
+            this.details.empty();
+            this.variationDetails.render();
+            if (model.Active) {
+                this.activateButton.attr('checked', 'checked');
+                $('*', this.details).removeAttr('disabled');
+            }
+            else {
+                this.activateButton.removeAttr('checked');
+                $('*', this.details).attr('disabled', 'disabled');
+            }
+        },
+        generateVariations: function () {
+            this.solutions = [];
+            this.exhaust(0, []);
+            this.trigger('variations-generated', this.solutions);
+        },
+        exhaust: function (index, element) {
+            if (index == this.model.get('data').AlgorithmParameters.length) {
+                // we found a solution! store it by creating a deep copy
+                this.solutions.push($.extend(true, [], element));
+                return;
+            }
+
+            var currentParameter = this.model.get('data').AlgorithmParameters[index];
+            if (currentParameter.Active && currentParameter.Generated) {
+                for (var i = 0; i < currentParameter.Generated.length; i++) {
+                    element[index] = {
+                        Name: currentParameter.Name,
+                        Value: currentParameter.Generated[i]
+                    };
+                    if (currentParameter.Options) {
+                        element[index].Options = currentParameter.Options;
+                    }
+                    this.exhaust(index + 1, element);
+                }
+            } else {
                 element[index] = {
                     Name: currentParameter.Name,
-                    Value: currentParameter.Generated[i]
+                    Value: currentParameter.Value
                 };
                 if (currentParameter.Options) {
@@ -502,210 +540,334 @@
                 this.exhaust(index + 1, element);
             }
-        } else {
-            element[index] = {
-                Name: currentParameter.Name,
-                Value: currentParameter.Value
-            };
-            if (currentParameter.Options) {
-                element[index].Options = currentParameter.Options;
-            }
-            this.exhaust(index + 1, element);
-        }
-    }
-});
-
-var TableEditView = Backbone.View.extend({
-    events: {
-        'change': 'valueChanged',
-        'click button[data-operation="Add"]': 'addClicked',
-        'click button[data-operation="Remove"]': 'removeClicked'
+        }
+    });
+
+    my.TableEditView = Backbone.View.extend({
+        events: {
+            'change': 'valueChanged',
+            'click button[data-operation="Add"]': 'addClicked',
+            'click button[data-operation="Remove"]': 'removeClicked'
+        },
+        render: function () {
+            this.$el.empty();
+            // http: //stackoverflow.com/questions/8749236/create-table-with-jquery-append
+            var table = $('<table></table>').addClass('editableTable');
+
+            // determine dimensions
+            var rows = this.model.length;
+            var columns = 1;
+            if ($.isArray(this.model[0])) {
+                columns = this.model[0].length;
+            }
+
+            // create head elements
+            var head = $('<thead></thead>');
+            var headerRow = $('<tr></tr>');
+            headerRow.appendTo(head);
+            if (this.options.rowNames) {
+                var rowNames = this.options.rowNames;
+                for (var i = 0; i < rowNames.length; i++) {
+                    $('<td />').text(rowNames[i]).appendTo(headerRow);
+                }
+            } else {
+                for (var i = 0; i < columns; i++) {
+                    $('<td />').text((i + 1) + '. Column').appendTo(headerRow);
+                }
+            }
+            head.appendTo(table);
+
+            // create body
+            var body = $('<tbody></tbody>');
+
+            for (var i = 0; i < rows; i++) {
+                var row = $('<tr></tr>');
+                for (var j = 0; j < columns; j++) {
+                    var rowContent = this.model[i];
+                    var columnEntry = $.isArray(rowContent) ? rowContent[j] : rowContent;
+                    var col = $('<td></td>');
+                    if (this.options.editable) {
+                        $('<input type="text" name="' + i + '_' + j + '" />').val(columnEntry).appendTo(col);
+                    } else {
+                        col.text(columnEntry);
+                    }
+                    col.appendTo(row);
+                }
+                if (this.options.editable) {
+                    $('<button data-operation="Add" name="' + i + '" />').val(columnEntry).text('+').appendTo(col);
+                    $('<button data-operation="Remove" name="' + i + '" />').val(columnEntry).text('-').appendTo(col);
+                }
+                row.appendTo(body);
+            }
+            body.appendTo(table);
+
+            table.appendTo(this.$el);
+            if (this.options.useDatatable)
+                table.dataTable();
+        },
+        valueChanged: function (evt) {
+            var target = $(evt.target);
+            var value = target.val();
+            var index = target.attr('name');
+            var splittedName = index.split('_');
+            var i = parseInt(splittedName[0]);
+            var j = parseInt(splittedName[1]);
+            if ($.isArray(this.model[i])) {
+                this.model[i][j] = parseFloat(value);
+            } else {
+                this.model[i] = parseFloat(value);
+            }
+        },
+        addClicked: function (evt) {
+            var target = $(evt.target);
+            var index = target.attr('name');
+            var i = parseInt(index);
+            if ($.isArray(this.model[i])) {
+                var cpy = [];
+                for (var j = 0; j < this.model[i].length; j++) {
+                    cpy.push(this.model[i][j]);
+                }
+                this.model.splice(i, 0, cpy);
+            } else {
+                this.model.splice(i, 0, this.model[i]);
+            }
+            // render after model changes
+            this.render();
+        },
+        removeClicked: function (evt) {
+            var target = $(evt.target);
+            var index = target.attr('name');
+            var i = parseInt(index);
+            this.model.splice(i, 1);
+            // render after model changes
+            this.render();
+        }
+    });
+
+    my.NumberEditableView = Backbone.View.extend({
+        events: {
+            'change': 'valueChanged'
+        },
+        render: function () {
+            $('<input type="text" />').val(this.model.Value).appendTo(this.$el);
+
+        },
+        valueChanged: function (evt) {
+            var value = $(evt.target).val();
+            if (!isNaN(value)) {
+                value = parseFloat(value);
+                this.model.Value = value;
+            } else {
+                $('input', this.$el).val(this.model.Value);
+            }
+        }
+    });
+
+    my.SelectionView = Backbone.View.extend({
+        events: {
+            'change': 'checked'
+        },
+        render: function () {
+            this.$el.empty();
+            var s = $('<select />').attr('data-name', this.model.Name).appendTo(this.$el);
+            for (var i = 0; i < this.model.Options.length; i++) {
+                $('<option />', { value: this.model.Options[i], text: this.model.Options[i] }).appendTo(s);
+            }
+            s.val(this.model.Value);
+        },
+        checked: function (evt) {
+            var value = $(evt.target).val();
+            var name = $(evt.target).attr('data-name')
+            this.trigger('selected', { name: name, value: value });
+        }
+    });
+
+    my.OptionSelectionView = Backbone.View.extend({
+        events: {
+            'change': 'checked'
+        },
+        render: function () {
+            this.$el.empty();
+            if ($.isArray(this.model)) {
+                for (var i = 0; i < this.model.length; i++) {
+                    $(_.template($('#checkbox_template').html(), { checked: false, name: this.model[i], text: this.model[i], hideText: this.options.hideText })).appendTo(this.$el);
+                }
+            }
+            else {
+                $(_.template($('#checkbox_template').html(), { checked: this.model, name: this.model, text: this.model, hideText: this.options.hideText })).appendTo(this.$el);
+            }
+        },
+        checked: function (evt) {
+            var checked = $(evt.target).is(':checked');
+            var name = $(evt.target).attr('name')
+            this.trigger('changed', { name: name, checked: checked });
+        }
+    });
+
+
+    my.PlotView = Backbone.View.extend({
+        render: function () {
+            this.$el.empty();
+            var plotLabels = undefined;
+            if (this.model.RowNames) {
+                plotLabels = [];
+                for (var i = 0; i < this.model.RowNames.length; i++) {
+                    plotLabels.push({ label: this.model.RowNames[i] });
+                }
+            }
+
+            var values = this.model.Value ? this.model.Value : this.model;
+
+            var plotValues = [];
+            if ($.isArray(values[0])) {
+                var columnCount = values[0].length;
+                var colVals = {};
+                for (var i = 0; i < columnCount; i++)
+                    colVals[i] = [];
+
+                for (var i = 0; i < values.length; i++) {
+                    for (var j = 0; j < columnCount; j++) {
+                        colVals[j].push(values[i][j]);
+                    }
+                }
+
+                for (var i = 0; i < columnCount; i++) {
+                    plotValues.push(colVals[i]);
+                }
+            } else {
+                plotValues.push(values);
+            }
+
+            if (!this.$el.attr('id')) {
+                this.$el.attr('id', my.PlotView.nextId());
+            }
+
+            this.$el.css('width', '500px');
+
+            this.plot = $.jqplot(this.$el.attr('id'), plotValues, {
+                cursor: {
+                    show: true,
+                    zoom: true,
+                    showTooltip: false
+                },
+                series: plotLabels,
+                seriesDefaults: {
+                    lineWidth: 1.5,
+                    markerOptions: {
+                        size: 2,
+                        lineWidth: 2
+                    }
+                },
+                legend: {
+                    show: true,
+                    placement: 'outsideGrid'
+                },
+                highlighter: {
+                    show: true,
+                    sizeAdjust: 7.5
+                }
+            });
+        },
+        refresh: function () {
+            if (this.plot)
+                this.plot.replot({ resetAxes: true });
+        }
     },
-    render: function () {
-        this.$el.empty();
-        // http: //stackoverflow.com/questions/8749236/create-table-with-jquery-append
-        var table = $('<table></table>').addClass('editableTable');
-
-        // determine dimensions
-        var rows = this.model.length;
-        var columns = 1;
-        if ($.isArray(this.model[0])) {
-            columns = this.model[0].length;
-        }
-
-        // create head elements
-        var head = $('<thead></thead>');
-        var headerRow = $('<tr></tr>');
-        headerRow.appendTo(head);
-        for (var i = 0; i < columns; i++) {
-            $('<td />').text((i + 1) + '. Column').appendTo(headerRow);
-        }
-        head.appendTo(table);
-
-        // create body
-        var body = $('<tbody></tbody>');
-
-        for (var i = 0; i < rows; i++) {
-            var row = $('<tr></tr>');
-            for (var j = 0; j < columns; j++) {
-                var rowContent = this.model[i];
-                var columnEntry = $.isArray(rowContent) ? rowContent[j] : rowContent;
-                var col = $('<td></td>');
-                $('<input type="text" name="' + i + '_' + j + '" />').val(columnEntry).appendTo(col);
-                col.appendTo(row);
-            }
-            if (this.options.editable) {
-                $('<button data-operation="Add" name="' + i + '" />').val(columnEntry).text('+').appendTo(col);
-                $('<button data-operation="Remove" name="' + i + '" />').val(columnEntry).text('-').appendTo(col);
-            }
-            row.appendTo(body);
-        }
-        body.appendTo(table);
-        table.appendTo(this.$el);
-    },
-    valueChanged: function (evt) {
-        var target = $(evt.target);
-        var value = target.val();
-        var index = target.getattr('name');
-        var splittedName = index.split('_');
-        var i = parseInt(splittedName[0]);
-        var j = parseInt(splittedName[1]);
-        if ($.isArray(this.model[i])) {
-            this.model[i][j] = parseFloat(value);
-        } else {
-            this.model[i] = parseFloat(value);
-        }
-    },
-    addClicked: function (evt) {
-        var target = $(evt.target);
-        var index = target.attr('name');
-        var i = parseInt(index);
-        if ($.isArray(this.model[i])) {
-            var cpy = [];
-            for (var j = 0; j < this.model[i].length; j++) {
-                cpy.push(this.model[i][j]);
-            }
-            this.model.splice(i, 0, cpy);
-        } else {
-            this.model.splice(i, 0, this.model[i]);
-        }
-        // render after model changes
-        this.render();
-    },
-    removeClicked: function (evt) {
-        var target = $(evt.target);
-        var index = target.attr('name');
-        var i = parseInt(index);
-        this.model.splice(i, 1);
-        // render after model changes
-        this.render();
-    }
-});
-
-var OptionSelectionView = Backbone.View.extend({
-    events: {
-        'change': 'checked'
-    },
-    render: function () {
-        this.$el.empty();
-
-        for (var i = 0; i < this.model.length; i++) {
-            $(_.template($('#checkbox_template').html(), { name: this.model[i], text: this.model[i] })).appendTo(this.$el);
-        }
-    },
-    checked: function (evt) {
-        var checked = $(evt.target).is(':checked');
-        var name = $(evt.target).attr('name')
-        this.trigger('changed', { name: name, checked: checked });
-    }
-});
-
-var VariationContentView = Backbone.View.extend({
-    render: function () {
-        var self = this;
-        if (this.model.Value === 'false' || this.model.Value === 'true' ||
-            this.model.Value === true || this.model.Value === false) {
-            $(_.template($('#variation_boolean_template').html(), {})).appendTo(this.$el);
-            this.model.Generated = [false, true];
-        }
-        else if (!isNaN(this.model.Value)) {
-            var elem = $(_.template($('#variation_number_template').html(), {}));
-            elem.appendTo(this.$el)
-            $('input[name="generate"]', elem).click(function (evt) { self.openGenerator(evt); });
-            if (!this.model.Generated) {
-                this.model.Generated = [0, 1, 2];
-            }
-            var tev = new TableEditView({ model: this.model.Generated, el: $('div div', this.$el), editable: true });
+  {
+      plotId: 1,
+      nextId: function () {
+          return my.PlotView.plotId++;
+      }
+  });
+
+    my.VariationContentView = Backbone.View.extend({
+        render: function () {
+            var self = this;
+            if (this.model.Value === 'false' || this.model.Value === 'true' ||
+              this.model.Value === true || this.model.Value === false) {
+                $(_.template($('#variation_boolean_template').html(), {})).appendTo(this.$el);
+                this.model.Generated = [false, true];
+            }
+            else if (!isNaN(this.model.Value)) {
+                var elem = $(_.template($('#variation_number_template').html(), {}));
+                elem.appendTo(this.$el)
+                $('input[name="generate"]', elem).click(function (evt) { self.openGenerator(evt); });
+                if (!this.model.Generated) {
+                    this.model.Generated = [0, 1, 2];
+                }
+                var tev = new my.TableEditView({ model: this.model.Generated, el: $('div div', this.$el), editable: true });
+                tev.render();
+            }
+            else if (this.model.Options) {
+                var osv = new my.OptionSelectionView({ model: this.model.Options, el: this.$el });
+                this.listenTo(osv, 'changed', function (evt) {
+                    self.selectionChanged(evt);
+                });
+                if (!this.model.Generated)
+                    this.model.Generated = [];
+                osv.render();
+                for (var i = 0; i < this.model.Generated.length; i++) {
+                    $('input[name="' + this.model.Generated[i] + '"]', this.$el).attr('checked', 'checked');
+                }
+            }
+        },
+        openGenerator: function (evt) {
+            var self = this;
+            var generator = new my.GeneratorDialog();
+            this.listenTo(generator, 'success', function (data) {
+                self.doGenerate(data);
+            });
+            generator.render();
+        },
+        doGenerate: function (data) {
+            if (data.minimum > data.maximum) {
+                var tmp = data.minimum;
+                data.minimum = data.maximum;
+                data.maximum = tmp;
+            }
+            if (data.step < 0)
+                data.step *= -1;
+            if (data.step == 0)
+                data.step = 1;
+            this.model.Generated = _.range(data.minimum, data.maximum + 1, data.step);
+            var tev = new my.TableEditView({ model: this.model.Generated, el: $('div div', this.$el), editable: true });
             tev.render();
-        }
-        else if (this.model.Options) {
-            var osv = new OptionSelectionView({ model: this.model.Options, el: this.$el });
-            this.listenTo(osv, 'changed', function (evt) {
-                self.selectionChanged(evt);
-            });
-            if (!this.model.Generated)
-                this.model.Generated = [];
-            osv.render();
-            for (var i = 0; i < this.model.Generated.length; i++) {
-                $('input[name="' + this.model.Generated[i] + '"]', this.$el).attr('checked', 'checked');
-            }
-        }
-    },
-    openGenerator: function (evt) {
-        var self = this;
-        var generator = new GeneratorDialog();
-        this.listenTo(generator, 'success', function (data) {
-            self.doGenerate(data);
-        });
-        generator.render();
-    },
-    doGenerate: function (data) {
-        if (data.minimum > data.maximum) {
-            var tmp = data.minimum;
-            data.minimum = data.maximum;
-            data.maximum = tmp;
-        }
-        if (data.step < 0)
-            data.step *= -1;
-        if (data.step == 0)
-            data.step = 1;
-        this.model.Generated = _.range(data.minimum, data.maximum + 1, data.step);
-        var tev = new TableEditView({ model: this.model.Generated, el: $('div div', this.$el), editable: true });
-        tev.render();
-    },
-    selectionChanged: function (evt) {
-        if (!evt.checked) {
-            this.model.Generated = _.without(this.model.Generated, evt.name);
-        } else if (_.indexOf(this.model.Generated, evt.name) == -1) {
-            this.model.Generated.push(evt.name);
-        }
-    }
-});
-
-var GeneratorDialog = Backbone.View.extend({
-    render: function() {
-        var self = this;
-        var generator = $(_.template($('#variation_generator_template').html(),{}));
-        generator.dialog({
-            buttons: {
-                "Abort": function () {
-                    $(this).dialog("close");
-                },
-                "OK": function () {
-                    $(this).dialog("close");
-                    self.trigger("success", {
-                        minimum: parseInt($('input[name="minimum"]', generator).val()),
-                        maximum: parseInt($('input[name="maximum"]', generator).val()),
-                        step: parseFloat($('input[name="step"]', generator).val())
-                    });
-                }
-            }
-        });
-    }
-});
-
-var VariationEntryView = Backbone.View.extend({
-    render: function () {
-        var entryTemplate = _.template($('#variationentry_template').html(), this.model);
-        $(entryTemplate).appendTo(this.$el);        
-    }
-});
+        },
+        selectionChanged: function (evt) {
+            if (!evt.checked) {
+                this.model.Generated = _.without(this.model.Generated, evt.name);
+            } else if (_.indexOf(this.model.Generated, evt.name) == -1) {
+                this.model.Generated.push(evt.name);
+            }
+        }
+    });
+
+    my.GeneratorDialog = Backbone.View.extend({
+        render: function () {
+            var self = this;
+            var generator = $(_.template($('#variation_generator_template').html(), {}));
+            generator.dialog({
+                buttons: {
+                    "Abort": function () {
+                        $(this).dialog("close");
+                    },
+                    "OK": function () {
+                        $(this).dialog("close");
+                        self.trigger("success", {
+                            minimum: parseInt($('input[name="minimum"]', generator).val()),
+                            maximum: parseInt($('input[name="maximum"]', generator).val()),
+                            step: parseFloat($('input[name="step"]', generator).val())
+                        });
+                    }
+                }
+            });
+        }
+    });
+
+    my.VariationEntryView = Backbone.View.extend({
+        render: function () {
+            var entryTemplate = _.template($('#variationentry_template').html(), this.model);
+            $(entryTemplate).appendTo(this.$el);
+        }
+    });
+    return my;
+} (OAAS_VIEW || {}, Backbone, _, $, OAAS_MODEL));
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/general.view.js
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/general.view.js	(revision 9324)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/general.view.js	(revision 9324)
@@ -0,0 +1,4 @@
+﻿var OAAS_VIEW = (function (my, Backbone, _, $, OAAS_MODEL) {
+   
+    return my;
+} (OAAS_VIEW || {}, Backbone, _, $, OAAS_MODEL));
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/hl/Site.css
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/hl/Site.css	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/hl/Site.css	(revision 9324)
@@ -447,2 +447,28 @@
     background: #EA8511;  
 }
+
+.loader
+{
+  width: 24px;
+  height: 24px;
+}
+
+.bigImage 
+{
+  text-align: center;
+  display: block;
+  margin-left: auto;
+  margin-right: auto;  
+}
+
+.selectedRow
+{
+  font-weight: bolder;
+}
+
+.experimentMenu 
+{
+    clear: left; 
+    float: left; 
+    display: inline;
+}
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.controller.js
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.controller.js	(revision 9324)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.controller.js	(revision 9324)
@@ -0,0 +1,36 @@
+﻿var OAAS_CONTROLLER = (function (my, Backbone, OAAS_VIEW, OAAS_MODEL, _, $) {
+    my.JobPageController = function () {
+        this.create = function () {
+            var self = this;
+            var jobList = new OAAS_MODEL.JobList();
+            var jobOverview = new OAAS_VIEW.JobOverView({ collection: jobList, el: $('#jobOverview') });
+
+            var listener = {};
+            // add listener capabilities to instance
+            _.extend(listener, Backbone.Events);
+
+            listener.listenTo(jobList, 'updated', function (evt) {
+                // refresh overview
+                jobOverview.render();
+            });
+
+            listener.listenTo(jobOverview, 'jobSelected', function (jobId) {
+                var runList = new OAAS_MODEL.RunList({ jobId: jobId });
+                var lv = new OAAS_VIEW.LoadingView({ el: $('#jobDetails'), model: 'Loading results of job...' });
+                lv.render();
+                runList.fetch({ cache: false, success: function () {
+                    $('#jobDetails').empty();
+                    var div = $('<div/>').appendTo($('#jobDetails'));
+                    var rv = new OAAS_VIEW.ResultView({ model: runList, el: div });
+                    rv.render();
+                    var av = new OAAS_VIEW.AccordionView({ el: div });
+                    av.render();
+                }
+                });
+            });
+
+            jobList.poll();
+        }
+    }
+    return my;
+} (OAAS_CONTROLLER || {}, Backbone, OAAS_VIEW, OAAS_MODEL, _, $));
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.model.js
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.model.js	(revision 9324)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.model.js	(revision 9324)
@@ -0,0 +1,78 @@
+﻿// Adapting the module pattern to prevent namespace polution; it's related to the namespace pattern
+// http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
+// http://stackoverflow.com/questions/881515/javascript-namespace-declaration#answer-3588712
+var OAAS_MODEL = (function (my, Backbone) {
+    // ================= MODEL ===================
+    my.Job = Backbone.Model.extend({
+        idAttribute: "Id",
+        defaults: {
+            Id: null,
+            Name: null,
+            Resource: null,
+            Group: null,
+            DateCreated: null,
+            State: 'Waiting',
+            Loading: true
+        },
+        url: function () {
+            return '/Job/Job?jobId=' + this.get('Id');
+        },
+        initialize: function (spec) {
+            // waiting or calculating
+            this.set({ Loading: spec.State == 0 || spec.State == 1 });
+        }
+    });
+
+    my.JobList = Backbone.Collection.extend({
+        url: function () {
+            return "/Job/JobList";
+        },
+        initialize: function (spec) {
+            this.listenTo(this, 'sync', this.adjustDate);
+        },
+        _poll: function () {
+            var self = this;
+            setTimeout(function () { self.poll() }, 5000);
+        },
+        poll: function () {
+            var self = this;
+            this.fetch({ cache: false, update: true, success: function () {
+                self._poll();
+            }
+            });
+        },
+        adjustDate: function () {
+            for (var i = 0; i < this.models.length; i++) {
+                // convert the MS date format here
+                var date = this.models[i].get('DateCreated');
+                // remove /Date(
+                if (!(date instanceof Date)) {
+                    var value = new Date(parseInt(date.substr(6)));
+                    this.models[i].set('DateCreated', value);
+                }
+            }
+            this.trigger('updated', this);
+        },
+        model: my.Job
+    });
+
+    my.Run = Backbone.Model.extend({
+        defaults: {
+            id: null,
+            name: null,
+            results: null
+        }
+    });
+
+    my.RunList = Backbone.Collection.extend({
+        initialize: function (spec) {
+            this.jobId = spec.jobId;
+        },
+        url: function () {
+            return "/Job/RunList?jobId=" + this.jobId;
+        },
+        model: my.Run
+    });
+
+    return my;
+} (OAAS_MODEL || {}, Backbone));
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.view.js
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.view.js	(revision 9324)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/job.view.js	(revision 9324)
@@ -0,0 +1,213 @@
+﻿var OAAS_VIEW = (function (my, Backbone, _, $) {
+    // ================= VIEWS ===================
+    my.LoadingView = Backbone.View.extend({
+        render: function () {
+            this.$el.empty();
+            this.template = _.template($('#loadingTemplate').html());
+            $(this.template({ text: this.model })).appendTo(this.$el);
+        }
+    });
+
+    my.JobOverView = Backbone.View.extend({
+        events: {
+            'click tr': 'rowClicked',
+            'click button[data-name="DeleteButton"]': 'deleteClicked'
+        },
+        initialize: function () {
+            this.collection.bind('remove', this.render, this);
+            //this.collection.bind('a', this.render, this);
+        },
+        render: function () {
+            var prevSettings = null;
+            if (this.table) {
+                prevSettings = this.table.fnSettings();
+            }
+            this.$el.empty();
+            // create header
+            var table = $('<table />');
+            this.template = _.template($('#jobHeaderTemplate').html());
+            $(this.template({})).appendTo(table);
+
+            // create content
+            var tbody = $('<tbody />');
+            this.collection.each(function (model) {
+                var row = new my.JobOverViewRow({ model: model });
+                row.render();
+                row.$el.appendTo(tbody);
+            });
+            tbody.appendTo(table);
+            table.appendTo(this.$el);
+            if (prevSettings != null) {
+                this.table = table.dataTable({
+                    'aaSorting': prevSettings.aaSorting,
+                    'iDisplayLength' : prevSettings._iDisplayLength,
+                    'iDisplayStart' : prevSettings._iDisplayStart,
+                });
+                this.table.fnFilter(prevSettings.oPreviousSearch.sSearch);
+            } else {
+                this.table = table.dataTable();
+            }
+            this.highlightSelectedJob();
+        },
+        highlightSelectedJob: function () {
+            $('tr', this.table).removeClass('selectedRow');
+            if (this.selectedJob) {
+                $('tr[data-jobId="' + this.selectedJob + '"]', this.table).addClass('selectedRow');
+            }
+        },
+        rowClicked: function (row) {
+            var jobId = $(row.target).parent("tr").attr("data-jobId");
+            if (jobId) {
+                this.selectedJob = jobId;
+                this.highlightSelectedJob();
+                this.trigger('jobSelected', jobId);
+            }
+        },
+        deleteClicked: function (evt) {
+            var target = $(evt.target);
+            var id = target.attr('data-id');
+            var jobs = this.collection.where({ Id: id });
+            if (jobs.length == 1) {
+                jobs[0].destroy(); // triggers a remove event on this.collection -> DELETE /Job/1 will be called
+            }
+        }
+    });
+
+    my.JobOverViewRow = Backbone.View.extend({
+        render: function () {
+            this.template = _.template($('#jobRowTemplate').html());
+            this.setElement($(this.template(this.model.attributes)));
+        }
+    });
+
+    my.ResultView = Backbone.View.extend({
+        render: function () {
+            this.template = _.template($('#runTemplate').html());
+            this.$el.empty();
+            for (var i = 0; i < this.model.models.length; i++) {
+                var rev = new my.ResultEntryView({ model: this.model.models[i], el: this.$el });
+                rev.render();
+            }
+        }
+    });
+
+    my.AccordionView = Backbone.View.extend({
+        render: function () {
+            this.$el.accordion({
+                heightStyle: 'content',
+                collapsible: true,
+                active: false
+            });
+        },
+        refresh: function () {
+            this.$el.accordtion("refresh");
+        }
+    });
+
+    my.ResizableView = Backbone.View.extend({
+        events: {
+            'resizestop': 'resized'
+        },
+        render: function () {
+            this.$el.resizable();
+        },
+        resized: function (evt) {
+            this.trigger('resized', evt);
+        }
+    });
+
+    my.TabView = Backbone.View.extend({
+        // model structure: [{ name: 
+        events: {
+            'tabsactivate': 'tabActivated'
+        },
+        render: function () {
+            this.$el.empty();
+            var header = $('<ul />').appendTo(this.$el);
+            for (var i = 0; i < this.model.length; i++) {
+                var li = $('<li/>').appendTo(header);
+                var id = 'tab_' + my.PlotView.nextId() + '_' + i;
+                $('<a />').attr('href', '#' + id).text(this.model[i].name).appendTo(li);
+
+                var targetDiv = $('<div/>').attr('id', id).appendTo(this.$el);
+                $(this.model[i].content).appendTo(targetDiv);
+            }
+            this.$el.tabs({
+                collapsible: true,
+                active: false
+            });
+        },
+        tabActivated: function (event, ui) {
+            var tabElement = $(ui.newPanel[0]);
+            this.trigger('tab-activated', { name: ui.newTab.text(), element: tabElement });
+        }
+    });
+
+    my.ResultEntryView = Backbone.View.extend({
+        initialize: function () {
+            this.plotted = {};
+        },
+        render: function () {
+            this.template = _.template($('#runTemplate').html());
+            var table = $(this.template(this.model.attributes));
+            var body = $("tbody", table);
+            table.appendTo(this.$el);
+            var results = this.model.get('results');
+            for (var i = 0; i < results.length; i++) {
+                var row = $('<tr/>').attr('data-index', i);
+                $('<td/>').text(results[i].Name).appendTo(row);
+                //TODO: Switch Value type and create different items here
+                if ($.isArray(results[i].Value)) {
+                    var col = $('<td/>').appendTo(row);
+                    var tevDiv = $('<div/>');
+                    // TODO: REMOVE TABLEEDITVIEW and create it only on demand!!!
+                    // var tev = new my.TableEditView({ model: results[i].Value, el: tevDiv, useDatatable: true });
+                    // tev.render();
+                    var plotDiv = $('<div/>').appendTo($('#tmp'));
+                    //var pv = new PlotView({model: results[i], el: plotDiv});
+                    //pv.render();
+                    this.plotted[i] = {};
+                    var tv = new my.TabView({
+                        model: [
+                          { name: 'Table', content: tevDiv },
+                          { name: 'Plot', content: plotDiv },
+                        ],
+                        el: col
+                    });
+                    this.listenTo(tv, 'tab-activated', this.tabActivated);
+                    tv.render();
+
+                }
+                else {
+                    $('<td/>').text(results[i].Value).appendTo(row);
+                }
+                row.appendTo(body);
+            }
+        },
+        tabActivated: function (evt) {
+            var index = parseInt(evt.element.parents('tr').attr('data-index'));
+            if (evt.name == 'Plot' && !this.plotted[index].Plot) {
+                this.plotted[index].Plot = true;
+                var plotDiv = $('<div/>').appendTo($('#tmp'));
+                var pv = new my.PlotView({ model: this.model.get('results')[index], el: plotDiv });
+                pv.render();
+                plotDiv.appendTo(evt.element);
+                var rv = new my.ResizableView({ el: evt.element });
+
+                this.listenTo(rv, 'resized', function (evt) {
+                    plotDiv.height($(evt.target).height() * 0.96);
+                    plotDiv.width($(evt.target).width() * 0.96);
+                    pv.refresh();
+                });
+                rv.render();
+            } else if (evt.name == 'Table' && !this.plotted[index].Table) {
+                this.plotted[index].Table = true;
+                var tevDiv = $('<div/>');
+                var tev = new my.TableEditView({ model: this.model.get('results')[index].Value, rowNames: this.model.get('results')[index].RowNames, useDatatable: true, el: tevDiv });
+                tev.render();
+                tevDiv.appendTo(evt.element)
+            }
+        }
+    });
+    return my;
+} (OAAS_VIEW || {}, Backbone, _, $));
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/moment.min.js
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/moment.min.js	(revision 9324)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/moment.min.js	(revision 9324)
@@ -0,0 +1,6 @@
+// moment.js
+// version : 2.0.0
+// author : Tim Wood
+// license : MIT
+// momentjs.com
+(function(e){function O(e,t){return function(n){return j(e.call(this,n),t)}}function M(e){return function(t){return this.lang().ordinal(e.call(this,t))}}function _(){}function D(e){H(this,e)}function P(e){var t=this._data={},n=e.years||e.year||e.y||0,r=e.months||e.month||e.M||0,i=e.weeks||e.week||e.w||0,s=e.days||e.day||e.d||0,o=e.hours||e.hour||e.h||0,u=e.minutes||e.minute||e.m||0,a=e.seconds||e.second||e.s||0,f=e.milliseconds||e.millisecond||e.ms||0;this._milliseconds=f+a*1e3+u*6e4+o*36e5,this._days=s+i*7,this._months=r+n*12,t.milliseconds=f%1e3,a+=B(f/1e3),t.seconds=a%60,u+=B(a/60),t.minutes=u%60,o+=B(u/60),t.hours=o%24,s+=B(o/24),s+=i*7,t.days=s%30,r+=B(s/30),t.months=r%12,n+=B(r/12),t.years=n}function H(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}function B(e){return e<0?Math.ceil(e):Math.floor(e)}function j(e,t){var n=e+"";while(n.length<t)n="0"+n;return n}function F(e,t,n){var r=t._milliseconds,i=t._days,s=t._months,o;r&&e._d.setTime(+e+r*n),i&&e.date(e.date()+i*n),s&&(o=e.date(),e.date(1).month(e.month()+s*n).date(Math.min(o,e.daysInMonth())))}function I(e){return Object.prototype.toString.call(e)==="[object Array]"}function q(e,t){var n=Math.min(e.length,t.length),r=Math.abs(e.length-t.length),i=0,s;for(s=0;s<n;s++)~~e[s]!==~~t[s]&&i++;return i+r}function R(e,t){return t.abbr=e,s[e]||(s[e]=new _),s[e].set(t),s[e]}function U(e){return e?(!s[e]&&o&&require("./lang/"+e),s[e]):t.fn._lang}function z(e){return e.match(/\[.*\]/)?e.replace(/^\[|\]$/g,""):e.replace(/\\/g,"")}function W(e){var t=e.match(a),n,r;for(n=0,r=t.length;n<r;n++)A[t[n]]?t[n]=A[t[n]]:t[n]=z(t[n]);return function(i){var s="";for(n=0;n<r;n++)s+=typeof t[n].call=="function"?t[n].call(i,e):t[n];return s}}function X(e,t){function r(t){return e.lang().longDateFormat(t)||t}var n=5;while(n--&&f.test(t))t=t.replace(f,r);return C[t]||(C[t]=W(t)),C[t](e)}function V(e){switch(e){case"DDDD":return p;case"YYYY":return d;case"YYYYY":return v;case"S":case"SS":case"SSS":case"DDD":return h;case"MMM":case"MMMM":case"dd":case"ddd":case"dddd":case"a":case"A":return m;case"X":return b;case"Z":case"ZZ":return g;case"T":return y;case"MM":case"DD":case"YY":case"HH":case"hh":case"mm":case"ss":case"M":case"D":case"d":case"H":case"h":case"m":case"s":return c;default:return new RegExp(e.replace("\\",""))}}function $(e,t,n){var r,i,s=n._a;switch(e){case"M":case"MM":s[1]=t==null?0:~~t-1;break;case"MMM":case"MMMM":r=U(n._l).monthsParse(t),r!=null?s[1]=r:n._isValid=!1;break;case"D":case"DD":case"DDD":case"DDDD":t!=null&&(s[2]=~~t);break;case"YY":s[0]=~~t+(~~t>68?1900:2e3);break;case"YYYY":case"YYYYY":s[0]=~~t;break;case"a":case"A":n._isPm=(t+"").toLowerCase()==="pm";break;case"H":case"HH":case"h":case"hh":s[3]=~~t;break;case"m":case"mm":s[4]=~~t;break;case"s":case"ss":s[5]=~~t;break;case"S":case"SS":case"SSS":s[6]=~~(("0."+t)*1e3);break;case"X":n._d=new Date(parseFloat(t)*1e3);break;case"Z":case"ZZ":n._useUTC=!0,r=(t+"").match(x),r&&r[1]&&(n._tzh=~~r[1]),r&&r[2]&&(n._tzm=~~r[2]),r&&r[0]==="+"&&(n._tzh=-n._tzh,n._tzm=-n._tzm)}t==null&&(n._isValid=!1)}function J(e){var t,n,r=[];if(e._d)return;for(t=0;t<7;t++)e._a[t]=r[t]=e._a[t]==null?t===2?1:0:e._a[t];r[3]+=e._tzh||0,r[4]+=e._tzm||0,n=new Date(0),e._useUTC?(n.setUTCFullYear(r[0],r[1],r[2]),n.setUTCHours(r[3],r[4],r[5],r[6])):(n.setFullYear(r[0],r[1],r[2]),n.setHours(r[3],r[4],r[5],r[6])),e._d=n}function K(e){var t=e._f.match(a),n=e._i,r,i;e._a=[];for(r=0;r<t.length;r++)i=(V(t[r]).exec(n)||[])[0],i&&(n=n.slice(n.indexOf(i)+i.length)),A[t[r]]&&$(t[r],i,e);e._isPm&&e._a[3]<12&&(e._a[3]+=12),e._isPm===!1&&e._a[3]===12&&(e._a[3]=0),J(e)}function Q(e){var t,n,r,i=99,s,o,u;while(e._f.length){t=H({},e),t._f=e._f.pop(),K(t),n=new D(t);if(n.isValid()){r=n;break}u=q(t._a,n.toArray()),u<i&&(i=u,r=n)}H(e,r)}function G(e){var t,n=e._i;if(w.exec(n)){e._f="YYYY-MM-DDT";for(t=0;t<4;t++)if(S[t][1].exec(n)){e._f+=S[t][0];break}g.exec(n)&&(e._f+=" Z"),K(e)}else e._d=new Date(n)}function Y(t){var n=t._i,r=u.exec(n);n===e?t._d=new Date:r?t._d=new Date(+r[1]):typeof n=="string"?G(t):I(n)?(t._a=n.slice(0),J(t)):t._d=n instanceof Date?new Date(+n):new Date(n)}function Z(e,t,n,r,i){return i.relativeTime(t||1,!!n,e,r)}function et(e,t,n){var i=r(Math.abs(e)/1e3),s=r(i/60),o=r(s/60),u=r(o/24),a=r(u/365),f=i<45&&["s",i]||s===1&&["m"]||s<45&&["mm",s]||o===1&&["h"]||o<22&&["hh",o]||u===1&&["d"]||u<=25&&["dd",u]||u<=45&&["M"]||u<345&&["MM",r(u/30)]||a===1&&["y"]||["yy",a];return f[2]=t,f[3]=e>0,f[4]=n,Z.apply({},f)}function tt(e,n,r){var i=r-n,s=r-e.day();return s>i&&(s-=7),s<i-7&&(s+=7),Math.ceil(t(e).add("d",s).dayOfYear()/7)}function nt(e){var n=e._i,r=e._f;return n===null||n===""?null:(typeof n=="string"&&(e._i=n=U().preparse(n)),t.isMoment(n)?(e=H({},n),e._d=new Date(+n._d)):r?I(r)?Q(e):K(e):Y(e),new D(e))}function rt(e,n){t.fn[e]=t.fn[e+"s"]=function(e){var t=this._isUTC?"UTC":"";return e!=null?(this._d["set"+t+n](e),this):this._d["get"+t+n]()}}function it(e){t.duration.fn[e]=function(){return this._data[e]}}function st(e,n){t.duration.fn["as"+e]=function(){return+this/n}}var t,n="2.0.0",r=Math.round,i,s={},o=typeof module!="undefined"&&module.exports,u=/^\/?Date\((\-?\d+)/i,a=/(\[[^\[]*\])|(\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|YYYYY|YYYY|YY|a|A|hh?|HH?|mm?|ss?|SS?S?|X|zz?|ZZ?|.)/g,f=/(\[[^\[]*\])|(\\)?(LT|LL?L?L?|l{1,4})/g,l=/([0-9a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+)/gi,c=/\d\d?/,h=/\d{1,3}/,p=/\d{3}/,d=/\d{1,4}/,v=/[+\-]?\d{1,6}/,m=/[0-9]*[a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF]+\s*?[\u0600-\u06FF]+/i,g=/Z|[\+\-]\d\d:?\d\d/i,y=/T/i,b=/[\+\-]?\d+(\.\d{1,3})?/,w=/^\s*\d{4}-\d\d-\d\d((T| )(\d\d(:\d\d(:\d\d(\.\d\d?\d?)?)?)?)?([\+\-]\d\d:?\d\d)?)?/,E="YYYY-MM-DDTHH:mm:ssZ",S=[["HH:mm:ss.S",/(T| )\d\d:\d\d:\d\d\.\d{1,3}/],["HH:mm:ss",/(T| )\d\d:\d\d:\d\d/],["HH:mm",/(T| )\d\d:\d\d/],["HH",/(T| )\d\d/]],x=/([\+\-]|\d\d)/gi,T="Month|Date|Hours|Minutes|Seconds|Milliseconds".split("|"),N={Milliseconds:1,Seconds:1e3,Minutes:6e4,Hours:36e5,Days:864e5,Months:2592e6,Years:31536e6},C={},k="DDD w W M D d".split(" "),L="M D H h m s w W".split(" "),A={M:function(){return this.month()+1},MMM:function(e){return this.lang().monthsShort(this,e)},MMMM:function(e){return this.lang().months(this,e)},D:function(){return this.date()},DDD:function(){return this.dayOfYear()},d:function(){return this.day()},dd:function(e){return this.lang().weekdaysMin(this,e)},ddd:function(e){return this.lang().weekdaysShort(this,e)},dddd:function(e){return this.lang().weekdays(this,e)},w:function(){return this.week()},W:function(){return this.isoWeek()},YY:function(){return j(this.year()%100,2)},YYYY:function(){return j(this.year(),4)},YYYYY:function(){return j(this.year(),5)},a:function(){return this.lang().meridiem(this.hours(),this.minutes(),!0)},A:function(){return this.lang().meridiem(this.hours(),this.minutes(),!1)},H:function(){return this.hours()},h:function(){return this.hours()%12||12},m:function(){return this.minutes()},s:function(){return this.seconds()},S:function(){return~~(this.milliseconds()/100)},SS:function(){return j(~~(this.milliseconds()/10),2)},SSS:function(){return j(this.milliseconds(),3)},Z:function(){var e=-this.zone(),t="+";return e<0&&(e=-e,t="-"),t+j(~~(e/60),2)+":"+j(~~e%60,2)},ZZ:function(){var e=-this.zone(),t="+";return e<0&&(e=-e,t="-"),t+j(~~(10*e/6),4)},X:function(){return this.unix()}};while(k.length)i=k.pop(),A[i+"o"]=M(A[i]);while(L.length)i=L.pop(),A[i+i]=O(A[i],2);A.DDDD=O(A.DDD,3),_.prototype={set:function(e){var t,n;for(n in e)t=e[n],typeof t=="function"?this[n]=t:this["_"+n]=t},_months:"January_February_March_April_May_June_July_August_September_October_November_December".split("_"),months:function(e){return this._months[e.month()]},_monthsShort:"Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),monthsShort:function(e){return this._monthsShort[e.month()]},monthsParse:function(e){var n,r,i,s;this._monthsParse||(this._monthsParse=[]);for(n=0;n<12;n++){this._monthsParse[n]||(r=t([2e3,n]),i="^"+this.months(r,"")+"|^"+this.monthsShort(r,""),this._monthsParse[n]=new RegExp(i.replace(".",""),"i"));if(this._monthsParse[n].test(e))return n}},_weekdays:"Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),weekdays:function(e){return this._weekdays[e.day()]},_weekdaysShort:"Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),weekdaysShort:function(e){return this._weekdaysShort[e.day()]},_weekdaysMin:"Su_Mo_Tu_We_Th_Fr_Sa".split("_"),weekdaysMin:function(e){return this._weekdaysMin[e.day()]},_longDateFormat:{LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D YYYY",LLL:"MMMM D YYYY LT",LLLL:"dddd, MMMM D YYYY LT"},longDateFormat:function(e){var t=this._longDateFormat[e];return!t&&this._longDateFormat[e.toUpperCase()]&&(t=this._longDateFormat[e.toUpperCase()].replace(/MMMM|MM|DD|dddd/g,function(e){return e.slice(1)}),this._longDateFormat[e]=t),t},meridiem:function(e,t,n){return e>11?n?"pm":"PM":n?"am":"AM"},_calendar:{sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[last] dddd [at] LT",sameElse:"L"},calendar:function(e,t){var n=this._calendar[e];return typeof n=="function"?n.apply(t):n},_relativeTime:{future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},relativeTime:function(e,t,n,r){var i=this._relativeTime[n];return typeof i=="function"?i(e,t,n,r):i.replace(/%d/i,e)},pastFuture:function(e,t){var n=this._relativeTime[e>0?"future":"past"];return typeof n=="function"?n(t):n.replace(/%s/i,t)},ordinal:function(e){return this._ordinal.replace("%d",e)},_ordinal:"%d",preparse:function(e){return e},postformat:function(e){return e},week:function(e){return tt(e,this._week.dow,this._week.doy)},_week:{dow:0,doy:6}},t=function(e,t,n){return nt({_i:e,_f:t,_l:n,_isUTC:!1})},t.utc=function(e,t,n){return nt({_useUTC:!0,_isUTC:!0,_l:n,_i:e,_f:t})},t.unix=function(e){return t(e*1e3)},t.duration=function(e,n){var r=t.isDuration(e),i=typeof e=="number",s=r?e._data:i?{}:e,o;return i&&(n?s[n]=e:s.milliseconds=e),o=new P(s),r&&e.hasOwnProperty("_lang")&&(o._lang=e._lang),o},t.version=n,t.defaultFormat=E,t.lang=function(e,n){var r;if(!e)return t.fn._lang._abbr;n?R(e,n):s[e]||U(e),t.duration.fn._lang=t.fn._lang=U(e)},t.langData=function(e){return e&&e._lang&&e._lang._abbr&&(e=e._lang._abbr),U(e)},t.isMoment=function(e){return e instanceof D},t.isDuration=function(e){return e instanceof P},t.fn=D.prototype={clone:function(){return t(this)},valueOf:function(){return+this._d},unix:function(){return Math.floor(+this._d/1e3)},toString:function(){return this.format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")},toDate:function(){return this._d},toJSON:function(){return t.utc(this).format("YYYY-MM-DD[T]HH:mm:ss.SSS[Z]")},toArray:function(){var e=this;return[e.year(),e.month(),e.date(),e.hours(),e.minutes(),e.seconds(),e.milliseconds()]},isValid:function(){return this._isValid==null&&(this._a?this._isValid=!q(this._a,(this._isUTC?t.utc(this._a):t(this._a)).toArray()):this._isValid=!isNaN(this._d.getTime())),!!this._isValid},utc:function(){return this._isUTC=!0,this},local:function(){return this._isUTC=!1,this},format:function(e){var n=X(this,e||t.defaultFormat);return this.lang().postformat(n)},add:function(e,n){var r;return typeof e=="string"?r=t.duration(+n,e):r=t.duration(e,n),F(this,r,1),this},subtract:function(e,n){var r;return typeof e=="string"?r=t.duration(+n,e):r=t.duration(e,n),F(this,r,-1),this},diff:function(e,n,r){var i=this._isUTC?t(e).utc():t(e).local(),s=(this.zone()-i.zone())*6e4,o,u;return n&&(n=n.replace(/s$/,"")),n==="year"||n==="month"?(o=(this.daysInMonth()+i.daysInMonth())*432e5,u=(this.year()-i.year())*12+(this.month()-i.month()),u+=(this-t(this).startOf("month")-(i-t(i).startOf("month")))/o,n==="year"&&(u/=12)):(o=this-i-s,u=n==="second"?o/1e3:n==="minute"?o/6e4:n==="hour"?o/36e5:n==="day"?o/864e5:n==="week"?o/6048e5:o),r?u:B(u)},from:function(e,n){return t.duration(this.diff(e)).lang(this.lang()._abbr).humanize(!n)},fromNow:function(e){return this.from(t(),e)},calendar:function(){var e=this.diff(t().startOf("day"),"days",!0),n=e<-6?"sameElse":e<-1?"lastWeek":e<0?"lastDay":e<1?"sameDay":e<2?"nextDay":e<7?"nextWeek":"sameElse";return this.format(this.lang().calendar(n,this))},isLeapYear:function(){var e=this.year();return e%4===0&&e%100!==0||e%400===0},isDST:function(){return this.zone()<t([this.year()]).zone()||this.zone()<t([this.year(),5]).zone()},day:function(e){var t=this._isUTC?this._d.getUTCDay():this._d.getDay();return e==null?t:this.add({d:e-t})},startOf:function(e){e=e.replace(/s$/,"");switch(e){case"year":this.month(0);case"month":this.date(1);case"week":case"day":this.hours(0);case"hour":this.minutes(0);case"minute":this.seconds(0);case"second":this.milliseconds(0)}return e==="week"&&this.day(0),this},endOf:function(e){return this.startOf(e).add(e.replace(/s?$/,"s"),1).subtract("ms",1)},isAfter:function(e,n){return n=typeof n!="undefined"?n:"millisecond",+this.clone().startOf(n)>+t(e).startOf(n)},isBefore:function(e,n){return n=typeof n!="undefined"?n:"millisecond",+this.clone().startOf(n)<+t(e).startOf(n)},isSame:function(e,n){return n=typeof n!="undefined"?n:"millisecond",+this.clone().startOf(n)===+t(e).startOf(n)},zone:function(){return this._isUTC?0:this._d.getTimezoneOffset()},daysInMonth:function(){return t.utc([this.year(),this.month()+1,0]).date()},dayOfYear:function(e){var n=r((t(this).startOf("day")-t(this).startOf("year"))/864e5)+1;return e==null?n:this.add("d",e-n)},isoWeek:function(e){var t=tt(this,1,4);return e==null?t:this.add("d",(e-t)*7)},week:function(e){var t=this.lang().week(this);return e==null?t:this.add("d",(e-t)*7)},lang:function(t){return t===e?this._lang:(this._lang=U(t),this)}};for(i=0;i<T.length;i++)rt(T[i].toLowerCase().replace(/s$/,""),T[i]);rt("year","FullYear"),t.fn.days=t.fn.day,t.fn.weeks=t.fn.week,t.fn.isoWeeks=t.fn.isoWeek,t.duration.fn=P.prototype={weeks:function(){return B(this.days()/7)},valueOf:function(){return this._milliseconds+this._days*864e5+this._months*2592e6},humanize:function(e){var t=+this,n=et(t,!e,this.lang());return e&&(n=this.lang().pastFuture(t,n)),this.lang().postformat(n)},lang:t.fn.lang};for(i in N)N.hasOwnProperty(i)&&(st(i,N[i]),it(i.toLowerCase()));st("Weeks",6048e5),t.lang("en",{ordinal:function(e){var t=e%10,n=~~(e%100/10)===1?"th":t===1?"st":t===2?"nd":t===3?"rd":"th";return e+n}}),o&&(module.exports=t),typeof ender=="undefined"&&(this.moment=t),typeof define=="function"&&define.amd&&define("moment",[],function(){return t})}).call(this);
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/BaseController.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/BaseController.cs	(revision 9324)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/BaseController.cs	(revision 9324)
@@ -0,0 +1,29 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+using HeuristicLab.Services.Optimization.Web.Helpers;
+
+namespace HeuristicLab.Services.Optimization.Web.Controllers
+{
+    public class BaseController : Controller
+    {
+      protected ControllerServiceHelper ControllerService {
+        get {
+          var helper = new ControllerServiceHelper(Session["pw"] as string);
+          RedirectToLoginIfNecessary();
+          return helper;
+        }
+      }
+
+      protected bool RedirectToLoginIfNecessary(string destination="%2fOptimization") {
+        var pw = Session["pw"] as string;
+        if (pw == null) {
+          Response.Redirect("/Account/Logon?ReturnUrl=" + destination);
+          return true;
+        }
+        return false;
+      }
+    }
+}
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/ExperimentController.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/ExperimentController.cs	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/ExperimentController.cs	(revision 9324)
@@ -14,16 +14,6 @@
 {
     [Authorize(Roles = "Web User")]
-    public class ExperimentController : Controller
+    public class ExperimentController : BaseController
     {
-        private ControllerServiceHelper ControllerService {
-          get {
-            var helper = new ControllerServiceHelper(Session["pw"] as string);
-            if (!helper.Valid) {
-              Response.Redirect("/Account/Logon?ReturnUrl=%2fExperiment");
-            }
-            return helper;
-          }
-        }
-
         //
         // GET: /Experiment/
@@ -31,5 +21,6 @@
         public ActionResult Index()
         {
-          return RedirectToAction("New");
+          RedirectToLoginIfNecessary("%2fExperiment%2fIndex");
+          return RedirectToAction("New", "Experiment");
           /*var model = new ExperimentViewModel();
           var scenarios = ControllerService.withControllerService<IEnumerable<string>>((service) => {
@@ -49,10 +40,13 @@
 
         public ActionResult New() {
+          RedirectToLoginIfNecessary("%2fExperiment%2fNew");
           return View();
         }
 
         public ActionResult NewEdit() {
+          RedirectToLoginIfNecessary("%2fExperiment%2fNewEdit");
           return View();
         }
+
 
         public ActionResult Edit() {
@@ -65,13 +59,5 @@
             model.Experiments.Add(experiment);
           return View(model);
-        }
-
-        public ActionResult DeleteExperiment(string experiment) {
-          ControllerService.withControllerService<bool>((service) => {
-            User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
-            return service.DeleteExperiment(u, experiment);
-          });
-          return RedirectToAction("Edit");
-        }
+        } 
 
       #region new experiment methdos
@@ -88,5 +74,5 @@
         var experiments = ControllerService.withControllerService<IEnumerable<Experiment>>(service => {
           User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
-          return service.GetExperiments(u);
+          return service.GetExperiments(u, namesOnly: true);
         });
         return Content(AlgorithmConverter.ConvertExperimentsToJson(experiments).ToString(), "application/json", System.Text.Encoding.UTF8);
@@ -124,4 +110,13 @@
       }
 
+      [HttpDelete]
+      [ActionName("Experiment")]
+      public JsonResult DeleteExperiment(string nodeId) {
+        var isExperimentDeleted = ControllerService.withControllerService<bool>(service => {
+          User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
+          return service.DeleteExperiment(u, nodeId);
+        });
+        return Json(isExperimentDeleted, JsonRequestBehavior.DenyGet);
+      }
 
       [HttpGet]
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/JobController.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/JobController.cs	(revision 9324)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/JobController.cs	(revision 9324)
@@ -0,0 +1,60 @@
+﻿using System; 
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+using HeuristicLab.Services.Optimization.ControllerService.Parsers;
+using HeuristicLab.Services.Optimization.ControllerService.Model;
+using HeuristicLab.Services.Optimization.Web.Models;
+
+using System.Web.Security;
+
+namespace HeuristicLab.Services.Optimization.Web.Controllers
+{
+    [Authorize(Roles = "Web User")]
+    public class JobController : BaseController
+    {
+      //
+      // GET: /Job/   
+      public ActionResult Index() {
+        RedirectToLoginIfNecessary("%2fJob");
+        return View();
+      }
+
+      [HttpDelete]
+      public JsonResult Job(string jobId) {
+        var success = ControllerService.withControllerService<bool>((service) => {
+          User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
+          return service.DeleteJob(u, jobId);
+        });
+        return Json(success, JsonRequestBehavior.DenyGet);
+      }
+
+      [HttpGet]
+      public JsonResult JobList() {
+        var jobs = ControllerService.withControllerService<IEnumerable<Job>>((service) => {
+          User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
+          return service.GetJobs(u);
+        });
+        return Json(jobs, JsonRequestBehavior.AllowGet);
+      }
+
+      /*[HttpGet]
+      public JsonResult Job(string jobId) {
+        var job = ControllerService.withControllerService<Job>((service) => {
+          User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
+          return service.GetJob(u, jobId);
+        });
+        return Json(job, JsonRequestBehavior.AllowGet);
+      }*/
+
+      [HttpGet]
+      public ActionResult RunList(string jobId) {
+        var runs = ControllerService.withControllerService<IList<Run>>((service) => {
+          User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
+          return service.GetJobResults(u, jobId);
+        });
+        return Content(AlgorithmConverter.ConvertRunsToJson(runs).ToString(), "application/json", System.Text.Encoding.UTF8);
+      }
+    }
+}
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/OptimizationController.cs
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/OptimizationController.cs	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/OptimizationController.cs	(revision 9324)
@@ -32,4 +32,6 @@
         public ActionResult Index()
         {
+          return RedirectToAction("Index", "Job");
+          /*
           var optModel = ControllerService.withControllerService<OptimizationModel>((service) => {
             OptimizationModel model = new OptimizationModel();
@@ -40,4 +42,5 @@
           });          
           return View(optModel);
+           */
         }
 
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/HeuristicLab.Services.Optimization.Web.csproj
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/HeuristicLab.Services.Optimization.Web.csproj	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/HeuristicLab.Services.Optimization.Web.csproj	(revision 9324)
@@ -105,4 +105,7 @@
     <Content Include="Content\backbone\underscore-min.js" />
     <Content Include="Content\backbone\underscore.js" />
+    <Content Include="Content\general.view.js" />
+    <Content Include="Content\job.controller.js" />
+    <Content Include="Content\job.model.js" />
     <Content Include="Content\Datatypemapping.js" />
     <Content Include="Content\dynatree\dist\jquery.dynatree.min.js" />
@@ -120,7 +123,9 @@
     <Compile Include="Controllers\AccountController.cs" />
     <Compile Include="Controllers\AdminController.cs" />
+    <Compile Include="Controllers\BaseController.cs" />
     <Compile Include="Controllers\ChartController.cs" />
     <Compile Include="Controllers\ExperimentController.cs" />
     <Compile Include="Controllers\HomeController.cs" />
+    <Compile Include="Controllers\JobController.cs" />
     <Compile Include="Controllers\OptimizationController.cs" />
     <Compile Include="Controllers\StatusController.cs" />
@@ -158,4 +163,5 @@
     <Content Include="Content\datatable\images\sort_desc_disabled.png" />
     <Content Include="Content\hl\images\ajax-loader.gif" />
+    <Content Include="Content\job.view.js" />
     <Content Include="Content\jqplot\src\changes.txt" />
     <Content Include="Content\jqplot\src\excanvas.js" />
@@ -230,4 +236,5 @@
     <Content Include="Content\jqplot\src\plugins\jqplot.trendline.js" />
     <Content Include="Content\jqplot\src\usage.txt" />
+    <Content Include="Content\moment.min.js" />
     <Content Include="Content\Styling.js" />
     <Content Include="Content\hl\images\._bg_footer.png" />
@@ -384,4 +391,5 @@
     <Content Include="Views\Experiment\New.cshtml" />
     <Content Include="Views\Experiment\NewEdit.cshtml" />
+    <Content Include="Views\Job\Index.cshtml" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment/New.cshtml
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment/New.cshtml	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment/New.cshtml	(revision 9324)
@@ -70,7 +70,14 @@
 <script type="text/template" id="checkbox_template">
 <div>
-    <input type="checkbox" name="<%=name%>"/><%=text%><br/>
-</div>
-</script>       
+    <input type="checkbox" name="<%=name%>"
+        <% if (checked) { %>
+            checked
+        <% } %>
+    />
+    <% if (!hideText) { %>
+         <%=text%><br/>
+    <% } %>
+</div>
+</script>   
 
 <script type="text/template" id="variation_generator_template">
@@ -93,5 +100,5 @@
 
 <script type="text/javascript">
-    var controller = new ExperimentPageController();
+    var controller = new OAAS_CONTROLLER.ExperimentPageController();
     $(document).ready(function () {
         controller.create();
@@ -141,8 +148,12 @@
     <div id="container" class="treeStyle"></div>    
     <p>Choose an algorithm:</p>
-    <div id="algorithms"></div>
+    <div id="algorithms">
+        <span>Loading ... <img src="@Url.Content("~/Content/ajax-loader.gif")" alt="Loading animation" />  </span>        
+    </div>
     <div class="clearer"></div>
     <p>Choose from your stored experiments:</p>
-    <div id="experiments"></div>
+    <div id="experiments">
+        <span>Loading ... <img src="@Url.Content("~/Content/ajax-loader.gif")" alt="Loading animation" />  </span>        
+    </div>
   </fieldset>
   </div>
@@ -196,6 +207,6 @@
 @section submenu {
     <ul>
-        <li class="selected">@Html.ActionLink("Build", "New")</li>    
-        <li>@Html.ActionLink("Edit", "NewEdit")</li>
+        <li class="selected">@Html.ActionLink("Build", "New", "Experiment")</li>    
+        <li>@Html.ActionLink("Edit", "NewEdit", "Experiment")</li>
         <li>@Html.ActionLink("Status", "Index", "Status")</li>
     </ul>
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment/NewEdit.cshtml
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment/NewEdit.cshtml	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment/NewEdit.cshtml	(revision 9324)
@@ -70,5 +70,12 @@
 <script type="text/template" id="checkbox_template">
 <div>
-    <input type="checkbox" name="<%=name%>"/><%=text%><br/>
+    <input type="checkbox" name="<%=name%>"
+        <% if (checked) { %>
+            checked
+        <% } %>
+    />
+    <% if (!hideText) { %>
+         <%=text%><br/>
+    <% } %>
 </div>
 </script>       
@@ -93,5 +100,5 @@
 
 <script type="text/javascript">
-    var controller = new ExperimentEditPageController();
+    var controller = new OAAS_CONTROLLER.ExperimentEditPageController();
     $(document).ready(function () {
         controller.create();
@@ -145,5 +152,10 @@
   <div id="step1">
   <fieldset>        
-    <div id="experiments"></div>
+    <div id="experiments">
+        <span>Loading ... <img src="@Url.Content("~/Content/ajax-loader.gif")" alt="Loading animation" />  </span>        
+    </div>
+    <div class="experimentMenu">
+        <button type="button" disabled="disabled" id="deleteExperimentButton">Delete</button>
+    </div>
   </fieldset>
   </div>
@@ -210,6 +222,6 @@
 @section submenu {
     <ul>
-        <li>@Html.ActionLink("Build", "New")</li>    
-        <li class="selected">@Html.ActionLink("Edit", "NewEdit")</li>
+        <li>@Html.ActionLink("Build", "New", "Experiment")</li>    
+        <li class="selected">@Html.ActionLink("Edit", "NewEdit", "Experiment")</li>
         <li>@Html.ActionLink("Status", "Index", "Status")</li>
     </ul>
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Job/Index.cshtml
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Job/Index.cshtml	(revision 9324)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Job/Index.cshtml	(revision 9324)
@@ -0,0 +1,100 @@
+﻿@section customHeader {
+    <script type='text/javascript' src='@Url.Content("~/Content/job.model.js")'></script>
+    <script type='text/javascript' src='@Url.Content("~/Content/job.view.js")'></script>
+    <script type='text/javascript' src='@Url.Content("~/Content/job.controller.js")'></script>
+    <script type='text/javascript' src='@Url.Content("~/Content/moment.min.js")'></script>
+}
+
+@{
+    ViewBag.Title = "Jobs";
+}
+
+<script type="text/template" id="loadingTemplate">
+    <span><%= text %> <img src="@Url.Content("~/Content/ajax-loader.gif")" alt="Loading animation" class="hugeLoading" /> </span>
+</script>
+
+<script type="text/template" id="jobRowTemplate">
+<tr data-jobId="<%= Id%>">
+  <td><%= Id%></td>
+  <td>
+    <%= moment(DateCreated).format('YYYY-MM-DD HH:mm:ss') %>
+  </td>
+  <td><%= Name%></td>
+  <td><%= Resource%></td>  
+  <td>
+  <% if (Loading) { %>
+    <img src="@Url.Content("~/Content/ajax-loader.gif")" alt="Loading animation" class="loader" />
+  <% }%>
+  <% if (State == 0) { %>    
+  <span>Waiting...</span>
+  <% } else if (State == 1) { %>
+  <span>Calculating...</span>
+  <% } else if (State == 2) { %>
+  <img src="@Url.Content("~/Content/warning-2.png")" alt="Loading animation" class="loader" />
+  <span>Aborted</span>
+  <% } else if (State == 3) { %>
+  <img src="@Url.Content("~/Content/warning-2.png")" alt="Loading animation" class="loader" />
+  <span>Failed</span>
+  <% } else { %>
+  <img src="@Url.Content("~/Content/ok-2.png")" alt="Loading animation" class="loader" />
+  <span>Finished</span>
+  <% } %>  
+  </td>
+  <td><button type="button" data-id="<%= Id %>" data-name="DeleteButton" >Delete</Button></td>
+</tr>
+</script>
+
+<script type="text/template" id="jobHeaderTemplate">
+<thead>
+<tr>
+  <th>Id</th>
+  <th>Created</th>
+  <th>Name</th>
+  <th>Resource</th>
+  <th>State</th>
+  <td>Delete</td>
+</tr>
+</thead>
+</script>
+
+<script type="text/template" id="runTemplate">
+  <h3><%= name %></h3>
+  <div>
+    <table>
+      <thead>
+        <tr>
+          <td>Key</td>
+          <td>Value</td>
+        </tr>
+      </thead>
+      <tbody>
+      </tbody>
+    </table>
+  </div>
+</script>
+
+
+<script type='text/javascript'>
+$(document).ready(function () {
+    var ctrl = new OAAS_CONTROLLER.JobPageController();
+    ctrl.create();
+  });
+
+</script>
+<noscript>
+<p>
+  Please activate JavaScript to view this page correctly!
+</p>
+</noscript>
+
+<h1>Job overview</h1>
+<div id='jobOverview' style='overflow: auto; height: 450px' class='bigImage'>
+    <p>Loading jobs... Please be patient...</p>
+    <img src="@Url.Content("~/Content/ajax-loader.gif")" alt="Loading animation" class="hugeLoading" />
+</div>
+
+
+<h1>Job results</h1>
+<div id='jobDetails'></div>
+<div id='tmp'>
+</div>
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Shared/_Layout.cshtml
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Shared/_Layout.cshtml	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Shared/_Layout.cshtml	(revision 9324)
@@ -32,5 +32,5 @@
 
     <!-- Experiment Additions -->
-    <script src="@Url.Content("~/Content/Datatypemapping.js")" type="text/javascript"></script>
+    
     <link href="@Url.Content("~/Content/smartwizard2.0/styles/smart_wizard.css")" rel="stylesheet" type="text/css" />
     <script type="text/javascript" src="@Url.Content("~/Content/smartwizard2.0/js/jquery.smartWizard-2.0.min.js")"></script>
@@ -40,7 +40,10 @@
     <script type='text/javascript' src='@Url.Content("~/Content/backbone/backbone-relational.js")'></script>
 
+    <script src="@Url.Content("~/Content/Datatypemapping.js")" type="text/javascript"></script>
     <script type='text/javascript' src='@Url.Content("~/Content/experiment.model.js")'></script>
     <script type='text/javascript' src='@Url.Content("~/Content/experiment.view.js")'></script>
     <script type='text/javascript' src='@Url.Content("~/Content/experiment.controller.js")'></script>
+
+    @RenderSection("customHeader", required: false)
 </head>
 <body>
Index: /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Status/Index.cshtml
===================================================================
--- /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Status/Index.cshtml	(revision 9323)
+++ /branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Status/Index.cshtml	(revision 9324)
@@ -103,6 +103,6 @@
 @section submenu {
     <ul>
-        <li>@Html.ActionLink("Build", "Index")</li>    
-        <li>@Html.ActionLink("Edit", "Edit")</li>
+        <li>@Html.ActionLink("Build", "New", "Experiment")</li>    
+        <li>@Html.ActionLink("Edit", "NewEdit", "Experiment")</li>
         <li class="selected">@Html.ActionLink("Status", "Index", "Status")</li>
     </ul>
