Index: branches/OaaS/HeuristicLab.Clients.Hive/3.3/Util/PluginUtil.cs
===================================================================
--- branches/OaaS/HeuristicLab.Clients.Hive/3.3/Util/PluginUtil.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Clients.Hive/3.3/Util/PluginUtil.cs	(revision 9227)
@@ -27,4 +27,5 @@
 using System.ServiceModel;
 using HeuristicLab.PluginInfrastructure;
+using System.Diagnostics;
 
 namespace HeuristicLab.Clients.Hive {
@@ -103,4 +104,7 @@
           CollectPluginDependencies(plugins, plugin);
         }
+        else if (plugin == null && !type.FullName.StartsWith("System")) {
+          Trace.WriteLine("No plugin available for: " + type.FullName);
+        }
       }
     }
Index: branches/OaaS/HeuristicLab.Services.Hive.WebRole/AzureLocalStorageTraceListener.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Hive.WebRole/AzureLocalStorageTraceListener.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Hive.WebRole/AzureLocalStorageTraceListener.cs	(revision 9227)
@@ -6,5 +6,5 @@
 
 namespace HeuristicLab.Services.Hive.WebRole {
-  public class AzureLocalStorageTraceListener : XmlWriterTraceListener {
+  /*public class AzureLocalStorageTraceListener : XmlWriterTraceListener {
     public AzureLocalStorageTraceListener()
       : base(Path.Combine(AzureLocalStorageTraceListener.GetLogDirectory().Path, "HeuristicLab.Services.Hive.WebRole.svclog")) {
@@ -18,4 +18,4 @@
       return directory;
     }
-  }
+  }*/
 }
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs	(revision 9227)
@@ -9,4 +9,5 @@
 using System.Diagnostics;
 using HeuristicLab.Services.Optimization.ControllerService.Model;
+using HeuristicLab.Services.Optimization.ControllerService.Parsers;
 
 namespace HeuristicLab.Services.Optimization.ControllerService.Azure {
@@ -15,5 +16,8 @@
     public static readonly string SCENARIO_BLOB_CONTAINER = "scenario";
     public static readonly string EXPERIMENT_TABLE = "Experiment";
+    public static readonly string EXPERIMENT_BLOB_CONTAINER = "experiment";
     public static readonly string CLOUD_SETTINGS_KEY = "Cloudia.WindowsAzure.Storage";
+
+    
   }
 
@@ -97,18 +101,14 @@
     }
 
-    public ExperimentEntity(string user, Experiment experiment) {
+    public ExperimentEntity(string user, string experimentName, string experimentUrl) {
       PartitionKey = "ScenarioPartition";
-      RowKey = user + "_" + experiment.Name;
-      var scenarios = "";
-      foreach (var scen in experiment.Scenarios) {
-        scenarios += scen.Id + ",";
-      }
-      Scenarios = scenarios.Remove(scenarios.Length - 1);
+      RowKey = user + "_" + experimentName;      
       User = user;
+      ExperimentJsonUrl = experimentUrl;
     }
 
     public string User { get; set; }
 
-    public string Scenarios { get; set; }
+    public string ExperimentJsonUrl { get; set; }
 
   }
@@ -122,7 +122,18 @@
         return false;
 
-      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
-      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
-      var entity = new ExperimentEntity(username, experiment);
+      // TODO: Save the whole experiment, not just the algorithm names!!!
+      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
+      container.CreateIfNotExist();
+      // For now we store it as JSON element in the blob store
+      // TODO: Make sure, that all required properties are part of the experiment!!
+      var experimentJson = AlgorithmConverter.ConvertJson(experiment);
+      Guid experimentJsonGuid = Guid.NewGuid();
+      var experimentJsonId = experiment.Name + "_" + experimentJsonGuid.ToString();
+      var blob = container.GetBlobReference(experimentJsonId);      
+      blob.UploadText(experimentJson);
+
+      TableServiceContext serviceContext = TableClient.GetDataServiceContext();      
+      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
+      var entity = new ExperimentEntity(username, experiment.Name, blob.Uri.ToString());
       serviceContext.AddObject(AzureConstants.EXPERIMENT_TABLE, entity);
       serviceContext.SaveChangesWithRetries();
@@ -139,4 +150,11 @@
       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);
@@ -156,14 +174,17 @@
       }
 
-      var exp = Convert(entity);
-      return exp;
-    }
-
-    private Experiment Convert(ExperimentEntity entity) {
-      var exp = new Experiment() { Name = entity.RowKey.Split('_')[1] };
-      foreach (var scenarioName in entity.Scenarios.Split(','))
-        exp.Scenarios.Add(new OptimizationScenario() { Id = scenarioName });
-      return exp;
-    }
+      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
+      container.CreateIfNotExist();
+      var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
+      return AlgorithmConverter.ConvertExperimentSimple(blob.DownloadText());
+    }
+
+    //private Experiment Convert(ExperimentEntity entity, string entityJson) {
+    //  // TODO: Read the whole experiment, not just the names!
+    //  var exp = new Experiment() { Name = entity.RowKey.Split('_')[1] };
+    //  foreach (var scenarioName in entity.Algorithms.Split(','))
+    //    exp.Algorithm.Add(new Algorithm() { Name = scenarioName });
+    //  return exp;
+    //}
 
     public IEnumerable<Model.Experiment> GetExperiments(string user) {
@@ -174,8 +195,29 @@
                     select e).ToList();
       var experiments = new List<Experiment>();
+      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
+      container.CreateIfNotExist();
       foreach (var entity in entites) {
-        experiments.Add(Convert(entity));
+        var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
+        experiments.Add(AlgorithmConverter.ConvertExperimentSimple(blob.DownloadText()));
       }
       return experiments;
+    }
+
+
+    public Experiment GetExperimentByName(string username, string scenario) {
+      TableServiceContext serviceContext = TableClient.GetDataServiceContext();
+      TableClient.CreateTableIfNotExist(AzureConstants.EXPERIMENT_TABLE);
+      var entity = (from e in serviceContext.CreateQuery<ExperimentEntity>(AzureConstants.EXPERIMENT_TABLE)
+                      where e.RowKey == username + "_" + scenario
+                      select e).FirstOrDefault();
+      if (entity == null || entity.ExperimentJsonUrl == null) {
+        return null;
+      }
+
+      CloudBlobContainer container = BlobClient.GetContainerReference(AzureConstants.EXPERIMENT_BLOB_CONTAINER);
+      container.CreateIfNotExist();
+      var blob = container.GetBlobReference(entity.ExperimentJsonUrl);
+      var exp = AlgorithmConverter.ConvertExperimentSimple(blob.DownloadText());
+      return exp;
     }
   }
@@ -224,5 +266,5 @@
       get {
         if (expDao == null) {
-          expDao = new ExperimentDao() { TableClient = StorageAccount.CreateCloudTableClient() };
+          expDao = new ExperimentDao() { TableClient = StorageAccount.CreateCloudTableClient(), BlobClient = StorageAccount.CreateCloudBlobClient() };
         }
         return expDao;
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/General/AlgorithmHelper.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/General/AlgorithmHelper.cs	(revision 9227)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/General/AlgorithmHelper.cs	(revision 9227)
@@ -0,0 +1,58 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Services.Optimization.ControllerService.Model;
+
+namespace HeuristicLab.Services.Optimization.ControllerService.General {
+  public class AlgorithmHelper {
+    public static bool HasToBeUpdated(Algorithm algo) {
+      if (algo.Parameters != null)
+        foreach (var param in algo.Parameters.Items) {
+          if (RequiresUpdate(param)) return true;
+        }
+
+      if (algo.Problem != null && algo.Problem.Parameters != null) 
+        foreach (var param in algo.Problem.Parameters.Items) {
+          if (RequiresUpdate(param)) return true;
+        }
+
+      return false;
+    }
+
+    private static bool RequiresUpdate(Parameter param) {
+      switch (param.Type) {
+        case ParameterType.Type:
+          return ((TypeValue)param.Value).Options == null;
+        default:
+          return false;
+      }
+    }
+
+    public static void Update(Algorithm algo, OptimizationScenario scenario) {
+      if (algo.Parameters != null)
+        for (var i=0; i < algo.Parameters.Items.Count; i++) {
+          if (RequiresUpdate(algo.Parameters.Items[i])) {
+            var otherParam = (from p in scenario.FirstAlgorithm.Parameters.Items where p.Value.Name == algo.Parameters.Items[i].Value.Name select p).FirstOrDefault();
+            UpdateParameter(algo.Parameters.Items[i], otherParam);
+          }
+        } 
+
+      if (algo.Problem != null && algo.Problem.Parameters != null)
+        for (var i = 0; i < algo.Problem.Parameters.Items.Count; i++) {
+          if (RequiresUpdate(algo.Problem.Parameters.Items[i])) {
+            var otherParam = (from p in scenario.FirstAlgorithm.Problem.Parameters.Items where p.Value.Name == algo.Problem.Parameters.Items[i].Value.Name select p).FirstOrDefault();
+            UpdateParameter(algo.Problem.Parameters.Items[i], otherParam);
+          }
+        }
+    }
+
+    private static void UpdateParameter(Parameter param, Parameter param2) {
+      switch (param.Type) {
+        case ParameterType.Type:
+          ((TypeValue)param.Value).Options = ((TypeValue)param2.Value).Options;
+          break;
+      }
+    }
+  }
+}
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs	(revision 9227)
@@ -58,8 +58,8 @@
       // algo.Problem = problem;      
       
-      IScenarioMapper mapper = GetMapper(scenario);
+      IScenarioMapper mapper = GetMapper(scenario.Id);
       IAlgorithm algo;
       mapper.MapScenario(scenario, out algo);
-      if (details.Repititions > 1) {
+      /*if (details.Repititions > 1) {
         BatchRun br = new BatchRun();
         //br.Name = details.JobTitle;
@@ -69,6 +69,57 @@
       }
       else {       
-        return SendExperimentToHive(user, algo, details);
-      }
+        
+      }*/
+      return SendExperimentToHive(user, algo, details);
+    }
+
+    private sealed class StackEntry {
+      public HeuristicLab.Optimization.Experiment Parent { get; set; }
+      public IList<Model.Algorithm> Children { get; set; }
+    }
+
+    public bool DispatchExperiment(User user, Model.Experiment exp, JobExecutionDetails details) {
+      // TODO: Determine how to build a tree of IAlgorithm
+      // For now the experiment will be flatened for execution
+      HeuristicLab.Optimization.Experiment hiveExperiment = new HeuristicLab.Optimization.Experiment(exp.Name);
+      var stack = new Stack<StackEntry>();
+      var children = new List<Model.Algorithm>();
+      foreach (var child in exp.Algorithm) {
+        children.Add(child);        
+      }
+      stack.Push(new StackEntry() { Parent = hiveExperiment, Children = children });
+
+      while (stack.Count > 0) {
+        var entry = stack.Pop();
+        // handle current entry
+
+        // TODO: Store scenario name in entry.Child.Mapper when saving
+        foreach (var child in entry.Children) {
+          // This is a template experiment; 
+          if (child.Name == null) {
+            var parent = new HeuristicLab.Optimization.Experiment(child.Name);
+            entry.Parent.Optimizers.Add(parent);
+            stack.Push(new StackEntry() { Parent = parent, Children = child.ChildAlgorithms });          
+          }
+          // This entity is mapable
+          else {           
+            IScenarioMapper mapper = GetMapper(child.Name);
+            if (mapper == null) { // TODO: We should really be able to difference Experiment/Algorithm types; this is a workaround
+              var parent = new HeuristicLab.Optimization.Experiment(child.Name);
+              entry.Parent.Optimizers.Add(parent);
+              stack.Push(new StackEntry() { Parent = parent, Children = child.ChildAlgorithms });          
+            }
+            else {
+              var optScen = new OptimizationScenario() { Id = child.Name };
+              optScen.Algorithm.Add(child);
+              IAlgorithm algo;
+              mapper.MapScenario(optScen, out algo);
+              entry.Parent.Optimizers.Add(algo);
+            }
+          }  
+        }
+      }
+      details.JobTitle = exp.Name;
+      return SendExperimentToHive(user, hiveExperiment, details) != null;
     }
 
@@ -113,6 +164,6 @@
     }
 
-    private IScenarioMapper GetMapper(Model.OptimizationScenario scenario) {
-      var id = scenario.Id;
+    private IScenarioMapper GetMapper(string scenarioId) {
+      var id = scenarioId;
       if (!mappers.ContainsKey(id)) {
         lock (lockable) {
@@ -121,4 +172,5 @@
           
           var mapperString = GetMapperFromBlobStore(id);
+          if (mapperString == null) return null;
           var mapper = CompileMapper(mapperString);
 
@@ -131,12 +183,14 @@
 
     private void MapExperiment(Model.OptimizationScenario scenario, out IAlgorithm algorithm) {      
-      IScenarioMapper mapper = GetMapper(scenario);
+      IScenarioMapper mapper = GetMapper(scenario.Id);
       mapper.MapScenario(scenario, out algorithm);     
     }
 
-    private void ConfigureHive(Model.User user) {
-      HiveServiceLocator.Instance.Username = user.Username;
-      HiveServiceLocator.Instance.Password = user.Password;
-      HiveServiceLocator.Instance.EndpointConfigurationName = Configuration.HiveEndpointName;      
+    private HiveServiceLocator ConfigureHive(Model.User user) {
+      var serviceLocator = new HiveServiceLocator();
+      serviceLocator.Username = user.Username;
+      serviceLocator.Password = user.Password;
+      serviceLocator.EndpointConfigurationName = Configuration.HiveEndpointName;
+      return serviceLocator;
     }
 
@@ -146,11 +200,23 @@
       job.Job.Name = details.JobTitle;
       job.Job.ResourceNames = details.Group;      
-      job.RefreshAutomatically = false;     
+      job.RefreshAutomatically = false;
+      
+      if (details.Repititions > 1) {
+        BatchRun br = new BatchRun();
+        br.Optimizer = exp;
+        br.Repetitions = details.Repititions;
+        exp = br;
+      }
+
       if (exp.ExecutionState != ExecutionState.Prepared) {
         exp.Prepare();
       }      
       job.HiveTasks.Add(new OptimizerHiveTask(exp));
-      ConfigureHive(user);
-      
+      var service = ConfigureHive(user);
+      
+      // TODO: Fix HiveClient class to be not dependent on singleton HiveServiceLocator!!!
+      HiveServiceLocator.Instance.Username = user.Username;
+      HiveServiceLocator.Instance.Password = user.Password;
+      HiveServiceLocator.Instance.EndpointConfigurationName = Configuration.HiveEndpointName;
       HiveClient.StartJob((ex) => { 
         Console.WriteLine(ex.StackTrace); 
@@ -163,6 +229,6 @@
 
     public IList<Model.Job> GetJobs(User user) {
-      ConfigureHive(user);
-      var jobsLoaded = HiveServiceLocator.Instance.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.Job>>(s => s.GetJobs());
+      var serviceLocator = ConfigureHive(user);
+      var jobsLoaded = serviceLocator.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.Job>>(s => s.GetJobs());
       IList<Model.Job> jobs = new List<Model.Job>();
 
@@ -189,21 +255,21 @@
 
     public Model.Job GetJob(User user, string id) {
-      ConfigureHive(user);
+      var serviceLocator = ConfigureHive(user);
       var guid = Guid.Parse(id);
-      return ConvertJob(user, HiveServiceLocator.Instance.CallHiveService<HeuristicLab.Clients.Hive.Job>(s => s.GetJob(guid)));
+      return ConvertJob(user, serviceLocator.CallHiveService<HeuristicLab.Clients.Hive.Job>(s => s.GetJob(guid)));
     }
 
 
     public bool DeleteJob(User user, string id) {
-      ConfigureHive(user);
+      var serviceLocator = ConfigureHive(user);
       var guid = Guid.Parse(id);      
-      HiveServiceLocator.Instance.CallHiveService(s => s.DeleteJob(guid));
+      serviceLocator.CallHiveService(s => s.DeleteJob(guid));
       return true;
     }
 
     public IList<Model.Run> GetJobResults(User user, string id) {
-      ConfigureHive(user);
+      var serviceLocator = ConfigureHive(user);
       var guid = Guid.Parse(id);
-      var jobTasks = HiveServiceLocator.Instance.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.LightweightTask>>(s => s.GetLightweightJobTasks(guid));
+      var jobTasks = serviceLocator.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.LightweightTask>>(s => s.GetLightweightJobTasks(guid));
 
       IList<Guid> taskIds = new List<Guid>();
@@ -211,4 +277,9 @@
         taskIds.Add(task.Id);
       }
+
+      // TODO: Fix problems with the HiveServiceLocater singleton!!!
+      HiveServiceLocator.Instance.Username = user.Username;
+      HiveServiceLocator.Instance.Password = user.Password;
+      HiveServiceLocator.Instance.EndpointConfigurationName = Configuration.HiveEndpointName;
       TaskDownloader downloader = new TaskDownloader(taskIds);
       downloader.StartAsync();
@@ -337,4 +408,5 @@
         result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = "Cannot be displayed as string" };
       }
+      // TODO: Add workaround for TSP
       return result;
     }
@@ -416,4 +488,7 @@
     public Model.Task GetTaskData(User u, string jobId, string taskId) {
       ConfigureHive(u);
+      HiveServiceLocator.Instance.Username = u.Username;
+      HiveServiceLocator.Instance.Password = u.Password;
+      HiveServiceLocator.Instance.EndpointConfigurationName = Configuration.HiveEndpointName;
       TaskDownloader downloader = new TaskDownloader(new List<Guid>(){Guid.Parse(taskId)});
       downloader.StartAsync();
@@ -446,6 +521,6 @@
 
     public Model.Job GetTasks(User u, string jobId) {
-      ConfigureHive(u);
-      var jobTasks = HiveServiceLocator.Instance.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.LightweightTask>>(s => s.GetLightweightJobTasks(Guid.Parse(jobId)));
+      var serviceLocator = ConfigureHive(u);
+      var jobTasks = serviceLocator.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.LightweightTask>>(s => s.GetLightweightJobTasks(Guid.Parse(jobId)));
       
       var job = new Model.Job();
@@ -455,5 +530,5 @@
       foreach (var task in jobTasks) {
         // TODO: Crawl children + parent and create hierarchy!
-        var children = HiveServiceLocator.Instance.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.LightweightTask>>(s => s.GetLightweightChildTasks(Guid.Parse(jobId), true, true));
+        var children = serviceLocator.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.LightweightTask>>(s => s.GetLightweightChildTasks(Guid.Parse(jobId), true, true));
         foreach (var child in children) {
           tasks[child.Id] = new Model.Task() {
@@ -483,4 +558,12 @@
       return job;
     }
+
+
+    public Model.Experiment GetExperimentByName(User user, string scenario) {
+      return dal.ExperimentDao.GetExperimentByName(user.Username, scenario);
+    }
+
+
+
   }
 }
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/HeuristicLab.Services.Optimization.ControllerService.csproj
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/HeuristicLab.Services.Optimization.ControllerService.csproj	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/HeuristicLab.Services.Optimization.ControllerService.csproj	(revision 9227)
@@ -168,4 +168,5 @@
   <ItemGroup>
     <Compile Include="Azure\DAL.cs" />
+    <Compile Include="General\AlgorithmHelper.cs" />
     <Compile Include="General\Configuration.cs" />
     <Compile Include="HL\HiveMapper.cs" />
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/DAL.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/DAL.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/DAL.cs	(revision 9227)
@@ -23,4 +23,5 @@
     Experiment FindByName(string username, string experiment);
     IEnumerable<Experiment> GetExperiments(string user);
+    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 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IControllerService.cs	(revision 9227)
@@ -21,4 +21,7 @@
     [OperationContract]
     bool ScheduleOptimizationScenario(User user, OptimizationScenario scenario, JobExecutionDetails details);
+
+    [OperationContract]
+    bool ScheduleExperiment(User user, string experiment, JobExecutionDetails details);
 
     [OperationContract]
@@ -54,4 +57,7 @@
     [OperationContract]
     Task GetTaskData(User u, string jobId, string taskId);
+
+    [OperationContract]
+    Experiment GetExperimentByName(User user, string scenario);
   }
 }
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IScenarioManager.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IScenarioManager.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IScenarioManager.cs	(revision 9227)
@@ -21,4 +21,7 @@
     Task GetTaskData(User u, string jobId, string taskId);
     Job GetTasks(User u, string jobId);
+
+    Experiment GetExperimentByName(User user, string scenario);
+    bool DispatchExperiment(User user, Experiment exp, JobExecutionDetails details);
   }
 }
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/Model/ControllerModel.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/Model/ControllerModel.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/Model/ControllerModel.cs	(revision 9227)
@@ -274,5 +274,5 @@
   [DataContract]
   public class Algorithm {
-    public Algorithm() { Parameters = new AlgorithmParameters(); }
+    public Algorithm() { Parameters = new AlgorithmParameters(); ChildAlgorithms = new List<Algorithm>(); }
 
     [DataMember]
@@ -290,4 +290,7 @@
     [DataMember]
     public string Mapper { get; set; }
+
+    [DataMember]
+    public string Name { get; set; }
   }
 
@@ -296,5 +299,7 @@
     [DataMember]
     public string Id { get; set; }
-   
+
+    public OptimizationScenario() { Algorithm = new List<Algorithm>(); }
+
     [DataMember]
     public IList<Algorithm> Algorithm { get; set; }
@@ -309,9 +314,12 @@
 
     [DataMember]
-    public IList<OptimizationScenario> Scenarios { get; set; }
+    public IList<Algorithm> Algorithm { get; set; }
 
     public Experiment() {
-      Scenarios = new List<OptimizationScenario>();
-    }
+      Algorithm = new List<Algorithm>();
+    }
+
+    [DataMember]
+    public JobExecutionDetails JobDetails { get; set; }
   }
 
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Mockup/MockupScenarioManager.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/Mockup/MockupScenarioManager.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/Mockup/MockupScenarioManager.cs	(revision 9227)
@@ -263,4 +263,14 @@
       throw new NotImplementedException();
     }
+
+
+    public Model.Experiment GetExperimentByName(User user, string scenario) {
+      throw new NotImplementedException();
+    }
+
+
+    public bool DispatchExperiment(User user, Model.Experiment exp, JobExecutionDetails details) {
+      throw new NotImplementedException();
+    }
   }
 }
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Parsers/AlgorithmConverter.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/Parsers/AlgorithmConverter.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/Parsers/AlgorithmConverter.cs	(revision 9227)
@@ -5,4 +5,5 @@
 using HeuristicLab.Services.Optimization.ControllerService.Model;
 using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
 
 namespace HeuristicLab.Services.Optimization.ControllerService.Parsers {
@@ -10,13 +11,17 @@
 
     public static Algorithm Convert(string json) {
+      var o = JObject.Parse(json);
+      return ParseAlgorithm(o);      
+    }
+
+    private static Algorithm ParseAlgorithm(JToken obj) {
       var algorithm = new Algorithm();
-      var o = JObject.Parse(json);
-      foreach (JProperty param in o["Algorithm Parameters"]) {
+
+      foreach (JProperty param in obj["Algorithm Parameters"]) {
         Parameter parameter = CreateParameter(param);
         algorithm.Parameters.Items.Add(parameter);
       }
 
-      var problemParams = o["Problem Parameters"];
-      // TODO: Store problem parameters
+      var problemParams = obj["Problem Parameters"];
       if (problemParams != null) {
         algorithm.Problem = new Problem();
@@ -69,8 +74,84 @@
         case JTokenType.String:
           return new Parameter() { Type = ParameterType.Type, Value = new TypeValue() { Name = property.Name, Value = (string)property.Value } };                  
+        case JTokenType.Array:
+          var arr = (JArray)token;
+          // its a matrix
+          if (arr[0].Type == JTokenType.Array) {
+            return CreateMatrixParameter(property.Name, arr);
+          }
+          return CreateVectorParameter(property.Name, arr);
         default:
           throw new Exception("Unhandled datatype: " + property.Type);
       }
     }
+
+    private static Parameter CreateMatrixParameter(string name, JArray arr) {
+      double[][] entries = new double[arr.Count][];
+      for (int i = 0; i < entries.Length; i++) {
+        entries[i] = (from d in arr[i] select (double)d).ToArray<double>();  
+      }
+      return new Parameter { Type = ParameterType.DecimalMatrix, Value = new DecimalMatrix() { Name = name, Value = entries } };
+    }
+
+    private static Parameter CreateVectorParameter(string name, JArray arr) {
+      double[] entries = (from d in arr select (double)d).ToArray<double>();
+      return new Parameter { Type = ParameterType.DecimalVector, Value = new DecimalVector() { Name = name, Value = entries } };
+    }
+
+    public static string ConvertJson(Algorithm algorithm) {
+      return JsonConvert.SerializeObject(algorithm);
+    }
+
+    
+    private class StackEntry {
+      public Algorithm Parent { get; set; }
+      public JToken Child { get; set; }
+    }
+
+    public static Experiment ConvertExperimentSimple(string json) {
+      return JsonConvert.DeserializeObject<Experiment>(json, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.Auto });
+    }
+
+    public static string ConvertJson(Experiment experiment) {
+      return JsonConvert.SerializeObject(experiment, Formatting.None, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto });
+    }
+
+    public static Experiment ConvertExperiment(string json) {
+      var experiment = new Experiment();
+      var jsonExperiment = JObject.Parse(json);
+      experiment.Name = (string)jsonExperiment["name"];
+      var stack = new Stack<StackEntry>();
+      var root = new Algorithm();
+
+      if ((bool)jsonExperiment["run"]) {
+        experiment.JobDetails = new JobExecutionDetails() {
+           Group = (string)jsonExperiment["group"],
+           Repititions = (int)jsonExperiment["repititions"]
+        };
+      }
+
+      foreach (var algo in jsonExperiment["algorithms"]["children"]) {
+        stack.Push(new StackEntry(){ Parent = root, Child = algo });
+      }
+
+      while (stack.Count > 0) {
+        var entry = stack.Pop();
+        var data = entry.Child["data"];
+        var currentAlgo = data == null ? new Algorithm() : ParseAlgorithm(entry.Child["data"]);
+        currentAlgo.Name = (string)entry.Child["name"];
+        entry.Parent.ChildAlgorithms.Add(currentAlgo);
+        // push children on stack (inverse order to preserve ordering)
+        var cnt = entry.Child["children"].Count();
+        for (var i=0; i < cnt; i++) {
+          stack.Push(new StackEntry() { Parent = currentAlgo, Child = entry.Child["children"][cnt - 1 - i] });
+        }
+      }
+
+      foreach (var algo in root.ChildAlgorithms) {
+        experiment.Algorithm.Add(algo);
+      }
+
+      return experiment;
+    }
   }
 }
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/PlaceholderControllerService.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/PlaceholderControllerService.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/PlaceholderControllerService.cs	(revision 9227)
@@ -6,4 +6,5 @@
 using HeuristicLab.Services.Optimization.ControllerService.Interfaces;
 using HeuristicLab.Services.Optimization.ControllerService.Model;
+using HeuristicLab.Services.Optimization.ControllerService.General;
 
 namespace HeuristicLab.Services.Optimization.ControllerService {
@@ -120,6 +121,35 @@
 
 
-    public bool SaveExperiment(User user, Experiment experiment) {
-      return hiveManager.SaveExperiment(user, experiment);
+    public bool SaveExperiment(User user, Experiment experiment) {      
+      // make sure all algorithms store their choices aswell
+      var scenarioMap = new Dictionary<string, OptimizationScenario>();
+      var algos = new Stack<Algorithm>();
+      foreach (var algo in experiment.Algorithm) algos.Push(algo);
+      
+      
+
+      while (algos.Count > 0) {
+        var algo = algos.Pop();
+        if (algo.ChildAlgorithms != null)
+          foreach (var child in algo.ChildAlgorithms) algos.Push(child);
+
+        if (AlgorithmHelper.HasToBeUpdated(algo)) {
+          OptimizationScenario scenario;
+          if (!scenarioMap.TryGetValue(algo.Name, out scenario)) {
+            scenario = GetOptimizationScenarioByName(algo.Name);
+            scenarioMap[algo.Name] = scenario;
+          }
+          
+          AlgorithmHelper.Update(algo, scenario);
+        }
+      }
+
+      // finally store the experiment
+      var success = hiveManager.SaveExperiment(user, experiment);
+      // if it has been stored, and jobdetails are present, run the job!
+      if (success && experiment.JobDetails != null) {
+        return ScheduleExperiment(user, experiment.Name, experiment.JobDetails);
+      }
+      return success;
     }
 
@@ -142,4 +172,15 @@
       return hiveManager.GetTaskData(u, jobId, taskId);
     }
+
+
+    public Experiment GetExperimentByName(User user, string scenario) {
+      return hiveManager.GetExperimentByName(user, scenario);
+    }
+
+
+    public bool ScheduleExperiment(User user, string experiment, JobExecutionDetails details) {
+      var exp = hiveManager.GetExperimentByName(user, experiment);
+      return hiveManager.DispatchExperiment(user, exp, details);
+    }
   }
 }
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/Binders/AlgorithmJsonAttribute.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/Binders/AlgorithmJsonAttribute.cs	(revision 9227)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/Binders/AlgorithmJsonAttribute.cs	(revision 9227)
@@ -0,0 +1,76 @@
+﻿// http://blog.duc.as/2011/06/07/making-mvc-3-a-little-more-dynamic/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+using System.IO;
+using System.Web.Helpers;
+using HeuristicLab.Services.Optimization.ControllerService.Model;
+using HeuristicLab.Services.Optimization.ControllerService.Parsers;
+
+namespace Mvc3TestApplication.Binders
+{
+  public class AlgorithmJsonAttribute : CustomModelBinderAttribute
+  {
+    public override IModelBinder GetBinder()
+    {
+      return new AlgorithmJsonBinder();
+    }
+  }
+
+  public class AlgorithmJsonBinder : IModelBinder
+  {
+    public AlgorithmJsonBinder()
+    {
+    }
+
+    public object BindModel(ControllerContext controllerCtx, ModelBindingContext bindingCtx)
+    {
+      var contentType = controllerCtx.HttpContext.Request.ContentType;
+      if (!contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
+        return null;
+
+      string body;
+      using (var stream = controllerCtx.HttpContext.Request.InputStream)
+      {
+        stream.Seek(0, System.IO.SeekOrigin.Begin);
+        using (var reader = new StreamReader(stream))
+          body = reader.ReadToEnd();
+      }
+      if (string.IsNullOrEmpty(body)) return null;
+      return AlgorithmConverter.Convert(body);
+    }
+
+    
+  }
+
+  public class ExperimentJsonAttribute : CustomModelBinderAttribute {
+    public override IModelBinder GetBinder() {
+      return new ExperimentJsonBinder();
+    }
+  }
+
+  public class ExperimentJsonBinder : IModelBinder {
+    public ExperimentJsonBinder() {
+    }
+
+    public object BindModel(ControllerContext controllerCtx, ModelBindingContext bindingCtx) {
+      var contentType = controllerCtx.HttpContext.Request.ContentType;
+      if (!contentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
+        return null;
+
+      string body;
+      using (var stream = controllerCtx.HttpContext.Request.InputStream) {
+        stream.Seek(0, System.IO.SeekOrigin.Begin);
+        using (var reader = new StreamReader(stream))
+          body = reader.ReadToEnd();
+      }
+      if (string.IsNullOrEmpty(body)) return null;
+      return AlgorithmConverter.ConvertExperiment(body);
+    }
+
+
+  }
+}
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/Datatypemapping.js
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/Datatypemapping.js	(revision 9227)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/Datatypemapping.js	(revision 9227)
@@ -0,0 +1,159 @@
+function DatatypeMapper() {
+}
+
+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);
+
+        }
+        // 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_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_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);      
+    }
+    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 $*/
+}
+
+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) {
+    // 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] = []
+                }
+
+                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 key in tableEntries) {
+            entry[key] = tableEntries[key];
+        }
+    }
+}
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/js/jquery.smartWizard-2.0.min.js
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/js/jquery.smartWizard-2.0.min.js	(revision 9227)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/js/jquery.smartWizard-2.0.min.js	(revision 9227)
@@ -0,0 +1,9 @@
+(function(a){a.fn.smartWizard=function(k){var c=a.extend({},a.fn.smartWizard.defaults,k),u=arguments;return this.each(function(){function z(){var d=b.children("div");b.children("ul").addClass("anchor");d.addClass("content");l=a("<div>Loading</div>").addClass("loader");i=a("<div></div>").addClass("actionBar");m=a("<div></div>").addClass("stepContainer");n=a("<a>"+c.labelNext+"</a>").attr("href","#").addClass("buttonNext");o=a("<a>"+c.labelPrevious+"</a>").attr("href","#").addClass("buttonPrevious");
+p=a("<a>"+c.labelFinish+"</a>").attr("href","#").addClass("buttonFinish");c.errorSteps&&c.errorSteps.length>0&&a.each(c.errorSteps,function(a,b){v(b,!0)});m.append(d);i.append(l);b.append(m);b.append(i);i.append(p).append(n).append(o);w=m.width();a(n).click(function(){x();return!1});a(o).click(function(){y();return!1});a(p).click(function(){if(!a(this).hasClass("buttonDisabled"))if(a.isFunction(c.onFinish))c.onFinish.call(this,a(f));else{var d=b.parents("form");d&&d.length&&d.submit()}return!1});
+a(f).bind("click",function(){if(f.index(this)==h)return!1;var a=f.index(this);f.eq(a).attr("isDone")-0==1&&q(a);return!1});c.keyNavigation&&a(document).keyup(function(a){a.which==39?x():a.which==37&&y()});A();q(h)}function A(){c.enableAllSteps?(a(f,b).removeClass("selected").removeClass("disabled").addClass("done"),a(f,b).attr("isDone",1)):(a(f,b).removeClass("selected").removeClass("done").addClass("disabled"),a(f,b).attr("isDone",0));a(f,b).each(function(d){a(a(this).attr("href"),b).hide();a(this).attr("rel",
+d+1)})}function q(d){var e=f.eq(d),g=c.contentURL,h=e.data("hasContent");stepNum=d+1;g&&g.length>0?c.contentCache&&h?t(d):a.ajax({url:g,type:"POST",data:{step_number:stepNum},dataType:"text",beforeSend:function(){l.show()},error:function(){l.hide()},success:function(c){l.hide();c&&c.length>0&&(e.data("hasContent",!0),a(a(e,b).attr("href"),b).html(c),t(d))}}):t(d)}function t(d){var e=f.eq(d),g=f.eq(h);if(d!=h&&a.isFunction(c.onLeaveStep)&&!c.onLeaveStep.call(this,a(g)))return!1;if(c.transitionEffect=="slide")a(a(g,b).attr("href"),b).slideUp("fast",function(){a(a(e,b).attr("href"),b).slideDown("fast");h=d;r(g,e)});else if(c.transitionEffect=="fade")a(a(g,b).attr("href"),b).fadeOut("fast",function(){a(a(e,b).attr("href"),b).fadeIn("fast");h=d;r(g,e)});else if(c.transitionEffect=="slideleft"){var i=0;d>h?(nextElmLeft1=w+10,nextElmLeft2=0,i=0-a(a(g,b).attr("href"),b).outerWidth()):(nextElmLeft1=0-a(a(e,b).attr("href"),b).outerWidth()+20,nextElmLeft2=0,i=10+
+a(a(g,b).attr("href"),b).outerWidth());d==h?(nextElmLeft1=a(a(e,b).attr("href"),b).outerWidth()+20,nextElmLeft2=0,i=0-a(a(g,b).attr("href"),b).outerWidth()):a(a(g,b).attr("href"),b).animate({left:i},"fast",function(){a(a(g,b).attr("href"),b).hide()});a(a(e,b).attr("href"),b).css("left",nextElmLeft1);a(a(e,b).attr("href"),b).show();a(a(e,b).attr("href"),b).animate({left:nextElmLeft2},"fast",function(){h=d;r(g,e)})}else a(a(g,b).attr("href"),b).hide(),a(a(e,b).attr("href"),b).show(),h=d,r(g,e);return!0}
+function r(d,e){a(d,b).removeClass("selected");a(d,b).addClass("done");a(e,b).removeClass("disabled");a(e,b).removeClass("done");a(e,b).addClass("selected");a(e,b).attr("isDone",1);c.cycleSteps||(0>=h?a(o).addClass("buttonDisabled"):a(o).removeClass("buttonDisabled"),f.length-1<=h?a(n).addClass("buttonDisabled"):a(n).removeClass("buttonDisabled"));!f.hasClass("disabled")||c.enableFinishButton?a(p).removeClass("buttonDisabled"):a(p).addClass("buttonDisabled");if(a.isFunction(c.onShowStep)&&!c.onShowStep.call(this,
+a(e)))return!1}function x(){var a=h+1;if(f.length<=a){if(!c.cycleSteps)return!1;a=0}q(a)}function y(){var a=h-1;if(0>a){if(!c.cycleSteps)return!1;a=f.length-1}q(a)}function B(b){a(".content",j).html(b);j.show()}function v(d,c){c?a(f.eq(d-1),b).addClass("error"):a(f.eq(d-1),b).removeClass("error")}var b=a(this),h=c.selected,f=a("ul > li > a",b),w=0,l,j,i,m,n,o,p;i=a(".actionBar",b);i.length==0&&(i=a("<div></div>").addClass("actionBar"));j=a(".msgBox",b);j.length==0&&(j=a('<div class="msgBox"><div class="content"></div><a href="#" class="close">X</a></div>'),
+i.append(j));a(".close",j).click(function(){j.fadeOut("normal");return!1});if(!k||k==="init"||typeof k==="object")z();else if(k==="showMessage"){var s=Array.prototype.slice.call(u,1);B(s[0]);return!0}else if(k==="setError")return s=Array.prototype.slice.call(u,1),v(s[0].stepnum,s[0].iserror),!0;else a.error("Method "+k+" does not exist")})};a.fn.smartWizard.defaults={selected:0,keyNavigation:!0,enableAllSteps:!1,transitionEffect:"fade",contentURL:null,contentCache:!0,cycleSteps:!1,enableFinishButton:!1,
+errorSteps:[],labelNext:"Next",labelPrevious:"Previous",labelFinish:"Finish",onLeaveStep:null,onShowStep:null,onFinish:null}})(jQuery);
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/readme.md
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/readme.md	(revision 9227)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/readme.md	(revision 9227)
@@ -0,0 +1,34 @@
+Overview
+--------
+Smart Wizard is a flexible jQuery plug-in for wizard like interface. 
+It allows to group contents into sections and so it saves page space and also gives a neat and stylish interface for users.
+
+Demos
+-----
+[Basic Example](http://techlaboratory.net/labs/SmartWizard2/index.htm)
+[Ajax Contents](http://techlaboratory.net/labs/SmartWizard2/smartwizard2-ajax.htm)
+[Step Validation](http://techlaboratory.net/labs/SmartWizard2/smartwizard2-validation.php)
+[Multiple Wizard](http://techlaboratory.net/labs/SmartWizard2/smartwizard2-multiple.htm)
+[Vertical Style](http://techlaboratory.net/labs/SmartWizard2/smartwizard2-vertical.htm) 
+
+Features
+--------
+      Easy to implement, Minimal HTML required.
+      Ajax contents loading option.
+      Cool animation effects on step navigation. (none/fade/slide/slideleft)
+      Keyboard navigation option.
+      Horizontal and vertical style step anchors.
+      Easy step input validation option
+      Option to highlight error steps
+      In-built message box
+      Easy navigation with step anchors and navigation buttons
+      Can have multiple wizards on same page
+      Option to enable all steps on first load
+
+License
+-------
+Free to use and modify on both personal and commercial environment
+
+Creative Commons License
+Licensed under a [Creative Commons Attribution-ShareAlike 3.0 Unported License.](http://creativecommons.org/licenses/by-sa/3.0/)
+ 
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/styles/smart_wizard.css
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/styles/smart_wizard.css	(revision 9227)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/styles/smart_wizard.css	(revision 9227)
@@ -0,0 +1,309 @@
+/*   
+  SmartWizard 2.0 plugin 
+  jQuery Wizard control Plugin
+  by Dipu
+  
+  http://www.techlaboratory.net
+  http://tech-laboratory.blogspot.com
+*/
+.swMain {
+  position:relative;
+  display:block;
+  margin:0;
+  padding:0;
+  border: 0px solid #CCC;
+  overflow:visible;
+  float:left;
+  width:980px;
+}
+.swMain .stepContainer {
+  display:block;
+  position: relative;
+  margin: 0;
+  padding:0;    
+  border: 0px solid #CCC;
+  min-height: 450px;    
+  overflow:hidden;
+  clear:both;
+  /*height:300px;*/
+}
+
+.swMain .stepContainer div.content {
+  display:block;
+  /*position: absolute;*/
+  position: relative;  
+  float:left;
+  margin: 0;
+  padding:5px;    
+  border: 1px solid #CCC; 
+  font: normal 12px Verdana, Arial, Helvetica, sans-serif; 
+  color:#5A5655;   
+  background-color:#F8F8F8;  
+  /*height:300px;*/
+  /* new property */
+  min-height: 450px;
+  text-align:left;
+  overflow:visible;    
+  z-index:88; 
+  -webkit-border-radius: 5px;
+  -moz-border-radius  : 5px;
+  width:968px;
+  clear:both;
+}
+
+.swMain div.actionBar {
+  display:block;
+  position: relative; 
+  clear:both;
+  margin:             3px 0 0 0;   
+  border:             1px solid #CCC;
+  padding:            0;    
+  color:              #5A5655;   
+  background-color:   #F8F8F8;
+  height:40px;
+  text-align:left;
+  overflow:auto;    
+  z-index:88; 
+
+  -webkit-border-radius: 5px;
+  -moz-border-radius  : 5px;
+  left:0;
+}
+
+.swMain .stepContainer .StepTitle {
+  display:block;
+  position: relative;
+  margin:0;   
+  border:1px solid #E0E0E0;
+  padding:5px;   
+  font: bold 16px Verdana, Arial, Helvetica, sans-serif; 
+  color:#5A5655;   
+  background-color:#E0E0E0;
+  clear:both;
+  text-align:left; 
+  z-index:88;
+  -webkit-border-radius: 5px;
+  -moz-border-radius  : 5px;    
+}
+.swMain ul.anchor {
+  position: relative;
+  display:block;
+  float:left;
+  list-style: none;
+  padding: 0px;  
+  margin: 10px 0;      
+  clear: both;
+  border: 0px solid #CCCCCC;    
+  background: transparent; /*#EEEEEE */
+}
+.swMain ul.anchor li{ 
+  position: relative; 
+  display:block;
+  margin: 0;
+  padding: 0; 
+  padding-left:3px;
+  padding-right: 3px;
+  border: 0px solid #E0E0E0;      
+  float: left;
+}
+/* Anchor Element Style */
+.swMain ul.anchor li a {
+  display:block;
+  position:relative;
+  float:left;
+  margin:0;
+  padding:3px;
+  height:60px;
+  width:312px;
+  text-decoration: none;
+  outline-style:none;
+  -moz-border-radius  : 5px;
+  -webkit-border-radius: 5px;
+  z-index:99;
+}
+.swMain ul.anchor li a .stepNumber{
+  position:relative;
+  float:left;
+  width:30px;
+  text-align: center;
+  padding:5px;
+  padding-top:0;
+  font: bold 45px Verdana, Arial, Helvetica, sans-serif;
+}
+.swMain ul.anchor li a .stepDesc{
+  position:relative;
+  display:block;
+  float:left;
+  text-align: left;
+  padding:5px;
+
+  font: bold 20px Verdana, Arial, Helvetica, sans-serif;
+}
+.swMain ul.anchor li a .stepDesc small{
+  font: normal 12px Verdana, Arial, Helvetica, sans-serif;
+}
+.swMain ul.anchor li a.selected{
+  color:#F8F8F8;
+  background: #EA8511;  /* EA8511 */
+  border: 1px solid #EA8511;
+  cursor:text;
+  -moz-box-shadow: 5px 5px 8px #888;
+  -webkit-box-shadow: 5px 5px 8px #888;
+  box-shadow: 5px 5px 8px #888;
+}
+.swMain ul.anchor li a.selected:hover {
+  color:#F8F8F8;  
+  background: #EA8511;  
+}
+
+.swMain ul.anchor li a.done { 
+  position:relative;
+  color:#FFF;  
+  background: #8CC63F;  
+  border: 1px solid #8CC63F;   
+  z-index:99;
+}
+.swMain ul.anchor li a.done:hover {
+  color:#5A5655;  
+  background: #8CC63F; 
+  border: 1px solid #5A5655;   
+}
+.swMain ul.anchor li a.disabled {
+  color:#CCCCCC;  
+  background: #F8F8F8;
+  border: 1px solid #CCC;  
+  cursor:text;   
+}
+.swMain ul.anchor li a.disabled:hover {
+  color:#CCCCCC;  
+  background: #F8F8F8;     
+}
+
+.swMain ul.anchor li a.error {
+  color:#6c6c6c !important;  
+  background: #f08f75 !important;
+  border: 1px solid #fb3500 !important;      
+}
+.swMain ul.anchor li a.error:hover {
+  color:#000 !important;       
+}
+
+.swMain .buttonNext {
+  display:block;
+  float:right;
+  margin:5px 3px 0 3px;
+  padding:5px;
+  text-decoration: none;
+  text-align: center;
+  font: bold 13px Verdana, Arial, Helvetica, sans-serif;
+  width:100px;
+  color:#FFF;
+  outline-style:none;
+  background-color:   #5A5655;
+  border: 1px solid #5A5655;
+  -moz-border-radius  : 5px; 
+  -webkit-border-radius: 5px;    
+}
+.swMain .buttonDisabled {
+  color:#F8F8F8  !important;
+  background-color: #CCCCCC !important;
+  border: 1px solid #CCCCCC  !important;
+  cursor:text;    
+}
+.swMain .buttonPrevious {
+  display:block;
+  float:right;
+  margin:5px 3px 0 3px;
+  padding:5px;
+  text-decoration: none;
+  text-align: center;
+  font: bold 13px Verdana, Arial, Helvetica, sans-serif;
+  width:100px;
+  color:#FFF;
+  outline-style:none;
+  background-color:   #5A5655;
+  border: 1px solid #5A5655;
+  -moz-border-radius  : 5px; 
+  -webkit-border-radius: 5px;    
+}
+.swMain .buttonFinish {
+  display:block;
+  float:right;
+  margin:5px 10px 0 3px;
+  padding:5px;
+  text-decoration: none;
+  text-align: center;
+  font: bold 13px Verdana, Arial, Helvetica, sans-serif;
+  width:100px;
+  color:#FFF;
+  outline-style:none;
+  background-color:   #5A5655;
+  border: 1px solid #5A5655;
+  -moz-border-radius  : 5px; 
+  -webkit-border-radius: 5px;    
+}
+
+/* Form Styles */
+
+.txtBox {
+  border:1px solid #CCCCCC;
+  color:#5A5655;
+  font:13px Verdana,Arial,Helvetica,sans-serif;
+  padding:2px;
+  width:430px;
+}
+.txtBox:focus {
+  border:1px solid #EA8511;
+}
+
+.swMain .loader {
+  position:relative;  
+  display:none;
+  float:left;  
+  margin: 2px 0 0 2px;
+  padding:8px 10px 8px 40px;
+  border: 1px solid #FFD700; 
+  font: bold 13px Verdana, Arial, Helvetica, sans-serif; 
+  color:#5A5655;       
+  background: #FFF url(../images/loader.gif) no-repeat 5px;  
+  -moz-border-radius  : 5px;
+  -webkit-border-radius: 5px;
+  z-index:998;
+}
+.swMain .msgBox {
+  position:relative;  
+  display:none;
+  float:left;
+  margin: 4px 0 0 5px;
+  padding:5px;
+  border: 1px solid #FFD700; 
+  background-color: #FFFFDD;  
+  font: normal 12px Verdana, Arial, Helvetica, sans-serif; 
+  color:#5A5655;         
+  -moz-border-radius  : 5px;
+  -webkit-border-radius: 5px;
+  z-index:999;
+  min-width:200px;  
+}
+.swMain .msgBox .content {
+  font: normal 12px Verdana,Arial,Helvetica,sans-serif;
+  padding: 0px;
+  float:left;
+}
+.swMain .msgBox .close {
+  border: 1px solid #CCC;
+  border-radius: 3px;
+  color: #CCC;
+  display: block;
+  float: right;
+  margin: 0 0 0 5px;
+  outline-style: none;
+  padding: 0 2px 0 2px;
+  position: relative;
+  text-align: center;
+  text-decoration: none;
+}
+.swMain .msgBox .close:hover{
+  color: #EA8511;
+  border: 1px solid #EA8511;  
+}
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/styles/smart_wizard_vertical.css
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/styles/smart_wizard_vertical.css	(revision 9227)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/Content/smartwizard2.0/styles/smart_wizard_vertical.css	(revision 9227)
@@ -0,0 +1,306 @@
+/*   
+  SmartWizard 2.0 plugin 
+  jQuery Wizard control Plugin
+  by Dipu
+  
+  http://www.techlaboratory.net
+  http://tech-laboratory.blogspot.com
+*/
+.swMain {
+  position:relative;
+  display:block;
+  margin:0;
+  padding:0;
+  border: 0px solid #CCC;
+  overflow:visible;
+  float:left;
+  width:980px;/* */
+}
+.swMain .stepContainer {
+  display:block;
+  position: relative;
+  margin: 0;
+  padding:0;    
+  border: 0px solid #CCC;    
+  overflow:hidden;
+  clear:right;
+  height:300px;
+}
+
+.swMain .stepContainer div.content {
+  display:block;
+  position: absolute;  
+  float:left;
+  margin: 0;
+  padding:5px;    
+  border: 1px solid #CCC; 
+  font: normal 12px Verdana, Arial, Helvetica, sans-serif; 
+  color:#5A5655;   
+  background-color:#F8F8F8;  
+  height:300px;
+  text-align:left;
+  overflow:auto;    
+  z-index:88; 
+  -webkit-border-radius: 5px;
+  -moz-border-radius  : 5px;
+  width:720px;
+  clear:both;
+}
+
+.swMain div.actionBar {
+  display:block;
+  position: relative; 
+  clear:right;
+  margin:             3px 0 0 0;   
+  border:             1px solid #CCC;
+  padding:            0;    
+  color:              #5A5655;   
+  background-color:   #F8F8F8;
+  height:40px;
+/*  width:730px; 
+  float:right; */  
+  text-align:left;
+  overflow:auto;    
+  z-index:88; 
+  -webkit-border-radius: 5px;
+  -moz-border-radius  : 5px;
+
+}
+
+.swMain .stepContainer .StepTitle {
+  display:block;
+  position: relative;
+  margin:0;   
+  border:1px solid #E0E0E0;
+  padding:5px;   
+  font: bold 16px Verdana, Arial, Helvetica, sans-serif; 
+  color:#5A5655;   
+  background-color:#E0E0E0;
+  clear:both;
+  text-align:left; 
+  z-index:88;
+  -webkit-border-radius: 5px;
+  -moz-border-radius  : 5px;    
+}
+.swMain ul.anchor {
+  position: relative;
+  display:block;
+  float:left;
+  list-style: none;
+  padding: 0px;  
+  margin: 5px 10px 0 0;
+  border: 0px solid #CCCCCC;    
+  background: transparent; /*#EEEEEE */
+}
+.swMain ul.anchor li{ 
+  position: relative; 
+  display:block;
+  margin: 0;
+  padding: 0; 
+  padding-top:3px;
+  padding-bottom: 3px;
+  border: 0px solid #E0E0E0;      
+  float: left;
+  clear:both;
+}
+/* Anchor Element Style */
+.swMain ul.anchor li a {
+  display:block;
+  position:relative;
+  float:left;
+  margin:0;
+  padding:3px;
+  height:70px;
+  width:230px;
+  text-decoration: none;
+  outline-style:none;
+  -moz-border-radius  : 5px;
+  -webkit-border-radius: 5px;
+  z-index:99;
+}
+.swMain ul.anchor li a .stepNumber{
+  position:relative;
+  float:left;
+  width:30px;
+  text-align: center;
+  padding:5px;
+  padding-top:0;
+  font: bold 45px Verdana, Arial, Helvetica, sans-serif;
+}
+.swMain ul.anchor li a .stepDesc{
+  position:relative;
+  display:block;
+  float:left;
+  text-align: left;
+  padding:5px;
+  width:70%;
+  font: bold 20px Verdana, Arial, Helvetica, sans-serif;
+}
+.swMain ul.anchor li a .stepDesc small{
+  font: normal 12px Verdana, Arial, Helvetica, sans-serif;
+}
+.swMain ul.anchor li a.selected{
+  color:#F8F8F8;
+  background: #EA8511;  /* EA8511 */
+  border: 1px solid #EA8511;
+  cursor:text;
+  -moz-box-shadow: 1px 5px 10px #888;
+  -webkit-box-shadow: 1px 5px 10px #888;
+  box-shadow: 1px 5px 10px #888;
+}
+.swMain ul.anchor li a.selected:hover {
+  color:#F8F8F8;  
+  background: #EA8511;  
+}
+
+.swMain ul.anchor li a.done { 
+  position:relative;
+  color:#FFF;  
+  background: #8CC63F;  
+  border: 1px solid #8CC63F;   
+  z-index:99;
+}
+.swMain ul.anchor li a.done:hover {
+  color:#5A5655;  
+  background: #8CC63F; 
+  border: 1px solid #5A5655;   
+}
+.swMain ul.anchor li a.disabled {
+  color:#CCCCCC;  
+  background: #F8F8F8;
+  border: 1px solid #CCC;  
+  cursor:text;   
+}
+.swMain ul.anchor li a.disabled:hover {
+  color:#CCCCCC;  
+  background: #F8F8F8;     
+}
+
+.swMain ul.anchor li a.error {
+  color:#6c6c6c !important;  
+  background: #f08f75 !important;
+  border: 1px solid #fb3500 !important;      
+}
+.swMain ul.anchor li a.error:hover {
+  color:#000 !important;       
+}
+
+.swMain .buttonNext {
+  display:block;
+  float:right;
+  margin:5px 3px 0 3px;
+  padding:5px;
+  text-decoration: none;
+  text-align: center;
+  font: bold 13px Verdana, Arial, Helvetica, sans-serif;
+  width:100px;
+  color:#FFF;
+  outline-style:none;
+  background-color:   #5A5655;
+  border: 1px solid #5A5655;
+  -moz-border-radius  : 5px; 
+  -webkit-border-radius: 5px;    
+}
+.swMain .buttonDisabled {
+  color:#F8F8F8  !important;
+  background-color: #CCCCCC !important;
+  border: 1px solid #CCCCCC  !important;
+  cursor:text;    
+}
+.swMain .buttonPrevious {
+  display:block;
+  float:right;
+  margin:5px 3px 0 3px;
+  padding:5px;
+  text-decoration: none;
+  text-align: center;
+  font: bold 13px Verdana, Arial, Helvetica, sans-serif;
+  width:100px;
+  color:#FFF;
+  outline-style:none;
+  background-color:   #5A5655;
+  border: 1px solid #5A5655;
+  -moz-border-radius  : 5px; 
+  -webkit-border-radius: 5px;    
+}
+.swMain .buttonFinish {
+  display:block;
+  float:right;
+  margin:5px 10px 0 3px;
+  padding:5px;
+  text-decoration: none;
+  text-align: center;
+  font: bold 13px Verdana, Arial, Helvetica, sans-serif;
+  width:100px;
+  color:#FFF;
+  outline-style:none;
+  background-color:   #5A5655;
+  border: 1px solid #5A5655;
+  -moz-border-radius  : 5px; 
+  -webkit-border-radius: 5px;    
+}
+
+/* Form Styles */
+
+.txtBox {
+  border:1px solid #CCCCCC;
+  color:#5A5655;
+  font:13px Verdana,Arial,Helvetica,sans-serif;
+  padding:2px;
+  width:430px;
+}
+.txtBox:focus {
+  border:1px solid #EA8511;
+}
+
+.swMain .loader {
+  position:relative;  
+  display:none;
+  float:left;  
+  margin: 2px 0 0 2px;
+  padding:8px 10px 8px 40px;
+  border: 1px solid #FFD700; 
+  font: bold 13px Verdana, Arial, Helvetica, sans-serif; 
+  color:#5A5655;       
+  background: #FFF url(../images/loader.gif) no-repeat 5px;  
+  -moz-border-radius  : 5px;
+  -webkit-border-radius: 5px;
+  z-index:998;
+}
+.swMain .msgBox {
+  position:relative;  
+  display:none;
+  float:left;
+  margin: 4px 0 0 5px;
+  padding:5px;
+  border: 1px solid #FFD700; 
+  background-color: #FFFFDD;  
+  font: normal 12px Verdana, Arial, Helvetica, sans-serif; 
+  color:#5A5655;         
+  -moz-border-radius  : 5px;
+  -webkit-border-radius: 5px;
+  z-index:999;
+  min-width:200px;  
+}
+.swMain .msgBox .content {
+  font: normal 12px Verdana,Arial,Helvetica,sans-serif;
+  padding: 0px;
+  float:left;
+}
+.swMain .msgBox .close {
+  border: 1px solid #CCC;
+  border-radius: 3px;
+  color: #CCC;
+  display: block;
+  float: right;
+  margin: 0 0 0 5px;
+  outline-style: none;
+  padding: 0 2px 0 2px;
+  position: relative;
+  text-align: center;
+  text-decoration: none;
+}
+.swMain .msgBox .close:hover{
+  color: #EA8511;
+  border: 1px solid #EA8511;  
+}
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/ExperimentController.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/ExperimentController.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/ExperimentController.cs	(revision 9227)
@@ -8,4 +8,6 @@
 using HeuristicLab.Services.Optimization.ControllerService.Model;
 using System.Web.Security;
+using Mvc3TestApplication.Binders;
+using HeuristicLab.Services.Optimization.ControllerService.Parsers;
 
 namespace HeuristicLab.Services.Optimization.Web.Controllers
@@ -41,6 +43,15 @@
           foreach (var scenario in scenarios)
             model.Scenarios.Add(scenario);
+
+          Session["experiment"] = new Experiment();
+
           return View(model);
         }
+
+        public ActionResult New() {
+          return Index();
+        }
+
+        public Experiment Experiment { get { return Session["experiment"] as Experiment; } set { Session["experiment"] = value;} }
 
         [HttpPost]
@@ -63,5 +74,5 @@
             if (currentNode.title == "Experiment")
               continue;
-            experiment.Scenarios.Add(new OptimizationScenario() { Id = currentNode.title });
+            experiment.Algorithm.Add(new Algorithm() { Name = currentNode.title });
           }
 
@@ -94,4 +105,90 @@
           return RedirectToAction("Edit");
         }
+
+        [HttpPost]
+        public JsonResult SaveExperiment([ExperimentJson] Experiment experiment) {
+          return Json(
+            new { 
+              Success = ControllerService.withControllerService<bool>(service => {
+                User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
+                return service.SaveExperiment(u, experiment);
+              })
+            });
+        }
+
+        private JsonResult ComplexExperimentCase(string scenario) {
+          // complex case, find children of experiment
+          var model = new GetParametersModel() { Type = "Complex" };
+          model.Subnames = new List<string>();
+
+          var experiment = ControllerService.withControllerService<Experiment>(service => {
+            User user = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
+            return service.GetExperimentByName(user, scenario);
+          });
+
+          // TODO: Make a tree out of subnames!!
+          if (experiment != null)
+            foreach (var algo in experiment.Algorithm)
+              model.Subnames.Add(algo.Name);
+
+          return Json(model, JsonRequestBehavior.AllowGet);
+        }
+
+        [HttpGet]
+        public JsonResult GetParameters(string scenario, string context, int index) {
+          if (context == "Experiment" || context == null) {
+            var optimizationScenario = ControllerService.withControllerService<OptimizationScenario>(service => {
+              return service.GetOptimizationScenarioByName(scenario);
+            });
+
+            if (optimizationScenario != null) {
+              var model = new GetParametersModel() { Type = "Basic" };
+              model.Algorithm = optimizationScenario.FirstAlgorithm;
+              model.Algorithm.Mapper = optimizationScenario.Id;
+              var json = Json(model, JsonRequestBehavior.AllowGet);
+              return json;
+            }
+            else {
+              // complex case, find children of experiment
+              var model = new GetParametersModel() { Type = "Complex" };
+              model.Subnames = new List<string>();
+
+              var experiment = ControllerService.withControllerService<Experiment>(service => {
+                User user = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
+                return service.GetExperimentByName(user, scenario);
+              });
+
+              // TODO: Make a tree out of subnames!!
+              if (experiment != null)
+                foreach (var algo in experiment.Algorithm)
+                  model.Subnames.Add(algo.Name);
+
+              return Json(model, JsonRequestBehavior.AllowGet);
+            }
+          }
+          else {
+            var experiment = ControllerService.withControllerService<Experiment>(service => {
+              User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
+              return service.GetExperimentByName(u, context);
+            });
+
+            // if child algorithm is a complex algorithm, return as such
+            if (experiment.Algorithm[index].ChildAlgorithms.Count > 0) {
+              var model = new GetParametersModel() { Type = "Complex" };
+              model.Subnames = new List<string>();
+              foreach (var algo in experiment.Algorithm[index].ChildAlgorithms)
+                model.Subnames.Add(algo.Name);
+              return Json(model, JsonRequestBehavior.AllowGet);
+            }
+            else {
+              // otherwise we have the algorithms just below it
+              var model = new GetParametersModel() { Type = "Basic" };
+              model.Algorithm = experiment.Algorithm[index];
+              model.Algorithm.Mapper = experiment.Algorithm[index].Name;
+              var json = Json(model, JsonRequestBehavior.AllowGet);
+              return json;
+            }
+          }
+        }
     }
 }
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/OptimizationController.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/OptimizationController.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/Controllers/OptimizationController.cs	(revision 9227)
@@ -57,16 +57,13 @@
 
         public ActionResult JobDetails(string jobId) {
-          Job job = ControllerService.withControllerService<Job>((service) => {
+          var model = ControllerService.withControllerService<JobDetailsModel>((service) => {
             User u = new User() { Username = Membership.GetUser().UserName, Password = Session["pw"] as string };
-            return service.GetJob(u, jobId);
+            var job = service.GetJob(u, jobId);
+            var runs = service.GetJobResults(u, jobId);
+            return new JobDetailsModel() { Job = job, Runs = runs };
           });
-          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);
-          });
-          JobDetailsModel jdm = new JobDetailsModel() { Job = job, Runs = runs };
-          Session["jobDetails"] = jdm;
-          return View(jdm);
-        }
+          Session["jobDetails"] = model;
+          return View(model);
+       } 
 
         [HttpPost]
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/HeuristicLab.Services.Optimization.Web.csproj
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/HeuristicLab.Services.Optimization.Web.csproj	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/HeuristicLab.Services.Optimization.Web.csproj	(revision 9227)
@@ -97,4 +97,6 @@
   </ItemGroup>
   <ItemGroup>
+    <Content Include="Content\ajax-loader.gif" />
+    <Content Include="Content\Datatypemapping.js" />
     <Content Include="Content\dynatree\dist\jquery.dynatree.min.js" />
     <Content Include="Content\dynatree\src\skin\icons-rtl.gif" />
@@ -105,4 +107,5 @@
     <Content Include="Content\dynatree\src\skin\vline.gif" />
     <Content Include="Content\ExperimentSupport.js" />
+    <Compile Include="Binders\AlgorithmJsonAttribute.cs" />
     <Compile Include="Controllers\AccountController.cs" />
     <Compile Include="Controllers\AdminController.cs" />
@@ -369,4 +372,5 @@
     </None>
     <Content Include="Views\Status\Index.cshtml" />
+    <Content Include="Views\Experiment\New.cshtml" />
   </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/Models/ExperimentModel.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/Models/ExperimentModel.cs	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/Models/ExperimentModel.cs	(revision 9227)
@@ -3,4 +3,5 @@
 using System.Linq;
 using System.Web;
+using HeuristicLab.Services.Optimization.ControllerService.Model;
 
 namespace HeuristicLab.Services.Optimization.Web.Models {
@@ -16,4 +17,10 @@
     public Node Experiment { get; set; }
     public string Name { get; set; }
+  }
+
+  public class GetParametersModel {
+    public string Type { get; set; }
+    public Algorithm Algorithm { get; set; }
+    public IList<string> Subnames { get; set; }
   }
 
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment/New.cshtml
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment/New.cshtml	(revision 9227)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Experiment/New.cshtml	(revision 9227)
@@ -0,0 +1,542 @@
+﻿@model HeuristicLab.Services.Optimization.Web.Models.ExperimentViewModel
+@{
+    ViewBag.Title = "Index.cshtml";
+}
+
+
+<script type="text/javascript">
+  function Experiment() {
+    this.algorithms = [];
+    this.nodeMapping = {};
+    this.name = "My Experiment"
+  }
+    
+  Experiment.prototype.buildAndStore = function(node, index, tree, ctx) {
+    var result = this.build(node, index, tree, 'Experiment');
+    this.algorithms = result.algorithms;
+    this.nodeMapping = result.mapping;
+  }
+
+  Experiment.prototype.build = function(node, index, tree, ctx) {
+    var stack = new Array();
+    var root = {name : node.title, children: [], context: ctx};
+    var nodeMapping = {};
+    this.fetchNode(root, node, index, tree);
+    if (node.title != 'Experiment')
+      nodeMapping[node.key] = root;
+      
+    if (node.children)
+        for (var i=0; i < node.children.length; i++) { 
+          stack.push({parent: root, child: node.children[node.children.length - 1 - i], index: node.children.length - 1 - i});
+        }
+    while(stack.length > 0) {
+      var tmp = stack.pop();
+      var parent = tmp.parent;
+      var child = tmp.child;
+      var newChild = { name : child.title, children: [], context: ctx}
+      // fetch the nodes from the server
+      this.fetchNode(newChild, child, tmp.index, tree);
+      nodeMapping[tmp.child.key] = newChild;      
+      parent.children.push(newChild);
+      if (child.children)
+          for (var i=0; i < child.children.length; i++) {
+            stack.push({parent: newChild, child: child.children[child.children.length - 1 - i], index: child.children.length - 1 - i});
+          }
+    }
+    return {algorithms: root, mapping: nodeMapping};
+  }
+
+  Experiment.prototype.fetchNode = function(modelNode, dynaNode, index, tree) {
+    if (modelNode.name == 'Experiment')
+      return;
+    var self = this;
+    var node = tree.getNodeByKey(dynaNode.key);
+    $.ajax({
+        type: "GET",
+        url: '/Experiment/GetParameters',
+        data: { scenario: modelNode.name, context: modelNode.context, index: index },
+        contentType: "application/json; charset=utf-8",
+        dataType: "json",
+        success: function (result) {
+            if (result.Type == "Complex") {
+                // extend the tree element
+                node.removeChildren();
+                var parent = self.nodeMapping[node.data.key];
+                for (var i=0; i < result.Subnames.length; i++) {
+                    // add node to dynatree
+                    var childNode = node.addChild({title: result.Subnames[i]});
+                    var internalResult = self.build(childNode.toDict(true), i, tree, modelNode.name);  
+                    parent.children.push(internalResult.algorithms);
+                    for (var attrname in internalResult.mapping) { self.nodeMapping[attrname] = internalResult.mapping[attrname]; }                  
+                }
+            } else if (result.Type == "Basic") {      
+                // replace the wizard    
+                previousWizards[node.data.key] = replaceWizard(result);
+                saveParameters(previousWizards[node.data.key], node);
+            }
+        }
+    });
+  }
+
+  Experiment.prototype.pushNode = function(parentKey, nodeKey, entryName, ctx) {
+    var entry = {name: entryName, children: [], context: ctx};
+    this.nodeMapping[parentKey].children.push(entry);
+    this.nodeMapping[nodeKey] = entry;
+  }
+
+  var experiment = new Experiment();
+  var previousWizards = {};
+
+  function saveExperiment() {
+    $('.buttonFinish').attr('disabled', 'disabled');
+    experiment["name"] = $('#name').val();
+    experiment["run"] = $('#runImmediately').attr('checked') == 'checked';
+    experiment["repititions"] = $('#repititions').val();
+    experiment["group"] = $('#group').val();
+
+     $.ajax({ type: "POST",
+      url: '/Experiment/SaveExperiment',
+      data: JSON.stringify(experiment),
+      contentType: "application/json; charset=utf-8",
+      dataType: "json",
+      success: function (result) {
+        $('#status-dialog').dialog("open");
+      },
+      error: function (result) {
+      }
+     });
+  }
+
+  function treeIndexOf(sibling) {
+    var i = 0;
+    var prev = sibling.getPrevSibling()
+    while (prev != null) {
+        i++;
+        prev = prev.getPrevSibling()
+    }
+    return i;
+  }
+
+  function saveParameters(wiz, node) {
+    var wiz = typeof wiz !== 'undefined' ? $(wiz) : $('.wizard', '#parameter-dialog-content');
+    var id = wiz.attr('id');
+    var node = typeof node !== 'undefined' ? node : $('#container2').dynatree("getActiveNode");
+    var data = {};   
+
+    for (var i = 1; i < 3; i++) {
+      var stepId = '#' + id + '_' + i;
+      var step = $(stepId);
+      if (step.length == 0) {
+        break;
+      }
+      var stepDesc = $('a[href="' + stepId + '"] span', wiz).contents()[0].data;
+      var dataEntries = $('input, select', step);
+      var entry = { };
+      var mapper = new DatatypeMapper();
+      for (var j = 0; j < dataEntries.length; j++) {
+        entry[dataEntries[j].name] = mapper.mapString(dataEntries[j].value);
+      }
+      data[stepDesc] = entry;
+    }
+    
+    // aggregate tables:
+    var mapper = new DatatypeMapper();
+    mapper.aggregateTables(data);
+
+    var experimentEntry = experiment.nodeMapping[node.data.key];
+    // we are at the node, update data
+    experimentEntry["data"] = data;
+    // Close dialog
+    $('#params').dialog("close");
+  }
+
+  function createParamterDiv(name, parameters) {
+    var mapper = new DatatypeMapper();
+    // get algorithm parameters
+    var paramsDiv = $('<div />').data("name", name);
+    for (var i=0; i < parameters.length; i++) {
+      var property = parameters[i];
+      var content = mapper.mapHtml(property.Value);
+
+      // add to canvas              
+      $('<h2/>').text(property.Value.Name).appendTo(paramsDiv);
+      content.appendTo(paramsDiv);
+      $('<div />').addClass('clearer').appendTo(paramsDiv);
+    }
+    return paramsDiv;
+  }
+
+  function createWizard(name, steps) {
+    var wizard = $('<div />', { id: name }).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(wizard);
+    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(wizard);
+    }
+    return wizard;
+  }
+
+
+  function makeTree() {
+    var tree = $('#container').dynatree({
+      onActivate: function (node) {
+        if (node && node.data.title !== "Experiment") {
+          $('input[name="RemoveNode"]').removeAttr("disabled");
+        } else if (node) {
+          $('input[name="RemoveNode"]').attr("disabled", "disabled");
+        }
+      },
+      onDeactivate: function (node) {
+      },
+      dnd: {
+        autoExpandMS: 750,
+
+        onDragStart: function (node) {
+          return node.data.title !== "Experiment";
+        },
+        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 (sourceNode) {
+            sourceNode.move(node, hitMode);
+          }
+          else {
+            newNode = { title: draggable.element[0].id };
+            if (hitMode == "over") {
+              node.addChild(newNode);
+              node.expand(true);
+            }
+            else if (hitMode == "before") {
+              node.parent.addChild(newNode, node);
+            }
+            else {
+              node.parent.addChild(newNode, node.getNextSibling());
+            }
+          }
+        },
+        onDragLeave: function (node, sourceNode) {
+        }
+      }
+    });
+
+    $('.dragables').each(function () {
+      $(this).draggable({
+        revert: true,
+        connectToDynatree: true,
+        cursorAt: { top: -5, left: -5 },
+        helper: "clone"
+      });
+    });
+
+    $('input[name="RemoveNode"]').click(function () {
+      var node = $("#container").dynatree("getActiveNode");
+      if (node && node.data.title !== "Experiment")
+        node.remove();
+      $(this).attr("disabled", "disabled");
+    });
+  }
+
+  function leaveStep(obj) {
+    var stepNum = obj.attr("rel");
+    return validateStep(stepNum);
+  }
+
+  function validateStep(stepNum) {
+    var isStepValid = true;
+    if (stepNum == 1) {
+      previousWizards = {}
+      experiment = new Experiment();
+      var data = $("#container").dynatree("getTree").toDict().children;
+      $("#container2").dynatree({
+        onActivate: editElement
+      });
+      var rootNode = $("#container2").dynatree("getRoot");
+      rootNode.removeChildren();
+      rootNode.addChild(data);
+      // based on the data rebuild the experiment
+      experiment.buildAndStore(data[0], 0, $("#container2").dynatree("getTree"));
+    }
+    return isStepValid;
+  }
+
+  function resetDialog() {
+    var canvas = $('#parameter-dialog-content');
+    canvas.empty();
+    $('<img />').attr('alt', 'Loading animation').attr('src', '@Url.Content("~/Content/ajax-loader.gif")').attr('class', 'loader').appendTo(canvas);
+    $('<div />').text("Loading...").appendTo(canvas);        
+  }
+
+  globalCounter = 0;
+
+  function replaceWizard(result) {
+    var canvas = $('#parameter-dialog-content');
+    canvas.empty();
+
+    // get parameters as div
+    var algoParamsDiv = null;
+
+    if (result.Algorithm.Parameters) {
+        algoParamsDiv = createParamterDiv("Algorithm Parameters", result.Algorithm.Parameters.Items);
+    }
+
+    var problemParamsDiv = null;
+    if (result.Algorithm.Problem && result.Algorithm.Problem.Parameters) {
+     problemParamsDiv = createParamterDiv("Problem Parameters", result.Algorithm.Problem.Parameters.Items);
+    }
+
+    var wizard = null;
+    if (result.Algorithm.Problem)
+     wizard = createWizard("TestWizard", [
+        { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoParamsDiv },
+        { heading: "Problem Parameters", description: "Adjust problem parameters", content: problemParamsDiv }
+    ]);
+    else
+     wizard = createWizard("TestWizard", [
+        { heading: "Algorithm Parameters", description: "Adjust algorithm parameters", content: algoParamsDiv }
+    ]);
+
+    wizard.appendTo(canvas);
+    $(".wizard", canvas).smartWizard({
+        onFinish: saveParameters,
+        labelFinish: 'Save'
+    });
+    return wizard;
+  }
+
+  function editElement(node) {
+    resetDialog();
+    $("#params").dialog("open");
+    // if we opened this windows before, use the previously created wizard
+    if (node.data.key in previousWizards) {
+      var canvas = $('#parameter-dialog-content');
+      canvas.empty();  
+      $(previousWizards[node.data.key]).appendTo(canvas);
+      var wiz = $(".wizard", canvas).smartWizard({
+        onFinish: saveParameters,
+        labelFinish: 'Save'
+      });
+      // we have to recreate the wizard, otherwise it is not responsive -> remove some multiple occuring wizard elements.
+      var parent = $('.stepContainer.content', wiz).parent('.stepContainer:not(.content)');
+      var elem = $('.stepContainer.content .content', wiz).detach();
+      elem.appendTo(parent);
+      $('.stepContainer.content', wiz).detach();
+      $('.actionBar.content', wiz).detach();
+    }
+    else {
+        $.ajax({
+          type: "GET",
+          url: '/Experiment/GetParameters',
+          data: { scenario: node.data.title, context: experiment.nodeMapping[node.data.key].context, index: treeIndexOf(node) },
+          contentType: "application/json; charset=utf-8",
+          dataType: "json",
+          success: function (result) {
+            if (result.Type == "Complex") $("#params").dialog("close");
+            /*if (result.Type == "Complex") {
+              // extend the tree element     
+              $("#params").dialog("close");     
+              node.removeChildren();
+              for (var i=0; i < result.Subnames.length; i++) {
+                // add node to dynatree
+                var childNode = node.addChild({title: result.Subnames[i]});
+                // add node to model
+                experiment.pushNode(node.data.key, childNode.data.key, result.Subnames[i], node.data.title);
+              }
+            } else*/
+            if (result.Type == "Basic") {      
+              // replace the wizard    
+              previousWizards[node.data.key] = replaceWizard(result);
+              saveParameters(previousWizards[node.data.key], node);
+            }
+          }
+        });
+     }
+  }
+
+  $(document).ready(function () {
+    var wiz = $(".wizard").smartWizard({
+      /*updateHeight: false*/
+      onLeaveStep: leaveStep,
+      onFinish: saveExperiment
+    });
+    makeTree();
+
+    $("#params").dialog({
+      autoOpen: false,
+      width: 1024,
+      height: 768,
+      /*modal: true,
+      buttons: {
+        "Save parameters": function () {
+          
+        }
+        ,
+        "Cancel": function () {
+          $(this).dialog("close");
+        }
+      },
+      close: function () {
+      }*/
+    });
+
+    $("#status-dialog").dialog({
+      autoOpen: false,
+      resizable: false,
+      height: 100,
+      modal: true,
+      buttons: { "OK" : function() { $(this).dialog('close'); $('.buttonFinish').removeAttr('disabled'); } }
+    });
+
+    $('#runImmediately').change(
+        function() {
+            if ($(this).is(':checked')) {
+                $('#repititions').removeAttr('disabled');
+                $('#group').removeAttr('disabled');
+            }
+            else {
+                $('#repititions').attr('disabled', 'disabled');
+                $('#group').attr('disabled', 'disabled');
+            }
+        });
+  });
+</script>
+
+<h2>Experiment</h2>
+
+<div class="wizard swMain">
+  <ul>
+    <li>
+      <a href="#step1">
+        <label class="stepNumber">1</label>
+        <span class="stepDesc">
+          Structure<br />
+          <small>Build your experiment</small>
+        </span>
+      </a>
+    </li>
+    <li>
+      <a href="#step2">
+        <label class="stepNumber">2</label>
+        <span class="stepDesc">
+          Customization<br />
+          <small>Change experiment parameters</small>
+        </span>
+      </a>
+    </li>
+    <li>
+      <a href="#step3">
+        <label class="stepNumber">3</label>
+        <span class="stepDesc">
+          Experiment Details<br />
+          <small>Set name of experiment</small>
+        </span>
+      </a>
+    </li>
+  </ul>
+  <div id="step1">
+  @using (Html.BeginForm("TreeData", "Tree"))
+  {
+  <fieldset>    
+    <div>
+    <p>Experiment Tree:</p>
+    </div>
+
+    <div id="container" class="treeStyle">
+      <ul>
+        <li id="root">Experiment</li>
+      </ul>
+    </div>
+    <input style="margin-top:5px;"  name="RemoveNode" type="button" value="Remove" disabled="disabled" />
+
+    
+     @if (Model.Scenarios.Count > 0) {
+        <p>Choose an algorithm:</p>
+        foreach (var scen in Model.Scenarios) {
+            <div class="dragables" id="@scen"><p>@scen</p></div>
+        }        
+        <div class="clearer"/>    
+     }
+    
+    @if (Model.Scenarios.Count > 0) {
+        <p>Choose from your stored experiments:</p>
+        foreach (var scen in Model.Experiments) {
+            <div class="dragables" id="@scen"><p>@scen</p></div>
+        }
+        <div class="clearer"/>
+    }   
+    
+  </fieldset>
+  }
+  </div>
+  <div id="step2">
+  <h2>Click on a experiment to adjust its parameters:</h2>
+  <div id="container2" class="treeStyle">
+      <ul>
+        <li>Experiment</li>
+      </ul>
+    </div>
+  </div>
+  <div id="step3">
+    <div class="editor-label">
+      <label for="name">Experiment Template Name:</label>
+    </div>
+
+    <div class="editor-field">
+      <input id="name" name="Name" type="text" value="My Experiment" />
+    </div>
+
+    <div class="editor-label">
+      <label for="name">Run experiment immediately?</label>
+    </div>
+
+    <div class="editor-field">
+      <input id="runImmediately" name="RunImmediately" type="checkbox" />
+    </div>
+
+    <div class="editor-label">
+      <label for="name">Repititions</label>
+    </div>
+
+    <div class="editor-field">
+      <input id="repititions" name="Repititions" type="text" value="1" disabled="disabled" />
+    </div>
+
+    <div class="editor-label">
+      <label for="name">Group</label>
+    </div>
+
+    <div class="editor-field">
+      <input id="group" name="Group" type="text" value="TESTAZURE" disabled="disabled" />
+    </div>
+  </div>  
+</div>
+
+<div id="status-dialog">
+    <div>
+      Experiment has been saved!
+    </div>            
+</div>
+
+<div id="params" title="Update parameters">
+    <!-- Note: The content must be loaded asynchronously -->
+    <div id="parameter-dialog-content">
+      <img src="@Url.Content("~/Content/ajax-loader.gif")" alt="Loading animation" class="loader" />
+      Loading ...      
+    </div>
+            
+  </div>
Index: branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Shared/_Layout.cshtml
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Shared/_Layout.cshtml	(revision 9215)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Web/Views/Shared/_Layout.cshtml	(revision 9227)
@@ -30,4 +30,9 @@
     <script type="text/javascript" src="@Url.Content("~/Content/dynatree/dist/jquery.dynatree.min.js")"></script>
     <script type="text/javascript" src="@Url.Content("~/Content/ExperimentSupport.js")"></script>
+
+    <!-- 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>
 </head>
 <body>
