Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/HiveJobView.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/HiveJobView.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/HiveJobView.cs	(revision 6267)
@@ -150,4 +150,32 @@
     }
 
+    protected virtual void OptimizerJob_ComputeInParallelChanged(object sender, EventArgs e) {
+      if (InvokeRequired) {
+        Invoke(new EventHandler(OptimizerJob_ComputeInParallelChanged), sender, e);
+      } else {
+        computeInParallelCheckBox.Checked = Content.ItemJob.ComputeInParallel;
+      }
+    }
+    #endregion
+
+    #region Child Control Events
+     protected virtual void computeInParallelCheckBox_CheckedChanged(object sender, EventArgs e) {
+      if (Content != null && Content.ItemJob != null) {
+        this.Content.ItemJob.ComputeInParallel = this.computeInParallelCheckBox.Checked;
+      }
+    }
+
+    protected virtual void exceptionTextBox_DoubleClick(object sender, EventArgs e) {
+      using (TextDialog dialog = new TextDialog("Exception", exceptionTextBox.Text, ReadOnly || !Content.CanChangeDescription)) {
+        if (dialog.ShowDialog(this) == DialogResult.OK)
+          Content.Description = dialog.Content;
+      }
+    }
+
+    protected virtual void modifyItemButton_Click(object sender, EventArgs e) {
+      MainFormManager.MainForm.ShowContent(Content.ItemJob.Item);
+    }
+    #endregion
+
     protected override void SetEnabledStateOfControls() {
       base.SetEnabledStateOfControls();
@@ -171,32 +199,4 @@
       optimizerItemView.ReadOnly = true;
     }
-
-    protected virtual void OptimizerJob_ComputeInParallelChanged(object sender, EventArgs e) {
-      if (InvokeRequired) {
-        Invoke(new EventHandler(OptimizerJob_ComputeInParallelChanged), sender, e);
-      } else {
-        computeInParallelCheckBox.Checked = Content.ItemJob.ComputeInParallel;
-      }
-    }
-    #endregion
-
-    #region Child Control Events
-     protected virtual void computeInParallelCheckBox_CheckedChanged(object sender, EventArgs e) {
-      if (Content != null && Content.ItemJob != null) {
-        this.Content.ItemJob.ComputeInParallel = this.computeInParallelCheckBox.Checked;
-      }
-    }
-
-    protected virtual void exceptionTextBox_DoubleClick(object sender, EventArgs e) {
-      using (TextDialog dialog = new TextDialog("Exception", exceptionTextBox.Text, ReadOnly || !Content.CanChangeDescription)) {
-        if (dialog.ShowDialog(this) == DialogResult.OK)
-          Content.Description = dialog.Content;
-      }
-    }
-
-    protected virtual void modifyItemButton_Click(object sender, EventArgs e) {
-      MainFormManager.MainForm.ShowContent(Content.ItemJob.Item);
-    }
-    #endregion
   }
 }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/OptimizerHiveJobView.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/OptimizerHiveJobView.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/OptimizerHiveJobView.cs	(revision 6267)
@@ -50,12 +50,4 @@
     }
     #region Content Events
-
-    protected override void SetEnabledStateOfControls() {
-      base.SetEnabledStateOfControls();
-
-      this.restartButton.Enabled = Content != null && !Content.Job.Command.HasValue && Content.Job.State == JobState.Paused;
-      this.pauseButton.Enabled = Content != null && !Content.Job.Command.HasValue && Content.Job.State == JobState.Calculating;
-      this.stopButton.Enabled = Content != null && !Content.Job.Command.HasValue && (Content.Job.State == JobState.Calculating || Content.Job.State == JobState.Waiting || Content.Job.State == JobState.Paused);
-    }
     #endregion
 
@@ -73,4 +65,12 @@
     }
     #endregion
+
+    protected override void SetEnabledStateOfControls() {
+      base.SetEnabledStateOfControls();
+
+      this.restartButton.Enabled = Content != null && !Content.Job.Command.HasValue && (Content.Job.State == JobState.Paused || Content.Job.State == JobState.Failed || Content.Job.State == JobState.Aborted);
+      this.pauseButton.Enabled = Content != null && !Content.Job.Command.HasValue && Content.Job.State == JobState.Calculating;
+      this.stopButton.Enabled = Content != null && !Content.Job.Command.HasValue && (Content.Job.State == JobState.Calculating || Content.Job.State == JobState.Waiting || Content.Job.State == JobState.Paused);
+    }
   }
 }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/RefreshableHiveExperiment.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/RefreshableHiveExperiment.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/RefreshableHiveExperiment.cs	(revision 6267)
@@ -276,5 +276,5 @@
     }
     public void UpdateTotalExecutionTime() {
-      hiveExperiment.ExecutionTime = TimeSpan.FromMilliseconds(hiveExperiment.GetAllHiveJobs().Sum(x => x.Job.ExecutionTime.HasValue ? x.Job.ExecutionTime.Value.TotalMilliseconds : 0));
+      hiveExperiment.ExecutionTime = TimeSpan.FromMilliseconds(hiveExperiment.GetAllHiveJobs().Sum(x => x.Job.ExecutionTime.TotalMilliseconds));
     }
     #endregion
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveServiceClient.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveServiceClient.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveServiceClient.cs	(revision 6267)
@@ -2,5 +2,5 @@
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:4.0.30319.208
+//     Runtime Version:4.0.30319.225
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
@@ -91,5 +91,5 @@
         
         [System.Runtime.Serialization.OptionalFieldAttribute()]
-        private System.Nullable<System.TimeSpan> ExecutionTimeField;
+        private System.TimeSpan ExecutionTimeField;
         
         [System.Runtime.Serialization.OptionalFieldAttribute()]
@@ -123,5 +123,5 @@
         
         [System.Runtime.Serialization.DataMemberAttribute()]
-        public System.Nullable<System.TimeSpan> ExecutionTime
+        public System.TimeSpan ExecutionTime
         {
             get
@@ -358,4 +358,7 @@
         
         [System.Runtime.Serialization.OptionalFieldAttribute()]
+        private bool IsPrivilegedField;
+        
+        [System.Runtime.Serialization.OptionalFieldAttribute()]
         private System.Nullable<System.DateTime> LastHeartbeatField;
         
@@ -433,4 +436,21 @@
                     this.IsParentJobField = value;
                     this.RaisePropertyChanged("IsParentJob");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public bool IsPrivileged
+        {
+            get
+            {
+                return this.IsPrivilegedField;
+            }
+            set
+            {
+                if ((this.IsPrivilegedField.Equals(value) != true))
+                {
+                    this.IsPrivilegedField = value;
+                    this.RaisePropertyChanged("IsPrivileged");
                 }
             }
@@ -758,4 +778,7 @@
         
         [System.Runtime.Serialization.OptionalFieldAttribute()]
+        private double CpuUtilizationField;
+        
+        [System.Runtime.Serialization.OptionalFieldAttribute()]
         private System.Nullable<int> FreeCoresField;
         
@@ -825,4 +848,21 @@
                     this.CpuSpeedField = value;
                     this.RaisePropertyChanged("CpuSpeed");
+                }
+            }
+        }
+        
+        [System.Runtime.Serialization.DataMemberAttribute()]
+        public double CpuUtilization
+        {
+            get
+            {
+                return this.CpuUtilizationField;
+            }
+            set
+            {
+                if ((this.CpuUtilizationField.Equals(value) != true))
+                {
+                    this.CpuUtilizationField = value;
+                    this.RaisePropertyChanged("CpuUtilization");
                 }
             }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/Job.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/Job.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/Job.cs	(revision 6267)
@@ -38,4 +38,5 @@
       this.FinishWhenChildJobsFinished = original.FinishWhenChildJobsFinished;
       this.HiveExperimentId = original.HiveExperimentId;
+      this.IsPrivileged = original.IsPrivileged;
     }
 
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/Slave.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/Slave.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/Slave.cs	(revision 6267)
@@ -42,4 +42,5 @@
       this.CpuArchitecture = original.CpuArchitecture;
       this.LastHeartbeat = original.LastHeartbeat;
+      this.CpuUtilization = original.CpuUtilization;
     }
 
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/ApplicationConstants.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/ApplicationConstants.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/ApplicationConstants.cs	(revision 6267)
@@ -28,9 +28,4 @@
     public static System.Data.IsolationLevel IsolationLevel = IsolationLevel.ReadUncommitted;
 
-    /// <summary>
-    /// ReadUncommitted to minimize deadlocks. 
-    /// </summary>
-    public static System.Transactions.IsolationLevel IsolationLevelScope = System.Transactions.IsolationLevel.ReadUncommitted;
-
     public static TimeSpan SlaveHeartbeatTimeout = TimeSpan.FromMinutes(1);
 
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Job.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Job.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Job.cs	(revision 6267)
@@ -44,4 +44,6 @@
     [DataMember]
     public Guid HiveExperimentId { get; set; }
+    [DataMember]
+    public bool IsPrivileged { get; set; }
 
     public Job() {
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/LightweightJob.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/LightweightJob.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/LightweightJob.cs	(revision 6267)
@@ -30,5 +30,5 @@
   public class LightweightJob : HiveItem {
     [DataMember]
-    public TimeSpan? ExecutionTime { get; set; }
+    public TimeSpan ExecutionTime { get; set; }
     [DataMember]
     public Guid? ParentJobId { get; set; }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/ServiceContracts/IHiveService.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/ServiceContracts/IHiveService.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/ServiceContracts/IHiveService.cs	(revision 6267)
@@ -155,4 +155,7 @@
 
     [OperationContract]
+    IEnumerable<Job> GetJobsByResourceId(Guid resourceId);
+
+    [OperationContract]
     void TriggerLifecycle(bool force);
     #endregion
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Convert.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Convert.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Convert.cs	(revision 6267)
@@ -34,5 +34,5 @@
         Id = source.JobId,
         CoresNeeded = source.CoresNeeded,
-        ExecutionTime = string.IsNullOrEmpty(source.ExecutionTime) ? TimeSpan.Zero : TimeSpan.Parse(source.ExecutionTime),
+        ExecutionTime = TimeSpan.FromMilliseconds(source.ExecutionTimeMs),
         MemoryNeeded = source.MemoryNeeded,
         ParentJobId = source.ParentJobId,
@@ -46,5 +46,6 @@
         Command = source.Command,
         LastJobDataUpdate = (source.JobData == null ? DateTime.MinValue : source.JobData.LastUpdate),
-        HiveExperimentId = source.HiveExperimentId
+        HiveExperimentId = source.HiveExperimentId,
+        IsPrivileged = source.IsPrivileged
       };
     }
@@ -58,5 +59,5 @@
         target.JobId = source.Id;
         target.CoresNeeded = source.CoresNeeded;
-        target.ExecutionTime = source.ExecutionTime.ToString();
+        target.ExecutionTimeMs = source.ExecutionTime.TotalMilliseconds;
         target.MemoryNeeded = source.MemoryNeeded;
         target.ParentJobId = source.ParentJobId;
@@ -68,5 +69,4 @@
           target.StateLogs.Add(Convert.ToEntity(sl));
         }
-        //target.StateLogs.AddRange(source.StateLog.Select(x => Convert.ToEntity(x)).OrderBy(x => x.DateTime));
         target.IsParentJob = source.IsParentJob;
         target.FinishWhenChildJobsFinished = source.FinishWhenChildJobsFinished;
@@ -74,4 +74,5 @@
         // RequiredPlugins are added by Dao
         target.HiveExperimentId = source.HiveExperimentId;
+        target.IsPrivileged = source.IsPrivileged;
       }
     }
@@ -338,7 +339,7 @@
         UserId = source.UserId,
         UsedCores = source.UsedCores,
-        ExecutionTime = string.IsNullOrEmpty(source.ExecutionTime) ? TimeSpan.Zero : TimeSpan.Parse(source.ExecutionTime),
-        ExecutionTimeFinishedJobs = string.IsNullOrEmpty(source.ExecutionTimeFinishedJobs) ? TimeSpan.Zero : TimeSpan.Parse(source.ExecutionTimeFinishedJobs),
-        StartToEndTime = string.IsNullOrEmpty(source.StartToEndTime) ? TimeSpan.Zero : TimeSpan.Parse(source.StartToEndTime)
+        ExecutionTime = TimeSpan.FromMilliseconds(source.ExecutionTimeMs),
+        ExecutionTimeFinishedJobs = TimeSpan.FromMilliseconds(source.ExecutionTimeMsFinishedJobs),
+        StartToEndTime = TimeSpan.FromMilliseconds(source.StartToEndTimeMs)
       };
     }
@@ -353,7 +354,7 @@
         target.UserId = source.UserId;
         target.UsedCores = source.UsedCores;
-        target.ExecutionTime = source.ExecutionTime.ToString();
-        target.ExecutionTimeFinishedJobs = source.ExecutionTimeFinishedJobs.ToString();
-        target.StartToEndTime = source.StartToEndTime.ToString();
+        target.ExecutionTimeMs = source.ExecutionTime.TotalMilliseconds;
+        target.ExecutionTimeMsFinishedJobs = source.ExecutionTimeFinishedJobs.TotalMilliseconds;
+        target.StartToEndTimeMs = source.StartToEndTime.TotalMilliseconds;
       }
     }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDao.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDao.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDao.cs	(revision 6267)
@@ -559,4 +559,31 @@
       CollectParentResources(resources, resource.ParentResource);
     }
+
+    /// <summary>
+    /// Returns all child resources of a resource (without the given resource)
+    /// </summary>
+    public IEnumerable<DT.Resource> GetChildResources(Guid resourceId) {
+      using (var db = CreateContext()) {
+        var childs = new List<DT.Resource>();
+        foreach (var child in db.Resources.Where(x => x.ParentResourceId == resourceId)) {
+          childs.Add(Convert.ToDto(child));
+          childs.AddRange(GetChildResources(child.ResourceId));
+        }
+        return childs;
+      }
+    }
+
+    public IEnumerable<DT.Job> GetJobsByResourceId(Guid resourceId) {
+      using (var db = CreateContext()) {
+        var resources = GetChildResources(resourceId).Select(x => x.Id).ToList();
+        resources.Add(resourceId);
+
+        var jobs = db.Jobs.Where(j =>
+          j.State == JobState.Calculating &&
+          j.StateLogs.OrderByDescending(x => x.DateTime).First().SlaveId.HasValue &&
+          resources.Contains(j.StateLogs.OrderByDescending(x => x.DateTime).First().SlaveId.Value));
+        return jobs.Select(j => Convert.ToDto(j)).ToArray();
+      }
+    }
     #endregion
 
@@ -689,20 +716,75 @@
     public List<DT.UserStatistics> GetUserStatistics() {
       using (var db = CreateContext()) {
+        var userStats = new Dictionary<Guid, DT.UserStatistics>();
+
+        var usedCoresByUser = from job in db.Jobs
+                              where job.State == JobState.Calculating
+                              group job by job.HiveExperiment.OwnerUserId into g
+                              select new { UserId = g.Key, UsedCores = g.Count() };
+
+        foreach (var item in usedCoresByUser) {
+          if (!userStats.ContainsKey(item.UserId)) {
+            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
+          }
+          userStats[item.UserId].UsedCores += item.UsedCores;
+        }
+
         var executionTimesByUser = from job in db.Jobs
                                    group job by job.HiveExperiment.OwnerUserId into g
-                                   select new { UserId = g.Key, ExecutionTimes = g.Select(x => x.ExecutionTime) };
-
-        var userStats = new List<DT.UserStatistics>();
+                                   select new { UserId = g.Key, ExecutionTime = TimeSpan.FromMilliseconds(g.Select(x => x.ExecutionTimeMs).Sum()) };
         foreach (var item in executionTimesByUser) {
-          userStats.Add(new DT.UserStatistics() {
-            UserId = item.UserId,
-            ExecutionTime = TimeSpan.FromMilliseconds(item.ExecutionTimes.Select(x => string.IsNullOrEmpty(x) ? 0 : TimeSpan.Parse(x).TotalMilliseconds).Sum())
-          });
-        }
-
-        // Todo: also consider executiontimes of DeletedJobStats 
-        // Todo: compute executionTimeFinishedJobs und StartToEndTime (=> dient zum errechnen der Efficiency/Overhead)
-
-        return userStats;
+          if (!userStats.ContainsKey(item.UserId)) {
+            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
+          }
+          userStats[item.UserId].ExecutionTime += item.ExecutionTime;
+        }
+
+        // execution times only of finished jobs - necessary to compute efficieny
+        var executionTimesFinishedJobs = from job in db.Jobs
+                                         where job.State == JobState.Finished
+                                         group job by job.HiveExperiment.OwnerUserId into g
+                                         select new { UserId = g.Key, ExecutionTimeFinishedJobs = TimeSpan.FromMilliseconds(g.Select(x => x.ExecutionTimeMs).Sum()) };
+
+        foreach (var item in executionTimesFinishedJobs) {
+          if (!userStats.ContainsKey(item.UserId)) {
+            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
+          }
+          userStats[item.UserId].ExecutionTimeFinishedJobs += item.ExecutionTimeFinishedJobs;
+        }
+
+        // start to end times only of finished jobs - necessary to compute efficiency
+        var startToEndTimesFinishedJobs = from job in db.Jobs
+                                          where job.State == JobState.Finished
+                                          group job by job.HiveExperiment.OwnerUserId into g
+                                          select new {
+                                            UserId = g.Key,
+                                            StartToEndTime = g.Select(x => x.StateLogs.OrderByDescending(sl => sl.DateTime).First().DateTime - x.StateLogs.OrderBy(sl => sl.DateTime).First().DateTime).Sum()
+                                          };
+        foreach (var item in startToEndTimesFinishedJobs) {
+          if (!userStats.ContainsKey(item.UserId)) {
+            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
+          }
+          userStats[item.UserId].StartToEndTime += item.StartToEndTime;
+        }
+
+        // also consider executiontimes of DeletedJobStats 
+        var deletedJobsExecutionTimesByUsers = from del in db.DeletedJobStatistics
+                                               group del by del.UserId into g
+                                               select new {
+                                                 UserId = g.Key,
+                                                 ExecutionTime = TimeSpan.FromMilliseconds(g.Select(x => x.ExecutionTimeMs).Sum()),
+                                                 ExecutionTimeFinishedJobs = TimeSpan.FromMilliseconds(g.Select(x => x.ExecutionTimeMsFinishedJobs).Sum()),
+                                                 StartToEndTime = TimeSpan.FromMilliseconds(g.Select(x => x.StartToEndTimeMs).Sum())
+                                               };
+        foreach (var item in deletedJobsExecutionTimesByUsers) {
+          if (!userStats.ContainsKey(item.UserId)) {
+            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
+          }
+          userStats[item.UserId].ExecutionTime += item.ExecutionTime;
+          userStats[item.UserId].ExecutionTimeFinishedJobs += item.ExecutionTimeFinishedJobs;
+          userStats[item.UserId].StartToEndTime += item.StartToEndTime;
+        }
+
+        return userStats.Values.ToList();
       }
     }
@@ -719,7 +801,10 @@
     }
     #endregion
-
-
-
+  }
+
+  public static class TimeSpanExtensions {
+    public static TimeSpan Sum(this IEnumerable<TimeSpan> ts) {
+      return new TimeSpan(ts.Sum(r => r.Ticks));
+    }
   }
 }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml	(revision 6267)
@@ -62,5 +62,5 @@
       <Column Name="JobId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
       <Column Name="JobState" Member="State" Type="global::HeuristicLab.Services.Hive.Common.DataTransfer.JobState" DbType="VarChar(30)" CanBeNull="false" />
-      <Column Name="ExecutionTime" Type="System.String" DbType="VarChar(30)" CanBeNull="true" />
+      <Column Name="ExecutionTimeMs" Storage="_ExecutionTime" Type="System.Double" DbType="float" CanBeNull="false" />
       <Column Name="LastHeartbeat" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
       <Column Name="ParentJobId" Type="System.Guid" DbType="UniqueIdentifier" CanBeNull="true" />
@@ -72,4 +72,5 @@
       <Column Name="Command" Type="global::HeuristicLab.Services.Hive.Common.DataTransfer.Command?" DbType="VarChar(30)" CanBeNull="true" />
       <Column Name="HiveExperimentId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" CanBeNull="false" />
+      <Column Name="IsPrivileged" Type="System.Boolean" DbType="Bit" CanBeNull="false" />
       <Association Name="Job_AssignedResource" Member="AssignedResources" ThisKey="JobId" OtherKey="JobId" Type="AssignedResource" />
       <Association Name="Job_RequiredPlugin" Member="RequiredPlugins" ThisKey="JobId" OtherKey="JobId" Type="RequiredPlugin" />
@@ -154,8 +155,9 @@
   <Table Name="" Member="DeletedJobStatistics">
     <Type Name="DeletedJobStatistics">
-      <Column Member="UserId" Type="System.String" IsPrimaryKey="true" CanBeNull="false" />
-      <Column Name="ExecutionTime" Type="System.String" DbType="VarChar(30)" CanBeNull="false" />
-      <Column Name="ExecutionTimeFinishedJobs" Type="System.String" DbType="VarChar(30)" CanBeNull="false" />
-      <Column Name="StartToEndTime" Type="System.String" DbType="VarChar(30)" CanBeNull="false" />
+      <Column Name="UserId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" CanBeNull="false" />
+      <Column Name="ExecutionTimeMs" Storage="_ExecutionTime" Type="System.Double" DbType="float" CanBeNull="false" />
+      <Column Name="ExecutionTimeMsFinishedJobs" Storage="_ExecutionTimeFinishedJobs" Type="System.Double" DbType="float" CanBeNull="false" />
+      <Column Name="StartToEndTimeMs" Storage="_StartToEndTime" Type="System.Double" DbType="float" CanBeNull="false" />
+      <Column Name="DeletedJobStatisticsId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
     </Type>
   </Table>
@@ -164,8 +166,8 @@
       <Column Name="StatisticsId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
       <Column Name="UserId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
-      <Column Name="ExecutionTime" Type="System.String" DbType="VarChar(30)" CanBeNull="false" />
+      <Column Name="ExecutionTimeMs" Storage="_ExecutionTime" Type="System.Double" DbType="float" CanBeNull="false" />
       <Column Name="UsedCores" Storage="_CoresUsed" Type="System.Int32" DbType="Int" CanBeNull="false" />
-      <Column Name="ExecutionTimeFinishedJobs" Type="System.String" DbType="VarChar(30)" CanBeNull="false" />
-      <Column Name="StartToEndTime" Type="System.String" DbType="VarChar(30)" CanBeNull="false" />
+      <Column Name="ExecutionTimeMsFinishedJobs" Storage="_ExecutionTimeFinishedJobs" Type="System.Double" DbType="float" CanBeNull="false" />
+      <Column Name="StartToEndTimeMs" Storage="_StartToEndTime" Type="System.Double" DbType="float" CanBeNull="false" />
       <Association Name="Statistics_UserStatistics" Member="Statistics" ThisKey="StatisticsId" OtherKey="StatisticsId" Type="Statistics" IsForeignKey="true" />
     </Type>
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml.layout
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml.layout	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml.layout	(revision 6267)
@@ -27,8 +27,8 @@
       </nestedChildShapes>
     </classShape>
-    <classShape Id="695bfc39-59f3-4e60-8644-f847964bf62c" absoluteBounds="6.5, 1, 2, 3.1170068359374996">
+    <classShape Id="695bfc39-59f3-4e60-8644-f847964bf62c" absoluteBounds="6.5, 1, 2, 3.3093082682291666">
       <DataClassMoniker Name="/HiveDataContext/Job" />
       <nestedChildShapes>
-        <elementListCompartment Id="a6a30e11-03d1-4869-82e6-b733f4ef9974" absoluteBounds="6.5150000000000006, 1.46, 1.9700000000000002, 2.5570068359375" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+        <elementListCompartment Id="a6a30e11-03d1-4869-82e6-b733f4ef9974" absoluteBounds="6.5150000000000006, 1.46, 1.9700000000000002, 2.7493082682291665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
       </nestedChildShapes>
     </classShape>
@@ -69,5 +69,5 @@
       </nodes>
     </inheritanceConnector>
-    <associationConnector edgePoints="[(11.9843735 : 2.57859537760417); (11.9843735 : 4.69314697265625); (10.875 : 4.69314697265625)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(11.9843735 : 2.57859537760417); (11.9843735 : 4.69314697265625); (10.875 : 4.69314697265625)]" fixedFrom="NotFixed" fixedTo="NotFixed">
       <AssociationMoniker Name="/HiveDataContext/Resource/Resource_AssignedResource" />
       <nodes>
@@ -76,5 +76,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(7.5 : 4.1170068359375); (7.5 : 4.751650890625); (8.875 : 4.751650890625)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(7.803710203125 : 4.30930826822917); (7.803710203125 : 4.84780160677083); (8.875 : 4.84780160677083)]" fixedFrom="Algorithm" fixedTo="Algorithm">
       <AssociationMoniker Name="/HiveDataContext/Job/Job_AssignedResource" />
       <nodes>
@@ -83,5 +83,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(7.10742140625 : 4.1170068359375); (7.10742140625 : 5.5)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+    <associationConnector edgePoints="[(7.0893551015625 : 4.30930826822917); (7.0893551015625 : 5.5)]" fixedFrom="Algorithm" fixedTo="Algorithm">
       <AssociationMoniker Name="/HiveDataContext/Job/Job_RequiredPlugin" />
       <nodes>
@@ -123,5 +123,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(6.5 : 1.69314697265625); (6.125 : 1.69314697265625)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+    <associationConnector edgePoints="[(6.5 : 1.69314697265625); (6.125 : 1.69314697265625)]" fixedFrom="Algorithm" fixedTo="Algorithm">
       <AssociationMoniker Name="/HiveDataContext/Job/Job_JobData" />
       <nodes>
@@ -156,5 +156,5 @@
       </nestedChildShapes>
     </classShape>
-    <associationConnector edgePoints="[(6.5 : 2.50564697265625); (3.75 : 2.50564697265625)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+    <associationConnector edgePoints="[(6.5 : 2.50564697265625); (3.75 : 2.50564697265625)]" fixedFrom="Algorithm" fixedTo="Algorithm">
       <AssociationMoniker Name="/HiveDataContext/Job/Job_StateLog" />
       <nodes>
@@ -163,5 +163,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(11.25 : 1.36339684440104); (10.9375 : 1.36339684440104); (10.9375 : 0.6875); (2.75 : 0.6875); (2.75 : 1)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+    <associationConnector edgePoints="[(11.25 : 1.78929768880208); (10.9375 : 1.78929768880208); (10.9375 : 0.6875); (2.75 : 0.6875); (2.75 : 1)]" fixedFrom="Algorithm" fixedTo="Algorithm">
       <AssociationMoniker Name="/HiveDataContext/Resource/Resource_StateLog" />
       <nodes>
@@ -183,5 +183,5 @@
       </nestedChildShapes>
     </classShape>
-    <associationConnector edgePoints="[(6.125 : 3.37100341796875); (6.5 : 3.37100341796875)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+    <associationConnector edgePoints="[(6.125 : 3.46715413411458); (6.5 : 3.46715413411458)]" fixedFrom="Algorithm" fixedTo="Algorithm">
       <AssociationMoniker Name="/HiveDataContext/HiveExperiment/HiveExperiment_Job" />
       <nodes>
@@ -190,8 +190,8 @@
       </nodes>
     </associationConnector>
-    <classShape Id="cdddf4da-eaef-46a1-9cfd-987bb6b3d03e" absoluteBounds="17, 3.125, 2, 1.5785953776041666">
+    <classShape Id="cdddf4da-eaef-46a1-9cfd-987bb6b3d03e" absoluteBounds="17, 3.125, 2.5, 1.7708968098958327">
       <DataClassMoniker Name="/HiveDataContext/DeletedJobStatistics" />
       <nestedChildShapes>
-        <elementListCompartment Id="b8738381-f696-4dba-a517-47e9cd96a9a6" absoluteBounds="17.015, 3.585, 1.9700000000000002, 1.0185953776041665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+        <elementListCompartment Id="b8738381-f696-4dba-a517-47e9cd96a9a6" absoluteBounds="17.015, 3.585, 2.4699999999999998, 1.2108968098958333" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
       </nestedChildShapes>
     </classShape>
@@ -214,5 +214,5 @@
       </nestedChildShapes>
     </classShape>
-    <associationConnector edgePoints="[(21.4375 : 4.19399251302083); (21.4375 : 4.5)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(21.4375 : 4.19399251302083); (21.4375 : 4.5)]" fixedFrom="NotFixed" fixedTo="NotFixed">
       <AssociationMoniker Name="/HiveDataContext/Statistics/Statistics_SlaveStatistics" />
       <nodes>
@@ -221,5 +221,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(22.5 : 4.19399251302083); (22.5 : 4.5)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(22.5 : 4.19399251302083); (22.5 : 4.5)]" fixedFrom="NotFixed" fixedTo="NotFixed">
       <AssociationMoniker Name="/HiveDataContext/Statistics/Statistics_UserStatistics" />
       <nodes>
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.designer.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.designer.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.designer.cs	(revision 6267)
@@ -1474,5 +1474,5 @@
 		private global::HeuristicLab.Services.Hive.Common.DataTransfer.JobState _State;
 		
-		private string _ExecutionTime;
+		private double _ExecutionTime;
 		
 		private System.Nullable<System.DateTime> _LastHeartbeat;
@@ -1493,4 +1493,6 @@
 		
 		private System.Guid _HiveExperimentId;
+		
+		private bool _IsPrivileged;
 		
 		private EntitySet<AssignedResource> _AssignedResources;
@@ -1516,6 +1518,6 @@
     partial void OnStateChanging(global::HeuristicLab.Services.Hive.Common.DataTransfer.JobState value);
     partial void OnStateChanged();
-    partial void OnExecutionTimeChanging(string value);
-    partial void OnExecutionTimeChanged();
+    partial void OnExecutionTimeMsChanging(double value);
+    partial void OnExecutionTimeMsChanged();
     partial void OnLastHeartbeatChanging(System.Nullable<System.DateTime> value);
     partial void OnLastHeartbeatChanged();
@@ -1536,4 +1538,6 @@
     partial void OnHiveExperimentIdChanging(System.Guid value);
     partial void OnHiveExperimentIdChanged();
+    partial void OnIsPrivilegedChanging(bool value);
+    partial void OnIsPrivilegedChanged();
     #endregion
 		
@@ -1590,6 +1594,6 @@
 		}
 		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTime", DbType="VarChar(30)")]
-		public string ExecutionTime
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTime", DbType="float")]
+		public double ExecutionTimeMs
 		{
 			get
@@ -1601,9 +1605,9 @@
 				if ((this._ExecutionTime != value))
 				{
-					this.OnExecutionTimeChanging(value);
+					this.OnExecutionTimeMsChanging(value);
 					this.SendPropertyChanging();
 					this._ExecutionTime = value;
-					this.SendPropertyChanged("ExecutionTime");
-					this.OnExecutionTimeChanged();
+					this.SendPropertyChanged("ExecutionTimeMs");
+					this.OnExecutionTimeMsChanged();
 				}
 			}
@@ -1794,4 +1798,24 @@
 					this.SendPropertyChanged("HiveExperimentId");
 					this.OnHiveExperimentIdChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_IsPrivileged", DbType="Bit")]
+		public bool IsPrivileged
+		{
+			get
+			{
+				return this._IsPrivileged;
+			}
+			set
+			{
+				if ((this._IsPrivileged != value))
+				{
+					this.OnIsPrivilegedChanging(value);
+					this.SendPropertyChanging();
+					this._IsPrivileged = value;
+					this.SendPropertyChanged("IsPrivileged");
+					this.OnIsPrivilegedChanged();
 				}
 			}
@@ -3430,11 +3454,13 @@
 		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
 		
-		private string _UserId;
-		
-		private string _ExecutionTime;
-		
-		private string _ExecutionTimeFinishedJobs;
-		
-		private string _StartToEndTime;
+		private System.Guid _UserId;
+		
+		private double _ExecutionTime;
+		
+		private double _ExecutionTimeFinishedJobs;
+		
+		private double _StartToEndTime;
+		
+		private System.Guid _DeletedJobStatisticsId;
 		
     #region Extensibility Method Definitions
@@ -3442,12 +3468,14 @@
     partial void OnValidate(System.Data.Linq.ChangeAction action);
     partial void OnCreated();
-    partial void OnUserIdChanging(string value);
+    partial void OnUserIdChanging(System.Guid value);
     partial void OnUserIdChanged();
-    partial void OnExecutionTimeChanging(string value);
-    partial void OnExecutionTimeChanged();
-    partial void OnExecutionTimeFinishedJobsChanging(string value);
-    partial void OnExecutionTimeFinishedJobsChanged();
-    partial void OnStartToEndTimeChanging(string value);
-    partial void OnStartToEndTimeChanged();
+    partial void OnExecutionTimeMsChanging(double value);
+    partial void OnExecutionTimeMsChanged();
+    partial void OnExecutionTimeMsFinishedJobsChanging(double value);
+    partial void OnExecutionTimeMsFinishedJobsChanged();
+    partial void OnStartToEndTimeMsChanging(double value);
+    partial void OnStartToEndTimeMsChanged();
+    partial void OnDeletedJobStatisticsIdChanging(System.Guid value);
+    partial void OnDeletedJobStatisticsIdChanged();
     #endregion
 		
@@ -3457,6 +3485,6 @@
 		}
 		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", CanBeNull=false, IsPrimaryKey=true)]
-		public string UserId
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", DbType="UniqueIdentifier NOT NULL")]
+		public System.Guid UserId
 		{
 			get
@@ -3477,6 +3505,6 @@
 		}
 		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTime", DbType="VarChar(30)", CanBeNull=false)]
-		public string ExecutionTime
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTime", DbType="float")]
+		public double ExecutionTimeMs
 		{
 			get
@@ -3488,15 +3516,15 @@
 				if ((this._ExecutionTime != value))
 				{
-					this.OnExecutionTimeChanging(value);
+					this.OnExecutionTimeMsChanging(value);
 					this.SendPropertyChanging();
 					this._ExecutionTime = value;
-					this.SendPropertyChanged("ExecutionTime");
-					this.OnExecutionTimeChanged();
-				}
-			}
-		}
-		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTimeFinishedJobs", DbType="VarChar(30)", CanBeNull=false)]
-		public string ExecutionTimeFinishedJobs
+					this.SendPropertyChanged("ExecutionTimeMs");
+					this.OnExecutionTimeMsChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTimeFinishedJobs", DbType="float")]
+		public double ExecutionTimeMsFinishedJobs
 		{
 			get
@@ -3508,15 +3536,15 @@
 				if ((this._ExecutionTimeFinishedJobs != value))
 				{
-					this.OnExecutionTimeFinishedJobsChanging(value);
+					this.OnExecutionTimeMsFinishedJobsChanging(value);
 					this.SendPropertyChanging();
 					this._ExecutionTimeFinishedJobs = value;
-					this.SendPropertyChanged("ExecutionTimeFinishedJobs");
-					this.OnExecutionTimeFinishedJobsChanged();
-				}
-			}
-		}
-		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_StartToEndTime", DbType="VarChar(30)", CanBeNull=false)]
-		public string StartToEndTime
+					this.SendPropertyChanged("ExecutionTimeMsFinishedJobs");
+					this.OnExecutionTimeMsFinishedJobsChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_StartToEndTime", DbType="float")]
+		public double StartToEndTimeMs
 		{
 			get
@@ -3528,9 +3556,29 @@
 				if ((this._StartToEndTime != value))
 				{
-					this.OnStartToEndTimeChanging(value);
+					this.OnStartToEndTimeMsChanging(value);
 					this.SendPropertyChanging();
 					this._StartToEndTime = value;
-					this.SendPropertyChanged("StartToEndTime");
-					this.OnStartToEndTimeChanged();
+					this.SendPropertyChanged("StartToEndTimeMs");
+					this.OnStartToEndTimeMsChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_DeletedJobStatisticsId", AutoSync=AutoSync.OnInsert, DbType="UniqueIdentifier NOT NULL", IsPrimaryKey=true, IsDbGenerated=true)]
+		public System.Guid DeletedJobStatisticsId
+		{
+			get
+			{
+				return this._DeletedJobStatisticsId;
+			}
+			set
+			{
+				if ((this._DeletedJobStatisticsId != value))
+				{
+					this.OnDeletedJobStatisticsIdChanging(value);
+					this.SendPropertyChanging();
+					this._DeletedJobStatisticsId = value;
+					this.SendPropertyChanged("DeletedJobStatisticsId");
+					this.OnDeletedJobStatisticsIdChanged();
 				}
 			}
@@ -3568,11 +3616,11 @@
 		private System.Guid _UserId;
 		
-		private string _ExecutionTime;
+		private double _ExecutionTime;
 		
 		private int _CoresUsed;
 		
-		private string _ExecutionTimeFinishedJobs;
-		
-		private string _StartToEndTime;
+		private double _ExecutionTimeFinishedJobs;
+		
+		private double _StartToEndTime;
 		
 		private EntityRef<Statistics> _Statistics;
@@ -3586,12 +3634,12 @@
     partial void OnUserIdChanging(System.Guid value);
     partial void OnUserIdChanged();
-    partial void OnExecutionTimeChanging(string value);
-    partial void OnExecutionTimeChanged();
+    partial void OnExecutionTimeMsChanging(double value);
+    partial void OnExecutionTimeMsChanged();
     partial void OnUsedCoresChanging(int value);
     partial void OnUsedCoresChanged();
-    partial void OnExecutionTimeFinishedJobsChanging(string value);
-    partial void OnExecutionTimeFinishedJobsChanged();
-    partial void OnStartToEndTimeChanging(string value);
-    partial void OnStartToEndTimeChanged();
+    partial void OnExecutionTimeMsFinishedJobsChanging(double value);
+    partial void OnExecutionTimeMsFinishedJobsChanged();
+    partial void OnStartToEndTimeMsChanging(double value);
+    partial void OnStartToEndTimeMsChanged();
     #endregion
 		
@@ -3646,6 +3694,6 @@
 		}
 		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTime", DbType="VarChar(30)", CanBeNull=false)]
-		public string ExecutionTime
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTime", DbType="float")]
+		public double ExecutionTimeMs
 		{
 			get
@@ -3657,9 +3705,9 @@
 				if ((this._ExecutionTime != value))
 				{
-					this.OnExecutionTimeChanging(value);
+					this.OnExecutionTimeMsChanging(value);
 					this.SendPropertyChanging();
 					this._ExecutionTime = value;
-					this.SendPropertyChanged("ExecutionTime");
-					this.OnExecutionTimeChanged();
+					this.SendPropertyChanged("ExecutionTimeMs");
+					this.OnExecutionTimeMsChanged();
 				}
 			}
@@ -3686,6 +3734,6 @@
 		}
 		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTimeFinishedJobs", DbType="VarChar(30)", CanBeNull=false)]
-		public string ExecutionTimeFinishedJobs
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTimeFinishedJobs", DbType="float")]
+		public double ExecutionTimeMsFinishedJobs
 		{
 			get
@@ -3697,15 +3745,15 @@
 				if ((this._ExecutionTimeFinishedJobs != value))
 				{
-					this.OnExecutionTimeFinishedJobsChanging(value);
+					this.OnExecutionTimeMsFinishedJobsChanging(value);
 					this.SendPropertyChanging();
 					this._ExecutionTimeFinishedJobs = value;
-					this.SendPropertyChanged("ExecutionTimeFinishedJobs");
-					this.OnExecutionTimeFinishedJobsChanged();
-				}
-			}
-		}
-		
-		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_StartToEndTime", DbType="VarChar(30)", CanBeNull=false)]
-		public string StartToEndTime
+					this.SendPropertyChanged("ExecutionTimeMsFinishedJobs");
+					this.OnExecutionTimeMsFinishedJobsChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_StartToEndTime", DbType="float")]
+		public double StartToEndTimeMs
 		{
 			get
@@ -3717,9 +3765,9 @@
 				if ((this._StartToEndTime != value))
 				{
-					this.OnStartToEndTimeChanging(value);
+					this.OnStartToEndTimeMsChanging(value);
 					this.SendPropertyChanging();
 					this._StartToEndTime = value;
-					this.SendPropertyChanged("StartToEndTime");
-					this.OnStartToEndTimeChanged();
+					this.SendPropertyChanged("StartToEndTimeMs");
+					this.OnStartToEndTimeMsChanged();
 				}
 			}
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Interfaces/IHiveDao.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Interfaces/IHiveDao.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Interfaces/IHiveDao.cs	(revision 6267)
@@ -95,4 +95,5 @@
     IEnumerable<DT.Resource> GetAssignedResources(Guid jobId);
     IEnumerable<DT.Resource> GetParentResources(Guid resourceId);
+    IEnumerable<DT.Job> GetJobsByResourceId(Guid resourceId);
     #endregion
 
@@ -123,7 +124,4 @@
     List<DT.UserStatistics> GetUserStatistics();
     #endregion
-
-
-
   }
 }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Tools/prepareHiveDatabase.sql
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Tools/prepareHiveDatabase.sql	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Tools/prepareHiveDatabase.sql	(revision 6267)
@@ -1,2 +1,3 @@
+USE [HeuristicLab.Hive-3.4]
 /* this script is supposed to be executed after the plain DB is generated by the linq-to-sql schema */
 
@@ -108,4 +109,8 @@
 GO
 
+ALTER TABLE [dbo].[DeletedJobStatistics] ALTER COLUMN DeletedJobStatisticsId ADD ROWGUIDCOL;
+ALTER TABLE [dbo].[DeletedJobStatistics] WITH NOCHECK ADD CONSTRAINT [DF_DeletedJobStatistics_DeletedJobStatisticsId] DEFAULT (newid()) FOR DeletedJobStatisticsId;
+GO
+
 ALTER TABLE [dbo].[SlaveStatistics]  DROP  CONSTRAINT [Statistics_SlaveStatistics]
 ALTER TABLE [dbo].[SlaveStatistics]  WITH CHECK ADD  CONSTRAINT [Statistics_SlaveStatistics] FOREIGN KEY([StatisticsId])
@@ -124,7 +129,36 @@
 /* create indices */
 CREATE INDEX Index_RequiredPlugins_JobId ON RequiredPlugins(JobId);
+GO
+
+/* views */
+-- =============================================
+-- Author:		cneumuel
+-- Description:	Returns the first StateLog entry for each job
+-- =============================================
+CREATE VIEW [dbo].[view_FirstState]
+AS
+SELECT     sl.JobId, sl.DateTime, sl.State
+FROM         dbo.StateLog AS sl INNER JOIN
+                          (SELECT     JobId, MIN(DateTime) AS DateTime
+                            FROM          dbo.StateLog
+                            GROUP BY JobId) AS minDate ON sl.DateTime = minDate.DateTime AND sl.JobId = minDate.JobId
+
+GO
+
+-- =============================================
+-- Author:		cneumuel
+-- Description:	Returns the last StateLog entry for each job
+-- =============================================
+CREATE VIEW [dbo].[view_LastState]
+AS
+SELECT     sl.JobId, sl.DateTime, sl.State
+FROM         dbo.StateLog AS sl INNER JOIN
+                          (SELECT     JobId, MAX(DateTime) AS DateTime
+                            FROM          dbo.StateLog
+                            GROUP BY JobId) AS minDate ON sl.DateTime = minDate.DateTime AND sl.JobId = minDate.JobId
+
+GO
 
 /* triggers */
-USE [HeuristicLab.Hive-3.4]
 GO
 /****** Object:  Trigger [dbo].[tr_HiveExperimentDeleteCascade]    Script Date: 04/19/2011 16:31:53 ******/
@@ -136,5 +170,6 @@
 -- Author:		cneumuel
 -- Create date: 19.04.2011
--- Description:	Deletes all associated jobs. This cannot be done with cascading delete, 
+-- Description:	(1) Writes the execution times of deleted jobs into DeletedJobStats to ensure correct statistics
+--				(2) Deletes all associated jobs. This cannot be done with cascading delete, 
 --              because the job table defines a INSTEAD OF DELETE trigger itself, which
 --              is not compatible with cascading deletes.
@@ -154,4 +189,23 @@
 CREATE TRIGGER [dbo].[tr_JobDeleteCascade] ON [dbo].[Job] INSTEAD OF DELETE AS 
 BEGIN
+	-- add statistics
+	INSERT INTO dbo.DeletedJobStatistics (UserId, ExecutionTimeMs, ExecutionTimeMsFinishedJobs, StartToEndTimeMs)
+	SELECT 
+		he.OwnerUserId AS UserId, 
+		SUM(j.ExecutionTimeMs) AS ExecutionTimeMs, 
+		SUM(CASE ls.State WHEN 'Finished' THEN j.ExecutionTimeMs END) AS ExecutionTimeMsFinishedJobs,
+		SUM(CASE ls.State WHEN 'Finished' THEN DATEDIFF(MS,fs.DateTime,ls.DateTime) ELSE 0 END) AS StartToEndMs
+	FROM 
+		deleted j, 
+		HiveExperiment he, 
+		view_FirstState fs, 
+		view_LastState ls
+	WHERE 
+		he.HiveExperimentId = j.HiveExperimentId AND 
+		fs.JobId = j.JobId AND 
+		ls.JobId = j.JobId
+	GROUP BY he.OwnerUserId
+
+	-- recursively delete jobs
 	CREATE TABLE #Table( 
 		JobId uniqueidentifier 
@@ -186,4 +240,6 @@
 --CREATE TRIGGER [dbo].[tr_DeletedJobStats] ON [dbo].[Job] AFTER DELETE AS
 --BEGIN
---	INSERT INTO DeletedJobStats SELECT JobId, ExecutionTime FROM deleted
+
+
 --END
+--GO
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/TransactionManager.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/TransactionManager.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/TransactionManager.cs	(revision 6267)
@@ -1,10 +1,9 @@
 ﻿using System;
 using System.Transactions;
-using HeuristicLab.Services.Hive.Common;
 
 namespace HeuristicLab.Services.Hive.DataAccess {
   public class TransactionManager {
-    public void UseTransaction(Action call) {
-      TransactionScope transaction = CreateTransaction();
+    public void UseTransaction(Action call, bool serializable = false) {
+      TransactionScope transaction = serializable ? CreateSerializableTransaction() : CreateTransaction();
       try {
         call();
@@ -16,6 +15,6 @@
     }
 
-    public T UseTransaction<T>(Func<T> call) {
-      TransactionScope transaction = CreateTransaction();
+    public T UseTransaction<T>(Func<T> call, bool serializable = false) {
+      TransactionScope transaction = serializable ? CreateSerializableTransaction() : CreateTransaction();
       try {
         T result = call();
@@ -29,5 +28,8 @@
 
     private static TransactionScope CreateTransaction() {
-      return new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = ApplicationConstants.IsolationLevelScope });
+      return new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadUncommitted });
+    }
+    private static TransactionScope CreateSerializableTransaction() {
+      return new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.Serializable });
     }
   }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/DaoTests.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/DaoTests.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/DaoTests.cs	(revision 6267)
@@ -39,4 +39,5 @@
       job1.Command = Command.Pause;
       job1.HiveExperimentId = he.Id;
+      job1.IsPrivileged = true;
 
       DT.JobData jobData1 = new DT.JobData();
@@ -75,4 +76,5 @@
       Assert.AreEqual(job1.Command, job1loaded.Command);
       Assert.AreEqual(job1.HiveExperimentId, job1loaded.HiveExperimentId);
+      Assert.AreEqual(job1.IsPrivileged, job1loaded.IsPrivileged);
       Assert.IsTrue(Math.Abs((job1loaded.LastJobDataUpdate - jobData1.LastUpdate).TotalSeconds) < 1);
       for (int i = 0; i < job1.StateLog.Count; i++) {
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/ServiceTests.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/ServiceTests.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/ServiceTests.cs	(revision 6267)
@@ -147,5 +147,17 @@
       jobLoaded = service.GetJob(job.Id);
       Assert.AreEqual(JobState.Calculating, jobLoaded.State);
-      Assert.AreEqual(new TimeSpan(1, 5, 10, 20, 30), jobLoaded.ExecutionTime.Value);
+      Assert.AreEqual(new TimeSpan(1, 5, 10, 20, 30), jobLoaded.ExecutionTime);
+
+      // test if the job is returned for the resource
+      var jobsBySlave = service.GetJobsByResourceId(slave.Id);
+      Assert.AreEqual(1, jobsBySlave.Count());
+      Assert.AreEqual(job.Id, jobsBySlave.Single().Id);
+      
+      // set it to finished
+      service.UpdateJobState(jobLoaded.Id, JobState.Finished, slave.Id, null, null);
+
+      // test if the job is returned for the resource
+      var jobsBySlave2 = service.GetJobsByResourceId(slave.Id);
+      Assert.AreEqual(0, jobsBySlave2.Count());
 
       // delete
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive/3.4/HiveService.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive/3.4/HiveService.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive/3.4/HiveService.cs	(revision 6267)
@@ -147,5 +147,5 @@
       return trans.UseTransaction(() => {
         Job job = dao.UpdateJobState(jobId, jobState, slaveId, userId, exception);
-        
+
         if (job.Command.HasValue && job.Command.Value == Command.Pause && job.State == JobState.Paused) {
           job.Command = null;
@@ -280,6 +280,6 @@
           dbSlave.Memory = slaveInfo.Memory;
           dbSlave.OperatingSystem = slaveInfo.OperatingSystem;
-          
-          dbSlave.LastHeartbeat = DateTime.Now;          
+
+          dbSlave.LastHeartbeat = DateTime.Now;
           dbSlave.SlaveState = SlaveState.Idle;
 
@@ -472,4 +472,5 @@
 
     public void TriggerLifecycle(bool force) {
+      // use a serializable transaction here to ensure not two threads execute this simultaniously (locking would not work since IIS may use multiple AppDomains)
       trans.UseTransaction(() => {
         DateTime lastCleanup = dao.GetLastCleanup();
@@ -478,5 +479,5 @@
           lifecycleManager.Cleanup();
         }
-      });
+      }, true);
     }
     #endregion
@@ -526,4 +527,8 @@
       return trans.UseTransaction(() => dao.GetAppointments(x => x.ResourceId == resourceId));
     }
+
+    public IEnumerable<Job> GetJobsByResourceId(Guid resourceId) {
+      return trans.UseTransaction(() => dao.GetJobsByResourceId(resourceId));
+    }
     #endregion
   }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive/3.4/LifecycleManager.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive/3.4/LifecycleManager.cs	(revision 6264)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive/3.4/LifecycleManager.cs	(revision 6267)
@@ -52,27 +52,4 @@
 
       dao.AddStatistics(stats);
-
-      //int slaveCount = slaves.Count();
-      //int cores = slaves.Select(x => x.Cores.HasValue ? x.Cores.Value : 0).Sum();
-      //int usedCores = slaves.Select(x => x.FreeCores.HasValue ? x.FreeCores.Value : 0).Sum();
-
-      //long memoryMb = slaves.Select(x => x.Memory.HasValue ? x.Memory.Value : 0).Sum(); ;
-      //long memoryUsedMb = slaves.Select(x => x.FreeMemory.HasValue ? x.FreeMemory.Value : 0).Sum();
-
-      //double averageCpuUtilization = slaves.Select(x => x.CpuUtilization.HasValue ? x.CpuUtilization.Value : 0).Average();
-
-      //int executionTimeDelta = 0; // since last update
-
-      //{ // per user
-      //  int activeJobs = 0; // calculating, transferring
-      //  int waitingJobs = 0; // waiting
-      //  int stoppedJobs = 0; // finished, failed, aborted, paused
-      //}
-
-      //{ // per slave
-      //  int activeJobs = 0; // calculating, transferring
-      //  double cpuUtilization = 0.0;
-      //}
-
     }
 
