Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/JobResultPoller.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/JobResultPoller.cs	(revision 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/JobResultPoller.cs	(revision 6229)
@@ -100,4 +100,5 @@
           IsPolling = false;
         }
+        if (stopRequested) return;
         if (!autoResumeOnException) return;
       }
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 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/RefreshableHiveExperiment.cs	(revision 6229)
@@ -175,6 +175,8 @@
     }
     private void jobResultPoller_IsPollingChanged(object sender, EventArgs e) {
-      this.refreshAutomatically = jobResultPoller.IsPolling;
-      OnRefreshAutomaticallyChanged();
+      if (this.refreshAutomatically != jobResultPoller.IsPolling) {
+        this.refreshAutomatically = jobResultPoller.IsPolling;
+        OnRefreshAutomaticallyChanged();
+      }
     }
     private void jobResultPoller_JobResultReceived(object sender, EventArgs<IEnumerable<LightweightJob>> e) {
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Slave.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Slave.cs	(revision 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Slave.cs	(revision 6229)
@@ -51,4 +51,6 @@
     [DataMember]
     public DateTime? LastHeartbeat { get; set; }
+    [DataMember]
+    public double CpuUtilization { get; set; }
 
     public Slave() {
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/SlaveStatistics.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/SlaveStatistics.cs	(revision 6229)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/SlaveStatistics.cs	(revision 6229)
@@ -0,0 +1,43 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Runtime.Serialization;
+
+namespace HeuristicLab.Services.Hive.Common.DataTransfer {
+  [DataContract]
+  [Serializable]
+  public class SlaveStatistics : HiveItem {
+    [DataMember]
+    public Guid SlaveId { get; set; }
+    [DataMember]
+    public int Cores { get; set; }
+    [DataMember]
+    public int FreeCores { get; set; }
+    [DataMember]
+    public int Memory { get; set; }
+    [DataMember]
+    public int FreeMemory { get; set; }
+    [DataMember]
+    public double CpuUtilization { get; set; }
+
+  }
+}
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Statistics.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Statistics.cs	(revision 6229)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/Statistics.cs	(revision 6229)
@@ -0,0 +1,39 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace HeuristicLab.Services.Hive.Common.DataTransfer {
+  [DataContract]
+  [Serializable]
+  public class Statistics : HiveItem {
+    [DataMember]
+    public DateTime TimeStamp { get; set; }
+    [DataMember]
+    public IEnumerable<UserStatistics> UserStatistics {get;set;}
+    [DataMember]
+    public IEnumerable<SlaveStatistics> SlaveStatistics {get;set;}
+
+    public Statistics() { }
+  }
+}
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/UserStatistics.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/UserStatistics.cs	(revision 6229)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/DataTransfer/UserStatistics.cs	(revision 6229)
@@ -0,0 +1,43 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2011 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
+using System.Runtime.Serialization;
+
+namespace HeuristicLab.Services.Hive.Common.DataTransfer {
+  [DataContract]
+  [Serializable]
+  public class UserStatistics : HiveItem {
+    [DataMember]
+    public Guid UserId { get; set; }
+    [DataMember]
+    public int UsedCores { get; set; }
+    [DataMember]
+    public TimeSpan ExecutionTime { get; set; }
+    [DataMember]
+    public TimeSpan ExecutionTimeFinishedJobs { get; set; }
+    [DataMember]
+    public TimeSpan StartToEndTime { get; set; }
+    
+
+
+  }
+}
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/HeuristicLab.Services.Hive.Common-3.4.csproj
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/HeuristicLab.Services.Hive.Common-3.4.csproj	(revision 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Common/3.4/HeuristicLab.Services.Hive.Common-3.4.csproj	(revision 6229)
@@ -95,4 +95,7 @@
   <ItemGroup>
     <Compile Include="ApplicationConstants.cs" />
+    <Compile Include="DataTransfer\SlaveStatistics.cs" />
+    <Compile Include="DataTransfer\Statistics.cs" />
+    <Compile Include="DataTransfer\UserStatistics.cs" />
     <Compile Include="ServiceFaults\PluginAlreadyExistsFault.cs" />
     <None Include="HeuristicLabServicesHiveCommonPlugin.cs.frame" />
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 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Convert.cs	(revision 6229)
@@ -213,5 +213,6 @@
         CpuArchitecture = source.CpuArchitecture,
         OperatingSystem = source.OperatingSystem,
-        LastHeartbeat = source.LastHeartbeat
+        LastHeartbeat = source.LastHeartbeat,
+        CpuUtilization = source.CpuUtilization
       };
     }
@@ -236,4 +237,5 @@
         target.OperatingSystem = source.OperatingSystem;
         target.LastHeartbeat = source.LastHeartbeat;
+        target.CpuUtilization = source.CpuUtilization;
       }
     }
@@ -273,4 +275,88 @@
     }
     #endregion
+
+    #region Statistics
+    public static DT.Statistics ToDto(Statistics source) {
+      if (source == null) return null;
+      return new DT.Statistics {
+        Id = source.StatisticsId,
+        TimeStamp = source.Timestamp,
+        SlaveStatistics = source.SlaveStatistics.Select(x => Convert.ToDto(x)).ToArray(),
+        UserStatistics = source.UserStatistics.Select(x => Convert.ToDto(x)).ToArray()
+      };
+    }
+    public static Statistics ToEntity(DT.Statistics source) {
+      if (source == null) return null;
+      var entity = new Statistics(); ToEntity(source, entity);
+      return entity;
+    }
+    public static void ToEntity(DT.Statistics source, Statistics target) {
+      if ((source != null) && (target != null)) {
+        target.StatisticsId = source.Id;
+        target.Timestamp = source.TimeStamp;
+
+      }
+    }
+    #endregion
+
+    #region SlaveStatistics
+    public static DT.SlaveStatistics ToDto(SlaveStatistics source) {
+      if (source == null) return null;
+      return new DT.SlaveStatistics {
+        Id = source.StatisticsId,
+        SlaveId = source.SlaveId,
+        Cores = source.Cores,
+        CpuUtilization = source.CpuUtilization,
+        FreeCores = source.FreeCores,
+        FreeMemory = source.FreeMemory,
+        Memory = source.Memory
+      };
+    }
+    public static SlaveStatistics ToEntity(DT.SlaveStatistics source) {
+      if (source == null) return null;
+      var entity = new SlaveStatistics(); ToEntity(source, entity);
+      return entity;
+    }
+    public static void ToEntity(DT.SlaveStatistics source, SlaveStatistics target) {
+      if ((source != null) && (target != null)) {
+        target.StatisticsId = source.Id;
+        target.SlaveId = source.SlaveId;
+        target.Cores = source.Cores;
+        target.CpuUtilization = source.CpuUtilization;
+        target.FreeCores = source.FreeCores;
+        target.FreeMemory = source.FreeMemory;
+        target.Memory = source.Memory;
+      }
+    }
+    #endregion
+
+    #region UserStatistics
+    public static DT.UserStatistics ToDto(UserStatistics source) {
+      if (source == null) return null;
+      return new DT.UserStatistics {
+        Id = source.StatisticsId,
+        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)
+      };
+    }
+    public static UserStatistics ToEntity(DT.UserStatistics source) {
+      if (source == null) return null;
+      var entity = new UserStatistics(); ToEntity(source, entity);
+      return entity;
+    }
+    public static void ToEntity(DT.UserStatistics source, UserStatistics target) {
+      if ((source != null) && (target != null)) {
+        target.StatisticsId = source.Id;
+        target.UserId = source.UserId;
+        target.UsedCores = source.UsedCores;
+        target.ExecutionTime = source.ExecutionTime.ToString();
+        target.ExecutionTimeFinishedJobs = source.ExecutionTimeFinishedJobs.ToString();
+        target.StartToEndTime = source.StartToEndTime.ToString();
+      }
+    }
+    #endregion
   }
 }
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 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDao.cs	(revision 6229)
@@ -97,6 +97,6 @@
                        && (from child in db.Jobs
                            where child.ParentJobId == ar.Job.JobId
-                           select child.State == JobState.Finished 
-                               || child.State == JobState.Aborted 
+                           select child.State == JobState.Finished
+                               || child.State == JobState.Aborted
                                || child.State == JobState.Failed).All(x => x)
                        && (from child in db.Jobs // avoid returning WaitForChildJobs jobs where no child-jobs exist (yet)
@@ -607,5 +607,5 @@
     #endregion
 
-    #region AppointmentMethods
+    #region Appointment Methods
     public Appointment GetAppointment(Guid id) {
       using (var db = CreateContext()) {
@@ -643,4 +643,66 @@
         if (entity != null) db.UptimeCalendars.DeleteOnSubmit(entity);
         db.SubmitChanges();
+      }
+    }
+    #endregion
+
+    #region Statistics Methods
+    public DT.Statistics GetStatistic(Guid id) {
+      using (var db = CreateContext()) {
+        return Convert.ToDto(db.Statistics.SingleOrDefault(x => x.StatisticsId == id));
+
+      }
+    }
+
+    public IEnumerable<DT.Statistics> GetStatistics(Expression<Func<Statistics, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.Statistics.Where(predicate).Select(x => Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public Guid AddStatistics(DT.Statistics dto) {
+      using (var db = CreateContext()) {
+        var entity = Convert.ToEntity(dto);
+        db.Statistics.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        foreach (var slaveStat in dto.SlaveStatistics) {
+          slaveStat.Id = entity.StatisticsId;
+          db.SlaveStatistics.InsertOnSubmit(Convert.ToEntity(slaveStat));
+        }
+        foreach (var userStat in dto.UserStatistics) {
+          userStat.Id = entity.StatisticsId;
+          db.UserStatistics.InsertOnSubmit(Convert.ToEntity(userStat));
+        }
+        db.SubmitChanges();
+        return entity.StatisticsId;
+      }
+    }
+
+    public void DeleteStatistics(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.Statistics.FirstOrDefault(x => x.StatisticsId == id);
+        if (entity != null) db.Statistics.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public List<DT.UserStatistics> GetUserStatistics() {
+      using (var db = CreateContext()) {
+        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>();
+        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;
       }
     }
@@ -657,4 +719,7 @@
     }
     #endregion
+
+
+
   }
 }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.cs	(revision 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.cs	(revision 6229)
@@ -1,3 +1,6 @@
 namespace HeuristicLab.Services.Hive.DataAccess {
+  partial class SlaveStatistics {
+  }
+
   partial class HiveDataContext {
   }
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 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml	(revision 6229)
@@ -53,4 +53,5 @@
         <Column Name="OperatingSystem" Type="System.String" DbType="VarChar(MAX)" CanBeNull="false" UpdateCheck="Never" />
         <Column Name="LastHeartbeat" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
+        <Column Name="CpuUtilization" Type="System.Double" DbType="float" CanBeNull="false" />
       </Type>
       <Type Name="SlaveGroup" InheritanceCode="GROUP" />
@@ -102,6 +103,6 @@
       <Column Name="LastAccessed" Type="System.DateTime" DbType="DateTime" CanBeNull="true" />
       <Column Name="IsHiveEngine" Type="System.Boolean" DbType="Bit" CanBeNull="false" />
+      <Association Name="HiveExperiment_Job" Member="Jobs" ThisKey="HiveExperimentId" OtherKey="HiveExperimentId" Type="Job" />
       <Association Name="HiveExperiment_HiveExperimentPermission" Member="HiveExperimentPermissions" ThisKey="HiveExperimentId" OtherKey="HiveExperimentId" Type="HiveExperimentPermission" />
-      <Association Name="HiveExperiment_Job" Member="Jobs" ThisKey="HiveExperimentId" OtherKey="HiveExperimentId" Type="Job" />
     </Type>
   </Table>
@@ -151,3 +152,42 @@
     </Type>
   </Table>
+  <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" />
+    </Type>
+  </Table>
+  <Table Name="" Member="UserStatistics">
+    <Type Name="UserStatistics">
+      <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="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" />
+      <Association Name="Statistics_UserStatistics" Member="Statistics" ThisKey="StatisticsId" OtherKey="StatisticsId" Type="Statistics" IsForeignKey="true" />
+    </Type>
+  </Table>
+  <Table Name="" Member="SlaveStatistics">
+    <Type Name="SlaveStatistics">
+      <Column Name="StatisticsId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="SlaveId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" CanBeNull="false" />
+      <Column Name="Cores" Type="System.Int32" DbType="Int" CanBeNull="false" />
+      <Column Name="FreeCores" Type="System.Int32" DbType="Int" CanBeNull="false" />
+      <Column Name="CpuUtilization" Type="System.Double" DbType="float" CanBeNull="false" />
+      <Column Name="Memory" Type="System.Int32" DbType="Int" CanBeNull="false" />
+      <Column Name="FreeMemory" Type="System.Int32" DbType="Int" CanBeNull="false" />
+      <Association Name="Statistics_SlaveStatistics" Member="Statistics" ThisKey="StatisticsId" OtherKey="StatisticsId" Type="Statistics" IsForeignKey="true" />
+    </Type>
+  </Table>
+  <Table Name="" Member="Statistics">
+    <Type Name="Statistics">
+      <Column Name="StatisticsId" Type="System.Guid" DbType="UniqueIdentifier NOT NULL" IsPrimaryKey="true" IsDbGenerated="true" CanBeNull="false" />
+      <Column Name="Timestamp" Type="System.DateTime" CanBeNull="false" />
+      <Association Name="Statistics_UserStatistics" Member="UserStatistics" ThisKey="StatisticsId" OtherKey="StatisticsId" Type="UserStatistics" />
+      <Association Name="Statistics_SlaveStatistics" Member="SlaveStatistics" ThisKey="StatisticsId" OtherKey="StatisticsId" Type="SlaveStatistics" />
+    </Type>
+  </Table>
 </Database>
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 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.dbml.layout	(revision 6229)
@@ -1,10 +1,10 @@
 ﻿<?xml version="1.0" encoding="utf-8"?>
-<ordesignerObjectsDiagram dslVersion="1.0.0.0" absoluteBounds="0, 0, 15.75, 8.5" name="HiveDataContext">
+<ordesignerObjectsDiagram dslVersion="1.0.0.0" absoluteBounds="0, 0, 24.25, 8.5" name="HiveDataContext">
   <DataContextMoniker Name="/HiveDataContext" />
   <nestedChildShapes>
-    <classShape Id="a929c9dc-69f4-4488-ba1c-a2342bf81d89" absoluteBounds="8.875, 3.875, 2, 1.3862939453124987">
+    <classShape Id="a929c9dc-69f4-4488-ba1c-a2342bf81d89" absoluteBounds="8.875, 4, 2, 1.3862939453124987">
       <DataClassMoniker Name="/HiveDataContext/AssignedResource" />
       <nestedChildShapes>
-        <elementListCompartment Id="8b005775-f0ee-41b0-ae10-6d1151003708" absoluteBounds="8.89, 4.3350000000000009, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+        <elementListCompartment Id="8b005775-f0ee-41b0-ae10-6d1151003708" absoluteBounds="8.89, 4.4600000000000009, 1.9700000000000002, 0.8262939453125" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
       </nestedChildShapes>
     </classShape>
@@ -45,8 +45,8 @@
       </nestedChildShapes>
     </classShape>
-    <classShape Id="26f4edfa-91dd-4941-a058-359f89e567a8" absoluteBounds="8.875, 0.75, 2, 2.9247054036458331">
+    <classShape Id="26f4edfa-91dd-4941-a058-359f89e567a8" absoluteBounds="8.875, 0.75, 2, 3.1170068359375">
       <DataClassMoniker Name="/HiveDataContext/Slave" />
       <nestedChildShapes>
-        <elementListCompartment Id="1e61f36b-08dc-4df7-8594-c9dcd95c0791" absoluteBounds="8.89, 1.21, 1.9700000000000002, 2.364705403645833" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+        <elementListCompartment Id="1e61f36b-08dc-4df7-8594-c9dcd95c0791" absoluteBounds="8.89, 1.21, 1.9700000000000002, 2.5570068359375" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
       </nestedChildShapes>
     </classShape>
@@ -69,5 +69,5 @@
       </nodes>
     </inheritanceConnector>
-    <associationConnector edgePoints="[(11.9843735 : 2.57859537760417); (11.9843735 : 4.56814697265625); (10.875 : 4.56814697265625)]" fixedFrom="NotFixed" fixedTo="NotFixed">
+    <associationConnector edgePoints="[(11.9843735 : 2.57859537760417); (11.9843735 : 4.69314697265625); (10.875 : 4.69314697265625)]" fixedFrom="Algorithm" fixedTo="Algorithm">
       <AssociationMoniker Name="/HiveDataContext/Resource/Resource_AssignedResource" />
       <nodes>
@@ -76,5 +76,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(7.8398428125 : 4.1170068359375); (7.8398428125 : 4.689150890625); (8.875 : 4.689150890625)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(7.5 : 4.1170068359375); (7.5 : 4.751650890625); (8.875 : 4.751650890625)]" 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="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(7.10742140625 : 4.1170068359375); (7.10742140625 : 5.5)]" fixedFrom="NotFixed" fixedTo="NotFixed">
       <AssociationMoniker Name="/HiveDataContext/Job/Job_RequiredPlugin" />
       <nodes>
@@ -123,5 +123,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(6.5 : 1.69314697265625); (6.125 : 1.69314697265625)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(6.5 : 1.69314697265625); (6.125 : 1.69314697265625)]" fixedFrom="NotFixed" fixedTo="NotFixed">
       <AssociationMoniker Name="/HiveDataContext/Job/Job_JobData" />
       <nodes>
@@ -156,5 +156,5 @@
       </nestedChildShapes>
     </classShape>
-    <associationConnector edgePoints="[(6.5 : 2.50564697265625); (3.75 : 2.50564697265625)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(6.5 : 2.50564697265625); (3.75 : 2.50564697265625)]" fixedFrom="NotFixed" fixedTo="NotFixed">
       <AssociationMoniker Name="/HiveDataContext/Job/Job_StateLog" />
       <nodes>
@@ -163,5 +163,5 @@
       </nodes>
     </associationConnector>
-    <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">
+    <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">
       <AssociationMoniker Name="/HiveDataContext/Resource/Resource_StateLog" />
       <nodes>
@@ -170,5 +170,5 @@
       </nodes>
     </associationConnector>
-    <associationConnector edgePoints="[(4.125 : 4.29890055338542); (3.75 : 4.29890055338542)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(4.125 : 4.29890055338542); (3.75 : 4.29890055338542)]" fixedFrom="NotFixed" fixedTo="NotFixed">
       <AssociationMoniker Name="/HiveDataContext/HiveExperiment/HiveExperiment_HiveExperimentPermission" />
       <nodes>
@@ -183,9 +183,47 @@
       </nestedChildShapes>
     </classShape>
-    <associationConnector edgePoints="[(6.125 : 3.37100341796875); (6.5 : 3.37100341796875)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+    <associationConnector edgePoints="[(6.125 : 3.37100341796875); (6.5 : 3.37100341796875)]" fixedFrom="NotFixed" fixedTo="NotFixed">
       <AssociationMoniker Name="/HiveDataContext/HiveExperiment/HiveExperiment_Job" />
       <nodes>
         <classShapeMoniker Id="e6f840cc-2968-4be1-b234-eef624ccacbb" />
         <classShapeMoniker Id="695bfc39-59f3-4e60-8644-f847964bf62c" />
+      </nodes>
+    </associationConnector>
+    <classShape Id="cdddf4da-eaef-46a1-9cfd-987bb6b3d03e" absoluteBounds="17, 3.125, 2, 1.5785953776041666">
+      <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" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="25442617-ff41-49a0-b5d5-4cbe0b2f0f45" absoluteBounds="22, 4.5, 2, 1.9631982421874996">
+      <DataClassMoniker Name="/HiveDataContext/UserStatistics" />
+      <nestedChildShapes>
+        <elementListCompartment Id="6edf08e7-054a-4253-8d4f-5bf2dfec2d29" absoluteBounds="22.015, 4.96, 1.9700000000000002, 1.4031982421875" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="f78ec989-4862-4bac-87e3-9b0aad4bc037" absoluteBounds="19.875, 4.5, 2, 2.1554996744791666">
+      <DataClassMoniker Name="/HiveDataContext/SlaveStatistics" />
+      <nestedChildShapes>
+        <elementListCompartment Id="98cb46fe-820e-4041-aee8-04e8bed3df23" absoluteBounds="19.89, 4.96, 1.9700000000000002, 1.5954996744791665" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <classShape Id="4d9f0606-b7ee-4dae-a8ac-aff88d25a941" absoluteBounds="21, 3, 2, 1.1939925130208327">
+      <DataClassMoniker Name="/HiveDataContext/Statistics" />
+      <nestedChildShapes>
+        <elementListCompartment Id="17821282-8edf-40b7-9065-84f53391d5c1" absoluteBounds="21.015, 3.46, 1.9700000000000002, 0.63399251302083326" name="DataPropertiesCompartment" titleTextColor="Black" itemTextColor="Black" />
+      </nestedChildShapes>
+    </classShape>
+    <associationConnector edgePoints="[(21.4375 : 4.19399251302083); (21.4375 : 4.5)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/HiveDataContext/Statistics/Statistics_SlaveStatistics" />
+      <nodes>
+        <classShapeMoniker Id="4d9f0606-b7ee-4dae-a8ac-aff88d25a941" />
+        <classShapeMoniker Id="f78ec989-4862-4bac-87e3-9b0aad4bc037" />
+      </nodes>
+    </associationConnector>
+    <associationConnector edgePoints="[(22.5 : 4.19399251302083); (22.5 : 4.5)]" fixedFrom="Algorithm" fixedTo="Algorithm">
+      <AssociationMoniker Name="/HiveDataContext/Statistics/Statistics_UserStatistics" />
+      <nodes>
+        <classShapeMoniker Id="4d9f0606-b7ee-4dae-a8ac-aff88d25a941" />
+        <classShapeMoniker Id="25442617-ff41-49a0-b5d5-4cbe0b2f0f45" />
       </nodes>
     </associationConnector>
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 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/HiveDataContext.designer.cs	(revision 6229)
@@ -3,5 +3,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
@@ -67,4 +67,16 @@
     partial void UpdateLifecycle(Lifecycle instance);
     partial void DeleteLifecycle(Lifecycle instance);
+    partial void InsertDeletedJobStatistics(DeletedJobStatistics instance);
+    partial void UpdateDeletedJobStatistics(DeletedJobStatistics instance);
+    partial void DeleteDeletedJobStatistics(DeletedJobStatistics instance);
+    partial void InsertUserStatistics(UserStatistics instance);
+    partial void UpdateUserStatistics(UserStatistics instance);
+    partial void DeleteUserStatistics(UserStatistics instance);
+    partial void InsertSlaveStatistics(SlaveStatistics instance);
+    partial void UpdateSlaveStatistics(SlaveStatistics instance);
+    partial void DeleteSlaveStatistics(SlaveStatistics instance);
+    partial void InsertStatistics(Statistics instance);
+    partial void UpdateStatistics(Statistics instance);
+    partial void DeleteStatistics(Statistics instance);
     #endregion
 		
@@ -186,4 +198,36 @@
 			{
 				return this.GetTable<Lifecycle>();
+			}
+		}
+		
+		public System.Data.Linq.Table<DeletedJobStatistics> DeletedJobStatistics
+		{
+			get
+			{
+				return this.GetTable<DeletedJobStatistics>();
+			}
+		}
+		
+		public System.Data.Linq.Table<UserStatistics> UserStatistics
+		{
+			get
+			{
+				return this.GetTable<UserStatistics>();
+			}
+		}
+		
+		public System.Data.Linq.Table<SlaveStatistics> SlaveStatistics
+		{
+			get
+			{
+				return this.GetTable<SlaveStatistics>();
+			}
+		}
+		
+		public System.Data.Linq.Table<Statistics> Statistics
+		{
+			get
+			{
+				return this.GetTable<Statistics>();
 			}
 		}
@@ -1126,4 +1170,6 @@
 		
 		private System.Nullable<System.DateTime> _LastHeartbeat;
+		
+		private double _CpuUtilization;
 		
     #region Extensibility Method Definitions
@@ -1153,4 +1199,6 @@
     partial void OnLastHeartbeatChanging(System.Nullable<System.DateTime> value);
     partial void OnLastHeartbeatChanged();
+    partial void OnCpuUtilizationChanging(double value);
+    partial void OnCpuUtilizationChanged();
     #endregion
 		
@@ -1376,4 +1424,24 @@
 					this.SendPropertyChanged("LastHeartbeat");
 					this.OnLastHeartbeatChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CpuUtilization", DbType="float")]
+		public double CpuUtilization
+		{
+			get
+			{
+				return this._CpuUtilization;
+			}
+			set
+			{
+				if ((this._CpuUtilization != value))
+				{
+					this.OnCpuUtilizationChanging(value);
+					this.SendPropertyChanging();
+					this._CpuUtilization = value;
+					this.SendPropertyChanged("CpuUtilization");
+					this.OnCpuUtilizationChanged();
 				}
 			}
@@ -2217,7 +2285,7 @@
 		private bool _IsHiveEngine;
 		
+		private EntitySet<Job> _Jobs;
+		
 		private EntitySet<HiveExperimentPermission> _HiveExperimentPermissions;
-		
-		private EntitySet<Job> _Jobs;
 		
     #region Extensibility Method Definitions
@@ -2245,6 +2313,6 @@
 		public HiveExperiment()
 		{
+			this._Jobs = new EntitySet<Job>(new Action<Job>(this.attach_Jobs), new Action<Job>(this.detach_Jobs));
 			this._HiveExperimentPermissions = new EntitySet<HiveExperimentPermission>(new Action<HiveExperimentPermission>(this.attach_HiveExperimentPermissions), new Action<HiveExperimentPermission>(this.detach_HiveExperimentPermissions));
-			this._Jobs = new EntitySet<Job>(new Action<Job>(this.attach_Jobs), new Action<Job>(this.detach_Jobs));
 			OnCreated();
 		}
@@ -2410,4 +2478,17 @@
 		}
 		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="HiveExperiment_Job", Storage="_Jobs", ThisKey="HiveExperimentId", OtherKey="HiveExperimentId")]
+		public EntitySet<Job> Jobs
+		{
+			get
+			{
+				return this._Jobs;
+			}
+			set
+			{
+				this._Jobs.Assign(value);
+			}
+		}
+		
 		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="HiveExperiment_HiveExperimentPermission", Storage="_HiveExperimentPermissions", ThisKey="HiveExperimentId", OtherKey="HiveExperimentId")]
 		public EntitySet<HiveExperimentPermission> HiveExperimentPermissions
@@ -2423,17 +2504,4 @@
 		}
 		
-		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="HiveExperiment_Job", Storage="_Jobs", ThisKey="HiveExperimentId", OtherKey="HiveExperimentId")]
-		public EntitySet<Job> Jobs
-		{
-			get
-			{
-				return this._Jobs;
-			}
-			set
-			{
-				this._Jobs.Assign(value);
-			}
-		}
-		
 		public event PropertyChangingEventHandler PropertyChanging;
 		
@@ -2456,5 +2524,5 @@
 		}
 		
-		private void attach_HiveExperimentPermissions(HiveExperimentPermission entity)
+		private void attach_Jobs(Job entity)
 		{
 			this.SendPropertyChanging();
@@ -2462,5 +2530,5 @@
 		}
 		
-		private void detach_HiveExperimentPermissions(HiveExperimentPermission entity)
+		private void detach_Jobs(Job entity)
 		{
 			this.SendPropertyChanging();
@@ -2468,5 +2536,5 @@
 		}
 		
-		private void attach_Jobs(Job entity)
+		private void attach_HiveExperimentPermissions(HiveExperimentPermission entity)
 		{
 			this.SendPropertyChanging();
@@ -2474,5 +2542,5 @@
 		}
 		
-		private void detach_Jobs(Job entity)
+		private void detach_HiveExperimentPermissions(HiveExperimentPermission entity)
 		{
 			this.SendPropertyChanging();
@@ -3355,4 +3423,750 @@
 		}
 	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+	public partial class DeletedJobStatistics : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private string _UserId;
+		
+		private string _ExecutionTime;
+		
+		private string _ExecutionTimeFinishedJobs;
+		
+		private string _StartToEndTime;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnUserIdChanging(string 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();
+    #endregion
+		
+		public DeletedJobStatistics()
+		{
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", CanBeNull=false, IsPrimaryKey=true)]
+		public string UserId
+		{
+			get
+			{
+				return this._UserId;
+			}
+			set
+			{
+				if ((this._UserId != value))
+				{
+					this.OnUserIdChanging(value);
+					this.SendPropertyChanging();
+					this._UserId = value;
+					this.SendPropertyChanged("UserId");
+					this.OnUserIdChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTime", DbType="VarChar(30)", CanBeNull=false)]
+		public string ExecutionTime
+		{
+			get
+			{
+				return this._ExecutionTime;
+			}
+			set
+			{
+				if ((this._ExecutionTime != value))
+				{
+					this.OnExecutionTimeChanging(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
+		{
+			get
+			{
+				return this._ExecutionTimeFinishedJobs;
+			}
+			set
+			{
+				if ((this._ExecutionTimeFinishedJobs != value))
+				{
+					this.OnExecutionTimeFinishedJobsChanging(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
+		{
+			get
+			{
+				return this._StartToEndTime;
+			}
+			set
+			{
+				if ((this._StartToEndTime != value))
+				{
+					this.OnStartToEndTimeChanging(value);
+					this.SendPropertyChanging();
+					this._StartToEndTime = value;
+					this.SendPropertyChanged("StartToEndTime");
+					this.OnStartToEndTimeChanged();
+				}
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+	public partial class UserStatistics : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private System.Guid _StatisticsId;
+		
+		private System.Guid _UserId;
+		
+		private string _ExecutionTime;
+		
+		private int _CoresUsed;
+		
+		private string _ExecutionTimeFinishedJobs;
+		
+		private string _StartToEndTime;
+		
+		private EntityRef<Statistics> _Statistics;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnStatisticsIdChanging(System.Guid value);
+    partial void OnStatisticsIdChanged();
+    partial void OnUserIdChanging(System.Guid value);
+    partial void OnUserIdChanged();
+    partial void OnExecutionTimeChanging(string value);
+    partial void OnExecutionTimeChanged();
+    partial void OnUsedCoresChanging(int value);
+    partial void OnUsedCoresChanged();
+    partial void OnExecutionTimeFinishedJobsChanging(string value);
+    partial void OnExecutionTimeFinishedJobsChanged();
+    partial void OnStartToEndTimeChanging(string value);
+    partial void OnStartToEndTimeChanged();
+    #endregion
+		
+		public UserStatistics()
+		{
+			this._Statistics = default(EntityRef<Statistics>);
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_StatisticsId", DbType="UniqueIdentifier NOT NULL", IsPrimaryKey=true)]
+		public System.Guid StatisticsId
+		{
+			get
+			{
+				return this._StatisticsId;
+			}
+			set
+			{
+				if ((this._StatisticsId != value))
+				{
+					if (this._Statistics.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnStatisticsIdChanging(value);
+					this.SendPropertyChanging();
+					this._StatisticsId = value;
+					this.SendPropertyChanged("StatisticsId");
+					this.OnStatisticsIdChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_UserId", DbType="UniqueIdentifier NOT NULL", IsPrimaryKey=true)]
+		public System.Guid UserId
+		{
+			get
+			{
+				return this._UserId;
+			}
+			set
+			{
+				if ((this._UserId != value))
+				{
+					this.OnUserIdChanging(value);
+					this.SendPropertyChanging();
+					this._UserId = value;
+					this.SendPropertyChanged("UserId");
+					this.OnUserIdChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTime", DbType="VarChar(30)", CanBeNull=false)]
+		public string ExecutionTime
+		{
+			get
+			{
+				return this._ExecutionTime;
+			}
+			set
+			{
+				if ((this._ExecutionTime != value))
+				{
+					this.OnExecutionTimeChanging(value);
+					this.SendPropertyChanging();
+					this._ExecutionTime = value;
+					this.SendPropertyChanged("ExecutionTime");
+					this.OnExecutionTimeChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CoresUsed", DbType="Int")]
+		public int UsedCores
+		{
+			get
+			{
+				return this._CoresUsed;
+			}
+			set
+			{
+				if ((this._CoresUsed != value))
+				{
+					this.OnUsedCoresChanging(value);
+					this.SendPropertyChanging();
+					this._CoresUsed = value;
+					this.SendPropertyChanged("UsedCores");
+					this.OnUsedCoresChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_ExecutionTimeFinishedJobs", DbType="VarChar(30)", CanBeNull=false)]
+		public string ExecutionTimeFinishedJobs
+		{
+			get
+			{
+				return this._ExecutionTimeFinishedJobs;
+			}
+			set
+			{
+				if ((this._ExecutionTimeFinishedJobs != value))
+				{
+					this.OnExecutionTimeFinishedJobsChanging(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
+		{
+			get
+			{
+				return this._StartToEndTime;
+			}
+			set
+			{
+				if ((this._StartToEndTime != value))
+				{
+					this.OnStartToEndTimeChanging(value);
+					this.SendPropertyChanging();
+					this._StartToEndTime = value;
+					this.SendPropertyChanged("StartToEndTime");
+					this.OnStartToEndTimeChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Statistics_UserStatistics", Storage="_Statistics", ThisKey="StatisticsId", OtherKey="StatisticsId", IsForeignKey=true)]
+		public Statistics Statistics
+		{
+			get
+			{
+				return this._Statistics.Entity;
+			}
+			set
+			{
+				Statistics previousValue = this._Statistics.Entity;
+				if (((previousValue != value) 
+							|| (this._Statistics.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Statistics.Entity = null;
+						previousValue.UserStatistics.Remove(this);
+					}
+					this._Statistics.Entity = value;
+					if ((value != null))
+					{
+						value.UserStatistics.Add(this);
+						this._StatisticsId = value.StatisticsId;
+					}
+					else
+					{
+						this._StatisticsId = default(System.Guid);
+					}
+					this.SendPropertyChanged("Statistics");
+				}
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+	public partial class SlaveStatistics : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private System.Guid _StatisticsId;
+		
+		private System.Guid _SlaveId;
+		
+		private int _Cores;
+		
+		private int _FreeCores;
+		
+		private double _CpuUtilization;
+		
+		private int _Memory;
+		
+		private int _FreeMemory;
+		
+		private EntityRef<Statistics> _Statistics;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnStatisticsIdChanging(System.Guid value);
+    partial void OnStatisticsIdChanged();
+    partial void OnSlaveIdChanging(System.Guid value);
+    partial void OnSlaveIdChanged();
+    partial void OnCoresChanging(int value);
+    partial void OnCoresChanged();
+    partial void OnFreeCoresChanging(int value);
+    partial void OnFreeCoresChanged();
+    partial void OnCpuUtilizationChanging(double value);
+    partial void OnCpuUtilizationChanged();
+    partial void OnMemoryChanging(int value);
+    partial void OnMemoryChanged();
+    partial void OnFreeMemoryChanging(int value);
+    partial void OnFreeMemoryChanged();
+    #endregion
+		
+		public SlaveStatistics()
+		{
+			this._Statistics = default(EntityRef<Statistics>);
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_StatisticsId", DbType="UniqueIdentifier NOT NULL", IsPrimaryKey=true)]
+		public System.Guid StatisticsId
+		{
+			get
+			{
+				return this._StatisticsId;
+			}
+			set
+			{
+				if ((this._StatisticsId != value))
+				{
+					if (this._Statistics.HasLoadedOrAssignedValue)
+					{
+						throw new System.Data.Linq.ForeignKeyReferenceAlreadyHasValueException();
+					}
+					this.OnStatisticsIdChanging(value);
+					this.SendPropertyChanging();
+					this._StatisticsId = value;
+					this.SendPropertyChanged("StatisticsId");
+					this.OnStatisticsIdChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_SlaveId", DbType="UniqueIdentifier NOT NULL", IsPrimaryKey=true)]
+		public System.Guid SlaveId
+		{
+			get
+			{
+				return this._SlaveId;
+			}
+			set
+			{
+				if ((this._SlaveId != value))
+				{
+					this.OnSlaveIdChanging(value);
+					this.SendPropertyChanging();
+					this._SlaveId = value;
+					this.SendPropertyChanged("SlaveId");
+					this.OnSlaveIdChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Cores", DbType="Int")]
+		public int Cores
+		{
+			get
+			{
+				return this._Cores;
+			}
+			set
+			{
+				if ((this._Cores != value))
+				{
+					this.OnCoresChanging(value);
+					this.SendPropertyChanging();
+					this._Cores = value;
+					this.SendPropertyChanged("Cores");
+					this.OnCoresChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_FreeCores", DbType="Int")]
+		public int FreeCores
+		{
+			get
+			{
+				return this._FreeCores;
+			}
+			set
+			{
+				if ((this._FreeCores != value))
+				{
+					this.OnFreeCoresChanging(value);
+					this.SendPropertyChanging();
+					this._FreeCores = value;
+					this.SendPropertyChanged("FreeCores");
+					this.OnFreeCoresChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_CpuUtilization", DbType="float")]
+		public double CpuUtilization
+		{
+			get
+			{
+				return this._CpuUtilization;
+			}
+			set
+			{
+				if ((this._CpuUtilization != value))
+				{
+					this.OnCpuUtilizationChanging(value);
+					this.SendPropertyChanging();
+					this._CpuUtilization = value;
+					this.SendPropertyChanged("CpuUtilization");
+					this.OnCpuUtilizationChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Memory", DbType="Int")]
+		public int Memory
+		{
+			get
+			{
+				return this._Memory;
+			}
+			set
+			{
+				if ((this._Memory != value))
+				{
+					this.OnMemoryChanging(value);
+					this.SendPropertyChanging();
+					this._Memory = value;
+					this.SendPropertyChanged("Memory");
+					this.OnMemoryChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_FreeMemory", DbType="Int")]
+		public int FreeMemory
+		{
+			get
+			{
+				return this._FreeMemory;
+			}
+			set
+			{
+				if ((this._FreeMemory != value))
+				{
+					this.OnFreeMemoryChanging(value);
+					this.SendPropertyChanging();
+					this._FreeMemory = value;
+					this.SendPropertyChanged("FreeMemory");
+					this.OnFreeMemoryChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Statistics_SlaveStatistics", Storage="_Statistics", ThisKey="StatisticsId", OtherKey="StatisticsId", IsForeignKey=true)]
+		public Statistics Statistics
+		{
+			get
+			{
+				return this._Statistics.Entity;
+			}
+			set
+			{
+				Statistics previousValue = this._Statistics.Entity;
+				if (((previousValue != value) 
+							|| (this._Statistics.HasLoadedOrAssignedValue == false)))
+				{
+					this.SendPropertyChanging();
+					if ((previousValue != null))
+					{
+						this._Statistics.Entity = null;
+						previousValue.SlaveStatistics.Remove(this);
+					}
+					this._Statistics.Entity = value;
+					if ((value != null))
+					{
+						value.SlaveStatistics.Add(this);
+						this._StatisticsId = value.StatisticsId;
+					}
+					else
+					{
+						this._StatisticsId = default(System.Guid);
+					}
+					this.SendPropertyChanged("Statistics");
+				}
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+	}
+	
+	[global::System.Data.Linq.Mapping.TableAttribute(Name="")]
+	public partial class Statistics : INotifyPropertyChanging, INotifyPropertyChanged
+	{
+		
+		private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
+		
+		private System.Guid _StatisticsId;
+		
+		private System.DateTime _Timestamp;
+		
+		private EntitySet<UserStatistics> _UserStatistics;
+		
+		private EntitySet<SlaveStatistics> _SlaveStatistics;
+		
+    #region Extensibility Method Definitions
+    partial void OnLoaded();
+    partial void OnValidate(System.Data.Linq.ChangeAction action);
+    partial void OnCreated();
+    partial void OnStatisticsIdChanging(System.Guid value);
+    partial void OnStatisticsIdChanged();
+    partial void OnTimestampChanging(System.DateTime value);
+    partial void OnTimestampChanged();
+    #endregion
+		
+		public Statistics()
+		{
+			this._UserStatistics = new EntitySet<UserStatistics>(new Action<UserStatistics>(this.attach_UserStatistics), new Action<UserStatistics>(this.detach_UserStatistics));
+			this._SlaveStatistics = new EntitySet<SlaveStatistics>(new Action<SlaveStatistics>(this.attach_SlaveStatistics), new Action<SlaveStatistics>(this.detach_SlaveStatistics));
+			OnCreated();
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_StatisticsId", AutoSync=AutoSync.OnInsert, DbType="UniqueIdentifier NOT NULL", IsPrimaryKey=true, IsDbGenerated=true)]
+		public System.Guid StatisticsId
+		{
+			get
+			{
+				return this._StatisticsId;
+			}
+			set
+			{
+				if ((this._StatisticsId != value))
+				{
+					this.OnStatisticsIdChanging(value);
+					this.SendPropertyChanging();
+					this._StatisticsId = value;
+					this.SendPropertyChanged("StatisticsId");
+					this.OnStatisticsIdChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Timestamp")]
+		public System.DateTime Timestamp
+		{
+			get
+			{
+				return this._Timestamp;
+			}
+			set
+			{
+				if ((this._Timestamp != value))
+				{
+					this.OnTimestampChanging(value);
+					this.SendPropertyChanging();
+					this._Timestamp = value;
+					this.SendPropertyChanged("Timestamp");
+					this.OnTimestampChanged();
+				}
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Statistics_UserStatistics", Storage="_UserStatistics", ThisKey="StatisticsId", OtherKey="StatisticsId")]
+		public EntitySet<UserStatistics> UserStatistics
+		{
+			get
+			{
+				return this._UserStatistics;
+			}
+			set
+			{
+				this._UserStatistics.Assign(value);
+			}
+		}
+		
+		[global::System.Data.Linq.Mapping.AssociationAttribute(Name="Statistics_SlaveStatistics", Storage="_SlaveStatistics", ThisKey="StatisticsId", OtherKey="StatisticsId")]
+		public EntitySet<SlaveStatistics> SlaveStatistics
+		{
+			get
+			{
+				return this._SlaveStatistics;
+			}
+			set
+			{
+				this._SlaveStatistics.Assign(value);
+			}
+		}
+		
+		public event PropertyChangingEventHandler PropertyChanging;
+		
+		public event PropertyChangedEventHandler PropertyChanged;
+		
+		protected virtual void SendPropertyChanging()
+		{
+			if ((this.PropertyChanging != null))
+			{
+				this.PropertyChanging(this, emptyChangingEventArgs);
+			}
+		}
+		
+		protected virtual void SendPropertyChanged(String propertyName)
+		{
+			if ((this.PropertyChanged != null))
+			{
+				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
+			}
+		}
+		
+		private void attach_UserStatistics(UserStatistics entity)
+		{
+			this.SendPropertyChanging();
+			entity.Statistics = this;
+		}
+		
+		private void detach_UserStatistics(UserStatistics entity)
+		{
+			this.SendPropertyChanging();
+			entity.Statistics = null;
+		}
+		
+		private void attach_SlaveStatistics(SlaveStatistics entity)
+		{
+			this.SendPropertyChanging();
+			entity.Statistics = this;
+		}
+		
+		private void detach_SlaveStatistics(SlaveStatistics entity)
+		{
+			this.SendPropertyChanging();
+			entity.Statistics = null;
+		}
+	}
 }
 #pragma warning restore 1591
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 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Interfaces/IHiveDao.cs	(revision 6229)
@@ -116,4 +116,14 @@
     #endregion
 
+    #region Statistics Methods
+    DT.Statistics GetStatistic(Guid id);
+    IEnumerable<DT.Statistics> GetStatistics(Expression<Func<Statistics, bool>> predicate);
+    Guid AddStatistics(DT.Statistics dto);
+    void DeleteStatistics(Guid id);
+    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 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.DataAccess/3.4/Tools/prepareHiveDatabase.sql	(revision 6229)
@@ -104,4 +104,22 @@
 GO
 
+ALTER TABLE [dbo].[Statistics] ALTER COLUMN StatisticsId ADD ROWGUIDCOL;
+ALTER TABLE [dbo].[Statistics] WITH NOCHECK ADD CONSTRAINT [DF_Statistics_StatisticsId] DEFAULT (newid()) FOR StatisticsId;
+GO
+
+ALTER TABLE [dbo].[SlaveStatistics]  DROP  CONSTRAINT [Statistics_SlaveStatistics]
+ALTER TABLE [dbo].[SlaveStatistics]  WITH CHECK ADD  CONSTRAINT [Statistics_SlaveStatistics] FOREIGN KEY([StatisticsId])
+REFERENCES [dbo].[Statistics] ([StatisticsId])
+ON UPDATE CASCADE
+ON DELETE CASCADE
+GO
+
+ALTER TABLE [dbo].[UserStatistics]  DROP  CONSTRAINT [Statistics_UserStatistics]
+ALTER TABLE [dbo].[UserStatistics]  WITH CHECK ADD  CONSTRAINT [Statistics_UserStatistics] FOREIGN KEY([StatisticsId])
+REFERENCES [dbo].[Statistics] ([StatisticsId])
+ON UPDATE CASCADE
+ON DELETE CASCADE
+GO
+
 /* create indices */
 CREATE INDEX Index_RequiredPlugins_JobId ON RequiredPlugins(JobId);
@@ -159,2 +177,13 @@
 	DELETE Job FROM Job INNER JOIN #Table ON Job.JobId = #Table.JobId
 END
+GO
+
+-- =============================================
+-- Author:		cneumuel
+-- Create date: 17.05.2011
+-- Description:	Writes the execution times of deleted jobs into DeletedJobStats to ensure correct statistics
+-- =============================================
+--CREATE TRIGGER [dbo].[tr_DeletedJobStats] ON [dbo].[Job] AFTER DELETE AS
+--BEGIN
+--	INSERT INTO DeletedJobStats SELECT JobId, ExecutionTime FROM deleted
+--END
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 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive.Tests/DaoTests.cs	(revision 6229)
@@ -7,4 +7,5 @@
 
 namespace HeuristicLab.Services.Hive.Tests {
+  using System.Collections.Generic;
   using System.Threading;
   using DT = HeuristicLab.Services.Hive.Common.DataTransfer;
@@ -83,5 +84,5 @@
         Assert.IsTrue(Math.Abs((job1.StateLog[i].DateTime - job1loaded.StateLog[i].DateTime).TotalSeconds) < 1);
       }
-      
+
       job1 = job1loaded;
 
@@ -236,4 +237,45 @@
 
     }
+
+
+    [TestMethod]
+    public void TestStatistics() {
+      IHiveDao dao = ServiceLocator.Instance.HiveDao;
+
+      var stats = new DT.Statistics();
+      stats.TimeStamp = DateTime.Now;
+      var slaveStats = new List<DT.SlaveStatistics>();
+      slaveStats.Add(new DT.SlaveStatistics() { Cores = 8, FreeCores = 3, Memory = 8000, FreeMemory = 3000, CpuUtilization = 0.8, SlaveId = Guid.NewGuid() });
+      slaveStats.Add(new DT.SlaveStatistics() { Cores = 2, FreeCores = 0, Memory = 1024, FreeMemory = 100, CpuUtilization = 0.99, SlaveId = Guid.NewGuid() });
+      slaveStats.Add(new DT.SlaveStatistics() { Cores = 4, FreeCores = 4, Memory = 3024, FreeMemory = 2300, CpuUtilization = 0.01, SlaveId = Guid.NewGuid() });
+      stats.SlaveStatistics = slaveStats;
+
+      var userStats = new List<DT.UserStatistics>();
+      userStats.Add(new DT.UserStatistics() { UsedCores = 15, ExecutionTime = TimeSpan.FromHours(123), UserId = Guid.NewGuid() });
+      userStats.Add(new DT.UserStatistics() { UsedCores = 42, ExecutionTime = TimeSpan.FromHours(945), UserId = Guid.NewGuid() });
+      stats.UserStatistics = userStats;
+
+      stats.Id = dao.AddStatistics(stats);
+
+      var statsLoaded = dao.GetStatistic(stats.Id);
+      Assert.AreEqual(stats.Id, statsLoaded.Id);
+      Assert.IsTrue(Math.Abs((stats.TimeStamp - statsLoaded.TimeStamp).TotalSeconds) < 1);
+
+      for (int i = 0; i  < slaveStats.Count; i ++) {
+        Assert.AreEqual(slaveStats[i].Cores, statsLoaded.SlaveStatistics.Single(x => x.SlaveId == slaveStats[i].SlaveId).Cores);
+        Assert.AreEqual(slaveStats[i].FreeCores, statsLoaded.SlaveStatistics.Single(x => x.SlaveId == slaveStats[i].SlaveId).FreeCores);
+        Assert.AreEqual(slaveStats[i].Memory, statsLoaded.SlaveStatistics.Single(x => x.SlaveId == slaveStats[i].SlaveId).Memory);
+        Assert.AreEqual(slaveStats[i].FreeMemory, statsLoaded.SlaveStatistics.Single(x => x.SlaveId == slaveStats[i].SlaveId).FreeMemory);
+        Assert.AreEqual(slaveStats[i].CpuUtilization, statsLoaded.SlaveStatistics.Single(x => x.SlaveId == slaveStats[i].SlaveId).CpuUtilization);
+      }
+
+      for (int i = 0; i < userStats.Count; i++) {
+        Assert.AreEqual(userStats[i].ExecutionTime, statsLoaded.UserStatistics.Single(x => x.UserId == userStats[i].UserId).ExecutionTime);
+        Assert.AreEqual(userStats[i].UsedCores, statsLoaded.UserStatistics.Single(x => x.UserId == userStats[i].UserId).UsedCores);        
+      }
+
+      dao.DeleteStatistics(stats.Id);
+      Assert.AreEqual(null, dao.GetStatistic(stats.Id));
+    }
   }
 }
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 6228)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Services.Hive/3.4/LifecycleManager.cs	(revision 6229)
@@ -1,3 +1,4 @@
 ﻿using System;
+using System.Collections.Generic;
 using System.Linq;
 using HeuristicLab.Services.Hive.Common;
@@ -26,5 +27,52 @@
       SetTimeoutSlavesOffline();
       SetTimeoutJobsWaiting();
-      FinishParentJobs();      
+      FinishParentJobs();
+      UpdateStatistics();
+    }
+
+    private void UpdateStatistics() {
+      var slaves = dao.GetSlaves(x => x.SlaveState == SlaveState.Calculating || x.SlaveState == SlaveState.Idle);
+
+      var stats = new Statistics();
+      stats.TimeStamp = DateTime.Now;
+      var slaveStats = new List<SlaveStatistics>();
+      foreach (var slave in slaves) {
+        slaveStats.Add(new SlaveStatistics() {
+          SlaveId = slave.Id,
+          Cores = slave.Cores.HasValue ? slave.Cores.Value : 0,
+          FreeCores = slave.FreeCores.HasValue ? slave.FreeCores.Value : 0,
+          Memory = slave.Memory.HasValue ? slave.Memory.Value : 0,
+          FreeMemory = slave.FreeMemory.HasValue ? slave.FreeMemory.Value : 0,
+          CpuUtilization = slave.CpuUtilization
+        });
+      }
+      stats.SlaveStatistics = slaveStats;
+
+      stats.UserStatistics = dao.GetUserStatistics();
+
+      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;
+      //}
+
     }
 
