Index: branches/HiveStatistics/sources/HeuristicLab 3.3 Services.sln
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab 3.3 Services.sln	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab 3.3 Services.sln	(revision 12691)
@@ -70,4 +70,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Services.WebApp.Statistics-3.3", "HeuristicLab.Services.WebApp.Statistics\3.3\HeuristicLab.Services.WebApp.Statistics-3.3.csproj", "{1BC54353-7D4C-4734-BAA9-3D11B3242B59}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleServiceTest", "ConsoleServiceTest\ConsoleServiceTest.csproj", "{72EAF349-27C8-4CFE-B03B-47E2C5E124FD}"
 EndProject
 Global
@@ -256,4 +258,12 @@
 		{1BC54353-7D4C-4734-BAA9-3D11B3242B59}.Release|x86.ActiveCfg = Release|x86
 		{1BC54353-7D4C-4734-BAA9-3D11B3242B59}.Release|x86.Build.0 = Release|x86
+		{72EAF349-27C8-4CFE-B03B-47E2C5E124FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{72EAF349-27C8-4CFE-B03B-47E2C5E124FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{72EAF349-27C8-4CFE-B03B-47E2C5E124FD}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{72EAF349-27C8-4CFE-B03B-47E2C5E124FD}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{72EAF349-27C8-4CFE-B03B-47E2C5E124FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{72EAF349-27C8-4CFE-B03B-47E2C5E124FD}.Release|Any CPU.Build.0 = Release|Any CPU
+		{72EAF349-27C8-4CFE-B03B-47E2C5E124FD}.Release|x64.ActiveCfg = Release|Any CPU
+		{72EAF349-27C8-4CFE-B03B-47E2C5E124FD}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/AccessService.dbml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/AccessService.dbml	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/AccessService.dbml	(revision 12691)
@@ -1,4 +1,4 @@
 ﻿<?xml version="1.0" encoding="utf-8"?><Database Name="HeuristicLab.ClientManagement" Class="AccessServiceDataContext" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">
-  <Connection Mode="AppSettings" ConnectionString="Data Source=.;Initial Catalog=HeuristicLab.AccessService;Integrated Security=True" SettingsObjectName="HeuristicLab.Services.Access.DataAccess.Properties.Settings" SettingsPropertyName="HeuristicLab_ClientManagementConnectionString" Provider="System.Data.SqlClient" />
+  <Connection Mode="AppSettings" ConnectionString="Data Source=.\SQLEXPRESS;Initial Catalog=HeuristicLab.AccessService;Integrated Security=True" SettingsObjectName="HeuristicLab.Services.Access.DataAccess.Properties.Settings" SettingsPropertyName="HeuristicLab_ClientManagementConnectionString" Provider="System.Data.SqlClient" />
   <Table Name="dbo.Resource" Member="Resources">
     <Type Name="Resource" InheritanceCode="Resource" IsInheritanceDefault="true">
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/AccessService.designer.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/AccessService.designer.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/AccessService.designer.cs	(revision 12691)
@@ -3,5 +3,5 @@
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:4.0.30319.34014
+//     Runtime Version:4.0.30319.34209
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/Properties/Settings.Designer.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/Properties/Settings.Designer.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/Properties/Settings.Designer.cs	(revision 12691)
@@ -2,5 +2,5 @@
 // <auto-generated>
 //     This code was generated by a tool.
-//     Runtime Version:4.0.30319.34014
+//     Runtime Version:4.0.30319.34209
 //
 //     Changes to this file may cause incorrect behavior and will be lost if
@@ -27,9 +27,9 @@
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
         [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
-        [global::System.Configuration.DefaultSettingValueAttribute("Data Source=.;Initial Catalog=HeuristicLab.Authentication;Integrated Security=Tru" +
-            "e")]
-        public string HeuristicLab_AuthenticationConnectionString {
+        [global::System.Configuration.DefaultSettingValueAttribute("Data Source=.\\SQLEXPRESS;Initial Catalog=HeuristicLab.AccessService;Integrated Se" +
+            "curity=True")]
+        public string HeuristicLab_ClientManagementConnectionString {
             get {
-                return ((string)(this["HeuristicLab_AuthenticationConnectionString"]));
+                return ((string)(this["HeuristicLab_ClientManagementConnectionString"]));
             }
         }
@@ -38,9 +38,9 @@
         [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
         [global::System.Configuration.SpecialSettingAttribute(global::System.Configuration.SpecialSetting.ConnectionString)]
-        [global::System.Configuration.DefaultSettingValueAttribute("Data Source=.;Initial Catalog=HeuristicLab.AccessService;Integrated Security=True" +
-            "")]
-        public string HeuristicLab_ClientManagementConnectionString {
+        [global::System.Configuration.DefaultSettingValueAttribute("Data Source=.\\SQLEXPRESS;Initial Catalog=HeuristicLab.Authentication;Integrated S" +
+            "ecurity=True")]
+        public string HeuristicLab_AuthenticationConnectionString {
             get {
-                return ((string)(this["HeuristicLab_ClientManagementConnectionString"]));
+                return ((string)(this["HeuristicLab_AuthenticationConnectionString"]));
             }
         }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/Properties/Settings.settings
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/Properties/Settings.settings	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/Properties/Settings.settings	(revision 12691)
@@ -3,19 +3,19 @@
   <Profiles />
   <Settings>
+    <Setting Name="HeuristicLab_ClientManagementConnectionString" Type="(Connection string)" Scope="Application">
+      <DesignTimeValue Profile="(Default)">&lt;?xml version="1.0" encoding="utf-16"?&gt;
+&lt;SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
+  &lt;ConnectionString&gt;Data Source=.\SQLEXPRESS;Initial Catalog=HeuristicLab.AccessService;Integrated Security=True&lt;/ConnectionString&gt;
+  &lt;ProviderName&gt;System.Data.SqlClient&lt;/ProviderName&gt;
+&lt;/SerializableConnectionString&gt;</DesignTimeValue>
+      <Value Profile="(Default)">Data Source=.\SQLEXPRESS;Initial Catalog=HeuristicLab.AccessService;Integrated Security=True</Value>
+    </Setting>
     <Setting Name="HeuristicLab_AuthenticationConnectionString" Type="(Connection string)" Scope="Application">
       <DesignTimeValue Profile="(Default)">&lt;?xml version="1.0" encoding="utf-16"?&gt;
 &lt;SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
-  &lt;ConnectionString&gt;Data Source=.;Initial Catalog=HeuristicLab.Authentication;Integrated Security=True&lt;/ConnectionString&gt;
+  &lt;ConnectionString&gt;Data Source=.\SQLEXPRESS;Initial Catalog=HeuristicLab.Authentication;Integrated Security=True&lt;/ConnectionString&gt;
   &lt;ProviderName&gt;System.Data.SqlClient&lt;/ProviderName&gt;
 &lt;/SerializableConnectionString&gt;</DesignTimeValue>
-      <Value Profile="(Default)">Data Source=.;Initial Catalog=HeuristicLab.Authentication;Integrated Security=True</Value>
-    </Setting>
-    <Setting Name="HeuristicLab_ClientManagementConnectionString" Type="(Connection string)" Scope="Application">
-      <DesignTimeValue Profile="(Default)">&lt;?xml version="1.0" encoding="utf-16"?&gt;
-&lt;SerializableConnectionString xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
-  &lt;ConnectionString&gt;Data Source=.;Initial Catalog=HeuristicLab.AccessService;Integrated Security=True&lt;/ConnectionString&gt;
-  &lt;ProviderName&gt;System.Data.SqlClient&lt;/ProviderName&gt;
-&lt;/SerializableConnectionString&gt;</DesignTimeValue>
-      <Value Profile="(Default)">Data Source=.;Initial Catalog=HeuristicLab.AccessService;Integrated Security=True</Value>
+      <Value Profile="(Default)">Data Source=.\SQLEXPRESS;Initial Catalog=HeuristicLab.Authentication;Integrated Security=True</Value>
     </Setting>
   </Settings>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/app.config
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/app.config	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Access.DataAccess/3.3/app.config	(revision 12691)
@@ -3,7 +3,7 @@
     <configSections>
     </configSections>
-    <connectionStrings>        
-        <add name="HeuristicLab.Services.Access.DataAccess.Properties.Settings.HeuristicLab_ClientManagementConnectionString" connectionString="Data Source=.;Initial Catalog=HeuristicLab.AccessService;Integrated Security=True" providerName="System.Data.SqlClient"/>
-        <add name="HeuristicLab.Services.Access.DataAccess.Properties.Settings.HeuristicLab_AuthenticationConnectionString" connectionString="Data Source=.;Initial Catalog=HeuristicLab.Authentication;Integrated Security=True" providerName="System.Data.SqlClient"/>
+    <connectionStrings>
+      <add name="HeuristicLab.Services.Access.DataAccess.Properties.Settings.HeuristicLab_ClientManagementConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=HeuristicLab.AccessService;Integrated Security=True" providerName="System.Data.SqlClient"/>
+      <add name="HeuristicLab.Services.Access.DataAccess.Properties.Settings.HeuristicLab_AuthenticationConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=HeuristicLab.Authentication;Integrated Security=SSPI" providerName="System.Data.SqlClient"/>
     </connectionStrings>
 <startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Access/3.3/App.config
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Access/3.3/App.config	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Access/3.3/App.config	(revision 12691)
@@ -2,5 +2,6 @@
 <configuration>
   <connectionStrings>
-    <add name="HeuristicLab.Authentication" connectionString="Data Source=.;Initial Catalog=HeuristicLab.Authentication;Integrated Security=True" providerName="System.Data.SqlClient"/>
+    <add name="HeuristicLab.Authentication" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=HeuristicLab.Authentication"/>
+    <add name="HeuristicLab.Services.Hive.DataAccess.Settings.HeuristicLab_Hive_LinqConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=HeuristicLab.Hive-3.3;Integrated Security=True;" providerName="System.Data.SqlClient"/>
   </connectionStrings>
   <system.web>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Access/3.3/Web.config
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Access/3.3/Web.config	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Access/3.3/Web.config	(revision 12691)
@@ -2,5 +2,6 @@
 <configuration>
   <connectionStrings>
-  <add name="HeuristicLab.Authentication" connectionString="data source=localhost;Integrated Security=SSPI;Initial Catalog=HeuristicLab.Authentication"/>
+    <add name="HeuristicLab.Authentication" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=HeuristicLab.Authentication"/>
+    <add name="HeuristicLab.Services.Hive.DataAccess.Settings.HeuristicLab_Hive_LinqConnectionString" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=HeuristicLab.Hive-3.3;Integrated Security=True;" providerName="System.Data.SqlClient"/>
   </connectionStrings>
   <system.web>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/AssignedResourceDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/AssignedResourceDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/AssignedResourceDao.cs	(revision 12691)
@@ -35,4 +35,24 @@
       return Table.Where(x => x.TaskId == taskId);
     }
+
+    public bool TaskIsAllowedToBeCalculatedBySlave(Guid taskId, Guid slaveId) {
+      return DataContext.ExecuteQuery<int>(TaskIsAllowedToBeCalculatedBySlaveQueryString, slaveId, taskId).First() > 0;
+    }
+
+    #region String queries
+    private const string TaskIsAllowedToBeCalculatedBySlaveQueryString = @"
+      WITH pr AS (
+        SELECT ResourceId, ParentResourceId
+        FROM [Resource]
+        WHERE ResourceId = {0}
+        UNION ALL
+        SELECT r.ResourceId, r.ParentResourceId
+        FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
+      )
+      SELECT COUNT(ar.TaskId)
+      FROM pr JOIN AssignedResources ar ON pr.ResourceId = ar.ResourceId
+      WHERE ar.TaskId = {1}
+    ";
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/DowntimeDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/DowntimeDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/DowntimeDao.cs	(revision 12691)
@@ -29,6 +29,18 @@
 
     public override Downtime GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.DowntimeId == id);
+      return GetByIdQuery(DataContext, id);
     }
+
+    public IQueryable<Downtime> GetByResourceId(Guid id) {
+      return Table.Where(x => x.ResourceId == id);
+    }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, Downtime> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid downtimeId) =>
+        (from downtime in db.GetTable<Downtime>()
+         where downtime.DowntimeId == downtimeId
+         select downtime).SingleOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/GenericDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/GenericDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/GenericDao.cs	(revision 12691)
@@ -109,5 +109,5 @@
 
     public bool Exists(T entity) {
-      return Table.Contains(entity);
+      return ExistsQuery(DataContext, entity);
     }
 
@@ -116,4 +116,10 @@
     }
     #endregion
+
+    #region Compiled queries
+    private static readonly Func<DataContext, T, bool> ExistsQuery =
+      CompiledQuery.Compile((DataContext db, T entity) =>
+        db.GetTable<T>().Contains(entity));
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimClientDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimClientDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimClientDao.cs	(revision 12691)
@@ -27,14 +27,10 @@
 namespace HeuristicLab.Services.Hive.DataAccess.Daos.HiveStatistics {
   public class DimClientDao : GenericDao<Guid, DimClient> {
-    private const string UpdateExpirationTimeQuery =
-      @"UPDATE [statistics].[DimClient] 
-           SET ExpirationTime = {0} 
-         WHERE Id IN ({1});";
-
     public DimClientDao(DataContext dataContext) : base(dataContext) { }
 
     public override DimClient GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.Id == id);
+      return GetByIdQuery(DataContext, id);
     }
+
     public IQueryable<DimClient> GetActiveClients() {
       return Table.Where(x => x.ExpirationTime == null);
@@ -53,4 +49,19 @@
       return 0;
     }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, DimClient> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid id) =>
+        (from dimClient in db.GetTable<DimClient>()
+         where dimClient.Id == id
+         select dimClient).SingleOrDefault());
+    #endregion
+
+    #region String queries
+    private const string UpdateExpirationTimeQuery =
+      @"UPDATE [statistics].[DimClient] 
+           SET ExpirationTime = {0} 
+         WHERE Id IN ({1});";
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimJobDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimJobDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimJobDao.cs	(revision 12691)
@@ -29,5 +29,5 @@
 
     public override DimJob GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.JobId == id);
+      return GetByIdQuery(DataContext, id);
     }
 
@@ -43,4 +43,12 @@
       return Table.Where(x => x.DateCompleted != null);
     }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, DimJob> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid id) =>
+        (from dimJob in db.GetTable<DimJob>()
+         where dimJob.JobId == id
+         select dimJob).SingleOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimTimeDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimTimeDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimTimeDao.cs	(revision 12691)
@@ -29,9 +29,23 @@
 
     public override DimTime GetById(DateTime id) {
-      return Table.SingleOrDefault(x => x.Time == id);
+      return GetByIdQuery(DataContext, id);
     }
     public DimTime GetLastEntry() {
-      return Table.OrderByDescending(x => x.Time).FirstOrDefault();
+      return GetLastEntryQuery(DataContext);
     }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, DateTime, DimTime> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, DateTime id) =>
+        (from dimTime in db.GetTable<DimTime>()
+         where dimTime.Time == id
+         select dimTime).SingleOrDefault());
+
+    private static readonly Func<DataContext, DimTime> GetLastEntryQuery =
+      CompiledQuery.Compile((DataContext db) =>
+        (from dimTime in db.GetTable<DimTime>()
+         orderby dimTime.Time descending
+         select dimTime).FirstOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimUserDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimUserDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/DimUserDao.cs	(revision 12691)
@@ -29,6 +29,14 @@
 
     public override DimUser GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.UserId == id);
+      return GetByIdQuery(DataContext, id);
     }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, DimUser> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid id) =>
+        (from dimUser in db.GetTable<DimUser>()
+         where dimUser.UserId == id
+         select dimUser).SingleOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/FactClientInfoDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/FactClientInfoDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/FactClientInfoDao.cs	(revision 12691)
@@ -53,9 +53,10 @@
       return from cf in Table
              join r in DimClientTable on cf.ClientId equals r.Id
-             group cf by r.ResourceId into grpFacts
-             select new LastUpdateTimestamp {
-               ResourceId = grpFacts.Key,
-               Timestamp = grpFacts.Max(x => x.Time),
-             };
+             group cf by r.ResourceId
+               into grpFacts
+               select new LastUpdateTimestamp {
+                 ResourceId = grpFacts.Key,
+                 Timestamp = grpFacts.Max(x => x.Time),
+               };
     }
 
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/FactTaskDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/FactTaskDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/HiveStatistics/FactTaskDao.cs	(revision 12691)
@@ -37,11 +37,8 @@
     }
 
-    private const string BatchDeleteQuery =
-      @"DELETE FROM [statistics].[FactTask]
-         WHERE TaskId IN ({0});";
     public FactTaskDao(DataContext dataContext) : base(dataContext) { }
 
     public override FactTask GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.TaskId == id);
+      return GetByIdQuery(DataContext, id);
     }
 
@@ -55,5 +52,5 @@
 
     public DateTime? GetLastCompletedTaskFromJob(Guid id) {
-      return Table.Where(x => x.JobId == id && x.EndTime != null).Max(x => x.EndTime);
+      return GetLastCompletedTaskFromJobQuery(DataContext, id);
     }
 
@@ -92,4 +89,24 @@
     }
 
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, FactTask> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid id) =>
+        (from factTask in db.GetTable<FactTask>()
+         where factTask.TaskId == id
+         select factTask).SingleOrDefault());
+
+
+    private static readonly Func<DataContext, Guid, DateTime?> GetLastCompletedTaskFromJobQuery =
+      CompiledQuery.Compile((DataContext db, Guid id) =>
+        (from factTask in db.GetTable<FactTask>()
+         where factTask.JobId == id && factTask.EndTime != null
+         select factTask.EndTime).Max());
+    #endregion
+
+    #region String queries
+    private const string BatchDeleteQuery =
+      @"DELETE FROM [statistics].[FactTask]
+         WHERE TaskId IN ({0});";
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/JobDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/JobDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/JobDao.cs	(revision 12691)
@@ -29,6 +29,14 @@
 
     public override Job GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.JobId == id);
+      return GetByIdQuery(DataContext, id);
     }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, Job> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid jobId) =>
+        (from job in db.GetTable<Job>()
+         where job.JobId == jobId
+         select job).SingleOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/JobPermissionDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/JobPermissionDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/JobPermissionDao.cs	(revision 12691)
@@ -33,6 +33,39 @@
 
     public JobPermission GetByJobAndUserId(Guid jobId, Guid userId) {
-      return Table.SingleOrDefault(x => x.JobId == jobId && x.GrantedUserId == userId);
+      return GetByJobAndUserIdQuery(DataContext, jobId, userId);
     }
+
+    public IQueryable<JobPermission> GetByJobId(Guid jobId) {
+      return Table.Where(x => x.JobId == jobId);
+    }
+
+    public void SetJobPermission(Guid jobId, Guid grantedByUserId, Guid grantedUserId, Permission permission) {
+      var jobPermission = GetByJobAndUserId(jobId, grantedUserId);
+      if (jobPermission != null) {
+        if (permission == Permission.NotAllowed) {
+          Delete(jobPermission);
+        } else {
+          jobPermission.Permission = permission;
+          jobPermission.GrantedByUserId = grantedByUserId;
+        }
+      } else {
+        if (permission != Permission.NotAllowed) {
+          Save(new JobPermission {
+            JobId = jobId,
+            GrantedByUserId = grantedByUserId,
+            GrantedUserId = grantedUserId,
+            Permission = permission
+          });
+        }
+      }
+    }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, Guid, JobPermission> GetByJobAndUserIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid jobId, Guid userId) =>
+        (from jobPermission in db.GetTable<JobPermission>()
+         where jobPermission.JobId == jobId && jobPermission.GrantedUserId == userId
+         select jobPermission).SingleOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/LifecycleDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/LifecycleDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/LifecycleDao.cs	(revision 12691)
@@ -20,4 +20,5 @@
 #endregion
 
+using System;
 using System.Data.Linq;
 using System.Linq;
@@ -28,6 +29,35 @@
 
     public override Lifecycle GetById(int id) {
-      return Table.SingleOrDefault(x => x.LifecycleId == id);
+      return GetByIdQuery(DataContext, id);
     }
+
+    public Lifecycle GetLastLifecycle() {
+      return GetLastLifecycleQuery(DataContext);
+    }
+
+    public void UpdateLifecycle() {
+      var entity = GetLastLifecycle();
+      if (entity != null) {
+        entity.LastCleanup = DateTime.Now;
+      } else {
+        Save(new Lifecycle {
+          LifecycleId = 0,
+          LastCleanup = DateTime.Now
+        });
+      }
+    }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, int, Lifecycle> GetByIdQuery =
+     CompiledQuery.Compile((DataContext db, int lifecycleId) =>
+       (from lifecycle in db.GetTable<Lifecycle>()
+        where lifecycle.LifecycleId == lifecycleId
+        select lifecycle).SingleOrDefault());
+
+    private static readonly Func<DataContext, Lifecycle> GetLastLifecycleQuery =
+      CompiledQuery.Compile((DataContext db) =>
+        (from lifecycle in db.GetTable<Lifecycle>()
+         select lifecycle).SingleOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/PluginDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/PluginDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/PluginDao.cs	(revision 12691)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using System.Data.Linq;
 using System.Linq;
@@ -29,6 +30,24 @@
 
     public override Plugin GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.PluginId == id);
+      return GetByIdQuery(DataContext, id);
     }
+
+    public IEnumerable<Plugin> GetByHash(byte[] hash) {
+      return GetByHashQuery(DataContext).Where(x => x.Hash.SequenceEqual(hash));
+    }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, Plugin> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid pluginId) =>
+        (from plugin in db.GetTable<Plugin>()
+         where plugin.PluginId == pluginId
+         select plugin).SingleOrDefault());
+
+    private static readonly Func<DataContext, IEnumerable<Plugin>> GetByHashQuery =
+      CompiledQuery.Compile((DataContext db) =>
+        (from plugin in db.GetTable<Plugin>()
+         where plugin.Hash != null
+         select plugin));
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/PluginDataDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/PluginDataDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/PluginDataDao.cs	(revision 12691)
@@ -29,6 +29,14 @@
 
     public override PluginData GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.PluginDataId == id);
+      return GetByIdQuery(DataContext, id);
     }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, PluginData> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid pluginDataId) =>
+        (from pluginData in db.GetTable<PluginData>()
+         where pluginData.PluginDataId == pluginDataId
+         select pluginData).SingleOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/RequiredPluginDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/RequiredPluginDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/RequiredPluginDao.cs	(revision 12691)
@@ -29,6 +29,14 @@
 
     public override RequiredPlugin GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.RequiredPluginId == id);
+      return GetByIdQuery(DataContext, id);
     }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, RequiredPlugin> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid requiredPluginId) =>
+        (from requiredPlugin in db.GetTable<RequiredPlugin>()
+         where requiredPlugin.RequiredPluginId == requiredPluginId
+         select requiredPlugin).SingleOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourceDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourceDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourceDao.cs	(revision 12691)
@@ -29,5 +29,9 @@
 
     public override Resource GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.ResourceId == id);
+      return GetByIdQuery(DataContext, id);
+    }
+
+    public Resource GetByName(string name) {
+      return GetByNameQuery(DataContext, name);
     }
 
@@ -35,4 +39,18 @@
       return Table.Where(x => x.OwnerUserId != null);
     }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, Resource> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid resourceId) =>
+        (from resource in db.GetTable<Resource>()
+         where resource.ResourceId == resourceId
+         select resource).SingleOrDefault());
+
+    private static readonly Func<DataContext, string, Resource> GetByNameQuery =
+     CompiledQuery.Compile((DataContext db, string name) =>
+       (from resource in db.GetTable<Resource>()
+        where resource.Name == name
+        select resource).FirstOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourcePermissionDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourcePermissionDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/ResourcePermissionDao.cs	(revision 12691)
@@ -21,5 +21,7 @@
 
 using System;
+using System.Collections.Generic;
 using System.Data.Linq;
+using System.Linq;
 
 namespace HeuristicLab.Services.Hive.DataAccess.Daos {
@@ -30,4 +32,31 @@
       throw new NotImplementedException();
     }
+
+    public IEnumerable<ResourcePermission> GetByResourceId(Guid id) {
+      return GetByResourceIdGetByIdQuery(DataContext, id);
+    }
+
+    public void DeleteByResourceAndGrantedUserId(Guid resourceId, IEnumerable<Guid> grantedUserId) {
+      string paramIds = string.Join(",", grantedUserId.Select(x => string.Format("'{0}'", x)));
+      if (!string.IsNullOrWhiteSpace(paramIds)) {
+        string query = string.Format(DeleteByGrantedUserQuery, resourceId, paramIds);
+        DataContext.ExecuteCommand(query);
+      }
+    }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, IEnumerable<ResourcePermission>> GetByResourceIdGetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid resourceId) =>
+        from resourcePermission in db.GetTable<ResourcePermission>()
+        where resourcePermission.ResourceId == resourceId
+        select resourcePermission);
+    #endregion
+
+    #region String queries
+    private const string DeleteByGrantedUserQuery =
+      @"DELETE FROM [ResourcePermission]
+         WHERE ResourceId = '{0}'
+           AND GrantedUserId IN ({1});";
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/SlaveDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/SlaveDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/SlaveDao.cs	(revision 12691)
@@ -46,5 +46,5 @@
     #region IGenericDao<Guid,Slave> Members
     public Slave GetById(Guid id) {
-      return Entities.SingleOrDefault(x => x.ResourceId == id);
+      return GetByIdQuery(dataContext, id);
     }
 
@@ -117,5 +117,5 @@
 
     public bool Exists(Slave entity) {
-      return Table.Contains(entity);
+      return ExistsQuery(dataContext, entity);
     }
 
@@ -124,4 +124,41 @@
     }
     #endregion
+
+    public bool SlaveHasToShutdownComputer(Guid slaveId) {
+      return dataContext.ExecuteQuery<int>(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Shutdown.ToString()).FirstOrDefault() > 0;
+    }
+
+    public bool SlaveIsAllowedToCalculate(Guid slaveId) {
+      return dataContext.ExecuteQuery<int>(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Offline.ToString()).FirstOrDefault() == 0;
+    }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, Slave> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid slaveId) =>
+        (from slave in db.GetTable<Resource>().OfType<Slave>()
+         where slave.ResourceId == slaveId
+         select slave).SingleOrDefault());
+
+    private static readonly Func<DataContext, Slave, bool> ExistsQuery =
+      CompiledQuery.Compile((DataContext db, Slave entity) =>
+        db.GetTable<Resource>().OfType<Slave>().Contains(entity));
+    #endregion
+
+    #region String queries
+    private const string DowntimeQueryString = @"
+      WITH pr AS (
+        SELECT ResourceId, ParentResourceId
+        FROM [Resource]
+        WHERE ResourceId = {0}
+        UNION ALL
+        SELECT r.ResourceId, r.ParentResourceId
+        FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
+      )
+      SELECT COUNT(dt.DowntimeId)
+      FROM pr JOIN [Downtime] dt ON pr.ResourceId = dt.ResourceId
+      WHERE {1} BETWEEN dt.StartDate AND dt.EndDate
+        AND dt.DowntimeType = {2}
+    ";
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/SlaveGroupDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/SlaveGroupDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/SlaveGroupDao.cs	(revision 12691)
@@ -45,5 +45,5 @@
     #region IGenericDao<Guid,SlaveGroup> Members
     public SlaveGroup GetById(Guid id) {
-      return Entities.SingleOrDefault(x => x.ResourceId == id);
+      return GetByIdQuery(dataContext, id);
     }
 
@@ -112,5 +112,5 @@
 
     public bool Exists(SlaveGroup entity) {
-      return Table.Contains(entity);
+      return ExistsQuery(dataContext, entity);
     }
 
@@ -119,4 +119,16 @@
     }
     #endregion
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, SlaveGroup> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid slaveGroupId) =>
+        (from slaveGroup in db.GetTable<Resource>().OfType<SlaveGroup>()
+         where slaveGroup.ResourceId == slaveGroupId
+         select slaveGroup).SingleOrDefault());
+
+    private static readonly Func<DataContext, SlaveGroup, bool> ExistsQuery =
+      CompiledQuery.Compile((DataContext db, SlaveGroup slaveGroup) =>
+        db.GetTable<Resource>().OfType<SlaveGroup>().Contains(slaveGroup));
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/StateLogDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/StateLogDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/StateLogDao.cs	(revision 12691)
@@ -26,5 +26,4 @@
 namespace HeuristicLab.Services.Hive.DataAccess.Daos {
   public class StateLogDao : GenericDao<Guid, StateLog> {
-
     private Table<Task> TaskTable {
       get { return DataContext.GetTable<Task>(); }
@@ -34,13 +33,25 @@
 
     public override StateLog GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.StateLogId == id);
+      return GetByIdQuery(DataContext, id);
     }
 
     public StateLog GetLastStateLogFromTask(Task task) {
-      return Table
-        .Where(x => x.TaskId == task.TaskId)
-        .OrderByDescending(x => x.DateTime)
-        .First(x => x.SlaveId != null);
+      return GetLastStateLogFromTaskQuery(DataContext, task);
     }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, StateLog> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid stateLogId) =>
+        (from stateLog in db.GetTable<StateLog>()
+         where stateLog.StateLogId == stateLogId
+         select stateLog).SingleOrDefault());
+
+    private static readonly Func<DataContext, Task, StateLog> GetLastStateLogFromTaskQuery =
+      CompiledQuery.Compile((DataContext db, Task task) =>
+        (from stateLog in db.GetTable<StateLog>()
+         where stateLog.TaskId == task.TaskId
+         orderby stateLog.DateTime descending
+         select stateLog).First(x => x.SlaveId != null));
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/TaskDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/TaskDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/TaskDao.cs	(revision 12691)
@@ -21,4 +21,5 @@
 
 using System;
+using System.Collections.Generic;
 using System.Data.Linq;
 using System.Linq;
@@ -29,5 +30,5 @@
 
     public override Task GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.TaskId == id);
+      return GetByIdQuery(DataContext, id);
     }
 
@@ -39,4 +40,55 @@
       return Table.Where(x => x.JobId == id);
     }
+    public class TaskPriorityInfo {
+      public Guid JobId { get; set; }
+      public Guid TaskId { get; set; }
+      public int Priority { get; set; }
+    }
+
+    public IEnumerable<TaskPriorityInfo> GetWaitingTasks(Slave slave) {
+      //Originally we checked here if there are parent tasks which should be calculated (with GetParentTasks(resourceIds, count, false);).
+      //Because there is at the moment no case where this makes sense (there don't exist parent tasks which need to be calculated), 
+      //we skip this step because it's wasted runtime
+      return DataContext.ExecuteQuery<TaskPriorityInfo>(GetWaitingTasksQueryString, slave.ResourceId, Enum.GetName(typeof(TaskState), TaskState.Waiting), slave.FreeCores, slave.FreeMemory).ToList();
+    }
+
+    public void UpdateExecutionTime(Guid taskId, double executionTime) {
+      DataContext.ExecuteCommand(UpdateExecutionTimeQuery, executionTime, DateTime.Now, taskId);
+    }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, Task> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid taskId) =>
+        (from task in db.GetTable<Task>()
+         where task.TaskId == taskId
+         select task).SingleOrDefault());
+    #endregion
+
+    #region String queries
+    private const string GetWaitingTasksQueryString = @"
+      WITH pr AS (
+        SELECT ResourceId, ParentResourceId
+        FROM [Resource]
+        WHERE ResourceId = {0}
+        UNION ALL
+        SELECT r.ResourceId, r.ParentResourceId
+        FROM [Resource] r JOIN pr ON r.ResourceId = pr.ParentResourceId
+      )
+      SELECT DISTINCT t.TaskId, t.JobId, t.Priority
+      FROM pr JOIN AssignedResources ar ON ar.ResourceId = pr.ResourceId
+          JOIN Task t ON t.TaskId = ar.TaskId
+      WHERE NOT (t.IsParentTask = 1 AND t.FinishWhenChildJobsFinished = 1)
+          AND t.TaskState = {1}
+          AND t.CoresNeeded <= {2}
+          AND t.MemoryNeeded <= {3}
+    ";
+
+    private const string UpdateExecutionTimeQuery = @"
+      UPDATE [Task] 
+         SET ExecutionTimeMs = {0},
+             LastHeartbeat = {1} 
+       WHERE TaskId = {2}
+    ";
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/TaskDataDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/TaskDataDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/TaskDataDao.cs	(revision 12691)
@@ -29,6 +29,14 @@
 
     public override TaskData GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.TaskId == id);
+      return GetByIdQuery(DataContext, id);
     }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, TaskData> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid taskId) =>
+        (from taskData in db.GetTable<TaskData>()
+         where taskData.TaskId == taskId
+         select taskData).SingleOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/UserPriorityDao.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/UserPriorityDao.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Daos/UserPriorityDao.cs	(revision 12691)
@@ -29,6 +29,14 @@
 
     public override UserPriority GetById(Guid id) {
-      return Table.SingleOrDefault(x => x.UserId == id);
+      return GetByIdQuery(DataContext, id);
     }
+
+    #region Compiled queries
+    private static readonly Func<DataContext, Guid, UserPriority> GetByIdQuery =
+      CompiledQuery.Compile((DataContext db, Guid userId) =>
+        (from userPriority in db.GetTable<UserPriority>()
+         where userPriority.UserId == userId
+         select userPriority).SingleOrDefault());
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Manager/PersistenceManager.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Manager/PersistenceManager.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.DataAccess/3.3/Manager/PersistenceManager.cs	(revision 12691)
@@ -35,92 +35,116 @@
 
     #region Hive daos
+
+    private AssignedResourceDao assignedResourceDao;
     public AssignedResourceDao AssignedResourceDao {
-      get { return new AssignedResourceDao(dataContext); }
-    }
-
+      get { return assignedResourceDao ?? (assignedResourceDao = new AssignedResourceDao(dataContext)); }
+    }
+
+    private DowntimeDao downtimeDao;
     public DowntimeDao DowntimeDao {
-      get { return new DowntimeDao(dataContext); }
-    }
-
+      get { return downtimeDao ?? (downtimeDao = new DowntimeDao(dataContext)); }
+    }
+
+    private JobDao jobDao;
     public JobDao JobDao {
-      get { return new JobDao(dataContext); }
-    }
-
+      get { return jobDao ?? (jobDao = new JobDao(dataContext)); }
+    }
+
+    private JobPermissionDao jobPermissionDao;
     public JobPermissionDao JobPermissionDao {
-      get { return new JobPermissionDao(dataContext); }
-    }
-
+      get { return jobPermissionDao ?? (jobPermissionDao = new JobPermissionDao(dataContext)); }
+    }
+
+    private LifecycleDao lifecycleDao;
     public LifecycleDao LifecycleDao {
-      get { return new LifecycleDao(dataContext); }
-    }
-
+      get { return lifecycleDao ?? (lifecycleDao = new LifecycleDao(dataContext)); }
+    }
+
+    private PluginDao pluginDao;
     public PluginDao PluginDao {
-      get { return new PluginDao(dataContext); }
-    }
-
+      get { return pluginDao ?? (pluginDao = new PluginDao(dataContext)); }
+    }
+
+    private PluginDataDao pluginDataDao;
     public PluginDataDao PluginDataDao {
-      get { return new PluginDataDao(dataContext); }
-    }
-
+      get { return pluginDataDao ?? (pluginDataDao = new PluginDataDao(dataContext)); }
+    }
+
+    private RequiredPluginDao requiredPluginDao;
     public RequiredPluginDao RequiredPluginDao {
-      get { return new RequiredPluginDao(dataContext); }
-    }
-
+      get { return requiredPluginDao ?? (requiredPluginDao = new RequiredPluginDao(dataContext)); }
+    }
+
+    private ResourceDao resourceDao;
     public ResourceDao ResourceDao {
-      get { return new ResourceDao(dataContext); }
-    }
-
+      get { return resourceDao ?? (resourceDao = new ResourceDao(dataContext)); }
+    }
+
+    private ResourcePermissionDao resourcePermissionDao;
     public ResourcePermissionDao ResourcePermissionDao {
-      get { return new ResourcePermissionDao(dataContext); }
-    }
-
+      get { return resourcePermissionDao ?? (resourcePermissionDao = new ResourcePermissionDao(dataContext)); }
+    }
+
+    private SlaveDao slaveDao;
     public SlaveDao SlaveDao {
-      get { return new SlaveDao(dataContext); }
-    }
-
+      get { return slaveDao ?? (slaveDao = new SlaveDao(dataContext)); }
+    }
+
+    private SlaveGroupDao slaveGroupDao;
     public SlaveGroupDao SlaveGroupDao {
-      get { return new SlaveGroupDao(dataContext); }
-    }
-
+      get { return slaveGroupDao ?? (slaveGroupDao = new SlaveGroupDao(dataContext)); }
+    }
+
+    private StateLogDao stateLogDao;
     public StateLogDao StateLogDao {
-      get { return new StateLogDao(dataContext); }
-    }
-
+      get { return stateLogDao ?? (stateLogDao = new StateLogDao(dataContext)); }
+    }
+
+    private TaskDao taskDao;
     public TaskDao TaskDao {
-      get { return new TaskDao(dataContext); }
-    }
-
+      get { return taskDao ?? (taskDao = new TaskDao(dataContext)); }
+    }
+
+    private TaskDataDao taskDataDao;
     public TaskDataDao TaskDataDao {
-      get { return new TaskDataDao(dataContext); }
-    }
-
+      get { return taskDataDao ?? (taskDataDao = new TaskDataDao(dataContext)); }
+    }
+
+    private UserPriorityDao userPriorityDao;
     public UserPriorityDao UserPriorityDao {
-      get { return new UserPriorityDao(dataContext); }
+      get { return userPriorityDao ?? (userPriorityDao = new UserPriorityDao(dataContext)); }
     }
     #endregion
 
     #region HiveStatistics daos
+
+    private DimClientDao dimClientDao;
     public DimClientDao DimClientDao {
-      get { return new DimClientDao(dataContext); }
-    }
-
+      get { return dimClientDao ?? (dimClientDao = new DimClientDao(dataContext)); }
+    }
+
+    private DimJobDao dimJobDao;
     public DimJobDao DimJobDao {
-      get { return new DimJobDao(dataContext); }
-    }
-
+      get { return dimJobDao ?? (dimJobDao = new DimJobDao(dataContext)); }
+    }
+
+    private DimTimeDao dimTimeDao;
     public DimTimeDao DimTimeDao {
-      get { return new DimTimeDao(dataContext); }
-    }
-
+      get { return dimTimeDao ?? (dimTimeDao = new DimTimeDao(dataContext)); }
+    }
+
+    private DimUserDao dimUserDao;
     public DimUserDao DimUserDao {
-      get { return new DimUserDao(dataContext); }
-    }
-
+      get { return dimUserDao ?? (dimUserDao = new DimUserDao(dataContext)); }
+    }
+
+    private FactClientInfoDao factClientInfoDao;
     public FactClientInfoDao FactClientInfoDao {
-      get { return new FactClientInfoDao(dataContext); }
-    }
-
+      get { return factClientInfoDao ?? (factClientInfoDao = new FactClientInfoDao(dataContext)); }
+    }
+
+    private FactTaskDao factTaskDao;
     public FactTaskDao FactTaskDao {
-      get { return new FactTaskDao(dataContext); }
+      get { return factTaskDao ?? (factTaskDao = new FactTaskDao(dataContext)); }
     }
     #endregion
@@ -130,4 +154,8 @@
       if (longRunning) context.CommandTimeout = (int)Settings.Default.LongRunningDatabaseCommandTimeout.TotalSeconds;
       dataContext = context;
+    }
+
+    public PersistenceManager(DataContext dataContext) {
+      this.dataContext = dataContext;
     }
 
@@ -179,7 +207,7 @@
 
     public void Dispose() {
-      if (dataContext != null) {
-        dataContext.Dispose();
-      }
+      //if (dataContext != null) {
+      //  dataContext.Dispose();
+      //}
     }
   }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/HiveService.svc
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/HiveService.svc	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/HiveService.svc	(revision 12691)
@@ -2,4 +2,4 @@
   Language="C#" 
   Debug="true" 
-  Service="HeuristicLab.Services.Hive.HiveService" 
+  Service="HeuristicLab.Services.Hive.NewHiveService" 
   %>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/Web.config
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/Web.config	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/Web.config	(revision 12691)
@@ -100,5 +100,5 @@
     </behaviors>
     <services>
-      <service behaviorConfiguration="ServiceBehaviour_IHiveService" name="HeuristicLab.Services.Hive.HiveService">
+      <service behaviorConfiguration="ServiceBehaviour_IHiveService" name="HeuristicLab.Services.Hive.NewHiveService">
         <endpoint address="mexhttp" binding="mexHttpBinding" bindingConfiguration="" name="MexHttpEndpoint" contract="IMetadataExchange"/>
         <endpoint address="mex" binding="mexTcpBinding" bindingConfiguration="" name="MexTcpEndpoint" contract="IMetadataExchange"/>
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Converter.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Converter.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Converter.cs	(revision 12691)
@@ -150,4 +150,55 @@
     #endregion
 
+    #region Slave
+    public static DT.Slave ToDto(this DA.Slave source) {
+      if (source == null) return null;
+      return new DT.Slave {
+        Id = source.ResourceId,
+        ParentResourceId = source.ParentResourceId,
+        Cores = source.Cores,
+        CpuSpeed = source.CpuSpeed,
+        FreeCores = source.FreeCores,
+        FreeMemory = source.FreeMemory,
+        IsAllowedToCalculate = source.IsAllowedToCalculate,
+        Memory = source.Memory,
+        Name = source.Name,
+        SlaveState = source.SlaveState.ToDto(),
+        CpuArchitecture = source.CpuArchitecture.ToDto(),
+        OperatingSystem = source.OperatingSystem,
+        LastHeartbeat = source.LastHeartbeat,
+        CpuUtilization = source.CpuUtilization,
+        HbInterval = source.HbInterval,
+        IsDisposable = source.IsDisposable,
+        OwnerUserId = source.OwnerUserId
+      };
+    }
+    public static DA.Slave ToEntity(this DT.Slave source) {
+      if (source == null) return null;
+      var result = new DA.Slave();
+      source.CopyToEntity(result);
+      return result;
+    }
+    public static void CopyToEntity(this DT.Slave source, DA.Slave target) {
+      if ((source == null) || (target == null)) return;
+      target.ResourceId = source.Id;
+      target.ParentResourceId = source.ParentResourceId;
+      target.Cores = source.Cores;
+      target.CpuSpeed = source.CpuSpeed;
+      target.FreeCores = source.FreeCores;
+      target.FreeMemory = source.FreeMemory;
+      target.IsAllowedToCalculate = source.IsAllowedToCalculate;
+      target.Memory = source.Memory;
+      target.Name = source.Name;
+      target.SlaveState = source.SlaveState.ToEntity();
+      target.CpuArchitecture = source.CpuArchitecture.ToEntity();
+      target.OperatingSystem = source.OperatingSystem;
+      target.LastHeartbeat = source.LastHeartbeat;
+      target.CpuUtilization = source.CpuUtilization;
+      target.HbInterval = source.HbInterval;
+      target.IsDisposable = source.IsDisposable;
+      target.OwnerUserId = source.OwnerUserId;
+    }
+    #endregion
+
     #region State
     public static DT.TaskState ToDto(this DA.TaskState source) {
@@ -206,4 +257,146 @@
     #endregion
 
+    #region Plugin
+    public static DT.Plugin ToDto(this DA.Plugin source) {
+      if (source == null) return null;
+      return new DT.Plugin {
+        Id = source.PluginId,
+        Name = source.Name,
+        Version = new Version(source.Version),
+        UserId = source.UserId,
+        DateCreated = source.DateCreated,
+        Hash = source.Hash
+      };
+    }
+    public static DA.Plugin ToEntity(this DT.Plugin source) {
+      if (source == null) return null;
+      var result = new DA.Plugin();
+      source.CopyToEntity(result);
+      return result;
+    }
+    public static void CopyToEntity(this DT.Plugin source, DA.Plugin target) {
+      if ((source == null) || (target == null)) return;
+      target.PluginId = source.Id;
+      target.Name = source.Name;
+      target.Version = source.Version.ToString();
+      target.UserId = source.UserId;
+      target.DateCreated = source.DateCreated;
+      target.Hash = source.Hash;
+    }
+    #endregion
+
+    #region PluginData
+    public static DT.PluginData ToDto(this DA.PluginData source) {
+      if (source == null) return null;
+      return new DT.PluginData {
+        Id = source.PluginDataId,
+        PluginId = source.PluginId,
+        Data = source.Data.ToArray(),
+        FileName = source.FileName
+      };
+    }
+
+    public static DA.PluginData ToEntity(this DT.PluginData source) {
+      if (source == null) return null;
+      var result = new DA.PluginData();
+      source.CopyToEntity(result);
+      return result;
+    }
+
+    public static void CopyToEntity(this DT.PluginData source, DA.PluginData target) {
+      if ((source == null) || (target == null)) return;
+      target.PluginDataId = source.Id;
+      target.PluginId = source.PluginId;
+      target.Data = source.Data;
+      target.FileName = source.FileName;
+    }
+    #endregion
+
+    #region ResourcePermission
+    public static DT.ResourcePermission ToDto(this DA.ResourcePermission source) {
+      if (source == null) return null;
+      return new DT.ResourcePermission {
+        ResourceId = source.ResourceId,
+        GrantedUserId = source.GrantedUserId,
+        GrantedByUserId = source.GrantedByUserId
+      };
+    }
+    public static DA.ResourcePermission ToEntity(this DT.ResourcePermission source) {
+      if (source == null) return null;
+      var result = new DA.ResourcePermission();
+      source.CopyToEntity(result);
+      return result;
+    }
+    public static void CopyToEntity(this DT.ResourcePermission source, DA.ResourcePermission target) {
+      if ((source == null) || (target == null)) return;
+      target.ResourceId = source.ResourceId;
+      target.GrantedUserId = source.GrantedUserId;
+      target.GrantedByUserId = source.GrantedByUserId;
+    }
+    #endregion
+
+    #region SlaveGroup
+    public static DT.SlaveGroup ToDto(this DA.SlaveGroup source) {
+      if (source == null) return null;
+      return new DT.SlaveGroup {
+        Id = source.ResourceId,
+        Name = source.Name,
+        ParentResourceId = source.ParentResourceId,
+        HbInterval = source.HbInterval,
+        OwnerUserId = source.OwnerUserId
+      };
+    }
+
+    public static DA.SlaveGroup ToEntity(this DT.SlaveGroup source) {
+      if (source == null) return null;
+      var result = new DA.SlaveGroup();
+      source.CopyToEntity(result);
+      return result;
+    }
+
+    public static void CopyToEntity(this DT.SlaveGroup source, DA.SlaveGroup target) {
+      if ((source == null) || (target == null)) return;
+      target.ResourceId = source.Id;
+      target.Name = source.Name;
+      target.ParentResourceId = source.ParentResourceId;
+      target.HbInterval = source.HbInterval;
+      target.OwnerUserId = source.OwnerUserId;
+    }
+    #endregion
+
+    #region Downtimes
+    public static DT.Downtime ToDto(this DA.Downtime source) {
+      if (source == null) return null;
+      return new DT.Downtime {
+        Id = source.DowntimeId,
+        AllDayEvent = source.AllDayEvent,
+        EndDate = source.EndDate,
+        Recurring = source.Recurring,
+        RecurringId = source.RecurringId,
+        ResourceId = source.ResourceId,
+        StartDate = source.StartDate,
+        DowntimeType = source.DowntimeType
+      };
+    }
+    public static DA.Downtime ToEntity(this DT.Downtime source) {
+      if (source == null) return null;
+      var result = new DA.Downtime();
+      source.CopyToEntity(result);
+      return result;
+    }
+    public static void CopyToEntity(this DT.Downtime source, DA.Downtime target) {
+      if ((source == null) || (target == null)) return;
+      target.DowntimeId = source.Id;
+      target.AllDayEvent = source.AllDayEvent;
+      target.EndDate = source.EndDate;
+      target.Recurring = source.Recurring;
+      target.RecurringId = source.RecurringId;
+      target.ResourceId = source.ResourceId;
+      target.StartDate = source.StartDate;
+      target.DowntimeType = source.DowntimeType;
+    }
+    #endregion
+
+
     #region Command
     public static DT.Command? ToDto(this DA.Command? source) {
@@ -252,4 +445,63 @@
     #endregion
 
+    #region CpuArchiteture
+    public static DT.CpuArchitecture ToDto(this DA.CpuArchitecture source) {
+      switch (source) {
+        case DA.CpuArchitecture.x64: return DT.CpuArchitecture.x64;
+        case DA.CpuArchitecture.x86: return DT.CpuArchitecture.x86;
+        default: return DT.CpuArchitecture.x86;
+      }
+    }
+
+    public static DA.CpuArchitecture ToEntity(this DT.CpuArchitecture source) {
+      switch (source) {
+        case DT.CpuArchitecture.x64: return DA.CpuArchitecture.x64;
+        case DT.CpuArchitecture.x86: return DA.CpuArchitecture.x86;
+        default: return DA.CpuArchitecture.x86;
+      }
+    }
+    #endregion
+
+    #region SlaveState
+    public static DT.SlaveState ToDto(this DA.SlaveState source) {
+      switch (source) {
+        case DA.SlaveState.Calculating: return DT.SlaveState.Calculating;
+        case DA.SlaveState.Idle: return DT.SlaveState.Idle;
+        case DA.SlaveState.Offline: return DT.SlaveState.Offline;
+        default: return DT.SlaveState.Offline;
+      }
+    }
+
+    public static DA.SlaveState ToEntity(this DT.SlaveState source) {
+      switch (source) {
+        case DT.SlaveState.Calculating: return DA.SlaveState.Calculating;
+        case DT.SlaveState.Idle: return DA.SlaveState.Idle;
+        case DT.SlaveState.Offline: return DA.SlaveState.Offline;
+        default: return DA.SlaveState.Offline;
+      }
+    }
+    #endregion
+
+    #region UserPriority
+    public static DT.UserPriority ToDto(this DA.UserPriority source) {
+      if (source == null) return null;
+      return new DT.UserPriority() {
+        Id = source.UserId,
+        DateEnqueued = source.DateEnqueued
+      };
+    }
+    public static DA.UserPriority ToEntity(this DT.UserPriority source) {
+      if (source == null) return null;
+      var result = new DA.UserPriority();
+      source.CopyToEntity(result);
+      return result;
+    }
+    public static void CopyToEntity(this DT.UserPriority source, DA.UserPriority target) {
+      if ((source == null) || (target == null)) return;
+      target.UserId = source.Id;
+      target.DateEnqueued = source.DateEnqueued;
+    }
+    #endregion
+
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj	(revision 12691)
@@ -146,4 +146,5 @@
     <Compile Include="HiveStatisticsGenerator.cs" />
     <Compile Include="Interfaces\IStatisticsGenerator.cs" />
+    <Compile Include="Manager\NewHeartbeatManager.cs" />
     <Compile Include="NewHiveService.cs" />
     <Compile Include="OptimizedHiveDao.cs" />
@@ -154,4 +155,6 @@
     <Compile Include="Interfaces\IHiveDao.cs" />
     <Compile Include="Interfaces\ITaskScheduler.cs" />
+    <Compile Include="PerformanceLogger.cs" />
+    <Compile Include="Scheduler\NewRoundRobinTaskScheduler.cs" />
     <Compile Include="Scheduler\TaskInfoForScheduler.cs" />
     <Compile Include="Scheduler\JobInfoForScheduler.cs" />
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 12691)
@@ -68,19 +68,21 @@
     public Guid AddTask(Task task, TaskData taskData, IEnumerable<Guid> resourceIds) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      return trans.UseTransaction(() => {
-        var t = DT.Convert.ToEntity(task);
-        t.RequiredPlugins.AddRange(task.PluginsNeededIds.Select(pluginId => new DA.RequiredPlugin { Task = t, PluginId = pluginId }));
-
-        t.JobData = DT.Convert.ToEntity(taskData);
-        t.JobData.LastUpdate = DateTime.Now;
-
-        optimizedDao.AddTask(t);
-
-        dao.AssignJobToResource(t.TaskId, resourceIds);
-
-        optimizedDao.UpdateTaskState(t.TaskId, DA.TaskState.Waiting, null, userManager.CurrentUserId, null);
-
-        return t.TaskId;
-      }, false, true);
+      using (new PerformanceLogger("Old_AddTask")) {
+        return trans.UseTransaction(() => {
+          var t = DT.Convert.ToEntity(task);
+          t.RequiredPlugins.AddRange(task.PluginsNeededIds.Select(pluginId => new DA.RequiredPlugin { Task = t, PluginId = pluginId }));
+
+          t.JobData = DT.Convert.ToEntity(taskData);
+          t.JobData.LastUpdate = DateTime.Now;
+
+          optimizedDao.AddTask(t);
+
+          dao.AssignJobToResource(t.TaskId, resourceIds);
+
+          optimizedDao.UpdateTaskState(t.TaskId, DA.TaskState.Waiting, null, userManager.CurrentUserId, null);
+
+          return t.TaskId;
+        }, false, true);
+      }
     }
 
@@ -88,5 +90,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       task.ParentTaskId = parentTaskId;
-      return AddTask(task, taskData, optimizedDao.GetAssignedResourceIds(parentTaskId).ToList());
+      List<Guid> list = null;
+      using (new PerformanceLogger("Old_AddChildTask")) {
+        list = optimizedDao.GetAssignedResourceIds(parentTaskId).ToList();
+      }
+      return AddTask(task, taskData, list);
     }
 
@@ -94,7 +100,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       author.AuthorizeForTask(taskId, Permission.Read);
-      return trans.UseTransaction(() => {
-        return DT.Convert.ToDto(optimizedDao.GetTaskById(taskId));
-      }, false, false);
+      using (new PerformanceLogger("Old_GetTask")) {
+        return trans.UseTransaction(() => {
+          return DT.Convert.ToDto(optimizedDao.GetTaskById(taskId));
+        }, false, false);
+      }
     }
 
@@ -134,8 +142,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       author.AuthorizeForJob(jobId, Permission.Read);
-
-      return trans.UseTransaction(() => {
-        return optimizedDao.GetLightweightTasks(jobId).ToArray();
-      }, false, true);
+      using (new PerformanceLogger("Old_GetLightweightJobTasks")) {
+        return trans.UseTransaction(() => {
+          return optimizedDao.GetLightweightTasks(jobId).ToArray();
+        }, false, true);
+      }
     }
 
@@ -143,8 +152,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       author.AuthorizeForJob(jobId, Permission.Read);
-
-      return trans.UseTransaction(() => {
-        return dao.GetLightweightTasksWithoutStateLog(task => task.JobId == jobId).ToArray();
-      }, false, false);
+      using (new PerformanceLogger("Old_GetLightweightJobTasksWithoutStateLog")) {
+        return trans.UseTransaction(() => {
+          return dao.GetLightweightTasksWithoutStateLog(task => task.JobId == jobId).ToArray();
+        }, false, false);
+      }
     }
 
@@ -153,7 +163,9 @@
       author.AuthorizeForTask(taskId, Permission.Read);
 
-      return trans.UseTransaction(() => {
-        return dao.GetTaskData(taskId);
-      });
+      using (new PerformanceLogger("Old_GetTaskData")) {
+        return trans.UseTransaction(() => {
+          return dao.GetTaskData(taskId);
+        });
+      }
     }
 
@@ -162,8 +174,10 @@
       author.AuthorizeForTask(taskDto.Id, Permission.Full);
 
-      trans.UseTransaction(() => {
-        var task = optimizedDao.GetTaskByDto(taskDto);
-        optimizedDao.UpdateTask(task);
-      });
+      using (new PerformanceLogger("Old_UpdateTask")) {
+        trans.UseTransaction(() => {
+          var task = optimizedDao.GetTaskByDto(taskDto);
+          optimizedDao.UpdateTask(task);
+        });
+      }
     }
 
@@ -172,14 +186,16 @@
       author.AuthorizeForTask(task.Id, Permission.Full);
 
-      trans.UseTransaction(() => {
-        var t = optimizedDao.GetTaskByDto(task);
-        optimizedDao.UpdateTask(t);
-      });
-
-      trans.UseTransaction(() => {
-        var data = optimizedDao.GetTaskDataByDto(taskData);
-        data.LastUpdate = DateTime.Now;
-        optimizedDao.UpdateTaskData(data);
-      });
+      using (new PerformanceLogger("Old_UpdateTaskData")) {
+        trans.UseTransaction(() => {
+          var t = optimizedDao.GetTaskByDto(task);
+          optimizedDao.UpdateTask(t);
+        });
+
+        trans.UseTransaction(() => {
+          var data = optimizedDao.GetTaskDataByDto(taskData);
+          data.LastUpdate = DateTime.Now;
+          optimizedDao.UpdateTaskData(data);
+        });
+      }
     }
 
@@ -207,21 +223,22 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       author.AuthorizeForTask(taskId, Permission.Full);
-
-      return trans.UseTransaction(() => {
-        var task = optimizedDao.UpdateTaskState(taskId, DT.Convert.ToEntity(taskState), slaveId, userId, exception);
-
-        if (task.Command.HasValue && task.Command.Value == DA.Command.Pause && task.State == DA.TaskState.Paused) {
-          task.Command = null;
-        } else if (task.Command.HasValue && task.Command.Value == DA.Command.Abort && task.State == DA.TaskState.Aborted) {
-          task.Command = null;
-        } else if (task.Command.HasValue && task.Command.Value == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
-          task.Command = null;
-        } else if (taskState == TaskState.Paused && !task.Command.HasValue) {
-          // slave paused and uploaded the task (no user-command) -> set waiting.
-          task = optimizedDao.UpdateTaskState(taskId, DA.TaskState.Waiting, slaveId, userId, exception);
-        }
-
-        return DT.Convert.ToDto(task);
-      });
+      using (new PerformanceLogger("Old_UpdateTaskState")) {
+        return trans.UseTransaction(() => {
+          var task = optimizedDao.UpdateTaskState(taskId, DT.Convert.ToEntity(taskState), slaveId, userId, exception);
+
+          if (task.Command.HasValue && task.Command.Value == DA.Command.Pause && task.State == DA.TaskState.Paused) {
+            task.Command = null;
+          } else if (task.Command.HasValue && task.Command.Value == DA.Command.Abort && task.State == DA.TaskState.Aborted) {
+            task.Command = null;
+          } else if (task.Command.HasValue && task.Command.Value == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
+            task.Command = null;
+          } else if (taskState == TaskState.Paused && !task.Command.HasValue) {
+            // slave paused and uploaded the task (no user-command) -> set waiting.
+            task = optimizedDao.UpdateTaskState(taskId, DA.TaskState.Waiting, slaveId, userId, exception);
+          }
+
+          return DT.Convert.ToDto(task);
+        });
+      }
     }
 
@@ -281,28 +298,32 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       author.AuthorizeForJob(id, Permission.Read);
-      return trans.UseTransaction(() => {
-        var job = dao.GetJobs(x =>
-              x.JobId == id
-              && (x.OwnerUserId == userManager.CurrentUserId || x.JobPermissions.Count(hep => hep.Permission != DA.Permission.NotAllowed && hep.GrantedUserId == userManager.CurrentUserId) > 0)
-            ).FirstOrDefault();
-        if (job != null) {
-          job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
-          job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
-        }
-        return job;
-      });
+      using (new PerformanceLogger("Old_GetJob")) {
+        return trans.UseTransaction(() => {
+          var job = dao.GetJobs(x =>
+                x.JobId == id
+                && (x.OwnerUserId == userManager.CurrentUserId || x.JobPermissions.Count(hep => hep.Permission != DA.Permission.NotAllowed && hep.GrantedUserId == userManager.CurrentUserId) > 0)
+              ).FirstOrDefault();
+          if (job != null) {
+            job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
+            job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
+          }
+          return job;
+        });
+      }
     }
 
     public IEnumerable<Job> GetJobs() {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      return trans.UseTransaction(() => {
-        var jobs = dao.GetJobs(x => x.OwnerUserId == userManager.CurrentUserId || x.JobPermissions.Count(hep => hep.Permission != DA.Permission.NotAllowed && hep.GrantedUserId == userManager.CurrentUserId) > 0);
-        foreach (var job in jobs) {
-          author.AuthorizeForJob(job.Id, Permission.Read);
-          job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
-          job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
-        }
-        return jobs;
-      });
+      using (new PerformanceLogger("Old_GetJobs")) {
+        return trans.UseTransaction(() => {
+          var jobs = dao.GetJobs(x => x.OwnerUserId == userManager.CurrentUserId || x.JobPermissions.Count(hep => hep.Permission != DA.Permission.NotAllowed && hep.GrantedUserId == userManager.CurrentUserId) > 0);
+          foreach (var job in jobs) {
+            author.AuthorizeForJob(job.Id, Permission.Read);
+            job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
+            job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
+          }
+          return jobs;
+        });
+      }
     }
 
@@ -321,9 +342,11 @@
     public Guid AddJob(Job jobDto) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      return trans.UseTransaction(() => {
-        jobDto.OwnerUserId = userManager.CurrentUserId;
-        jobDto.DateCreated = DateTime.Now;
-        return dao.AddJob(jobDto);
-      });
+      using (new PerformanceLogger("Old_AddJob")) {
+        return trans.UseTransaction(() => {
+          jobDto.OwnerUserId = userManager.CurrentUserId;
+          jobDto.DateCreated = DateTime.Now;
+          return dao.AddJob(jobDto);
+        });
+      }
     }
 
@@ -370,9 +393,12 @@
     public IEnumerable<JobPermission> GetJobPermissions(Guid jobId) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      return trans.UseTransaction(() => {
-        DA.Permission currentUserPermission = dao.GetPermissionForJob(jobId, userManager.CurrentUserId);
-        if (currentUserPermission != DA.Permission.Full) throw new FaultException<FaultReason>(new FaultReason("Not allowed to list permissions for this experiment"));
-        return dao.GetJobPermissions(x => x.JobId == jobId);
-      });
+      using (new PerformanceLogger("GetJobPermissions")) {
+        return trans.UseTransaction(() => {
+          DA.Permission currentUserPermission = dao.GetPermissionForJob(jobId, userManager.CurrentUserId);
+          if (currentUserPermission != DA.Permission.Full)
+            throw new FaultException<FaultReason>(new FaultReason("Not allowed to list permissions for this experiment"));
+          return dao.GetJobPermissions(x => x.JobId == jobId);
+        });
+      }
     }
 
@@ -389,41 +415,45 @@
         slaveInfo.OwnerUserId = userManager.CurrentUserId;
 
-      trans.UseTransaction(() => {
-        var slave = dao.GetSlave(slaveInfo.Id);
-
-        if (slave == null) {
-          dao.AddSlave(slaveInfo);
-        } else {
-          slave.Name = slaveInfo.Name;
-          slave.Description = slaveInfo.Description;
-          slave.OwnerUserId = slaveInfo.OwnerUserId;
-
-          slave.Cores = slaveInfo.Cores;
-          slave.CpuArchitecture = slaveInfo.CpuArchitecture;
-          slave.CpuSpeed = slaveInfo.CpuSpeed;
-          slave.FreeCores = slaveInfo.FreeCores;
-          slave.FreeMemory = slaveInfo.FreeMemory;
-          slave.Memory = slaveInfo.Memory;
-          slave.OperatingSystem = slaveInfo.OperatingSystem;
-
-          slave.LastHeartbeat = DateTime.Now;
-          slave.SlaveState = SlaveState.Idle;
-
-          // don't update those properties: dbSlave.IsAllowedToCalculate, dbSlave.ParentResourceId 
-
-          dao.UpdateSlave(slave);
-        }
-      });
+      using (new PerformanceLogger("Old_Hello")) {
+        trans.UseTransaction(() => {
+          var slave = dao.GetSlave(slaveInfo.Id);
+
+          if (slave == null) {
+            dao.AddSlave(slaveInfo);
+          } else {
+            slave.Name = slaveInfo.Name;
+            slave.Description = slaveInfo.Description;
+            slave.OwnerUserId = slaveInfo.OwnerUserId;
+
+            slave.Cores = slaveInfo.Cores;
+            slave.CpuArchitecture = slaveInfo.CpuArchitecture;
+            slave.CpuSpeed = slaveInfo.CpuSpeed;
+            slave.FreeCores = slaveInfo.FreeCores;
+            slave.FreeMemory = slaveInfo.FreeMemory;
+            slave.Memory = slaveInfo.Memory;
+            slave.OperatingSystem = slaveInfo.OperatingSystem;
+
+            slave.LastHeartbeat = DateTime.Now;
+            slave.SlaveState = SlaveState.Idle;
+
+            // don't update those properties: dbSlave.IsAllowedToCalculate, dbSlave.ParentResourceId 
+
+            dao.UpdateSlave(slave);
+          }
+        });
+      }
     }
 
     public void GoodBye(Guid slaveId) {
       authen.AuthenticateForAnyRole(HiveRoles.Slave);
-      trans.UseTransaction(() => {
-        var slave = dao.GetSlave(slaveId);
-        if (slave != null) {
-          slave.SlaveState = SlaveState.Offline;
-          dao.UpdateSlave(slave);
-        }
-      });
+      using (new PerformanceLogger("Old_GoodBye")) {
+        trans.UseTransaction(() => {
+          var slave = dao.GetSlave(slaveId);
+          if (slave != null) {
+            slave.SlaveState = SlaveState.Offline;
+            dao.UpdateSlave(slave);
+          }
+        });
+      }
     }
     #endregion
@@ -435,10 +465,11 @@
       List<MessageContainer> result = new List<MessageContainer>();
       try {
-        result = heartbeatManager.ProcessHeartbeat(heartbeat);
+        using (new PerformanceLogger("Old_ProcessHeartbeat")) {
+          result = heartbeatManager.ProcessHeartbeat(heartbeat);
+        }
       }
       catch (Exception ex) {
         DA.LogFactory.GetLogger(this.GetType().Namespace).Log("Exception processing Heartbeat: " + ex.ToString());
       }
-
       if (HeuristicLab.Services.Hive.Properties.Settings.Default.TriggerEventManagerInHeartbeat) {
         TriggerEventManager(false);
@@ -489,7 +520,9 @@
     public IEnumerable<Plugin> GetPlugins() {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
-      return trans.UseTransaction(() => {
-        return dao.GetPlugins(x => x.Hash != null);
-      });
+      using (new PerformanceLogger("Old_GetPlugins")) {
+        return trans.UseTransaction(() => {
+          return dao.GetPlugins(x => x.Hash != null);
+        });
+      }
     }
 
@@ -497,10 +530,12 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       var pluginDatas = new List<PluginData>();
-      return trans.UseTransaction(() => {
-        foreach (Guid guid in pluginIds) {
-          pluginDatas.AddRange(dao.GetPluginDatas(x => x.PluginId == guid).ToList());
-        }
-        return pluginDatas;
-      });
+      using (new PerformanceLogger("Old_GetPluginData")) {
+        return trans.UseTransaction(() => {
+          foreach (Guid guid in pluginIds) {
+            pluginDatas.AddRange(dao.GetPluginDatas(x => x.PluginId == guid).ToList());
+          }
+          return pluginDatas;
+        });
+      }
     }
 
@@ -654,12 +689,14 @@
     public Guid GetResourceId(string resourceName) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      return trans.UseTransaction(() => {
-        var resource = dao.GetResources(x => x.Name == resourceName).FirstOrDefault();
-        if (resource != null) {
-          return resource.Id;
-        } else {
-          return Guid.Empty;
-        }
-      });
+      using (new PerformanceLogger("Old_GetResourceId")) {
+        return trans.UseTransaction(() => {
+          var resource = dao.GetResources(x => x.Name == resourceName).FirstOrDefault();
+          if (resource != null) {
+            return resource.Id;
+          } else {
+            return Guid.Empty;
+          }
+        });
+      }
     }
 
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs	(revision 12691)
@@ -20,6 +20,6 @@
 #endregion
 
-using HeuristicLab.Services.Hive.DataAccess;
 using HeuristicLab.Services.Hive.DataAccess.Interfaces;
+using HeuristicLab.Services.Hive.Manager;
 
 namespace HeuristicLab.Services.Hive {
@@ -34,6 +34,8 @@
     ITransactionManager TransactionManager { get; }
     Access.IUserManager UserManager { get; }
+    NewHeartbeatManager NewHeartbeatManager { get; }
     HeartbeatManager HeartbeatManager { get; }
     ITaskScheduler TaskScheduler { get; }
+    ITaskScheduler NewTaskScheduler { get; }
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs	(revision 12691)
@@ -22,5 +22,8 @@
 using System;
 using System.Security;
+using HeuristicLab.Services.Access;
 using HeuristicLab.Services.Hive.DataAccess;
+using HeuristicLab.Services.Hive.DataAccess.Interfaces;
+using DA = HeuristicLab.Services.Hive.DataAccess;
 using DT = HeuristicLab.Services.Hive.DataTransfer;
 
@@ -28,27 +31,75 @@
 namespace HeuristicLab.Services.Hive {
   public class AuthorizationManager : IAuthorizationManager {
+
+    private const string NOT_AUTHORIZED = "Current user is not authorized to access the requested resource";
+    private IPersistenceManager PersistenceManager {
+      get { return ServiceLocator.Instance.PersistenceManager; }
+    }
+
+    private IUserManager UserManager {
+      get { return ServiceLocator.Instance.UserManager; }
+    }
+
+    private IRoleVerifier RoleVerifier {
+      get { return ServiceLocator.Instance.RoleVerifier; }
+    }
+
     public void Authorize(Guid userId) {
       if (userId != ServiceLocator.Instance.UserManager.CurrentUserId)
-        throw new SecurityException("Current user is not authorized to access object");
+        throw new SecurityException(NOT_AUTHORIZED);
     }
 
     public void AuthorizeForTask(Guid taskId, DT.Permission requiredPermission) {
       if (ServiceLocator.Instance.RoleVerifier.IsInRole(HiveRoles.Slave)) return; // slave-users can access all tasks
-
-      Permission permission = ServiceLocator.Instance.HiveDao.GetPermissionForTask(taskId, ServiceLocator.Instance.UserManager.CurrentUserId);
-      if (permission == Permission.NotAllowed || (permission != DT.Convert.ToEntity(requiredPermission) && DT.Convert.ToEntity(requiredPermission) == Permission.Full))
-        throw new SecurityException("Current user is not authorized to access task");
+      using (var pm = PersistenceManager) {
+        var taskDao = pm.TaskDao;
+        pm.UseTransaction(() => {
+          var task = taskDao.GetById(taskId);
+          if (task == null) throw new SecurityException(NOT_AUTHORIZED);
+          AuthorizeJob(pm, task.JobId, requiredPermission);
+        });
+      }
     }
 
     public void AuthorizeForJob(Guid jobId, DT.Permission requiredPermission) {
-      Permission permission = ServiceLocator.Instance.HiveDao.GetPermissionForJob(jobId, ServiceLocator.Instance.UserManager.CurrentUserId);
-      if (permission == Permission.NotAllowed || (permission != DT.Convert.ToEntity(requiredPermission) && DT.Convert.ToEntity(requiredPermission) == Permission.Full))
-        throw new SecurityException("Current user is not authorized to access task");
+      using (var pm = PersistenceManager) {
+        pm.UseTransaction(() => {
+          AuthorizeJob(pm, jobId, requiredPermission);
+        });
+      }
     }
 
     public void AuthorizeForResourceAdministration(Guid resourceId) {
-      Resource resource = DT.Convert.ToEntity(ServiceLocator.Instance.HiveDao.GetResource(resourceId));
-      if (resource.OwnerUserId != ServiceLocator.Instance.UserManager.CurrentUserId && !ServiceLocator.Instance.RoleVerifier.IsInRole(HiveRoles.Administrator))
-        throw new SecurityException("Current user is not authorized to access resource");
+      using (var pm = PersistenceManager) {
+        var resourceDao = pm.ResourceDao;
+        pm.UseTransaction(() => {
+          var resource = resourceDao.GetById(resourceId);
+          if (resource == null) throw new SecurityException(NOT_AUTHORIZED);
+          if (resource.OwnerUserId != UserManager.CurrentUserId
+              && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
+            throw new SecurityException(NOT_AUTHORIZED);
+          }
+        });
+      }
+    }
+
+    private DA.Permission GetPermissionForJob(IPersistenceManager pm, Guid jobId, Guid userId) {
+      var jobDao = pm.JobDao;
+      var jobPermissionDao = pm.JobPermissionDao;
+      var job = jobDao.GetById(jobId);
+      if (job == null) return DA.Permission.NotAllowed;
+      if (job.OwnerUserId == userId) return DA.Permission.Full;
+      var jobPermission = jobPermissionDao.GetByJobAndUserId(jobId, userId);
+      if (jobPermission == null) return DA.Permission.NotAllowed;
+      return jobPermission.Permission;
+    }
+
+    private void AuthorizeJob(IPersistenceManager pm, Guid jobId, DT.Permission requiredPermission) {
+      var requiredPermissionEntity = requiredPermission.ToEntity();
+      DA.Permission permission = GetPermissionForJob(pm, jobId, UserManager.CurrentUserId);
+      if (permission == Permission.NotAllowed
+          || ((permission != requiredPermissionEntity) && requiredPermissionEntity == Permission.Full)) {
+        throw new SecurityException(NOT_AUTHORIZED);
+      }
     }
   }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs	(revision 12691)
@@ -47,6 +47,6 @@
     /// <returns>a list of actions the slave should do</returns>
     public List<MessageContainer> ProcessHeartbeat(Heartbeat heartbeat) {
+
       List<MessageContainer> actions = new List<MessageContainer>();
-
       Slave slave = null;
       trans.UseTransaction(() => {
@@ -62,5 +62,4 @@
           actions.Add(new MessageContainer(MessageContainer.MessageType.ShutdownComputer));
         }
-
         // update slave data
         slave.FreeCores = heartbeat.FreeCores;
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Manager/NewHeartbeatManager.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Manager/NewHeartbeatManager.cs	(revision 12691)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Manager/NewHeartbeatManager.cs	(revision 12691)
@@ -0,0 +1,206 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Linq;
+using System.Threading;
+using HeuristicLab.Services.Hive.DataAccess;
+using HeuristicLab.Services.Hive.DataAccess.Interfaces;
+using HeuristicLab.Services.Hive.DataTransfer;
+using DA = HeuristicLab.Services.Hive.DataAccess;
+
+namespace HeuristicLab.Services.Hive.Manager {
+  public class NewHeartbeatManager {
+    private const string MutexName = "HiveTaskSchedulingMutex";
+
+    private IPersistenceManager PersistenceManager {
+      get { return ServiceLocator.Instance.PersistenceManager; }
+    }
+
+    private ITaskScheduler TaskScheduler {
+      get { return ServiceLocator.Instance.NewTaskScheduler; }
+    }
+
+    /// <summary>
+    /// This method will be called every time a slave sends a heartbeat (-> very often; concurrency is important!)
+    /// </summary>
+    /// <returns>a list of actions the slave should do</returns>
+    public List<MessageContainer> ProcessHeartbeat(Heartbeat heartbeat) {
+      List<MessageContainer> actions = new List<MessageContainer>();
+      using (var pm = PersistenceManager) {
+        var slaveDao = pm.SlaveDao;
+        var taskDao = pm.TaskDao;
+
+        var slave = pm.UseTransaction(() => slaveDao.GetById(heartbeat.SlaveId));
+        if (slave == null) {
+          actions.Add(new MessageContainer(MessageContainer.MessageType.SayHello));
+        } else {
+          if (heartbeat.HbInterval != slave.HbInterval) {
+            actions.Add(new MessageContainer(MessageContainer.MessageType.NewHBInterval));
+          }
+          if (slaveDao.SlaveHasToShutdownComputer(slave.ResourceId)) {
+            actions.Add(new MessageContainer(MessageContainer.MessageType.ShutdownComputer));
+          }
+          // update slave data  
+          slave.FreeCores = heartbeat.FreeCores;
+          slave.FreeMemory = heartbeat.FreeMemory;
+          slave.CpuUtilization = heartbeat.CpuUtilization;
+          slave.SlaveState = (heartbeat.JobProgress != null && heartbeat.JobProgress.Count > 0)
+            ? DA.SlaveState.Calculating
+            : DA.SlaveState.Idle;
+          slave.LastHeartbeat = DateTime.Now;
+          pm.UseTransaction(() => {
+            slave.IsAllowedToCalculate = slaveDao.SlaveIsAllowedToCalculate(slave.ResourceId);
+            pm.SubmitChanges();
+          });
+
+          // update task data
+          actions.AddRange(UpdateTasks(pm, heartbeat, slave.IsAllowedToCalculate));
+
+          // assign new task
+          if (heartbeat.AssignJob && slave.IsAllowedToCalculate && heartbeat.FreeCores > 0) {
+            bool mutexAquired = false;
+            var mutex = new Mutex(false, MutexName);
+            try {
+              mutexAquired = mutex.WaitOne(Properties.Settings.Default.SchedulingPatience);
+              if (mutexAquired) {
+                var waitingTasks = pm.UseTransaction(() => taskDao.GetWaitingTasks(slave)
+                  .Select(x => new TaskInfoForScheduler {
+                    TaskId = x.TaskId,
+                    JobId = x.JobId,
+                    Priority = x.Priority
+                  })
+                  .ToList()
+                );
+                var availableTasks = TaskScheduler.Schedule(waitingTasks);
+                if (availableTasks.Any()) {
+                  var task = availableTasks.First();
+                  AssignTask(pm, slave, task.TaskId);
+                  actions.Add(new MessageContainer(MessageContainer.MessageType.CalculateTask, task.TaskId));
+                }
+              } else {
+                LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling could not be aquired.");
+              }
+            }
+            catch (AbandonedMutexException) {
+              LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling has been abandoned.");
+            }
+            catch (Exception ex) {
+              LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("HeartbeatManager threw an exception in ProcessHeartbeat: {0}", ex));
+            }
+            finally {
+              if (mutexAquired) mutex.ReleaseMutex();
+            }
+          }
+        }
+      }
+      return actions;
+    }
+
+    private void AssignTask(IPersistenceManager pm, DA.Slave slave, Guid taskId) {
+      const DA.TaskState transferring = DA.TaskState.Transferring;
+      DateTime now = DateTime.Now;
+      var taskDao = pm.TaskDao;
+      var stateLogDao = pm.StateLogDao;
+      pm.UseTransaction(() => {
+        var task = taskDao.GetById(taskId);
+        stateLogDao.Save(new DA.StateLog {
+          State = transferring,
+          DateTime = now,
+          TaskId = taskId,
+          SlaveId = slave.ResourceId,
+          UserId = null,
+          Exception = null
+        });
+        task.State = transferring;
+        task.LastHeartbeat = now;
+        pm.SubmitChanges();
+      });
+    }
+
+    /// <summary>
+    /// Update the progress of each task
+    /// Checks if all the task sent by heartbeat are supposed to be calculated by this slave
+    /// </summary>
+    private IEnumerable<MessageContainer> UpdateTasks(IPersistenceManager pm, Heartbeat heartbeat, bool isAllowedToCalculate) {
+      var taskDao = pm.TaskDao;
+      var assignedResourceDao = pm.AssignedResourceDao;
+      var actions = new List<MessageContainer>();
+      if (heartbeat.JobProgress == null)
+        return actions;
+
+      if (!isAllowedToCalculate && heartbeat.JobProgress.Count != 0) {
+        actions.Add(new MessageContainer(MessageContainer.MessageType.PauseAll));
+      } else {
+        // select all tasks and statelogs with one query
+        var taskIds = heartbeat.JobProgress.Select(x => x.Key).ToList();
+        var taskInfos =
+          (from task in taskDao.GetAll()
+           where taskIds.Contains(task.TaskId)
+           let lastStateLog = task.StateLogs.OrderByDescending(x => x.DateTime).FirstOrDefault()
+           select new {
+             TaskId = task.TaskId,
+             Command = task.Command,
+             SlaveId = lastStateLog != null ? lastStateLog.SlaveId : default(Guid)
+           })
+           .ToList();
+
+        // process the jobProgresses
+        foreach (var jobProgress in heartbeat.JobProgress) {
+          var progress = jobProgress;
+          var curTask = taskInfos.SingleOrDefault(x => x.TaskId == progress.Key);
+          if (curTask == null) {
+            actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, progress.Key));
+            LogFactory.GetLogger(this.GetType().Namespace).Log("Task on slave " + heartbeat.SlaveId + " does not exist in DB: " + jobProgress.Key);
+          } else {
+            var slaveId = curTask.SlaveId;
+            if (slaveId == Guid.Empty || slaveId != heartbeat.SlaveId) {
+              // assigned slave does not match heartbeat
+              actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.TaskId));
+              LogFactory.GetLogger(this.GetType().Namespace).Log("The slave " + heartbeat.SlaveId + " is not supposed to calculate task: " + curTask.TaskId);
+            } else if (!assignedResourceDao.TaskIsAllowedToBeCalculatedBySlave(curTask.TaskId, heartbeat.SlaveId)) {
+              // assigned resources ids of task do not match with slaveId (and parent resourceGroupIds); this might happen when slave is moved to different group
+              actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.TaskId));
+            } else {
+              // update task execution time
+              pm.UseTransaction(() => {
+                taskDao.UpdateExecutionTime(curTask.TaskId, progress.Value.TotalMilliseconds);
+              });
+              switch (curTask.Command) {
+                case DA.Command.Stop:
+                  actions.Add(new MessageContainer(MessageContainer.MessageType.StopTask, curTask.TaskId));
+                  break;
+                case DA.Command.Pause:
+                  actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.TaskId));
+                  break;
+                case DA.Command.Abort:
+                  actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.TaskId));
+                  break;
+              }
+            }
+          }
+        }
+      }
+      return actions;
+    }
+  }
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/NewHiveService.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/NewHiveService.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/NewHiveService.cs	(revision 12691)
@@ -1,8 +1,34 @@
-﻿using System;
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Diagnostics;
 using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Security;
+using System.ServiceModel;
 using HeuristicLab.Services.Access;
 using HeuristicLab.Services.Hive.DataAccess.Interfaces;
 using HeuristicLab.Services.Hive.DataTransfer;
+using HeuristicLab.Services.Hive.Manager;
 using HeuristicLab.Services.Hive.ServiceContracts;
 using DA = HeuristicLab.Services.Hive.DataAccess;
@@ -10,4 +36,10 @@
 
 namespace HeuristicLab.Services.Hive {
+  /// <summary>
+  /// Implementation of the Hive service (interface <see cref="IHiveService"/>).
+  /// We need 'IgnoreExtensionDataObject' Attribute for the slave to work. 
+  /// </summary>
+  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IgnoreExtensionDataObject = true)]
+  [HiveOperationContextBehavior]
   public class NewHiveService : IHiveService {
     private static readonly DA.TaskState[] CompletedStates = { DA.TaskState.Finished, DA.TaskState.Aborted, DA.TaskState.Failed };
@@ -28,8 +60,16 @@
       get { return ServiceLocator.Instance.AuthorizationManager; }
     }
-
+    private IEventManager EventManager {
+      get { return ServiceLocator.Instance.EventManager; }
+    }
+    private NewHeartbeatManager HeartbeatManager {
+      get { return ServiceLocator.Instance.NewHeartbeatManager; }
+    }
+
+    #region Task Methods
     public Guid AddTask(DT.Task task, DT.TaskData taskData, IEnumerable<Guid> resourceIds) {
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddTask")) {
         var taskDao = pm.TaskDao;
         var stateLogDao = pm.StateLogDao;
@@ -62,5 +102,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       IEnumerable<Guid> resourceIds;
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddChildTask")) {
         var assignedResourceDao = pm.AssignedResourceDao;
         resourceIds = pm.UseTransaction(() => {
@@ -77,5 +118,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetTask")) {
         var taskDao = pm.TaskDao;
         return pm.UseTransaction(() => {
@@ -104,8 +146,10 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetLightweightJobTasks")) {
         var taskDao = pm.TaskDao;
         return pm.UseTransaction(() => {
           return taskDao.GetByJobId(jobId)
+            .ToList()
             .Select(x => new DT.LightweightTask {
               Id = x.TaskId,
@@ -118,5 +162,6 @@
               Command = x.Command.ToDto(),
               LastTaskDataUpdate = x.JobData.LastUpdate
-            });
+            })
+            .ToList();
         }, false, true);
       }
@@ -126,8 +171,10 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetLightweightJobTasksWithoutStateLog")) {
         var taskDao = pm.TaskDao;
         return pm.UseTransaction(() => {
           return taskDao.GetByJobId(jobId)
+            .ToList()
             .Select(x => new DT.LightweightTask {
               Id = x.TaskId,
@@ -138,5 +185,6 @@
               Command = x.Command.ToDto(),
               LastTaskDataUpdate = x.JobData.LastUpdate
-            });
+            })
+            .ToList();
         }, false, true);
       }
@@ -146,5 +194,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetTaskData")) {
         var taskDataDao = pm.TaskDataDao;
         return pm.UseTransaction(() => taskDataDao.GetById(taskId).ToDto());
@@ -155,5 +204,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateTask")) {
         var taskDao = pm.TaskDao;
         pm.UseTransaction(() => {
@@ -168,5 +218,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateTaskData")) {
         var taskDao = pm.TaskDao;
         var taskDataDao = pm.TaskDataDao;
@@ -195,5 +246,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateTaskState")) {
         var taskDao = pm.TaskDao;
         var stateLogDao = pm.StateLogDao;
@@ -206,30 +258,12 @@
       }
     }
-
-    private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
-      var stateLogDao = pm.StateLogDao;
-      var taskStateEntity = taskState.ToEntity();
-      if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
-          || task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
-          || task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
-        task.Command = null;
-      } else if (taskStateEntity == DA.TaskState.Paused) {
-        taskStateEntity = DA.TaskState.Waiting;
-      }
-      stateLogDao.Save(new DA.StateLog {
-        State = taskStateEntity,
-        DateTime = DateTime.Now,
-        TaskId = task.TaskId,
-        UserId = userId,
-        SlaveId = slaveId,
-        Exception = exception
-      });
-      task.State = taskStateEntity;
-    }
-
+    #endregion
+
+    #region Task Control Methods
     public void StopTask(Guid taskId) {
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("StopTask")) {
         var taskDao = pm.TaskDao;
         pm.UseTransaction(() => {
@@ -250,5 +284,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("PauseTask")) {
         var taskDao = pm.TaskDao;
         pm.UseTransaction(() => {
@@ -256,7 +291,6 @@
           if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
             task.Command = DA.Command.Pause;
-          } else {
-            UpdateTaskState(pm, task, DT.TaskState.Paused, null, null, string.Empty);
-          }
+          }
+          UpdateTaskState(pm, task, DT.TaskState.Paused, null, null, string.Empty);
           pm.SubmitChanges();
         });
@@ -267,5 +301,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("RestartTask")) {
         var taskDao = pm.TaskDao;
         pm.UseTransaction(() => {
@@ -277,13 +312,16 @@
       }
     }
-
-
-    public Job GetJob(Guid id) {
-      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      AuthorizationManager.AuthorizeForJob(id, Permission.Read);
-      using (var pm = PersistenceManager) {
+    #endregion
+
+    #region Job Methods
+    public DT.Job GetJob(Guid id) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(id, DT.Permission.Read);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetJob")) {
         var jobDao = pm.JobDao;
         var jobPermissionDao = pm.JobPermissionDao;
         var taskDao = pm.TaskDao;
+        var currentUserId = UserManager.CurrentUserId;
         return pm.UseTransaction(() => {
           var job = jobDao.GetById(id).ToDto();
@@ -301,7 +339,11 @@
               job.FinishedCount = statistics.FinishedCount;
             }
-            // TODO
-            //job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
             job.OwnerUsername = UserManager.GetUserById(job.OwnerUserId).UserName;
+            if (currentUserId == job.OwnerUserId) {
+              job.Permission = Permission.Full;
+            } else {
+              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
+              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
+            }
           }
           return job;
@@ -310,6 +352,48 @@
     }
 
-    public IEnumerable<Job> GetJobs() {
-      throw new NotImplementedException();
+    public IEnumerable<DT.Job> GetJobs() {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetJobs")) {
+        var jobDao = pm.JobDao;
+        var jobPermissionDao = pm.JobPermissionDao;
+        var taskDao = pm.TaskDao;
+        var currentUserId = UserManager.CurrentUserId;
+        return pm.UseTransaction(() => {
+          var jobs = jobDao.GetAll()
+            .Where(x => x.OwnerUserId == currentUserId
+                     || x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
+                                                 && y.GrantedUserId == currentUserId) > 0)
+            .Select(x => x.ToDto())
+            .ToList();
+          var statistics = taskDao.GetAll()
+              .GroupBy(x => x.JobId)
+              .Select(x => new {
+                x.Key,
+                TotalCount = x.Count(),
+                CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
+                FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
+              })
+              .ToList();
+          foreach (var job in jobs) {
+            // TODO: improve performance of authorization (batch authorization)
+            AuthorizationManager.AuthorizeForJob(job.Id, DT.Permission.Read);
+            var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
+            if (statistic != null) {
+              job.JobCount = statistic.TotalCount;
+              job.CalculatingCount = statistic.CalculatingCount;
+              job.FinishedCount = statistic.FinishedCount;
+            }
+            job.OwnerUsername = UserManager.GetUserById(job.OwnerUserId).UserName;
+            if (currentUserId == job.OwnerUserId) {
+              job.Permission = Permission.Full;
+            } else {
+              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
+              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
+            }
+          }
+          return jobs;
+        });
+      }
     }
 
@@ -320,45 +404,172 @@
 
     public Guid AddJob(Job jobDto) {
-      throw new NotImplementedException();
-    }
-
-    public void UpdateJob(Job jobDto) {
-      throw new NotImplementedException();
-    }
-
-    public void DeleteJob(Guid JobId) {
-      throw new NotImplementedException();
-    }
-
-    public void GrantPermission(Guid jobId, Guid grantedUserId, Permission permission) {
-      throw new NotImplementedException();
-    }
-
-    public void RevokePermission(Guid hiveExperimentId, Guid grantedUserId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddJob")) {
+        var jobDao = pm.JobDao;
+        return pm.UseTransaction(() => {
+          jobDto.OwnerUserId = UserManager.CurrentUserId;
+          jobDto.DateCreated = DateTime.Now;
+          var job = jobDao.Save(jobDto.ToEntity());
+          pm.SubmitChanges();
+          return job.JobId;
+        });
+      }
+    }
+
+    public void UpdateJob(DT.Job jobDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateJob")) {
+        bool exists = true;
+        var jobDao = pm.JobDao;
+        pm.UseTransaction(() => {
+          var job = jobDao.GetById(jobDto.Id);
+          if (job == null) {
+            exists = false;
+            job = new DA.Job();
+          }
+          jobDto.CopyToEntity(job);
+          if (!exists) {
+            jobDao.Save(job);
+          }
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public void DeleteJob(Guid jobId) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("DeleteJob")) {
+        var jobDao = pm.JobDao;
+        pm.UseTransaction(() => {
+          jobDao.Delete(jobId);
+          pm.SubmitChanges();
+        });
+      }
+    }
+    #endregion
+
+    #region JobPermission Methods
+    public void GrantPermission(Guid jobId, Guid grantedUserId, DT.Permission permission) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GrantPermission")) {
+        var jobPermissionDao = pm.JobPermissionDao;
+        var currentUserId = UserManager.CurrentUserId;
+        pm.UseTransaction(() => {
+          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, permission.ToEntity());
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public void RevokePermission(Guid jobId, Guid grantedUserId) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("RevokePermission")) {
+        var jobPermissionDao = pm.JobPermissionDao;
+        var currentUserId = UserManager.CurrentUserId;
+        pm.UseTransaction(() => {
+          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, DA.Permission.NotAllowed);
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public IEnumerable<JobPermission> GetJobPermissions(Guid jobId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetJobPermissions")) {
+        var jobPermissionDao = pm.JobPermissionDao;
+        return pm.UseTransaction(() => jobPermissionDao.GetByJobId(jobId)
+          .Select(x => x.ToDto())
+          .ToList()
+        );
+      }
     }
 
     public bool IsAllowedPrivileged() {
-      throw new NotImplementedException();
-    }
-
-    public void Hello(Slave slave) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      return RoleVerifier.IsInRole(HiveRoles.IsAllowedPrivileged);
+    }
+    #endregion
+
+    #region Login Methods
+    public void Hello(DT.Slave slaveInfo) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
+      if (UserManager.CurrentUser.UserName != "hiveslave") {
+        slaveInfo.OwnerUserId = UserManager.CurrentUserId;
+      }
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("Hello")) {
+        var slaveDao = pm.SlaveDao;
+        pm.UseTransaction(() => {
+          var slave = slaveDao.GetById(slaveInfo.Id);
+          if (slave == null) {
+            slaveDao.Save(slaveInfo.ToEntity());
+          } else {
+            bool oldIsAllowedToCalculate = slave.IsAllowedToCalculate;
+            Guid? oldParentResourceId = slave.ParentResourceId;
+            slaveInfo.CopyToEntity(slave);
+            slave.IsAllowedToCalculate = oldIsAllowedToCalculate;
+            slave.ParentResourceId = oldParentResourceId;
+            slave.LastHeartbeat = DateTime.Now;
+            slave.SlaveState = DA.SlaveState.Idle;
+          }
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public void GoodBye(Guid slaveId) {
-      throw new NotImplementedException();
-    }
-
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GoodBye")) {
+        var slaveDao = pm.SlaveDao;
+        pm.UseTransaction(() => {
+          var slave = slaveDao.GetById(slaveId);
+          if (slave != null) {
+            slave.SlaveState = DA.SlaveState.Offline;
+            pm.SubmitChanges();
+          }
+        });
+      }
+    }
+    #endregion
+
+    #region Heartbeat Methods
     public List<MessageContainer> Heartbeat(Heartbeat heartbeat) {
-      throw new NotImplementedException();
-    }
-
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
+      List<MessageContainer> result = new List<MessageContainer>();
+      try {
+        using (new PerformanceLogger("ProcessHeartbeat")) {
+          result = HeartbeatManager.ProcessHeartbeat(heartbeat);
+        }
+      }
+      catch (Exception ex) {
+        DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
+      }
+      if (HeuristicLab.Services.Hive.Properties.Settings.Default.TriggerEventManagerInHeartbeat) {
+        TriggerEventManager(false);
+      }
+      return result;
+    }
+    #endregion
+
+    #region Plugin Methods
     public Plugin GetPlugin(Guid pluginId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetPlugin")) {
+        var pluginDao = pm.PluginDao;
+        return pm.UseTransaction(() => pluginDao.GetById(pluginId).ToDto());
+      }
     }
 
@@ -369,13 +580,51 @@
 
     public Guid AddPlugin(Plugin plugin, List<PluginData> pluginData) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddPlugin")) {
+        var pluginDao = pm.PluginDao;
+        plugin.UserId = UserManager.CurrentUserId;
+        plugin.DateCreated = DateTime.Now;
+        return pm.UseTransaction(() => {
+          var pluginEntity = pluginDao.GetByHash(plugin.Hash).SingleOrDefault();
+          if (pluginEntity != null) {
+            throw new FaultException<PluginAlreadyExistsFault>(new PluginAlreadyExistsFault(pluginEntity.PluginId));
+          }
+          pluginEntity = plugin.ToEntity();
+          foreach (var data in pluginData) {
+            data.PluginId = default(Guid);
+            pluginEntity.PluginData.Add(data.ToEntity());
+          }
+          pluginDao.Save(pluginEntity);
+          pm.SubmitChanges();
+          return pluginEntity.PluginId;
+        });
+      }
     }
 
     public IEnumerable<Plugin> GetPlugins() {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetPlugins")) {
+        var pluginDao = pm.PluginDao;
+        return pm.UseTransaction(() => pluginDao.GetAll()
+          .Where(x => x.Hash != null)
+          .Select(x => x.ToDto())
+          .ToList()
+        );
+      }
     }
 
     public IEnumerable<PluginData> GetPluginDatas(List<Guid> pluginIds) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetPluginDatas")) {
+        var pluginDataDao = pm.PluginDataDao;
+        return pm.UseTransaction(() => pluginDataDao.GetAll()
+            .Where(x => pluginIds.Contains(x.PluginId))
+            .Select(x => x.ToDto())
+            .ToList()
+        );
+      }
     }
 
@@ -384,32 +633,96 @@
       throw new NotImplementedException();
     }
-
+    #endregion
+
+    #region ResourcePermission Methods
     public void GrantResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GrantResourcePermissions")) {
+        pm.UseTransaction(() => {
+          var resource = AuthorizeForResource(pm, resourceId);
+          var resourcePermissions = resource.ResourcePermissions.ToList();
+          foreach (var id in grantedUserIds) {
+            if (resourcePermissions.All(x => x.GrantedUserId != id)) {
+              resource.ResourcePermissions.Add(new DA.ResourcePermission {
+                GrantedUserId = id,
+                GrantedByUserId = UserManager.CurrentUserId
+              });
+            }
+          }
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public void RevokeResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("RevokeResourcePermissions")) {
+        var resourcePermissionDao = pm.ResourcePermissionDao;
+        pm.UseTransaction(() => {
+          AuthorizeForResource(pm, resourceId);
+          resourcePermissionDao.DeleteByResourceAndGrantedUserId(resourceId, grantedUserIds);
+        });
+      }
     }
 
     public IEnumerable<ResourcePermission> GetResourcePermissions(Guid resourceId) {
-      throw new NotImplementedException();
-    }
-
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetResourcePermissions")) {
+        var resourcePermissionDao = pm.ResourcePermissionDao;
+        return pm.UseTransaction(() => resourcePermissionDao.GetByResourceId(resourceId)
+          .Select(x => x.ToDto())
+          .ToList()
+        );
+      }
+    }
+    #endregion
+
+    #region Resource Methods
     public IEnumerable<Resource> GetChildResources(Guid resourceId) {
       // unused
       throw new NotImplementedException();
     }
-
-    public Guid AddSlave(Slave slave) {
-      throw new NotImplementedException();
-    }
-
-    public Guid AddSlaveGroup(SlaveGroup slaveGroup) {
-      throw new NotImplementedException();
+    #endregion
+
+    #region Slave Methods
+    public Guid AddSlave(DT.Slave slaveDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddSlave")) {
+        var slaveDao = pm.SlaveDao;
+        return pm.UseTransaction(() => {
+          var slave = slaveDao.Save(slaveDto.ToEntity());
+          pm.SubmitChanges();
+          return slave.ResourceId;
+        });
+      }
+    }
+
+    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddSlaveGroup")) {
+        var slaveGroupDao = pm.SlaveGroupDao;
+        return pm.UseTransaction(() => {
+          if (slaveGroupDto.Id == Guid.Empty) {
+            slaveGroupDto.Id = Guid.NewGuid();
+          }
+          var slaveGroup = slaveGroupDao.Save(slaveGroupDto.ToEntity());
+          pm.SubmitChanges();
+          return slaveGroup.ResourceId;
+        });
+      }
     }
 
     public Slave GetSlave(Guid slaveId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetSlave")) {
+        var slaveDao = pm.SlaveDao;
+        return pm.UseTransaction(() => slaveDao.GetById(slaveId).ToDto());
+      }
     }
 
@@ -420,37 +733,147 @@
 
     public IEnumerable<Slave> GetSlaves() {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetSlaves")) {
+        var slaveDao = pm.SlaveDao;
+        var resourcePermissionDao = pm.ResourcePermissionDao;
+        var currentUserId = UserManager.CurrentUserId;
+        return pm.UseTransaction(() => {
+          var resourcePermissions = resourcePermissionDao.GetAll();
+          return slaveDao.GetAll()
+            .Where(x => isAdministrator
+              || x.OwnerUserId == null
+              || x.OwnerUserId == currentUserId
+              || UserManager.VerifyUser(currentUserId, resourcePermissions
+                  .Where(y => y.ResourceId == x.ResourceId)
+                  .Select(z => z.GrantedUserId)
+                  .ToList())
+              )
+            .Select(x => x.ToDto())
+            .ToList();
+        });
+      }
     }
 
     public IEnumerable<SlaveGroup> GetSlaveGroups() {
-      throw new NotImplementedException();
-    }
-
-    public void UpdateSlave(Slave slave) {
-      throw new NotImplementedException();
-    }
-
-    public void UpdateSlaveGroup(SlaveGroup slaveGroup) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetSlaveGroups")) {
+        var slaveGroupDao = pm.SlaveGroupDao;
+        var resourcePermissionDao = pm.ResourcePermissionDao;
+        var currentUserId = UserManager.CurrentUserId;
+        return pm.UseTransaction(() => {
+          var resourcePermissions = resourcePermissionDao.GetAll();
+          return slaveGroupDao.GetAll()
+            .Where(x => isAdministrator
+              || x.OwnerUserId == null
+              || x.OwnerUserId == currentUserId
+              || UserManager.VerifyUser(currentUserId, resourcePermissions
+                  .Where(y => y.ResourceId == x.ResourceId)
+                  .Select(z => z.GrantedUserId)
+                  .ToList())
+              )
+            .Select(x => x.ToDto())
+            .ToList();
+        });
+      }
+    }
+
+    public void UpdateSlave(DT.Slave slaveDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateSlave")) {
+        var slaveDao = pm.SlaveDao;
+        pm.UseTransaction(() => {
+          var slave = slaveDao.GetById(slaveDto.Id);
+          if (slave != null) {
+            slaveDto.CopyToEntity(slave);
+          } else {
+            slaveDao.Save(slaveDto.ToEntity());
+          }
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateSlaveGroup")) {
+        var slaveGroupDao = pm.SlaveGroupDao;
+        pm.UseTransaction(() => {
+          var slaveGroup = slaveGroupDao.GetById(slaveGroupDto.Id);
+          if (slaveGroup != null) {
+            slaveGroupDto.CopyToEntity(slaveGroup);
+          } else {
+            slaveGroupDao.Save(slaveGroupDto.ToEntity());
+          }
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public void DeleteSlave(Guid slaveId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("DeleteSlave")) {
+        var slaveDao = pm.SlaveDao;
+        pm.UseTransaction(() => {
+          slaveDao.Delete(slaveId);
+        });
+      }
     }
 
     public void DeleteSlaveGroup(Guid slaveGroupId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("DeleteSlaveGroup")) {
+        var slaveGroupDao = pm.SlaveGroupDao;
+        pm.UseTransaction(() => {
+          slaveGroupDao.Delete(slaveGroupId);
+        });
+      }
     }
 
     public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddResourceToGroup")) {
+        var resourceDao = pm.ResourceDao;
+        pm.UseTransaction(() => {
+          var resource = resourceDao.GetById(resourceId);
+          resource.ParentResourceId = slaveGroupId;
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("RemoveResourceFromGroup")) {
+        var resourceDao = pm.ResourceDao;
+        pm.UseTransaction(() => {
+          var resource = resourceDao.GetById(resourceId);
+          resource.ParentResourceId = null;
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public Guid GetResourceId(string resourceName) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetResourceId")) {
+        var resourceDao = pm.ResourceDao;
+        return pm.UseTransaction(() => {
+          var resource = resourceDao.GetByName(resourceName);
+          return resource != null ? resource.ResourceId : Guid.Empty;
+        });
+      }
     }
 
@@ -461,40 +884,128 @@
 
     public void TriggerEventManager(bool force) {
-      // private method...
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Slave);
+      // use a serializable transaction here to ensure not two threads execute this simultaniously (mutex-lock would not work since IIS may use multiple AppDomains)
+      bool cleanup;
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("TriggerEventManager")) {
+        cleanup = false;
+        var lifecycleDao = pm.LifecycleDao;
+        pm.UseTransaction(() => {
+          var lastLifecycle = lifecycleDao.GetLastLifecycle();
+          DateTime lastCleanup = lastLifecycle != null ? lastLifecycle.LastCleanup : DateTime.MinValue;
+          if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
+            lifecycleDao.UpdateLifecycle();
+            cleanup = true;
+            pm.SubmitChanges();
+          }
+        }, true);
+      }
+      if (cleanup) {
+        EventManager.Cleanup();
+      }
     }
 
     public int GetNewHeartbeatInterval(Guid slaveId) {
-      throw new NotImplementedException();
-    }
-
-    public Guid AddDowntime(Downtime downtime) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetNewHeartbeatInterval")) {
+        var slaveDao = pm.SlaveDao;
+        return pm.UseTransaction(() => {
+          var slave = slaveDao.GetById(slaveId);
+          if (slave != null) {
+            return slave.HbInterval;
+          }
+          return -1;
+        });
+      }
+    }
+    #endregion
+
+    #region Downtime Methods
+    public Guid AddDowntime(DT.Downtime downtimeDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddDowntime")) {
+        var downtimeDao = pm.DowntimeDao;
+        return pm.UseTransaction(() => {
+          var downtime = downtimeDao.Save(downtimeDto.ToEntity());
+          pm.SubmitChanges();
+          return downtime.ResourceId;
+        });
+      }
     }
 
     public void DeleteDowntime(Guid downtimeId) {
-      throw new NotImplementedException();
-    }
-
-    public void UpdateDowntime(Downtime downtime) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("DeleteDowntime")) {
+        var downtimeDao = pm.DowntimeDao;
+        pm.UseTransaction(() => {
+          downtimeDao.Delete(downtimeId);
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public void UpdateDowntime(DT.Downtime downtimeDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateDowntime")) {
+        var downtimeDao = pm.DowntimeDao;
+        pm.UseTransaction(() => {
+          var downtime = downtimeDao.GetById(downtimeDto.Id);
+          if (downtime != null) {
+            downtimeDto.CopyToEntity(downtime);
+          } else {
+            downtimeDao.Save(downtimeDto.ToEntity());
+          }
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public IEnumerable<Downtime> GetDowntimesForResource(Guid resourceId) {
-      throw new NotImplementedException();
-    }
-
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetDowntimesForResource")) {
+        var downtimeDao = pm.DowntimeDao;
+        return pm.UseTransaction(() => downtimeDao.GetByResourceId(resourceId)
+          .Select(x => x.ToDto())
+          .ToList()
+        );
+      }
+    }
+    #endregion
+
+    #region User Methods
     public string GetUsernameByUserId(Guid userId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      var user = UserManager.GetUserById(userId);
+      return user != null ? user.UserName : null;
     }
 
     public Guid GetUserIdByUsername(string username) {
-      throw new NotImplementedException();
-    }
-
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
+      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
+    }
+    #endregion
+
+    #region UserPriorities Methods
     public IEnumerable<UserPriority> GetUserPriorities() {
-      throw new NotImplementedException();
-    }
-
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetUserPriorities")) {
+        var userPriorityDao = pm.UserPriorityDao;
+        return pm.UseTransaction(() => userPriorityDao.GetAll()
+          .Select(x => x.ToDto())
+          .ToList()
+        );
+      }
+    }
+    #endregion
+
+    #region Statistics Methods
     public IEnumerable<Statistics> GetStatistics() {
       // unused
@@ -506,4 +1017,46 @@
       throw new NotImplementedException();
     }
+    #endregion
+
+    #region Private Helper Methods
+    private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
+      var stateLogDao = pm.StateLogDao;
+      var taskStateEntity = taskState.ToEntity();
+      if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
+          || task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
+          || task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
+        task.Command = null;
+      } else if (taskStateEntity == DA.TaskState.Paused && task.Command != null) {
+        taskStateEntity = DA.TaskState.Waiting;
+      }
+      stateLogDao.Save(new DA.StateLog {
+        State = taskStateEntity,
+        DateTime = DateTime.Now,
+        TaskId = task.TaskId,
+        UserId = userId,
+        SlaveId = slaveId,
+        Exception = exception
+      });
+      task.State = taskStateEntity;
+    }
+
+    private DA.Resource AuthorizeForResource(IPersistenceManager pm, Guid resourceId) {
+      var resourceDao = pm.ResourceDao;
+      var resource = resourceDao.GetById(resourceId);
+      if (resource == null) throw new SecurityException("Not authorized");
+      if (resource.OwnerUserId != UserManager.CurrentUserId
+          && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
+        throw new SecurityException("Not authorized");
+      }
+      return resource;
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    public string GetCurrentMethod() {
+      StackTrace st = new StackTrace();
+      StackFrame sf = st.GetFrame(1);
+      return sf.GetMethod().Name;
+    }
+    #endregion
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/PerformanceLogger.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/PerformanceLogger.cs	(revision 12691)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/PerformanceLogger.cs	(revision 12691)
@@ -0,0 +1,42 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Diagnostics;
+using HeuristicLab.Services.Hive.DataAccess;
+
+namespace HeuristicLab.Services.Hive {
+  public class PerformanceLogger : IDisposable {
+
+    private readonly Stopwatch stopwatch;
+    private string name;
+
+    public PerformanceLogger(string name) {
+      this.name = name;
+      stopwatch = new Stopwatch();
+      stopwatch.Start();
+    }
+    public void Dispose() {
+      stopwatch.Stop();
+      LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("{0} took {1}ms", name, stopwatch.ElapsedMilliseconds));
+    }
+  }
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Scheduler/NewRoundRobinTaskScheduler.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Scheduler/NewRoundRobinTaskScheduler.cs	(revision 12691)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/Scheduler/NewRoundRobinTaskScheduler.cs	(revision 12691)
@@ -0,0 +1,105 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 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.Linq;
+using HeuristicLab.Services.Hive.DataAccess.Interfaces;
+using DA = HeuristicLab.Services.Hive.DataAccess;
+
+namespace HeuristicLab.Services.Hive {
+  public class NewRoundRobinTaskScheduler : ITaskScheduler {
+    private IPersistenceManager PersistenceManager {
+      get { return ServiceLocator.Instance.PersistenceManager; }
+    }
+
+    public IEnumerable<TaskInfoForScheduler> Schedule(IEnumerable<TaskInfoForScheduler> tasks, int count = 1) {
+      if (!tasks.Any()) return Enumerable.Empty<TaskInfoForScheduler>();
+
+      using (var pm = PersistenceManager) {
+        var userPriorityDao = pm.UserPriorityDao;
+        var jobDao = pm.JobDao;
+
+        var userPriorities = pm.UseTransaction(() => userPriorityDao.GetAll()
+          .OrderBy(x => x.DateEnqueued)
+          .ToArray()
+        );
+
+        var userIds = userPriorities.Select(x => x.UserId).ToList();
+        var jobs = pm.UseTransaction(() => {
+          return jobDao.GetAll()
+            .Where(x => userIds.Contains(x.OwnerUserId))
+            .Select(x => new {
+              Id = x.JobId,
+              DateCreated = x.DateCreated,
+              OwnerUserId = x.OwnerUserId
+            })
+            .ToList();
+        });
+
+        var taskJobRelations = tasks.Join(jobs,
+          task => task.JobId,
+          job => job.Id,
+          (task, job) => new { Task = task, JobInfo = job })
+          .OrderByDescending(x => x.Task.Priority)
+          .ToList();
+
+        var scheduledTasks = new List<TaskInfoForScheduler>();
+        int priorityIndex = 0;
+
+        if (count == 0 || count > taskJobRelations.Count) count = taskJobRelations.Count;
+
+        for (int i = 0; i < count; i++) {
+          var defaultEntry = taskJobRelations.First(); // search first task which is not included yet
+          var priorityEntries = taskJobRelations.Where(x => x.JobInfo.OwnerUserId == userPriorities[priorityIndex].UserId).ToArray(); // search for tasks with desired user priority
+          while (!priorityEntries.Any() && priorityIndex < userPriorities.Length - 1) {
+            priorityIndex++;
+            priorityEntries = taskJobRelations.Where(x => x.JobInfo.OwnerUserId == userPriorities[priorityIndex].UserId).ToArray();
+          }
+          if (priorityEntries.Any()) { // tasks with desired user priority found
+            var priorityEntry = priorityEntries.OrderByDescending(x => x.Task.Priority).ThenBy(x => x.JobInfo.DateCreated).First();
+            if (defaultEntry.Task.Priority <= priorityEntry.Task.Priority) {
+              taskJobRelations.Remove(priorityEntry);
+              scheduledTasks.Add(priorityEntry.Task);
+              UpdateUserPriority(pm, userPriorities[priorityIndex]);
+              priorityIndex++;
+            } else { // there are other tasks with higher priorities
+              taskJobRelations.Remove(defaultEntry);
+              scheduledTasks.Add(defaultEntry.Task);
+            }
+          } else {
+            taskJobRelations.Remove(defaultEntry);
+            scheduledTasks.Add(defaultEntry.Task);
+          }
+          if (priorityIndex >= (userPriorities.Length - 1)) priorityIndex = 0;
+        }
+        return scheduledTasks;
+      }
+    }
+
+    private void UpdateUserPriority(IPersistenceManager pm, DA.UserPriority up) {
+      pm.UseTransaction(() => {
+        up.DateEnqueued = DateTime.Now;
+        pm.SubmitChanges();
+      });
+    }
+  }
+}
Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs	(revision 12691)
@@ -23,4 +23,5 @@
 using HeuristicLab.Services.Hive.DataAccess.Interfaces;
 using HeuristicLab.Services.Hive.DataAccess.Manager;
+using HeuristicLab.Services.Hive.Manager;
 
 namespace HeuristicLab.Services.Hive {
@@ -37,5 +38,10 @@
 
     public IPersistenceManager PersistenceManager {
-      get { return new PersistenceManager(); }
+      get {
+        var dataContext = HiveOperationContext.Current != null
+                            ? HiveOperationContext.Current.DataContext
+                            : new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString);
+        return new PersistenceManager(dataContext);
+      }
     }
 
@@ -102,4 +108,12 @@
     }
 
+    private NewHeartbeatManager newheartbeatManager;
+    public NewHeartbeatManager NewHeartbeatManager {
+      get {
+        if (newheartbeatManager == null) newheartbeatManager = new NewHeartbeatManager();
+        return newheartbeatManager;
+      }
+    }
+
     private HeartbeatManager heartbeatManager;
     public HeartbeatManager HeartbeatManager {
@@ -117,4 +131,11 @@
       }
     }
+    private ITaskScheduler newtaskScheduler;
+    public ITaskScheduler NewTaskScheduler {
+      get {
+        if (newtaskScheduler == null) newtaskScheduler = new RoundRobinTaskScheduler();
+        return newtaskScheduler;
+      }
+    }
   }
 }
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApi/DataController.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApi/DataController.cs	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApi/DataController.cs	(revision 12691)
@@ -85,9 +85,9 @@
           }).FirstOrDefault();
         var calculatingTasks = factTasks.Where(x => x.TaskState == TaskState.Calculating);
-        int count = calculatingTasks.Count();
+        int count = calculatingTasks.Count() / 3;
         return new DT.TimeStatus {
           MinCalculatingTime = lastCalculatingTimes != null ? lastCalculatingTimes.Min : 0,
           MaxCalculatingTime = lastCalculatingTimes != null ? lastCalculatingTimes.Max : 0,
-          AvgWaitingTime = count > 0 ? (long)calculatingTasks.OrderBy(x => x.StartTime).Take(count / 3).Average(x => x.InitialWaitingTime) : 0,
+          AvgWaitingTime = count > 0 ? (long)calculatingTasks.OrderBy(x => x.StartTime).Take(count).Average(x => x.InitialWaitingTime) : 0,
           AvgCalculatingTime = lastCalculatingTimes != null ? lastCalculatingTimes.Avg : 0,
           TotalCpuTime = factTasks.Sum(x => x.CalculatingTime),
Index: branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApp/history/history.cshtml
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApp/history/history.cshtml	(revision 12689)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.WebApp.Status/3.3/WebApp/history/history.cshtml	(revision 12691)
@@ -33,5 +33,6 @@
             <div class="btn-group" dropdown dropdown-append-to-body>
                 <button type="button" class="btn btn-default dropdown-toggle" dropdown-toggle style="width: 130px; text-align: left;">
-                    {{curQuickSelection.name}} <span class="glyphicon glyphicon-chevron-down" style="margin-top: 3px; float:right"></span>
+                    <span class="text-left" style="display: inline-block; width: 85px;">{{curQuickSelection.name}}</span>
+                    <span class="glyphicon glyphicon-chevron-down" style="margin-top: 3px;"></span>
                 </button>
                 <ul class="dropdown-menu" role="menu">
