Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs	(revision 9395)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/Azure/DAL.cs	(revision 9508)
@@ -225,12 +225,4 @@
     }
 
-    //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, bool namesOnly=false) {
       TableServiceContext serviceContext = TableClient.GetDataServiceContext();
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HLMapper.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HLMapper.cs	(revision 9395)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HLMapper.cs	(revision 9508)
@@ -37,5 +37,9 @@
     public static DoubleMatrix ConvertToDoubleMatrix(Parameter parameter) {
       var matrix = parameter.Value as DecimalMatrix;
-      // TODO: Check for empty matrices
+      
+      if (matrix.Value.Length == 0 || matrix.Value[0].Length == 0) {
+        return new DoubleMatrix(new double[0, 0]);
+      }
+
       double[,] data = new double[matrix.Value.Length, matrix.Value[0].Length];
       for (int i=0; i < matrix.Value.Length; i++) {
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs	(revision 9395)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/HL/HiveScenarioManager.cs	(revision 9508)
@@ -81,5 +81,4 @@
 
     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);
@@ -94,6 +93,4 @@
         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; 
@@ -215,11 +212,7 @@
       }      
       job.HiveTasks.Add(new OptimizerHiveTask(exp));
-      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.Store(job, new CancellationToken());
+            
+      var locator = ConfigureHive(user);
+      HiveClient.Store(job, new CancellationToken(), locator);
       
       job.StopResultPolling();
@@ -277,10 +270,6 @@
         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);
+ 
+      TaskDownloader downloader = new TaskDownloader(taskIds, ConfigureHive(user));
       downloader.StartAsync();
       while (!downloader.IsFinished) {        
@@ -291,5 +280,4 @@
         }
       }
-      //var experiment = dal.JobDao.FindByJobId(user.Username, id);
 
       IDictionary<Guid, HiveTask> hiveTasks = downloader.Results;
@@ -330,6 +318,4 @@
       return runs;
     }
-
-    //TODO: We might need images / +++
     
     private Parameter MapHiveDataType(string name, IItem item) {
@@ -341,9 +327,4 @@
       var result = new Parameter();
       result.Type = ParameterType.String;
-      //TODO: How shall we handle dll specific datatypes?      
-      //if (item is PathTSPTour) {
-      //  var tour = item as PathTSPTour;           
-      //}
-      //else 
       if (item is IStringConvertibleValue) {
         var value = (item as IStringConvertibleValue).GetValue();
@@ -440,5 +421,4 @@
         result.Value = new HeuristicLab.Services.Optimization.ControllerService.Model.StringValue() { Name = name, Value = item.ItemName != null ? item.ItemName + " (Cannot be displayed properly as string)" : "Cannot be displayed properly as string" };
       }
-      // TODO: Add workaround for TSP
       return result;
     }
@@ -541,9 +521,5 @@
 
     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)});
+      TaskDownloader downloader = new TaskDownloader(new List<Guid>(){Guid.Parse(taskId)}, ConfigureHive(u));
       downloader.StartAsync();
       while (!downloader.IsFinished) {
@@ -583,5 +559,4 @@
       // push all elements to dictionary
       foreach (var task in jobTasks) {
-        // TODO: Crawl children + parent and create hierarchy!
         var children = serviceLocator.CallHiveService<IEnumerable<HeuristicLab.Clients.Hive.LightweightTask>>(s => s.GetLightweightChildTasks(Guid.Parse(jobId), true, true));
         foreach (var child in children) {
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/HeuristicLab.Services.Optimization.ControllerService.csproj
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/HeuristicLab.Services.Optimization.ControllerService.csproj	(revision 9395)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/HeuristicLab.Services.Optimization.ControllerService.csproj	(revision 9508)
@@ -177,4 +177,5 @@
     <Compile Include="Interfaces\IScenarioManager.cs" />
     <Compile Include="Interfaces\Model\ControllerModel.cs" />
+    <Compile Include="Logging\TableStorageTraceListener.cs" />
     <Compile Include="Mockup\MockupDAL.cs" />
     <Compile Include="Mockup\MockupScenarioManager.cs" />
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IControllerService.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IControllerService.cs	(revision 9395)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/Interfaces/IControllerService.cs	(revision 9508)
@@ -8,48 +8,151 @@
 
 namespace HeuristicLab.Services.Optimization.ControllerService {
+  /// <summary>
+  /// The ControllerService represents the entry point of 
+  /// the OaaS backend. It contains all possible operations 
+  /// of OaaS.
+  /// </summary>
   [ServiceContract(ProtectionLevel = ProtectionLevel.EncryptAndSign)]
   public interface IControllerService {
+    /// <summary>
+    /// Retrieves all available scenarios, including all
+    /// their information.
+    /// </summary>
+    /// <returns>All scenarios</returns>
     [OperationContract]
     IEnumerable<OptimizationScenario> GetOptimizationScenarios();
 
+    /// <summary>
+    /// Returns the names of all scenarios. This doesn't load
+    /// parameters or other scenario specific data.
+    /// </summary>
+    /// <returns>
+    /// The names of the scenarios, 
+    /// e. g. ["Benchmark Algorithm", "Genetic Algorithm - TSP"]
+    /// </returns>
     [OperationContract]
     IEnumerable<string> GetOptimizationScenarioNames();
 
+    /// <summary>
+    /// Retrieves a scenario by a given name including all of
+    /// it's data. 
+    /// </summary>
+    /// <param name="name">
+    /// The scenario to lookup, e. g. "Benchmark Algorithm"
+    /// </param>
+    /// <returns></returns>
     [OperationContract]
     OptimizationScenario GetOptimizationScenarioByName(string name);
 
+    /// <summary>
+    /// Schedules a scenario for certain user.    
+    /// </summary>
+    /// <param name="user">The user which wants to execute a scenario.</param>
+    /// <param name="scenario">The scenario to execute.</param>
+    /// <param name="details">The title of the job, the number of repititions of the scenario and the group of the job.</param>
+    /// <returns>true, if the scenario has been successfully scheduled.</returns>
     [OperationContract]
     bool ScheduleOptimizationScenario(User user, OptimizationScenario scenario, JobExecutionDetails details);
 
+    /// <summary>
+    /// Schedules an experiment for a certain user.
+    /// </summary>
+    /// <param name="user">The user which wants to execute a scenario.</param>
+    /// <param name="experiment">The name of the experiment to schedule.</param>
+    /// <param name="details">The title of the job, the number of repititions of the experiment and the group of the job.</param>
+    /// <returns></returns>
     [OperationContract]
     bool ScheduleExperiment(User user, string experiment, JobExecutionDetails details);
 
+    /// <summary>
+    /// Returns all available jobs of a user.
+    /// </summary>
+    /// <param name="user">The user to query the jobs for.</param>
+    /// <returns>All jobs for a certain user.</returns>
     [OperationContract]
     IEnumerable<Job> GetJobs(User user);
 
+    /// <summary>
+    /// Retrievs a job by it's id.
+    /// </summary>
+    /// <param name="user">The owner of the job.</param>
+    /// <param name="id">The id of the job.</param>
+    /// <returns>The job with the given user and id.</returns>
     [OperationContract]
     Job GetJob(User user, string id);
 
+    /// <summary>
+    /// Deletes a job of a user.
+    /// </summary>
+    /// <param name="user">The owner of the job.</param>
+    /// <param name="id">The job to delete.</param>
+    /// <returns>true, if the job has been deleted.</returns>
     [OperationContract]
     bool DeleteJob(User user, string id);
 
+    /// <summary>
+    /// Returns the results of a job including the input parameters and result parameters.
+    /// </summary>
+    /// <param name="user">The owner of the job.</param>
+    /// <param name="id">The id of the job.</param>
+    /// <returns>The result and input parameters of the job.</returns>
     [OperationContract]
     IList<Model.Run> GetJobResults(User user, string id);
 
+    /// <summary>    
+    /// Adds a new scenario to the system. This has to include a valid scenario xml representing all necessary inputs
+    /// for the new scenario and a scenario mapper which is capable of converting the OaaS-scenario-model into the
+    /// hive specific version.
+    /// Note: This method might be only usable by an underlying hive data access layer.
+    /// </summary>
+    /// <param name="user">The owner of the scenario (must have administrator privileges).</param>
+    /// <param name="scenarioXml">The new scenario to upload.</param>
+    /// <param name="scenarioMapper">The converter between OaaS-model and hive model.</param>
+    /// <returns>true, if the scenario has been successfully saved.</returns>
     [OperationContract]
     bool AddHiveScenario(User user, string scenarioXml, string scenarioMapper);
-
+    
+    /// <summary>
+    /// Deletes a stored scenario including its xml and mapper.
+    /// </summary>
+    /// <param name="user">An administrator of the system.</param>
+    /// <param name="scenarioName">The name of the scenario.</param>
+    /// <returns>true, if the scenario has been deleted.</returns>
     [OperationContract]
     bool DeleteHiveScenario(User user, string scenarioName);
 
+    /// <summary>
+    /// Stores an experiment which is a tree of experiments and scenarios.
+    /// This method will schedule the experiment, if it contains job details.
+    /// </summary>
+    /// <param name="user">The owner of the experiment.</param>
+    /// <param name="experiment">The experiment including all of it's details.</param>
+    /// <returns>If scheduled it will return the job id. In every other case null will be returned.</returns>
     [OperationContract]
     string SaveExperiment(User user, Experiment experiment);
 
+    /// <summary>
+    /// Returns the names of the experiments for a certain user.
+    /// </summary>
+    /// <param name="user">The owner of the experiments.</param>
+    /// <returns>A list of experiment names.</returns>
     [OperationContract]
     IEnumerable<string> GetExperimentNames(User user);
 
+    /// <summary>
+    /// Returns all experiments. If "namesOnly" is false, the experiments include all of their details.    
+    /// </summary>
+    /// <param name="user">The owner of the experiments.</param>
+    /// <param name="namesOnly">If true, returns only a list of experiments where only the Name parameter is set.</param>
+    /// <returns></returns>
     [OperationContract]
     IEnumerable<Experiment> GetExperiments(User user, bool namesOnly = false);
 
+    /// <summary>
+    /// TODO
+    /// </summary>
+    /// <param name="user"></param>
+    /// <param name="experiment"></param>
+    /// <returns></returns>
     [OperationContract]
     bool DeleteExperiment(User user, string experiment);
Index: branches/OaaS/HeuristicLab.Services.Optimization.Controller/Logging/TableStorageTraceListener.cs
===================================================================
--- branches/OaaS/HeuristicLab.Services.Optimization.Controller/Logging/TableStorageTraceListener.cs	(revision 9508)
+++ branches/OaaS/HeuristicLab.Services.Optimization.Controller/Logging/TableStorageTraceListener.cs	(revision 9508)
@@ -0,0 +1,94 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Diagnostics;
+using Microsoft.WindowsAzure.StorageClient;
+using Microsoft.WindowsAzure;
+using System.Threading;
+
+namespace HeuristicLab.Services.Optimization.ControllerService.Logging {
+  public class TableStorageTraceEntry : TableServiceEntity {
+    public TableStorageTraceEntry(string message) {
+      this.PartitionKey = "Trace";
+      this.RowKey = Guid.NewGuid().ToString();
+      this.Message = message;
+    }
+
+    public string Message { get; set; }
+  };
+
+  public class TableStorageTraceListener : TraceListener {
+
+    private string traceTable;
+
+    public string TraceTable {
+      get {
+        if (traceTable == null) {
+          traceTable = CloudConfigurationManager.GetSetting("TraceTable");
+        }
+        return traceTable; 
+      }
+    }
+
+    private bool traceEnabled = false;
+    private DateTime? lastChecked = null;
+    public bool TraceEnabled {
+      get {
+        if (!lastChecked.HasValue || (DateTime.Now - lastChecked.Value).TotalSeconds > 20) {
+          lastChecked = DateTime.Now;
+          traceEnabled = CloudConfigurationManager.GetSetting("TraceTableEnabled") != null && CloudConfigurationManager.GetSetting("TraceTableEnabled").ToLower() == "true";
+        }
+        return traceEnabled;
+      }
+    }
+
+    private CloudStorageAccount account;
+    private TableServiceContext context;
+    private CloudTableClient client;
+    private ThreadLocal<bool> doLog = new ThreadLocal<bool>();
+
+    public TableServiceContext Context {
+      get {
+        if (account == null) {
+          account = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
+          client = account.CreateCloudTableClient();
+          context = client.GetDataServiceContext();          
+        }
+        client.CreateTableIfNotExist(TraceTable);
+        return context;
+      }
+    }
+
+
+    public override void Write(string message) {
+      if (!doLog.IsValueCreated) {
+        doLog.Value = true;
+      }
+
+      // prevent stack overflows
+      if (!doLog.Value) {
+        return;
+      }
+
+      doLog.Value = false;
+      if (TraceEnabled) {
+        Context.AddObject(TraceTable, new TableStorageTraceEntry(message));
+        Context.SaveChangesWithRetries();
+      }
+      doLog.Value = true;
+    }
+
+    public override void WriteLine(string message) {
+      Write(message + "\n");
+    }
+
+    public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data) {
+      Write(data.ToString());
+    }
+
+    public override void TraceEvent(TraceEventCache eventCache, string source, TraceEventType eventType, int id, string message) {
+      Write(message);
+    }
+  }
+}
