Index: /branches/HivePerformance/sources/HeuristicLab 3.3 Services.sln
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab 3.3 Services.sln	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab 3.3 Services.sln	(revision 9434)
@@ -1,5 +1,5 @@
 ﻿
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{96396439-A764-4022-A8D2-BE021449B8D1}"
 	ProjectSection(SolutionItems) = preProject
@@ -24,5 +24,5 @@
 	ProjectSection(WebsiteProperties) = preProject
 		TargetFrameworkMoniker = ".NETFramework,Version%3Dv4.0"
-		ProjectReferences = "{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}|HeuristicLab.Services.Hive-3.3.dll;{EC2C8109-6E1E-4C88-9A2B-908CFF2EF4AC}|HeuristicLab.Services.Hive.DataAccess-3.3.dll;"
+		ProjectReferences = "{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}|HeuristicLab.Services.Hive-3.3.dll;{EC2C8109-6E1E-4C88-9A2B-908CFF2EF4AC}|HeuristicLab.Services.Hive.DataAccess-3.3.dll;{9FAC0B23-2730-452A-9BA0-D7CA1746C541}|HeuristicLab.Services.Access.dll;{BE9B0229-9150-49A4-AEA6-BB58E055992F}|HeuristicLab.GeoIP.dll;{0F652437-998A-4EAB-8BF1-444B5FE8CE97}|HeuristicLab.Services.Access.DataAccess.dll;"
 		Debug.AspNetCompiler.VirtualPath = "/Hive-3.3"
 		Debug.AspNetCompiler.PhysicalPath = "HeuristicLab.Services.Hive.Web\Hive-3.3\"
@@ -57,4 +57,6 @@
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Services.OKB-3.3", "HeuristicLab.Services.OKB\3.3\HeuristicLab.Services.OKB-3.3.csproj", "{766DA4B7-2A0E-4CDE-8F90-93D8B1AD62CF}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HeuristicLab.Services.Hive.SelfHost-3.3", "HeuristicLab.Services.Hive.SelfHost\3.3\HeuristicLab.Services.Hive.SelfHost-3.3.csproj", "{DAACE3EB-5D88-419D-9EEC-5707E273491A}"
 EndProject
 Global
@@ -222,4 +224,12 @@
 		{766DA4B7-2A0E-4CDE-8F90-93D8B1AD62CF}.Release|x86.ActiveCfg = Release|x86
 		{766DA4B7-2A0E-4CDE-8F90-93D8B1AD62CF}.Release|x86.Build.0 = Release|x86
+		{DAACE3EB-5D88-419D-9EEC-5707E273491A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{DAACE3EB-5D88-419D-9EEC-5707E273491A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{DAACE3EB-5D88-419D-9EEC-5707E273491A}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{DAACE3EB-5D88-419D-9EEC-5707E273491A}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{DAACE3EB-5D88-419D-9EEC-5707E273491A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{DAACE3EB-5D88-419D-9EEC-5707E273491A}.Release|Any CPU.Build.0 = Release|Any CPU
+		{DAACE3EB-5D88-419D-9EEC-5707E273491A}.Release|x64.ActiveCfg = Release|Any CPU
+		{DAACE3EB-5D88-419D-9EEC-5707E273491A}.Release|x86.ActiveCfg = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/App.config
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/App.config	(revision 9434)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/App.config	(revision 9434)
@@ -0,0 +1,104 @@
+﻿<?xml version="1.0"?>
+<configuration>
+  <configSections>
+    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+      <section name="HeuristicLab.Services.Hive.DataAccess.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+    </sectionGroup>
+  </configSections>
+
+  <appSettings>
+    <add key="ChartImageHandler" value="storage=file;timeout=20;dir=c:\TempImageFiles\;" />
+  </appSettings>
+  <applicationSettings>
+    <HeuristicLab.Services.Hive.DataAccess.Settings>
+      <setting name="LongRunningDatabaseCommandTimeout" serializeAs="String">
+        <value>00:05:00</value>
+      </setting>
+      <setting name="EventLogName" serializeAs="String">
+        <value>HL.Hive</value>
+      </setting>
+    </HeuristicLab.Services.Hive.DataAccess.Settings>
+  </applicationSettings>
+  <connectionStrings>
+    <add name="HeuristicLab.Authentication" connectionString="data source=localhost;Integrated Security=SSPI;Initial Catalog=HeuristicLab.Authentication"/>
+    <add name="HeuristicLab.Services.Hive.DataAccess.Settings.HeuristicLab_Hive_LinqConnectionString"
+       connectionString="Data Source=localhost;Initial Catalog=HeuristicLab.Hive-3.3;Integrated Security=True;"
+       providerName="System.Data.SqlClient" />
+  </connectionStrings>
+  <system.web>
+    <authentication mode="Forms" />
+    <compilation debug="true" targetFramework="4.0">
+      <assemblies>
+        <add assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
+      </assemblies>
+    </compilation>
+    <membership>
+      <providers>
+        <clear/>
+        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="HeuristicLab.Authentication" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="HeuristicLab.Authentication"/>
+      </providers>
+    </membership>
+    <roleManager enabled="true">
+      <providers>
+        <clear/>
+        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="HeuristicLab.Authentication" applicationName="HeuristicLab.Authentication"/>
+      </providers>
+    </roleManager>
+    <pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID">
+      <controls>
+        <add tagPrefix="asp" namespace="System.Web.UI.DataVisualization.Charting"
+         assembly="System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
+      </controls>
+    </pages>
+    <httpRuntime maxRequestLength="1048576"/>
+  </system.web>
+  <system.serviceModel>
+    <diagnostics performanceCounters="All">
+      <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="3000"/>
+    </diagnostics>
+    <bindings>
+      <wsHttpBinding>
+        <binding name="WSHttpBinding_IHiveService" messageEncoding="Mtom" receiveTimeout="00:15:00" sendTimeout="00:10:00" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647">
+          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
+          <security mode="Message">
+            <transport clientCredentialType="Certificate"/>
+            <message clientCredentialType="UserName"/>
+          </security>
+        </binding>
+      </wsHttpBinding>
+    </bindings>
+    <behaviors>
+      <serviceBehaviors>
+        <behavior name="ServiceBehaviour_IHiveService">
+          <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
+          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false"/>
+          <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
+          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true"/>
+          <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="AspNetSqlRoleProvider"/>
+          <serviceCredentials>
+            <serviceCertificate findValue="localhost" x509FindType="FindBySubjectName"/>
+            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="AspNetSqlMembershipProvider"/>
+          </serviceCredentials>
+          <serviceSecurityAudit auditLogLocation="Application" suppressAuditFailure="false" messageAuthenticationAuditLevel="SuccessOrFailure"/>
+          <serviceThrottling maxConcurrentCalls="100"/>
+          <dataContractSerializer maxItemsInObjectGraph="2147483647"/>
+        </behavior>
+      </serviceBehaviors>
+    </behaviors>
+    <services>
+      <service behaviorConfiguration="ServiceBehaviour_IHiveService" name="HeuristicLab.Services.Hive.HiveService">
+        <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" name="MexEndpoint" contract="IMetadataExchange"/>
+        <endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IHiveService" name="WSHttpBinding_IHiveService" contract="HeuristicLab.Services.Hive.ServiceContracts.IHiveService"/>
+      </service>
+    </services>
+    <serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
+  </system.serviceModel>
+  <system.webServer>
+    <directoryBrowse enabled="true" />
+    <handlers>
+      <remove name="ChartImageHandler" />
+      <add name="ChartImageHandler" preCondition="integratedMode" verb="GET,HEAD,POST"
+       path="ChartImg.axd" type="System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
+    </handlers>
+  </system.webServer>
+</configuration>
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/HeuristicLab.Services.Hive.SelfHost-3.3.csproj
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/HeuristicLab.Services.Hive.SelfHost-3.3.csproj	(revision 9434)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/HeuristicLab.Services.Hive.SelfHost-3.3.csproj	(revision 9434)
@@ -0,0 +1,104 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{DAACE3EB-5D88-419D-9EEC-5707E273491A}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Services.Hive.SelfHost</RootNamespace>
+    <AssemblyName>HeuristicLab.Services.Hive.SelfHost-3.3</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <PublishUrl>publish\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.ServiceModel" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Program.cs" />
+    <None Include="App.config" />
+    <None Include="Properties\AssemblyInfo.cs.frame" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Services.Hive\3.3\HeuristicLab.Services.Hive-3.3.csproj">
+      <Project>{cf9da321-ac1b-4fd3-9ec3-67bc6b861bde}</Project>
+      <Name>HeuristicLab.Services.Hive-3.3</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include=".NETFramework,Version=v4.0">
+      <Visible>False</Visible>
+      <ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Windows.Installer.4.5">
+      <Visible>False</Visible>
+      <ProductName>Windows Installer 4.5</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>set Path=%25Path%25;$(ProjectDir);$(SolutionDir)
+set ProjectDir=$(ProjectDir)
+set SolutionDir=$(SolutionDir)
+set Outdir=$(Outdir)
+
+call PreBuildEvent.cmd</PreBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/Program.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/Program.cs	(revision 9434)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/Program.cs	(revision 9434)
@@ -0,0 +1,41 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.ServiceModel;
+namespace HeuristicLab.Services.Hive.SelfHost {
+  class Program {
+    static void Main(string[] args) {
+      var baseAdress = new Uri(@"http://localhost/Hive-3.3/HiveService.svc");
+
+      using (var host = new ServiceHost(typeof(HiveService), baseAdress)) {
+        host.Open();
+
+        Console.WriteLine("Service is ready at {0}", baseAdress);
+        Console.WriteLine("Press <Enter> to stop the service.");
+
+        Console.ReadLine();
+
+        host.Close();
+      }
+    }
+  }
+}
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/Properties/AssemblyInfo.cs.frame
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/Properties/AssemblyInfo.cs.frame	(revision 9434)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive.SelfHost/3.3/Properties/AssemblyInfo.cs.frame	(revision 9434)
@@ -0,0 +1,57 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("HeuristicLab.Services.Hive.SelfHost")]
+[assembly: AssemblyDescription("Self host for HeuristicLab.Hive services")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("HeuristicLab")]
+[assembly: AssemblyCopyright("(c) 2002-2012 HEAL")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("c229754f-fecf-4476-b7df-c865a709a93d")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("3.3.0.0")]
+[assembly: AssemblyFileVersion("3.3.7.$WCREV$")]
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/Status.aspx.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/Status.aspx.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive.Web/Hive-3.3/Status.aspx.cs	(revision 9434)
@@ -36,5 +36,5 @@
 public partial class Status : System.Web.UI.Page {
   protected void Page_Load(object sender, EventArgs e) {
-    var dao = ServiceLocator.Instance.HiveDtoDao;
+    var dao = ServiceLocator.Instance.HiveDao;
     var transactionManager = ServiceLocator.Instance.TransactionManager;
     var resourceName = Request.QueryString["resource"];
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Convert.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Convert.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Convert.cs	(revision 9434)
@@ -103,5 +103,5 @@
     public static DT.TaskData ToDto(DB.TaskData source) {
       if (source == null) return null;
-      return new DT.TaskData { TaskId = source.TaskId, Data = source.Data.ToArray(), LastUpdate = source.LastUpdate };
+      return new DT.TaskData { TaskId = source.TaskId, Data = source.Data, LastUpdate = source.LastUpdate };
     }
     public static DB.TaskData ToEntity(DT.TaskData source) {
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj	(revision 9434)
@@ -137,10 +137,10 @@
     <Compile Include="DataTransfer\Statistics.cs" />
     <Compile Include="DataTransfer\UserStatistics.cs" />
+    <Compile Include="OptimizedHiveDao.cs" />
     <Compile Include="HiveDao.cs" />
-    <Compile Include="HiveDtoDao.cs" />
     <Compile Include="HiveJanitor.cs" />
     <Compile Include="HiveOperationContext.cs" />
+    <Compile Include="Interfaces\IOptimizedHiveDao.cs" />
     <Compile Include="Interfaces\IHiveDao.cs" />
-    <Compile Include="Interfaces\IHiveDtoDao.cs" />
     <Compile Include="Interfaces\ITaskScheduler.cs" />
     <Compile Include="Scheduler\TaskInfoForScheduler.cs" />
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveDao.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveDao.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveDao.cs	(revision 9434)
@@ -22,252 +22,994 @@
 using System;
 using System.Collections.Generic;
-using System.Data.Linq;
 using System.Linq;
+using System.Linq.Expressions;
 using DT = HeuristicLab.Services.Hive.DataTransfer;
 
 namespace HeuristicLab.Services.Hive.DataAccess {
   public class HiveDao : IHiveDao {
-    private HiveDataContext Db { get { return HiveOperationContext.Current.DataContext; } }
+    public static HiveDataContext CreateContext(bool longRunning = false) {
+      var context = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString);
+      if (longRunning) context.CommandTimeout = (int)Settings.Default.LongRunningDatabaseCommandTimeout.TotalSeconds;
+      return context;
+    }
 
     #region Task Methods
-    public Task GetTaskById(Guid taskId) {
-      return GetTaskByIdQuery(Db, taskId).SingleOrDefault();
-    }
-
-    private static Func<HiveDataContext, Guid, IQueryable<Task>> GetTaskByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
-      from t in db.Tasks
-      where t.TaskId == taskId
-      select t
-    );
-
-    public Task GetTaskByDto(DT.Task taskDto) {
-      var task = GetTaskById(taskDto.Id);
-      DT.Convert.ToEntity(taskDto, task);
-      return task;
-    }
-
-    public Tuple<Task, Guid?> GetTaskByIdAndLastStateLogSlaveId(Guid taskId) {
-      return GetTaskByIdAndLastStateLogSlaveIdQuery(Db, taskId).SingleOrDefault();
-    }
-
-    private static Func<HiveDataContext, Guid, IQueryable<Tuple<Task, Guid?>>> GetTaskByIdAndLastStateLogSlaveIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
-       from t in db.Tasks
-       join sl in db.StateLogs on t.TaskId equals sl.TaskId
-       where t.TaskId == taskId
-       orderby sl.DateTime descending
-       group sl by t into logs
-       select new Tuple<Task, Guid?>(logs.Key, logs.First().SlaveId)
-    );
-
-    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}
-    ";
-
-    public IEnumerable<TaskInfoForScheduler> 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 Db.ExecuteQuery<TaskInfoForScheduler>(GetWaitingTasksQueryString, slave.ResourceId, Enum.GetName(typeof(TaskState), TaskState.Waiting), slave.FreeCores, slave.FreeMemory);
-    }
-
-    public IQueryable<DT.LightweightTask> GetLightweightTasks(Guid jobId) {
-      return GetLightweightTasksQuery(Db, jobId);
-    }
-
-    private static Func<HiveDataContext, Guid, IQueryable<DT.LightweightTask>> GetLightweightTasksQuery = CompiledQuery.Compile((HiveDataContext db, Guid jobId) =>
-        from task in db.Tasks
-        where task.JobId == jobId
-        select new DT.LightweightTask {
-          Id = task.TaskId,
-          ExecutionTime = TimeSpan.FromMilliseconds(task.ExecutionTimeMs),
-          ParentTaskId = task.ParentTaskId,
-          StateLog = task.StateLogs.Select(sl => ConvertStateLog(sl)).ToList(),
-          State = ConvertTaskState(task.State),
-          Command = ConvertCommand(task.Command),
-          LastTaskDataUpdate = task.JobData.LastUpdate
-        }
-    );
-
-    static Func<StateLog, DT.StateLog> ConvertStateLog = sl => DT.Convert.ToDto(sl);
-    static Func<TaskState, DT.TaskState> ConvertTaskState = ts => DT.Convert.ToDto(ts);
-    static Func<Command?, DT.Command?> ConvertCommand = c => DT.Convert.ToDto(c);
-
-    public void UpdateTask(Task task) {
-      Db.SubmitChanges();
-    }
-
-    public Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
-      Db.StateLogs.InsertOnSubmit(new StateLog {
-        TaskId = taskId,
-        State = taskState,
-        SlaveId = slaveId,
-        UserId = userId,
-        Exception = exception,
-        DateTime = DateTime.Now
-      });
-
-      var task = GetTaskById(taskId);
-      task.State = taskState;
-
-      Db.SubmitChanges();
-
-      return task;
-    }
-
-    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}
-    ";
-
-    public bool TaskIsAllowedToBeCalculatedBySlave(Guid taskId, Guid slaveId) {
-      return Db.ExecuteQuery<int>(TaskIsAllowedToBeCalculatedBySlaveQueryString, slaveId, taskId).First() > 0;
+    public DT.Task GetTask(Guid id) {
+      using (var db = CreateContext()) {
+        return DT.Convert.ToDto(db.Tasks.SingleOrDefault(x => x.TaskId == id));
+      }
+    }
+
+    public IEnumerable<DT.Task> GetTasks(Expression<Func<Task, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.Tasks.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public IEnumerable<DT.LightweightTask> GetLightweightTasks(Expression<Func<Task, bool>> predicate) {
+      List<DT.LightweightTask> tasks = new List<DT.LightweightTask>();
+
+      using (var db = CreateContext()) {
+        var tasksQuery = db.Tasks.Where(predicate).Select(task => new { task.TaskId, task.ExecutionTimeMs, task.ParentTaskId, task.StateLogs, task.State, task.Command });
+        var taskDatasQuery = db.Tasks.Where(predicate).Where(task => task.JobData != null).Select(task => new { task.TaskId, task.JobData.LastUpdate });
+
+        foreach (var task in tasksQuery) {
+          DT.LightweightTask t = new DT.LightweightTask();
+          t.Id = task.TaskId;
+          t.ExecutionTime = TimeSpan.FromMilliseconds(task.ExecutionTimeMs);
+          t.ParentTaskId = task.ParentTaskId;
+          t.StateLog = task.StateLogs == null ? new List<DT.StateLog>() : task.StateLogs.Select(x => DataTransfer.Convert.ToDto(x)).OrderBy(x => x.DateTime).ToList();
+          t.State = DataTransfer.Convert.ToDto(task.State);
+          t.Command = DataTransfer.Convert.ToDto(task.Command);
+          t.LastTaskDataUpdate = taskDatasQuery.Where(x => x.TaskId == task.TaskId).Count() > 0 ? taskDatasQuery.Select(x => x.LastUpdate).First() : DateTime.MinValue;
+          tasks.Add(t);
+        }
+      }
+      return tasks;
+    }
+
+    public IEnumerable<DT.LightweightTask> GetLightweightTasksWithoutStateLog(Expression<Func<Task, bool>> predicate) {
+      List<DT.LightweightTask> tasks = new List<DT.LightweightTask>();
+
+      using (var db = CreateContext()) {
+        var tasksQuery = db.Tasks.Where(predicate).Select(task => new { task.TaskId, task.ExecutionTimeMs, task.ParentTaskId, task.State, task.Command });
+        var taskDatasQuery = db.Tasks.Where(predicate).Where(task => task.JobData != null).Select(task => new { task.TaskId, task.JobData.LastUpdate });
+
+        foreach (var task in tasksQuery) {
+          DT.LightweightTask t = new DT.LightweightTask();
+          t.Id = task.TaskId;
+          t.ExecutionTime = TimeSpan.FromMilliseconds(task.ExecutionTimeMs);
+          t.ParentTaskId = task.ParentTaskId;
+          t.StateLog = new List<DT.StateLog>();
+          t.State = DataTransfer.Convert.ToDto(task.State);
+          t.Command = DataTransfer.Convert.ToDto(task.Command);
+          t.LastTaskDataUpdate = taskDatasQuery.Where(x => x.TaskId == task.TaskId).Count() > 0 ? taskDatasQuery.Select(x => x.LastUpdate).First() : DateTime.MinValue;
+          tasks.Add(t);
+        }
+      }
+      return tasks;
+    }
+
+    public Guid AddTask(DT.Task dto) {
+      using (var db = CreateContext()) {
+        var entity = DT.Convert.ToEntity(dto);
+        db.Tasks.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        foreach (Guid pluginId in dto.PluginsNeededIds) {
+          db.RequiredPlugins.InsertOnSubmit(new RequiredPlugin() { TaskId = entity.TaskId, PluginId = pluginId });
+        }
+        db.SubmitChanges();
+        return entity.TaskId;
+      }
+    }
+
+    public void UpdateTaskAndPlugins(DT.Task dto) {
+      using (var db = CreateContext()) {
+        var entity = db.Tasks.FirstOrDefault(x => x.TaskId == dto.Id);
+        if (entity == null) db.Tasks.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        foreach (Guid pluginId in dto.PluginsNeededIds) {
+          if (db.RequiredPlugins.Count(p => p.PluginId == pluginId) == 0) {
+            db.RequiredPlugins.InsertOnSubmit(new RequiredPlugin() { TaskId = entity.TaskId, PluginId = pluginId });
+          }
+        }
+        db.SubmitChanges();
+      }
+    }
+
+    public void UpdateTaskAndStateLogs(DT.Task dto) {
+      using (var db = CreateContext()) {
+        var entity = db.Tasks.FirstOrDefault(x => x.TaskId == dto.Id);
+        if (entity == null) db.Tasks.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void UpdateTask(DT.Task dto) {
+      using (var db = CreateContext()) {
+        db.DeferredLoadingEnabled = false;
+
+        var entity = db.Tasks.FirstOrDefault(x => x.TaskId == dto.Id);
+        if (entity == null) db.Tasks.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntityTaskOnly(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeleteTask(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.Tasks.FirstOrDefault(x => x.TaskId == id);
+        if (entity != null) db.Tasks.DeleteOnSubmit(entity);
+        db.SubmitChanges(); // taskData and child tasks are deleted by db-trigger
+      }
+    }
+
+    /// <summary>
+    /// returns all parent tasks which are waiting for their child tasks to finish
+    /// </summary>
+    /// <param name="resourceIds">list of resourceids which for which the task should be valid</param>
+    /// <param name="count">maximum number of task to return</param>
+    /// <param name="finished">if true, all parent task which have FinishWhenChildJobsFinished=true are returned, otherwise only FinishWhenChildJobsFinished=false are returned</param>
+    /// <returns></returns>
+    public IEnumerable<DT.Task> GetParentTasks(IEnumerable<Guid> resourceIds, int count, bool finished) {
+      using (var db = CreateContext()) {
+        var query = from ar in db.AssignedResources
+                    where resourceIds.Contains(ar.ResourceId)
+                       && ar.Task.State == TaskState.Waiting
+                       && ar.Task.IsParentTask
+                       && (finished ? ar.Task.FinishWhenChildJobsFinished : !ar.Task.FinishWhenChildJobsFinished)
+                       && (from child in db.Tasks
+                           where child.ParentTaskId == ar.Task.TaskId
+                           select child.State == TaskState.Finished
+                               || child.State == TaskState.Aborted
+                               || child.State == TaskState.Failed).All(x => x)
+                       && (from child in db.Tasks // avoid returning WaitForChildTasks task where no child-task exist (yet)
+                           where child.ParentTaskId == ar.Task.TaskId
+                           select child).Count() > 0
+                    orderby ar.Task.Priority descending, db.Random()
+                    select DT.Convert.ToDto(ar.Task);
+        return count == 0 ? query.ToArray() : query.Take(count).ToArray();
+      }
+    }
+
+    public IEnumerable<TaskInfoForScheduler> GetWaitingTasks(DT.Slave slave) {
+      using (var db = CreateContext()) {
+        var resourceIds = GetParentResources(slave.Id).Select(r => r.Id);
+        //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
+
+        var query = from ar in db.AssignedResources
+                    where resourceIds.Contains(ar.ResourceId)
+                       && !(ar.Task.IsParentTask && ar.Task.FinishWhenChildJobsFinished)
+                       && ar.Task.State == TaskState.Waiting
+                       && ar.Task.CoresNeeded <= slave.FreeCores
+                       && ar.Task.MemoryNeeded <= slave.FreeMemory
+                    select new TaskInfoForScheduler() { TaskId = ar.Task.TaskId, JobId = ar.Task.JobId, Priority = ar.Task.Priority };
+        var waitingTasks = query.ToArray();
+        return waitingTasks;
+      }
+    }
+
+    public DT.Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
+      using (var db = CreateContext()) {
+        db.DeferredLoadingEnabled = false;
+
+        db.StateLogs.InsertOnSubmit(new StateLog {
+          TaskId = taskId,
+          State = taskState,
+          SlaveId = slaveId,
+          UserId = userId,
+          Exception = exception,
+          DateTime = DateTime.Now
+        });
+        db.SubmitChanges();
+      }
+
+      using (var db = CreateContext()) {
+        db.DeferredLoadingEnabled = false;
+
+        var task = db.Tasks.SingleOrDefault(x => x.TaskId == taskId);
+        task.State = taskState;
+        db.SubmitChanges();
+      }
+
+      using (var db = CreateContext()) {
+        var task = db.Tasks.SingleOrDefault(x => x.TaskId == taskId);
+        return DT.Convert.ToDto(task);
+      }
     }
     #endregion
 
     #region TaskData Methods
-    public TaskData GetTaskDataById(Guid id) {
-      return GetTaskDataByIdQuery(Db, id).SingleOrDefault();
-    }
-
-    private static Func<HiveDataContext, Guid, IQueryable<TaskData>> GetTaskDataByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid id) =>
-      from t in db.TaskDatas
-      where t.TaskId == id
-      select t
-    );
-
-    public TaskData GetTaskDataByDto(DT.TaskData dto) {
-      var taskData = GetTaskDataById(dto.TaskId);
-      DT.Convert.ToEntity(dto, taskData);
-      return taskData;
-    }
-
-    public void UpdateTaskData(TaskData taskData) {
-      Db.SubmitChanges();
+    public DT.TaskData GetTaskData(Guid id) {
+      using (var db = CreateContext(true)) {
+        return DT.Convert.ToDto(db.TaskDatas.SingleOrDefault(x => x.TaskId == id));
+      }
+    }
+
+    public IEnumerable<DT.TaskData> GetTaskDatas(Expression<Func<TaskData, bool>> predicate) {
+      using (var db = CreateContext(true)) {
+        return db.TaskDatas.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public Guid AddTaskData(DT.TaskData dto) {
+      using (var db = CreateContext(true)) {
+        var entity = DT.Convert.ToEntity(dto);
+        db.TaskDatas.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.TaskId;
+      }
+    }
+
+    public void UpdateTaskData(DT.TaskData dto) {
+      using (var db = CreateContext(true)) {
+        var entity = db.TaskDatas.FirstOrDefault(x => x.TaskId == dto.TaskId);
+        if (entity == null) db.TaskDatas.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeleteTaskData(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.TaskDatas.FirstOrDefault(x => x.TaskId == id); // check if all the byte[] is loaded into memory here. otherwise work around to delete without loading it
+        if (entity != null) db.TaskDatas.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
     }
     #endregion
 
     #region StateLog Methods
-
+    public DT.StateLog GetStateLog(Guid id) {
+      using (var db = CreateContext()) {
+        return DT.Convert.ToDto(db.StateLogs.SingleOrDefault(x => x.StateLogId == id));
+      }
+    }
+
+    public IEnumerable<DT.StateLog> GetStateLogs(Expression<Func<StateLog, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.StateLogs.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public Guid AddStateLog(DT.StateLog dto) {
+      using (var db = CreateContext()) {
+        var entity = DT.Convert.ToEntity(dto);
+        db.StateLogs.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.StateLogId;
+      }
+    }
+
+    public void UpdateStateLog(DT.StateLog dto) {
+      using (var db = CreateContext()) {
+        var entity = db.StateLogs.FirstOrDefault(x => x.StateLogId == dto.Id);
+        if (entity == null) db.StateLogs.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeleteStateLog(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.StateLogs.FirstOrDefault(x => x.StateLogId == id);
+        if (entity != null) db.StateLogs.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
     #endregion
 
     #region Job Methods
-
+    public DT.Job GetJob(Guid id) {
+      using (var db = CreateContext()) {
+        return AddStatsToJob(db, DT.Convert.ToDto(db.Jobs.SingleOrDefault(x => x.JobId == id)));
+      }
+    }
+
+    private DT.Job AddStatsToJob(HiveDataContext db, DT.Job exp) {
+      if (exp == null)
+        return null;
+
+      var jobs = db.Tasks.Where(j => j.JobId == exp.Id);
+      exp.JobCount = jobs.Count();
+      exp.CalculatingCount = jobs.Count(j => j.State == TaskState.Calculating);
+      exp.FinishedCount = jobs.Count(j => j.State == TaskState.Finished);
+      return exp;
+    }
+
+    public IEnumerable<DT.Job> GetJobs(Expression<Func<Job, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.Jobs.Where(predicate).Select(x => AddStatsToJob(db, DT.Convert.ToDto(x))).ToArray();
+      }
+    }
+
+    public IEnumerable<JobInfoForScheduler> GetJobInfoForScheduler(Expression<Func<Job, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.Jobs.Where(predicate).Select(x => new JobInfoForScheduler() { Id = x.JobId, DateCreated = x.DateCreated, OwnerUserId = x.OwnerUserId }).ToArray();
+      }
+    }
+
+    public Guid AddJob(DT.Job dto) {
+      using (var db = CreateContext()) {
+        var entity = DT.Convert.ToEntity(dto);
+        db.Jobs.InsertOnSubmit(entity);
+        if (!db.UserPriorities.Any(x => x.UserId == dto.OwnerUserId))
+          EnqueueUserPriority(new DT.UserPriority { Id = dto.OwnerUserId, DateEnqueued = dto.DateCreated });
+        db.SubmitChanges();
+        return entity.JobId;
+      }
+    }
+
+    public void UpdateJob(DT.Job dto) {
+      using (var db = CreateContext()) {
+        var entity = db.Jobs.FirstOrDefault(x => x.JobId == dto.Id);
+        if (entity == null) db.Jobs.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeleteJob(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.Jobs.FirstOrDefault(x => x.JobId == id);
+        if (entity != null) db.Jobs.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
     #endregion
 
     #region JobPermission Methods
-
+    public DT.JobPermission GetJobPermission(Guid jobId, Guid grantedUserId) {
+      using (var db = CreateContext()) {
+        return DT.Convert.ToDto(db.JobPermissions.SingleOrDefault(x => x.JobId == jobId && x.GrantedUserId == grantedUserId));
+      }
+    }
+
+    public IEnumerable<DT.JobPermission> GetJobPermissions(Expression<Func<JobPermission, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.JobPermissions.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public void AddJobPermission(DT.JobPermission dto) {
+      using (var db = CreateContext()) {
+        var entity = DT.Convert.ToEntity(dto);
+        db.JobPermissions.InsertOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void UpdateJobPermission(DT.JobPermission dto) {
+      using (var db = CreateContext()) {
+        var entity = db.JobPermissions.FirstOrDefault(x => x.JobId == dto.JobId && x.GrantedUserId == dto.GrantedUserId);
+        if (entity == null) db.JobPermissions.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeleteJobPermission(Guid jobId, Guid grantedUserId) {
+      using (var db = CreateContext()) {
+        var entity = db.JobPermissions.FirstOrDefault(x => x.JobId == jobId && x.GrantedUserId == grantedUserId);
+        if (entity != null) db.JobPermissions.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
+
+    /// <summary>
+    /// Sets the permissions for a experiment. makes sure that only one permission per user exists.
+    /// </summary>
+    public void SetJobPermission(Guid jobId, Guid grantedByUserId, Guid grantedUserId, Permission permission) {
+      using (var db = CreateContext()) {
+        JobPermission jobPermission = db.JobPermissions.SingleOrDefault(x => x.JobId == jobId && x.GrantedUserId == grantedUserId);
+        if (jobPermission != null) {
+          if (permission == Permission.NotAllowed) {
+            // not allowed, delete
+            db.JobPermissions.DeleteOnSubmit(jobPermission);
+          } else {
+            // update
+            jobPermission.Permission = permission;
+            jobPermission.GrantedByUserId = grantedByUserId; // update grantedByUserId, always the last "granter" is stored
+          }
+        } else {
+          // insert
+          if (permission != Permission.NotAllowed) {
+            jobPermission = new JobPermission() { JobId = jobId, GrantedByUserId = grantedByUserId, GrantedUserId = grantedUserId, Permission = permission };
+            db.JobPermissions.InsertOnSubmit(jobPermission);
+          }
+        }
+        db.SubmitChanges();
+      }
+    }
     #endregion
 
     #region Plugin Methods
-    public Plugin GetPluginById(Guid pluginId) {
-      return GetPluginByIdQuery(Db, pluginId).SingleOrDefault();
-    }
-
-    private static Func<HiveDataContext, Guid, IQueryable<Plugin>> GetPluginByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid pluginId) =>
-      from p in db.Plugins
-      where p.PluginId == pluginId
-      select p
-    );
-
+    public DT.Plugin GetPlugin(Guid id) {
+      using (var db = CreateContext()) {
+        return DT.Convert.ToDto(db.Plugins.SingleOrDefault(x => x.PluginId == id));
+      }
+    }
+
+    public IEnumerable<DT.Plugin> GetPlugins(Expression<Func<Plugin, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.Plugins.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public Guid AddPlugin(DT.Plugin dto) {
+      using (var db = CreateContext()) {
+        var entity = DT.Convert.ToEntity(dto);
+        db.Plugins.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.PluginId;
+      }
+    }
+
+    public void UpdatePlugin(DT.Plugin dto) {
+      using (var db = CreateContext()) {
+        var entity = db.Plugins.FirstOrDefault(x => x.PluginId == dto.Id);
+        if (entity == null) db.Plugins.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeletePlugin(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.Plugins.FirstOrDefault(x => x.PluginId == id);
+        if (entity != null) db.Plugins.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
     #endregion
 
     #region PluginData Methods
-
+    public DT.PluginData GetPluginData(Guid id) {
+      using (var db = CreateContext()) {
+        return DT.Convert.ToDto(db.PluginDatas.SingleOrDefault(x => x.PluginDataId == id));
+      }
+    }
+
+    public IEnumerable<DT.PluginData> GetPluginDatas(Expression<Func<PluginData, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.PluginDatas.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public Guid AddPluginData(DT.PluginData dto) {
+      using (var db = CreateContext()) {
+        var entity = DT.Convert.ToEntity(dto);
+        db.PluginDatas.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.PluginDataId;
+      }
+    }
+
+    public void UpdatePluginData(DT.PluginData dto) {
+      using (var db = CreateContext()) {
+        var entity = db.PluginDatas.FirstOrDefault(x => x.PluginId == dto.PluginId);
+        if (entity == null) db.PluginDatas.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeletePluginData(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.PluginDatas.FirstOrDefault(x => x.PluginDataId == id);
+        if (entity != null) db.PluginDatas.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
     #endregion
 
     #region Slave Methods
-    public Slave GetSlaveById(Guid id) {
-      return GetSlaveByIdQuery(Db, id).SingleOrDefault();
-    }
-
-    private static Func<HiveDataContext, Guid, IQueryable<Slave>> GetSlaveByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid slaveId) =>
-      from s in db.Resources.OfType<Slave>()
-      where s.ResourceId == slaveId
-      select s
-    );
-
-    public void UpdateSlave(Slave slave) {
-      Db.SubmitChanges();
-    }
-
-    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}
-      ";
-
-    public bool SlaveHasToShutdownComputer(Guid slaveId) {
-      return Db.ExecuteQuery<int>(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Shutdown).First() > 0;
-    }
-
-    public bool SlaveIsAllowedToCalculate(Guid slaveId) {
-      return Db.ExecuteQuery<int>(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Offline).First() == 0;
+    public DT.Slave GetSlave(Guid id) {
+      using (var db = CreateContext()) {
+        return DT.Convert.ToDto(db.Resources.OfType<Slave>().SingleOrDefault(x => x.ResourceId == id));
+      }
+    }
+
+    public IEnumerable<DT.Slave> GetSlaves(Expression<Func<Slave, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.Resources.OfType<Slave>().Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public Guid AddSlave(DT.Slave dto) {
+      using (var db = CreateContext()) {
+        var entity = DT.Convert.ToEntity(dto);
+        db.Resources.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.ResourceId;
+      }
+    }
+
+    public void UpdateSlave(DT.Slave dto) {
+      using (var db = CreateContext()) {
+        var entity = db.Resources.OfType<Slave>().FirstOrDefault(x => x.ResourceId == dto.Id);
+        if (entity == null) db.Resources.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeleteSlave(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.Resources.OfType<Slave>().FirstOrDefault(x => x.ResourceId == id);
+        if (entity != null) db.Resources.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
     }
     #endregion
 
     #region SlaveGroup Methods
-
+    public DT.SlaveGroup GetSlaveGroup(Guid id) {
+      using (var db = CreateContext()) {
+        return DT.Convert.ToDto(db.Resources.OfType<SlaveGroup>().SingleOrDefault(x => x.ResourceId == id));
+      }
+    }
+
+    public IEnumerable<DT.SlaveGroup> GetSlaveGroups(Expression<Func<SlaveGroup, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.Resources.OfType<SlaveGroup>().Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public Guid AddSlaveGroup(DT.SlaveGroup dto) {
+      using (var db = CreateContext()) {
+        if (dto.Id == Guid.Empty)
+          dto.Id = Guid.NewGuid();
+        var entity = DT.Convert.ToEntity(dto);
+        db.Resources.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.ResourceId;
+      }
+    }
+
+    public void UpdateSlaveGroup(DT.SlaveGroup dto) {
+      using (var db = CreateContext()) {
+        var entity = db.Resources.OfType<SlaveGroup>().FirstOrDefault(x => x.ResourceId == dto.Id);
+        if (entity == null) db.Resources.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeleteSlaveGroup(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.Resources.OfType<SlaveGroup>().FirstOrDefault(x => x.ResourceId == id);
+        if (entity != null) {
+          if (db.Resources.Where(r => r.ParentResourceId == id).Count() > 0) {
+            throw new InvalidOperationException("Cannot delete SlaveGroup as long as there are Slaves in the group");
+          }
+          db.Resources.DeleteOnSubmit(entity);
+        }
+        db.SubmitChanges();
+      }
+    }
     #endregion
 
     #region Resource Methods
+    public DT.Resource GetResource(Guid id) {
+      using (var db = CreateContext()) {
+        return DT.Convert.ToDto(db.Resources.SingleOrDefault(x => x.ResourceId == id));
+      }
+    }
+
+    public IEnumerable<DT.Resource> GetResources(Expression<Func<Resource, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.Resources.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public Guid AddResource(DT.Resource dto) {
+      using (var db = CreateContext()) {
+        var entity = DT.Convert.ToEntity(dto);
+        db.Resources.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.ResourceId;
+      }
+    }
+
+    public void UpdateResource(DT.Resource dto) {
+      using (var db = CreateContext()) {
+        var entity = db.Resources.FirstOrDefault(x => x.ResourceId == dto.Id);
+        if (entity == null) db.Resources.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeleteResource(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.Resources.FirstOrDefault(x => x.ResourceId == id);
+        if (entity != null) db.Resources.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void AssignJobToResource(Guid taskId, IEnumerable<Guid> resourceIds) {
+      using (var db = CreateContext()) {
+        db.DeferredLoadingEnabled = false;
+
+        List<AssignedResource> assignedResources = new List<AssignedResource>();
+        foreach (Guid rId in resourceIds) {
+          assignedResources.Add(new AssignedResource() { TaskId = taskId, ResourceId = rId });
+        }
+        db.AssignedResources.InsertAllOnSubmit(assignedResources);
+        db.SubmitChanges();
+      }
+    }
+
+    public IEnumerable<DT.Resource> GetAssignedResources(Guid jobId) {
+      using (var db = CreateContext()) {
+        var job = db.Tasks.Where(x => x.TaskId == jobId).Single();
+        return job.AssignedResources.Select(x => DT.Convert.ToDto(x.Resource)).ToArray();
+      }
+    }
+
+    /// <summary>
+    /// Returns all parent resources of a resource (the given resource is also added)
+    /// </summary>
+    public IEnumerable<DT.Resource> GetParentResources(Guid resourceId) {
+      using (var db = CreateContext()) {
+        var resources = new List<Resource>();
+        CollectParentResources(resources, db.Resources.Where(r => r.ResourceId == resourceId).Single());
+        return resources.Select(r => DT.Convert.ToDto(r)).ToArray();
+      }
+    }
+
+    private static void CollectParentResources(ICollection<Resource> resources, Resource resource) {
+      if (resource == null) return;
+      resources.Add(resource);
+      CollectParentResources(resources, resource.ParentResource);
+    }
+
+    /// <summary>
+    /// Returns all child resources of a resource (without the given resource)
+    /// </summary>
+    public IEnumerable<DT.Resource> GetChildResources(Guid resourceId) {
+      using (var db = CreateContext()) {
+        return CollectChildResources(resourceId, db);
+      }
+    }
+
+    public IEnumerable<DT.Resource> CollectChildResources(Guid resourceId, HiveDataContext db) {
+      var childs = new List<DT.Resource>();
+      foreach (var child in db.Resources.Where(x => x.ParentResourceId == resourceId)) {
+        childs.Add(DT.Convert.ToDto(child));
+        childs.AddRange(CollectChildResources(child.ResourceId, db));
+      }
+      return childs;
+    }
+
+    public IEnumerable<DT.Task> GetJobsByResourceId(Guid resourceId) {
+      using (var db = CreateContext()) {
+        var resources = GetChildResources(resourceId).Select(x => x.Id).ToList();
+        resources.Add(resourceId);
+
+        var jobs = db.Tasks.Where(j =>
+          j.State == TaskState.Calculating &&
+          j.StateLogs.OrderByDescending(x => x.DateTime).First().SlaveId.HasValue &&
+          resources.Contains(j.StateLogs.OrderByDescending(x => x.DateTime).First().SlaveId.Value));
+        return jobs.Select(j => DT.Convert.ToDto(j)).ToArray();
+      }
+    }
     #endregion
 
     #region ResourcePermission Methods
-
+    public DT.ResourcePermission GetResourcePermission(Guid resourceId, Guid grantedUserId) {
+      using (var db = CreateContext()) {
+        return DT.Convert.ToDto(db.ResourcePermissions.SingleOrDefault(x => x.ResourceId == resourceId && x.GrantedUserId == grantedUserId));
+      }
+    }
+
+    public IEnumerable<DT.ResourcePermission> GetResourcePermissions(Expression<Func<ResourcePermission, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.ResourcePermissions.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public void AddResourcePermission(DT.ResourcePermission dto) {
+      using (var db = CreateContext()) {
+        var entity = db.ResourcePermissions.SingleOrDefault(x => x.ResourceId == dto.ResourceId && x.GrantedUserId == dto.GrantedUserId);
+        if (entity == null) { db.ResourcePermissions.InsertOnSubmit(DT.Convert.ToEntity(dto)); db.SubmitChanges(); }
+      }
+    }
+
+    public void UpdateResourcePermission(DT.ResourcePermission dto) {
+      using (var db = CreateContext()) {
+        var entity = db.ResourcePermissions.FirstOrDefault(x => x.ResourceId == dto.ResourceId && x.GrantedUserId == dto.GrantedUserId);
+        if (entity == null) db.ResourcePermissions.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeleteResourcePermission(Guid resourceId, Guid grantedUserId) {
+      using (var db = CreateContext()) {
+        var entity = db.ResourcePermissions.FirstOrDefault(x => x.ResourceId == resourceId && x.GrantedUserId == grantedUserId);
+        if (entity != null) db.ResourcePermissions.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
     #endregion
 
     #region Authorization Methods
-
+    public Permission GetPermissionForTask(Guid taskId, Guid userId) {
+      using (var db = CreateContext()) {
+        return GetPermissionForJob(GetJobForTask(taskId), userId);
+      }
+    }
+
+    public Permission GetPermissionForJob(Guid jobId, Guid userId) {
+      using (var db = CreateContext()) {
+        Job job = db.Jobs.SingleOrDefault(x => x.JobId == jobId);
+        if (job == null) return Permission.NotAllowed;
+        if (job.OwnerUserId == userId) return Permission.Full;
+        JobPermission permission = db.JobPermissions.SingleOrDefault(p => p.JobId == jobId && p.GrantedUserId == userId);
+        return permission != null ? permission.Permission : Permission.NotAllowed;
+      }
+    }
+
+    public Guid GetJobForTask(Guid taskId) {
+      using (var db = CreateContext()) {
+        return db.Tasks.Single(j => j.TaskId == taskId).JobId;
+      }
+    }
     #endregion
 
     #region Lifecycle Methods
-
+    public DateTime GetLastCleanup() {
+      using (var db = CreateContext()) {
+        var entity = db.Lifecycles.SingleOrDefault();
+        return entity != null ? entity.LastCleanup : DateTime.MinValue;
+      }
+    }
+
+    public void SetLastCleanup(DateTime datetime) {
+      using (var db = CreateContext()) {
+        var entity = db.Lifecycles.SingleOrDefault();
+        if (entity != null) {
+          entity.LastCleanup = datetime;
+        } else {
+          entity = new Lifecycle();
+          entity.LifecycleId = 0; // always only one entry with ID:0
+          entity.LastCleanup = datetime;
+          db.Lifecycles.InsertOnSubmit(entity);
+        }
+        db.SubmitChanges();
+      }
+    }
     #endregion
 
     #region Downtime Methods
+    public DT.Downtime GetDowntime(Guid id) {
+      using (var db = CreateContext()) {
+        return DT.Convert.ToDto(db.Downtimes.SingleOrDefault(x => x.DowntimeId == id));
+      }
+    }
+
+    public IEnumerable<DT.Downtime> GetDowntimes(Expression<Func<Downtime, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.Downtimes.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public Guid AddDowntime(DT.Downtime dto) {
+      using (var db = CreateContext()) {
+        var entity = DT.Convert.ToEntity(dto);
+        db.Downtimes.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        return entity.DowntimeId;
+      }
+    }
+
+    public void UpdateDowntime(DT.Downtime dto) {
+      using (var db = CreateContext()) {
+        var entity = db.Downtimes.FirstOrDefault(x => x.DowntimeId == dto.Id);
+        if (entity == null) db.Downtimes.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public void DeleteDowntime(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.Downtimes.FirstOrDefault(x => x.DowntimeId == id);
+        if (entity != null) db.Downtimes.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
     #endregion
 
     #region Statistics Methods
-
+    public DT.Statistics GetStatistic(Guid id) {
+      using (var db = CreateContext()) {
+        return DT.Convert.ToDto(db.Statistics.SingleOrDefault(x => x.StatisticsId == id));
+      }
+    }
+
+    public IEnumerable<DT.Statistics> GetStatistics(Expression<Func<Statistics, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.Statistics.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public Guid AddStatistics(DT.Statistics dto) {
+      using (var db = CreateContext()) {
+        var entity = DT.Convert.ToEntity(dto);
+        db.Statistics.InsertOnSubmit(entity);
+        db.SubmitChanges();
+        foreach (var slaveStat in dto.SlaveStatistics) {
+          slaveStat.Id = entity.StatisticsId;
+          db.SlaveStatistics.InsertOnSubmit(DT.Convert.ToEntity(slaveStat));
+        }
+        if (dto.UserStatistics != null) {
+          foreach (var userStat in dto.UserStatistics) {
+            userStat.Id = entity.StatisticsId;
+            db.UserStatistics.InsertOnSubmit(DT.Convert.ToEntity(userStat));
+          }
+        }
+        db.SubmitChanges();
+        return entity.StatisticsId;
+      }
+    }
+
+    public void DeleteStatistics(Guid id) {
+      using (var db = CreateContext()) {
+        var entity = db.Statistics.FirstOrDefault(x => x.StatisticsId == id);
+        if (entity != null) db.Statistics.DeleteOnSubmit(entity);
+        db.SubmitChanges();
+      }
+    }
+
+    public Dictionary<Guid, int> GetWaitingTasksByUser() {
+      using (var db = CreateContext()) {
+        var waitingTasksByUser = from task in db.Tasks
+                                 where task.State == TaskState.Waiting
+                                 group task by task.Job.OwnerUserId into g
+                                 select new { UserId = g.Key, UsedCores = g.Count() };
+        return waitingTasksByUser.ToDictionary(x => x.UserId, x => x.UsedCores);
+      }
+    }
+
+    public Dictionary<Guid, int> GetWaitingTasksByUserForResources(List<Guid> resourceIds) {
+      using (var db = CreateContext()) {
+        var waitingTasksByUser = from task in db.Tasks
+                                 where task.State == TaskState.Waiting && task.AssignedResources.Any(x => resourceIds.Contains(x.ResourceId))
+                                 group task by task.Job.OwnerUserId into g
+                                 select new { UserId = g.Key, UsedCores = g.Count() };
+        return waitingTasksByUser.ToDictionary(x => x.UserId, x => x.UsedCores);
+      }
+    }
+
+    public Dictionary<Guid, int> GetCalculatingTasksByUser() {
+      using (var db = CreateContext()) {
+        var calculatingTasksByUser = from task in db.Tasks
+                                     where task.State == TaskState.Calculating
+                                     group task by task.Job.OwnerUserId into g
+                                     select new { UserId = g.Key, UsedCores = g.Count() };
+        return calculatingTasksByUser.ToDictionary(x => x.UserId, x => x.UsedCores);
+      }
+    }
+
+    public Dictionary<Guid, int> GetCalculatingTasksByUserForResources(List<Guid> resourceIds) {
+      using (var db = CreateContext()) {
+        var calculatingTasksByUser = from task in db.Tasks
+                                     where task.State == TaskState.Calculating && task.AssignedResources.Any(x => resourceIds.Contains(x.ResourceId))
+                                     group task by task.Job.OwnerUserId into g
+                                     select new { UserId = g.Key, UsedCores = g.Count() };
+        return calculatingTasksByUser.ToDictionary(x => x.UserId, x => x.UsedCores);
+      }
+    }
+
+    public List<DT.UserStatistics> GetUserStatistics() {
+      using (var db = CreateContext()) {
+        var userStats = new Dictionary<Guid, DT.UserStatistics>();
+
+        var usedCoresByUser = from job in db.Tasks
+                              where job.State == TaskState.Calculating
+                              group job by job.Job.OwnerUserId into g
+                              select new { UserId = g.Key, UsedCores = g.Count() };
+
+        foreach (var item in usedCoresByUser) {
+          if (!userStats.ContainsKey(item.UserId)) {
+            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
+          }
+          userStats[item.UserId].UsedCores += item.UsedCores;
+        }
+
+        var executionTimesByUser = from task in db.Tasks
+                                   group task by task.Job.OwnerUserId into g
+                                   select new { UserId = g.Key, ExecutionTime = TimeSpan.FromMilliseconds(g.Select(x => x.ExecutionTimeMs).Sum()) };
+        foreach (var item in executionTimesByUser) {
+          if (!userStats.ContainsKey(item.UserId)) {
+            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
+          }
+          userStats[item.UserId].ExecutionTime += item.ExecutionTime;
+        }
+
+        // execution times only of finished task - necessary to compute efficieny
+        var executionTimesFinishedJobs = from job in db.Tasks
+                                         where job.State == TaskState.Finished
+                                         group job by job.Job.OwnerUserId into g
+                                         select new { UserId = g.Key, ExecutionTimeFinishedJobs = TimeSpan.FromMilliseconds(g.Select(x => x.ExecutionTimeMs).Sum()) };
+
+        foreach (var item in executionTimesFinishedJobs) {
+          if (!userStats.ContainsKey(item.UserId)) {
+            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
+          }
+          userStats[item.UserId].ExecutionTimeFinishedJobs += item.ExecutionTimeFinishedJobs;
+        }
+
+        // start to end times only of finished task - necessary to compute efficiency
+        var startToEndTimesFinishedJobs = from job in db.Tasks
+                                          where job.State == TaskState.Finished
+                                          group job by job.Job.OwnerUserId into g
+                                          select new {
+                                            UserId = g.Key,
+                                            StartToEndTime = new TimeSpan(g.Select(x => x.StateLogs.OrderByDescending(sl => sl.DateTime).First().DateTime - x.StateLogs.OrderBy(sl => sl.DateTime).First().DateTime).Sum(ts => ts.Ticks))
+                                          };
+        foreach (var item in startToEndTimesFinishedJobs) {
+          if (!userStats.ContainsKey(item.UserId)) {
+            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
+          }
+          userStats[item.UserId].StartToEndTime += item.StartToEndTime;
+        }
+
+        // also consider executiontimes of DeletedJobStats 
+        var deletedJobsExecutionTimesByUsers = from del in db.DeletedJobStatistics
+                                               group del by del.UserId into g
+                                               select new {
+                                                 UserId = g.Key,
+                                                 ExecutionTime = TimeSpan.FromSeconds(g.Select(x => x.ExecutionTimeS).Sum()),
+                                                 ExecutionTimeFinishedJobs = TimeSpan.FromSeconds(g.Select(x => x.ExecutionTimeSFinishedJobs).Sum()),
+                                                 StartToEndTime = TimeSpan.FromSeconds(g.Select(x => x.StartToEndTimeS).Sum())
+                                               };
+        foreach (var item in deletedJobsExecutionTimesByUsers) {
+          if (!userStats.ContainsKey(item.UserId)) {
+            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
+          }
+          userStats[item.UserId].ExecutionTime += item.ExecutionTime;
+          userStats[item.UserId].ExecutionTimeFinishedJobs += item.ExecutionTimeFinishedJobs;
+          userStats[item.UserId].StartToEndTime += item.StartToEndTime;
+        }
+
+        return userStats.Values.ToList();
+      }
+    }
     #endregion
 
     #region UserPriority Methods
-
+    public IEnumerable<DT.UserPriority> GetUserPriorities(Expression<Func<UserPriority, bool>> predicate) {
+      using (var db = CreateContext()) {
+        return db.UserPriorities.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
+      }
+    }
+
+    public void EnqueueUserPriority(DT.UserPriority dto) {
+      using (var db = CreateContext()) {
+        var entity = db.UserPriorities.FirstOrDefault(x => x.UserId == dto.Id);
+        if (entity == null) db.UserPriorities.InsertOnSubmit(DT.Convert.ToEntity(dto));
+        else DT.Convert.ToEntity(dto, entity);
+        db.SubmitChanges();
+      }
+    }
     #endregion
 
     #region Helpers
-
+    private void CollectChildTasks(HiveDataContext db, Guid parentTaskId, List<Task> collection) {
+      var tasks = db.Tasks.Where(j => j.ParentTaskId == parentTaskId);
+      foreach (var task in tasks) {
+        collection.Add(task);
+        if (task.IsParentTask)
+          CollectChildTasks(db, task.TaskId, collection);
+      }
+    }
     #endregion
   }
Index: anches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveDtoDao.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveDtoDao.cs	(revision 9433)
+++ 	(revision )
@@ -1,1018 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 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.Linq.Expressions;
-using DT = HeuristicLab.Services.Hive.DataTransfer;
-
-namespace HeuristicLab.Services.Hive.DataAccess {
-  public class HiveDtoDao : IHiveDtoDao {
-    public static HiveDataContext CreateContext(bool longRunning = false) {
-      var context = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString);
-      if (longRunning) context.CommandTimeout = (int)Settings.Default.LongRunningDatabaseCommandTimeout.TotalSeconds;
-      return context;
-    }
-
-    public HiveDtoDao() { }
-
-    #region Task Methods
-    public DT.Task GetTask(Guid id) {
-      using (var db = CreateContext()) {
-        return DT.Convert.ToDto(db.Tasks.SingleOrDefault(x => x.TaskId == id));
-      }
-    }
-
-    public IEnumerable<DT.Task> GetTasks(Expression<Func<Task, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.Tasks.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public IEnumerable<DT.LightweightTask> GetLightweightTasks(Expression<Func<Task, bool>> predicate) {
-      List<DT.LightweightTask> tasks = new List<DT.LightweightTask>();
-
-      using (var db = CreateContext()) {
-        var tasksQuery = db.Tasks.Where(predicate).Select(task => new { task.TaskId, task.ExecutionTimeMs, task.ParentTaskId, task.StateLogs, task.State, task.Command });
-        var taskDatasQuery = db.Tasks.Where(predicate).Where(task => task.JobData != null).Select(task => new { task.TaskId, task.JobData.LastUpdate });
-
-        foreach (var task in tasksQuery) {
-          DT.LightweightTask t = new DT.LightweightTask();
-          t.Id = task.TaskId;
-          t.ExecutionTime = TimeSpan.FromMilliseconds(task.ExecutionTimeMs);
-          t.ParentTaskId = task.ParentTaskId;
-          t.StateLog = task.StateLogs == null ? new List<DT.StateLog>() : task.StateLogs.Select(x => DataTransfer.Convert.ToDto(x)).OrderBy(x => x.DateTime).ToList();
-          t.State = DataTransfer.Convert.ToDto(task.State);
-          t.Command = DataTransfer.Convert.ToDto(task.Command);
-          t.LastTaskDataUpdate = taskDatasQuery.Where(x => x.TaskId == task.TaskId).Count() > 0 ? taskDatasQuery.Select(x => x.LastUpdate).First() : DateTime.MinValue;
-          tasks.Add(t);
-        }
-      }
-      return tasks;
-    }
-
-    public IEnumerable<DT.LightweightTask> GetLightweightTasksWithoutStateLog(Expression<Func<Task, bool>> predicate) {
-      List<DT.LightweightTask> tasks = new List<DT.LightweightTask>();
-
-      using (var db = CreateContext()) {
-        var tasksQuery = db.Tasks.Where(predicate).Select(task => new { task.TaskId, task.ExecutionTimeMs, task.ParentTaskId, task.State, task.Command });
-        var taskDatasQuery = db.Tasks.Where(predicate).Where(task => task.JobData != null).Select(task => new { task.TaskId, task.JobData.LastUpdate });
-
-        foreach (var task in tasksQuery) {
-          DT.LightweightTask t = new DT.LightweightTask();
-          t.Id = task.TaskId;
-          t.ExecutionTime = TimeSpan.FromMilliseconds(task.ExecutionTimeMs);
-          t.ParentTaskId = task.ParentTaskId;
-          t.StateLog = new List<DT.StateLog>();
-          t.State = DataTransfer.Convert.ToDto(task.State);
-          t.Command = DataTransfer.Convert.ToDto(task.Command);
-          t.LastTaskDataUpdate = taskDatasQuery.Where(x => x.TaskId == task.TaskId).Count() > 0 ? taskDatasQuery.Select(x => x.LastUpdate).First() : DateTime.MinValue;
-          tasks.Add(t);
-        }
-      }
-      return tasks;
-    }
-
-    public Guid AddTask(DT.Task dto) {
-      using (var db = CreateContext()) {
-        var entity = DT.Convert.ToEntity(dto);
-        db.Tasks.InsertOnSubmit(entity);
-        db.SubmitChanges();
-        foreach (Guid pluginId in dto.PluginsNeededIds) {
-          db.RequiredPlugins.InsertOnSubmit(new RequiredPlugin() { TaskId = entity.TaskId, PluginId = pluginId });
-        }
-        db.SubmitChanges();
-        return entity.TaskId;
-      }
-    }
-
-    public void UpdateTaskAndPlugins(DT.Task dto) {
-      using (var db = CreateContext()) {
-        var entity = db.Tasks.FirstOrDefault(x => x.TaskId == dto.Id);
-        if (entity == null) db.Tasks.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        foreach (Guid pluginId in dto.PluginsNeededIds) {
-          if (db.RequiredPlugins.Count(p => p.PluginId == pluginId) == 0) {
-            db.RequiredPlugins.InsertOnSubmit(new RequiredPlugin() { TaskId = entity.TaskId, PluginId = pluginId });
-          }
-        }
-        db.SubmitChanges();
-      }
-    }
-
-    public void UpdateTaskAndStateLogs(DT.Task dto) {
-      using (var db = CreateContext()) {
-        var entity = db.Tasks.FirstOrDefault(x => x.TaskId == dto.Id);
-        if (entity == null) db.Tasks.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void UpdateTask(DT.Task dto) {
-      using (var db = CreateContext()) {
-        db.DeferredLoadingEnabled = false;
-
-        var entity = db.Tasks.FirstOrDefault(x => x.TaskId == dto.Id);
-        if (entity == null) db.Tasks.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntityTaskOnly(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeleteTask(Guid id) {
-      using (var db = CreateContext()) {
-        var entity = db.Tasks.FirstOrDefault(x => x.TaskId == id);
-        if (entity != null) db.Tasks.DeleteOnSubmit(entity);
-        db.SubmitChanges(); // taskData and child tasks are deleted by db-trigger
-      }
-    }
-
-    /// <summary>
-    /// returns all parent tasks which are waiting for their child tasks to finish
-    /// </summary>
-    /// <param name="resourceIds">list of resourceids which for which the task should be valid</param>
-    /// <param name="count">maximum number of task to return</param>
-    /// <param name="finished">if true, all parent task which have FinishWhenChildJobsFinished=true are returned, otherwise only FinishWhenChildJobsFinished=false are returned</param>
-    /// <returns></returns>
-    public IEnumerable<DT.Task> GetParentTasks(IEnumerable<Guid> resourceIds, int count, bool finished) {
-      using (var db = CreateContext()) {
-        var query = from ar in db.AssignedResources
-                    where resourceIds.Contains(ar.ResourceId)
-                       && ar.Task.State == TaskState.Waiting
-                       && ar.Task.IsParentTask
-                       && (finished ? ar.Task.FinishWhenChildJobsFinished : !ar.Task.FinishWhenChildJobsFinished)
-                       && (from child in db.Tasks
-                           where child.ParentTaskId == ar.Task.TaskId
-                           select child.State == TaskState.Finished
-                               || child.State == TaskState.Aborted
-                               || child.State == TaskState.Failed).All(x => x)
-                       && (from child in db.Tasks // avoid returning WaitForChildTasks task where no child-task exist (yet)
-                           where child.ParentTaskId == ar.Task.TaskId
-                           select child).Count() > 0
-                    orderby ar.Task.Priority descending, db.Random()
-                    select DT.Convert.ToDto(ar.Task);
-        return count == 0 ? query.ToArray() : query.Take(count).ToArray();
-      }
-    }
-
-    public IEnumerable<TaskInfoForScheduler> GetWaitingTasks(DT.Slave slave) {
-      using (var db = CreateContext()) {
-        var resourceIds = GetParentResources(slave.Id).Select(r => r.Id);
-        //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
-
-        var query = from ar in db.AssignedResources
-                    where resourceIds.Contains(ar.ResourceId)
-                       && !(ar.Task.IsParentTask && ar.Task.FinishWhenChildJobsFinished)
-                       && ar.Task.State == TaskState.Waiting
-                       && ar.Task.CoresNeeded <= slave.FreeCores
-                       && ar.Task.MemoryNeeded <= slave.FreeMemory
-                    select new TaskInfoForScheduler() { TaskId = ar.Task.TaskId, JobId = ar.Task.JobId, Priority = ar.Task.Priority };
-        var waitingTasks = query.ToArray();
-        return waitingTasks;
-      }
-    }
-
-    public DT.Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
-      using (var db = CreateContext()) {
-        db.DeferredLoadingEnabled = false;
-
-        db.StateLogs.InsertOnSubmit(new StateLog {
-          TaskId = taskId,
-          State = taskState,
-          SlaveId = slaveId,
-          UserId = userId,
-          Exception = exception,
-          DateTime = DateTime.Now
-        });
-        db.SubmitChanges();
-      }
-
-      using (var db = CreateContext()) {
-        db.DeferredLoadingEnabled = false;
-
-        var task = db.Tasks.SingleOrDefault(x => x.TaskId == taskId);
-        task.State = taskState;
-        db.SubmitChanges();
-      }
-
-      using (var db = CreateContext()) {
-        var task = db.Tasks.SingleOrDefault(x => x.TaskId == taskId);
-        return DT.Convert.ToDto(task);
-      }
-    }
-    #endregion
-
-    #region TaskData Methods
-    public DT.TaskData GetTaskData(Guid id) {
-      using (var db = CreateContext(true)) {
-        return DT.Convert.ToDto(db.TaskDatas.SingleOrDefault(x => x.TaskId == id));
-      }
-    }
-
-    public IEnumerable<DT.TaskData> GetTaskDatas(Expression<Func<TaskData, bool>> predicate) {
-      using (var db = CreateContext(true)) {
-        return db.TaskDatas.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public Guid AddTaskData(DT.TaskData dto) {
-      using (var db = CreateContext(true)) {
-        var entity = DT.Convert.ToEntity(dto);
-        db.TaskDatas.InsertOnSubmit(entity);
-        db.SubmitChanges();
-        return entity.TaskId;
-      }
-    }
-
-    public void UpdateTaskData(DT.TaskData dto) {
-      using (var db = CreateContext(true)) {
-        var entity = db.TaskDatas.FirstOrDefault(x => x.TaskId == dto.TaskId);
-        if (entity == null) db.TaskDatas.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeleteTaskData(Guid id) {
-      using (var db = CreateContext()) {
-        var entity = db.TaskDatas.FirstOrDefault(x => x.TaskId == id); // check if all the byte[] is loaded into memory here. otherwise work around to delete without loading it
-        if (entity != null) db.TaskDatas.DeleteOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region StateLog Methods
-    public DT.StateLog GetStateLog(Guid id) {
-      using (var db = CreateContext()) {
-        return DT.Convert.ToDto(db.StateLogs.SingleOrDefault(x => x.StateLogId == id));
-      }
-    }
-
-    public IEnumerable<DT.StateLog> GetStateLogs(Expression<Func<StateLog, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.StateLogs.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public Guid AddStateLog(DT.StateLog dto) {
-      using (var db = CreateContext()) {
-        var entity = DT.Convert.ToEntity(dto);
-        db.StateLogs.InsertOnSubmit(entity);
-        db.SubmitChanges();
-        return entity.StateLogId;
-      }
-    }
-
-    public void UpdateStateLog(DT.StateLog dto) {
-      using (var db = CreateContext()) {
-        var entity = db.StateLogs.FirstOrDefault(x => x.StateLogId == dto.Id);
-        if (entity == null) db.StateLogs.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeleteStateLog(Guid id) {
-      using (var db = CreateContext()) {
-        var entity = db.StateLogs.FirstOrDefault(x => x.StateLogId == id);
-        if (entity != null) db.StateLogs.DeleteOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region Job Methods
-    public DT.Job GetJob(Guid id) {
-      using (var db = CreateContext()) {
-        return AddStatsToJob(db, DT.Convert.ToDto(db.Jobs.SingleOrDefault(x => x.JobId == id)));
-      }
-    }
-
-    private DT.Job AddStatsToJob(HiveDataContext db, DT.Job exp) {
-      if (exp == null)
-        return null;
-
-      var jobs = db.Tasks.Where(j => j.JobId == exp.Id);
-      exp.JobCount = jobs.Count();
-      exp.CalculatingCount = jobs.Count(j => j.State == TaskState.Calculating);
-      exp.FinishedCount = jobs.Count(j => j.State == TaskState.Finished);
-      return exp;
-    }
-
-    public IEnumerable<DT.Job> GetJobs(Expression<Func<Job, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.Jobs.Where(predicate).Select(x => AddStatsToJob(db, DT.Convert.ToDto(x))).ToArray();
-      }
-    }
-
-    public IEnumerable<JobInfoForScheduler> GetJobInfoForScheduler(Expression<Func<Job, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.Jobs.Where(predicate).Select(x => new JobInfoForScheduler() { Id = x.JobId, DateCreated = x.DateCreated, OwnerUserId = x.OwnerUserId }).ToArray();
-      }
-    }
-
-    public Guid AddJob(DT.Job dto) {
-      using (var db = CreateContext()) {
-        var entity = DT.Convert.ToEntity(dto);
-        db.Jobs.InsertOnSubmit(entity);
-        if (!db.UserPriorities.Any(x => x.UserId == dto.OwnerUserId))
-          EnqueueUserPriority(new DT.UserPriority { Id = dto.OwnerUserId, DateEnqueued = dto.DateCreated });
-        db.SubmitChanges();
-        return entity.JobId;
-      }
-    }
-
-    public void UpdateJob(DT.Job dto) {
-      using (var db = CreateContext()) {
-        var entity = db.Jobs.FirstOrDefault(x => x.JobId == dto.Id);
-        if (entity == null) db.Jobs.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeleteJob(Guid id) {
-      using (var db = CreateContext()) {
-        var entity = db.Jobs.FirstOrDefault(x => x.JobId == id);
-        if (entity != null) db.Jobs.DeleteOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region JobPermission Methods
-    public DT.JobPermission GetJobPermission(Guid jobId, Guid grantedUserId) {
-      using (var db = CreateContext()) {
-        return DT.Convert.ToDto(db.JobPermissions.SingleOrDefault(x => x.JobId == jobId && x.GrantedUserId == grantedUserId));
-      }
-    }
-
-    public IEnumerable<DT.JobPermission> GetJobPermissions(Expression<Func<JobPermission, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.JobPermissions.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public void AddJobPermission(DT.JobPermission dto) {
-      using (var db = CreateContext()) {
-        var entity = DT.Convert.ToEntity(dto);
-        db.JobPermissions.InsertOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void UpdateJobPermission(DT.JobPermission dto) {
-      using (var db = CreateContext()) {
-        var entity = db.JobPermissions.FirstOrDefault(x => x.JobId == dto.JobId && x.GrantedUserId == dto.GrantedUserId);
-        if (entity == null) db.JobPermissions.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeleteJobPermission(Guid jobId, Guid grantedUserId) {
-      using (var db = CreateContext()) {
-        var entity = db.JobPermissions.FirstOrDefault(x => x.JobId == jobId && x.GrantedUserId == grantedUserId);
-        if (entity != null) db.JobPermissions.DeleteOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-
-    /// <summary>
-    /// Sets the permissions for a experiment. makes sure that only one permission per user exists.
-    /// </summary>
-    public void SetJobPermission(Guid jobId, Guid grantedByUserId, Guid grantedUserId, Permission permission) {
-      using (var db = CreateContext()) {
-        JobPermission jobPermission = db.JobPermissions.SingleOrDefault(x => x.JobId == jobId && x.GrantedUserId == grantedUserId);
-        if (jobPermission != null) {
-          if (permission == Permission.NotAllowed) {
-            // not allowed, delete
-            db.JobPermissions.DeleteOnSubmit(jobPermission);
-          } else {
-            // update
-            jobPermission.Permission = permission;
-            jobPermission.GrantedByUserId = grantedByUserId; // update grantedByUserId, always the last "granter" is stored
-          }
-        } else {
-          // insert
-          if (permission != Permission.NotAllowed) {
-            jobPermission = new JobPermission() { JobId = jobId, GrantedByUserId = grantedByUserId, GrantedUserId = grantedUserId, Permission = permission };
-            db.JobPermissions.InsertOnSubmit(jobPermission);
-          }
-        }
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region Plugin Methods
-    public DT.Plugin GetPlugin(Guid id) {
-      using (var db = CreateContext()) {
-        return DT.Convert.ToDto(db.Plugins.SingleOrDefault(x => x.PluginId == id));
-      }
-    }
-
-    public IEnumerable<DT.Plugin> GetPlugins(Expression<Func<Plugin, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.Plugins.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public Guid AddPlugin(DT.Plugin dto) {
-      using (var db = CreateContext()) {
-        var entity = DT.Convert.ToEntity(dto);
-        db.Plugins.InsertOnSubmit(entity);
-        db.SubmitChanges();
-        return entity.PluginId;
-      }
-    }
-
-    public void UpdatePlugin(DT.Plugin dto) {
-      using (var db = CreateContext()) {
-        var entity = db.Plugins.FirstOrDefault(x => x.PluginId == dto.Id);
-        if (entity == null) db.Plugins.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeletePlugin(Guid id) {
-      using (var db = CreateContext()) {
-        var entity = db.Plugins.FirstOrDefault(x => x.PluginId == id);
-        if (entity != null) db.Plugins.DeleteOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region PluginData Methods
-    public DT.PluginData GetPluginData(Guid id) {
-      using (var db = CreateContext()) {
-        return DT.Convert.ToDto(db.PluginDatas.SingleOrDefault(x => x.PluginDataId == id));
-      }
-    }
-
-    public IEnumerable<DT.PluginData> GetPluginDatas(Expression<Func<PluginData, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.PluginDatas.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public Guid AddPluginData(DT.PluginData dto) {
-      using (var db = CreateContext()) {
-        var entity = DT.Convert.ToEntity(dto);
-        db.PluginDatas.InsertOnSubmit(entity);
-        db.SubmitChanges();
-        return entity.PluginDataId;
-      }
-    }
-
-    public void UpdatePluginData(DT.PluginData dto) {
-      using (var db = CreateContext()) {
-        var entity = db.PluginDatas.FirstOrDefault(x => x.PluginId == dto.PluginId);
-        if (entity == null) db.PluginDatas.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeletePluginData(Guid id) {
-      using (var db = CreateContext()) {
-        var entity = db.PluginDatas.FirstOrDefault(x => x.PluginDataId == id);
-        if (entity != null) db.PluginDatas.DeleteOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region Slave Methods
-    public DT.Slave GetSlave(Guid id) {
-      using (var db = CreateContext()) {
-        return DT.Convert.ToDto(db.Resources.OfType<Slave>().SingleOrDefault(x => x.ResourceId == id));
-      }
-    }
-
-    public IEnumerable<DT.Slave> GetSlaves(Expression<Func<Slave, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.Resources.OfType<Slave>().Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public Guid AddSlave(DT.Slave dto) {
-      using (var db = CreateContext()) {
-        var entity = DT.Convert.ToEntity(dto);
-        db.Resources.InsertOnSubmit(entity);
-        db.SubmitChanges();
-        return entity.ResourceId;
-      }
-    }
-
-    public void UpdateSlave(DT.Slave dto) {
-      using (var db = CreateContext()) {
-        var entity = db.Resources.OfType<Slave>().FirstOrDefault(x => x.ResourceId == dto.Id);
-        if (entity == null) db.Resources.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeleteSlave(Guid id) {
-      using (var db = CreateContext()) {
-        var entity = db.Resources.OfType<Slave>().FirstOrDefault(x => x.ResourceId == id);
-        if (entity != null) db.Resources.DeleteOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region SlaveGroup Methods
-    public DT.SlaveGroup GetSlaveGroup(Guid id) {
-      using (var db = CreateContext()) {
-        return DT.Convert.ToDto(db.Resources.OfType<SlaveGroup>().SingleOrDefault(x => x.ResourceId == id));
-      }
-    }
-
-    public IEnumerable<DT.SlaveGroup> GetSlaveGroups(Expression<Func<SlaveGroup, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.Resources.OfType<SlaveGroup>().Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public Guid AddSlaveGroup(DT.SlaveGroup dto) {
-      using (var db = CreateContext()) {
-        if (dto.Id == Guid.Empty)
-          dto.Id = Guid.NewGuid();
-        var entity = DT.Convert.ToEntity(dto);
-        db.Resources.InsertOnSubmit(entity);
-        db.SubmitChanges();
-        return entity.ResourceId;
-      }
-    }
-
-    public void UpdateSlaveGroup(DT.SlaveGroup dto) {
-      using (var db = CreateContext()) {
-        var entity = db.Resources.OfType<SlaveGroup>().FirstOrDefault(x => x.ResourceId == dto.Id);
-        if (entity == null) db.Resources.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeleteSlaveGroup(Guid id) {
-      using (var db = CreateContext()) {
-        var entity = db.Resources.OfType<SlaveGroup>().FirstOrDefault(x => x.ResourceId == id);
-        if (entity != null) {
-          if (db.Resources.Where(r => r.ParentResourceId == id).Count() > 0) {
-            throw new InvalidOperationException("Cannot delete SlaveGroup as long as there are Slaves in the group");
-          }
-          db.Resources.DeleteOnSubmit(entity);
-        }
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region Resource Methods
-    public DT.Resource GetResource(Guid id) {
-      using (var db = CreateContext()) {
-        return DT.Convert.ToDto(db.Resources.SingleOrDefault(x => x.ResourceId == id));
-      }
-    }
-
-    public IEnumerable<DT.Resource> GetResources(Expression<Func<Resource, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.Resources.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public Guid AddResource(DT.Resource dto) {
-      using (var db = CreateContext()) {
-        var entity = DT.Convert.ToEntity(dto);
-        db.Resources.InsertOnSubmit(entity);
-        db.SubmitChanges();
-        return entity.ResourceId;
-      }
-    }
-
-    public void UpdateResource(DT.Resource dto) {
-      using (var db = CreateContext()) {
-        var entity = db.Resources.FirstOrDefault(x => x.ResourceId == dto.Id);
-        if (entity == null) db.Resources.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeleteResource(Guid id) {
-      using (var db = CreateContext()) {
-        var entity = db.Resources.FirstOrDefault(x => x.ResourceId == id);
-        if (entity != null) db.Resources.DeleteOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void AssignJobToResource(Guid taskId, IEnumerable<Guid> resourceIds) {
-      using (var db = CreateContext()) {
-        db.DeferredLoadingEnabled = false;
-
-        List<AssignedResource> assignedResources = new List<AssignedResource>();
-        foreach (Guid rId in resourceIds) {
-          assignedResources.Add(new AssignedResource() { TaskId = taskId, ResourceId = rId });
-        }
-        db.AssignedResources.InsertAllOnSubmit(assignedResources);
-        db.SubmitChanges();
-      }
-    }
-
-    public IEnumerable<DT.Resource> GetAssignedResources(Guid jobId) {
-      using (var db = CreateContext()) {
-        var job = db.Tasks.Where(x => x.TaskId == jobId).Single();
-        return job.AssignedResources.Select(x => DT.Convert.ToDto(x.Resource)).ToArray();
-      }
-    }
-
-    /// <summary>
-    /// Returns all parent resources of a resource (the given resource is also added)
-    /// </summary>
-    public IEnumerable<DT.Resource> GetParentResources(Guid resourceId) {
-      using (var db = CreateContext()) {
-        var resources = new List<Resource>();
-        CollectParentResources(resources, db.Resources.Where(r => r.ResourceId == resourceId).Single());
-        return resources.Select(r => DT.Convert.ToDto(r)).ToArray();
-      }
-    }
-
-    private static void CollectParentResources(ICollection<Resource> resources, Resource resource) {
-      if (resource == null) return;
-      resources.Add(resource);
-      CollectParentResources(resources, resource.ParentResource);
-    }
-
-    /// <summary>
-    /// Returns all child resources of a resource (without the given resource)
-    /// </summary>
-    public IEnumerable<DT.Resource> GetChildResources(Guid resourceId) {
-      using (var db = CreateContext()) {
-        return CollectChildResources(resourceId, db);
-      }
-    }
-
-    public IEnumerable<DT.Resource> CollectChildResources(Guid resourceId, HiveDataContext db) {
-      var childs = new List<DT.Resource>();
-      foreach (var child in db.Resources.Where(x => x.ParentResourceId == resourceId)) {
-        childs.Add(DT.Convert.ToDto(child));
-        childs.AddRange(CollectChildResources(child.ResourceId, db));
-      }
-      return childs;
-    }
-
-    public IEnumerable<DT.Task> GetJobsByResourceId(Guid resourceId) {
-      using (var db = CreateContext()) {
-        var resources = GetChildResources(resourceId).Select(x => x.Id).ToList();
-        resources.Add(resourceId);
-
-        var jobs = db.Tasks.Where(j =>
-          j.State == TaskState.Calculating &&
-          j.StateLogs.OrderByDescending(x => x.DateTime).First().SlaveId.HasValue &&
-          resources.Contains(j.StateLogs.OrderByDescending(x => x.DateTime).First().SlaveId.Value));
-        return jobs.Select(j => DT.Convert.ToDto(j)).ToArray();
-      }
-    }
-    #endregion
-
-    #region ResourcePermission Methods
-    public DT.ResourcePermission GetResourcePermission(Guid resourceId, Guid grantedUserId) {
-      using (var db = CreateContext()) {
-        return DT.Convert.ToDto(db.ResourcePermissions.SingleOrDefault(x => x.ResourceId == resourceId && x.GrantedUserId == grantedUserId));
-      }
-    }
-
-    public IEnumerable<DT.ResourcePermission> GetResourcePermissions(Expression<Func<ResourcePermission, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.ResourcePermissions.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public void AddResourcePermission(DT.ResourcePermission dto) {
-      using (var db = CreateContext()) {
-        var entity = db.ResourcePermissions.SingleOrDefault(x => x.ResourceId == dto.ResourceId && x.GrantedUserId == dto.GrantedUserId);
-        if (entity == null) { db.ResourcePermissions.InsertOnSubmit(DT.Convert.ToEntity(dto)); db.SubmitChanges(); }
-      }
-    }
-
-    public void UpdateResourcePermission(DT.ResourcePermission dto) {
-      using (var db = CreateContext()) {
-        var entity = db.ResourcePermissions.FirstOrDefault(x => x.ResourceId == dto.ResourceId && x.GrantedUserId == dto.GrantedUserId);
-        if (entity == null) db.ResourcePermissions.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeleteResourcePermission(Guid resourceId, Guid grantedUserId) {
-      using (var db = CreateContext()) {
-        var entity = db.ResourcePermissions.FirstOrDefault(x => x.ResourceId == resourceId && x.GrantedUserId == grantedUserId);
-        if (entity != null) db.ResourcePermissions.DeleteOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region Authorization Methods
-    public Permission GetPermissionForTask(Guid taskId, Guid userId) {
-      using (var db = CreateContext()) {
-        return GetPermissionForJob(GetJobForTask(taskId), userId);
-      }
-    }
-
-    public Permission GetPermissionForJob(Guid jobId, Guid userId) {
-      using (var db = CreateContext()) {
-        Job job = db.Jobs.SingleOrDefault(x => x.JobId == jobId);
-        if (job == null) return Permission.NotAllowed;
-        if (job.OwnerUserId == userId) return Permission.Full;
-        JobPermission permission = db.JobPermissions.SingleOrDefault(p => p.JobId == jobId && p.GrantedUserId == userId);
-        return permission != null ? permission.Permission : Permission.NotAllowed;
-      }
-    }
-
-    public Guid GetJobForTask(Guid taskId) {
-      using (var db = CreateContext()) {
-        return db.Tasks.Single(j => j.TaskId == taskId).JobId;
-      }
-    }
-    #endregion
-
-    #region Lifecycle Methods
-    public DateTime GetLastCleanup() {
-      using (var db = CreateContext()) {
-        var entity = db.Lifecycles.SingleOrDefault();
-        return entity != null ? entity.LastCleanup : DateTime.MinValue;
-      }
-    }
-
-    public void SetLastCleanup(DateTime datetime) {
-      using (var db = CreateContext()) {
-        var entity = db.Lifecycles.SingleOrDefault();
-        if (entity != null) {
-          entity.LastCleanup = datetime;
-        } else {
-          entity = new Lifecycle();
-          entity.LifecycleId = 0; // always only one entry with ID:0
-          entity.LastCleanup = datetime;
-          db.Lifecycles.InsertOnSubmit(entity);
-        }
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region Downtime Methods
-    public DT.Downtime GetDowntime(Guid id) {
-      using (var db = CreateContext()) {
-        return DT.Convert.ToDto(db.Downtimes.SingleOrDefault(x => x.DowntimeId == id));
-      }
-    }
-
-    public IEnumerable<DT.Downtime> GetDowntimes(Expression<Func<Downtime, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.Downtimes.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public Guid AddDowntime(DT.Downtime dto) {
-      using (var db = CreateContext()) {
-        var entity = DT.Convert.ToEntity(dto);
-        db.Downtimes.InsertOnSubmit(entity);
-        db.SubmitChanges();
-        return entity.DowntimeId;
-      }
-    }
-
-    public void UpdateDowntime(DT.Downtime dto) {
-      using (var db = CreateContext()) {
-        var entity = db.Downtimes.FirstOrDefault(x => x.DowntimeId == dto.Id);
-        if (entity == null) db.Downtimes.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public void DeleteDowntime(Guid id) {
-      using (var db = CreateContext()) {
-        var entity = db.Downtimes.FirstOrDefault(x => x.DowntimeId == id);
-        if (entity != null) db.Downtimes.DeleteOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region Statistics Methods
-    public DT.Statistics GetStatistic(Guid id) {
-      using (var db = CreateContext()) {
-        return DT.Convert.ToDto(db.Statistics.SingleOrDefault(x => x.StatisticsId == id));
-      }
-    }
-
-    public IEnumerable<DT.Statistics> GetStatistics(Expression<Func<Statistics, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.Statistics.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public Guid AddStatistics(DT.Statistics dto) {
-      using (var db = CreateContext()) {
-        var entity = DT.Convert.ToEntity(dto);
-        db.Statistics.InsertOnSubmit(entity);
-        db.SubmitChanges();
-        foreach (var slaveStat in dto.SlaveStatistics) {
-          slaveStat.Id = entity.StatisticsId;
-          db.SlaveStatistics.InsertOnSubmit(DT.Convert.ToEntity(slaveStat));
-        }
-        if (dto.UserStatistics != null) {
-          foreach (var userStat in dto.UserStatistics) {
-            userStat.Id = entity.StatisticsId;
-            db.UserStatistics.InsertOnSubmit(DT.Convert.ToEntity(userStat));
-          }
-        }
-        db.SubmitChanges();
-        return entity.StatisticsId;
-      }
-    }
-
-    public void DeleteStatistics(Guid id) {
-      using (var db = CreateContext()) {
-        var entity = db.Statistics.FirstOrDefault(x => x.StatisticsId == id);
-        if (entity != null) db.Statistics.DeleteOnSubmit(entity);
-        db.SubmitChanges();
-      }
-    }
-
-    public Dictionary<Guid, int> GetWaitingTasksByUser() {
-      using (var db = CreateContext()) {
-        var waitingTasksByUser = from task in db.Tasks
-                                 where task.State == TaskState.Waiting
-                                 group task by task.Job.OwnerUserId into g
-                                 select new { UserId = g.Key, UsedCores = g.Count() };
-        return waitingTasksByUser.ToDictionary(x => x.UserId, x => x.UsedCores);
-      }
-    }
-
-    public Dictionary<Guid, int> GetWaitingTasksByUserForResources(List<Guid> resourceIds) {
-      using (var db = CreateContext()) {
-        var waitingTasksByUser = from task in db.Tasks
-                                 where task.State == TaskState.Waiting && task.AssignedResources.Any(x => resourceIds.Contains(x.ResourceId))
-                                 group task by task.Job.OwnerUserId into g
-                                 select new { UserId = g.Key, UsedCores = g.Count() };
-        return waitingTasksByUser.ToDictionary(x => x.UserId, x => x.UsedCores);
-      }
-    }
-
-    public Dictionary<Guid, int> GetCalculatingTasksByUser() {
-      using (var db = CreateContext()) {
-        var calculatingTasksByUser = from task in db.Tasks
-                                     where task.State == TaskState.Calculating
-                                     group task by task.Job.OwnerUserId into g
-                                     select new { UserId = g.Key, UsedCores = g.Count() };
-        return calculatingTasksByUser.ToDictionary(x => x.UserId, x => x.UsedCores);
-      }
-    }
-
-    public Dictionary<Guid, int> GetCalculatingTasksByUserForResources(List<Guid> resourceIds) {
-      using (var db = CreateContext()) {
-        var calculatingTasksByUser = from task in db.Tasks
-                                     where task.State == TaskState.Calculating && task.AssignedResources.Any(x => resourceIds.Contains(x.ResourceId))
-                                     group task by task.Job.OwnerUserId into g
-                                     select new { UserId = g.Key, UsedCores = g.Count() };
-        return calculatingTasksByUser.ToDictionary(x => x.UserId, x => x.UsedCores);
-      }
-    }
-
-    public List<DT.UserStatistics> GetUserStatistics() {
-      using (var db = CreateContext()) {
-        var userStats = new Dictionary<Guid, DT.UserStatistics>();
-
-        var usedCoresByUser = from job in db.Tasks
-                              where job.State == TaskState.Calculating
-                              group job by job.Job.OwnerUserId into g
-                              select new { UserId = g.Key, UsedCores = g.Count() };
-
-        foreach (var item in usedCoresByUser) {
-          if (!userStats.ContainsKey(item.UserId)) {
-            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
-          }
-          userStats[item.UserId].UsedCores += item.UsedCores;
-        }
-
-        var executionTimesByUser = from task in db.Tasks
-                                   group task by task.Job.OwnerUserId into g
-                                   select new { UserId = g.Key, ExecutionTime = TimeSpan.FromMilliseconds(g.Select(x => x.ExecutionTimeMs).Sum()) };
-        foreach (var item in executionTimesByUser) {
-          if (!userStats.ContainsKey(item.UserId)) {
-            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
-          }
-          userStats[item.UserId].ExecutionTime += item.ExecutionTime;
-        }
-
-        // execution times only of finished task - necessary to compute efficieny
-        var executionTimesFinishedJobs = from job in db.Tasks
-                                         where job.State == TaskState.Finished
-                                         group job by job.Job.OwnerUserId into g
-                                         select new { UserId = g.Key, ExecutionTimeFinishedJobs = TimeSpan.FromMilliseconds(g.Select(x => x.ExecutionTimeMs).Sum()) };
-
-        foreach (var item in executionTimesFinishedJobs) {
-          if (!userStats.ContainsKey(item.UserId)) {
-            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
-          }
-          userStats[item.UserId].ExecutionTimeFinishedJobs += item.ExecutionTimeFinishedJobs;
-        }
-
-        // start to end times only of finished task - necessary to compute efficiency
-        var startToEndTimesFinishedJobs = from job in db.Tasks
-                                          where job.State == TaskState.Finished
-                                          group job by job.Job.OwnerUserId into g
-                                          select new {
-                                            UserId = g.Key,
-                                            StartToEndTime = new TimeSpan(g.Select(x => x.StateLogs.OrderByDescending(sl => sl.DateTime).First().DateTime - x.StateLogs.OrderBy(sl => sl.DateTime).First().DateTime).Sum(ts => ts.Ticks))
-                                          };
-        foreach (var item in startToEndTimesFinishedJobs) {
-          if (!userStats.ContainsKey(item.UserId)) {
-            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
-          }
-          userStats[item.UserId].StartToEndTime += item.StartToEndTime;
-        }
-
-        // also consider executiontimes of DeletedJobStats 
-        var deletedJobsExecutionTimesByUsers = from del in db.DeletedJobStatistics
-                                               group del by del.UserId into g
-                                               select new {
-                                                 UserId = g.Key,
-                                                 ExecutionTime = TimeSpan.FromSeconds(g.Select(x => x.ExecutionTimeS).Sum()),
-                                                 ExecutionTimeFinishedJobs = TimeSpan.FromSeconds(g.Select(x => x.ExecutionTimeSFinishedJobs).Sum()),
-                                                 StartToEndTime = TimeSpan.FromSeconds(g.Select(x => x.StartToEndTimeS).Sum())
-                                               };
-        foreach (var item in deletedJobsExecutionTimesByUsers) {
-          if (!userStats.ContainsKey(item.UserId)) {
-            userStats.Add(item.UserId, new DT.UserStatistics() { UserId = item.UserId });
-          }
-          userStats[item.UserId].ExecutionTime += item.ExecutionTime;
-          userStats[item.UserId].ExecutionTimeFinishedJobs += item.ExecutionTimeFinishedJobs;
-          userStats[item.UserId].StartToEndTime += item.StartToEndTime;
-        }
-
-        return userStats.Values.ToList();
-      }
-    }
-    #endregion
-
-    #region UserPriority Methods
-    public IEnumerable<DT.UserPriority> GetUserPriorities(Expression<Func<UserPriority, bool>> predicate) {
-      using (var db = CreateContext()) {
-        return db.UserPriorities.Where(predicate).Select(x => DT.Convert.ToDto(x)).ToArray();
-      }
-    }
-
-    public void EnqueueUserPriority(DT.UserPriority dto) {
-      using (var db = CreateContext()) {
-        var entity = db.UserPriorities.FirstOrDefault(x => x.UserId == dto.Id);
-        if (entity == null) db.UserPriorities.InsertOnSubmit(DT.Convert.ToEntity(dto));
-        else DT.Convert.ToEntity(dto, entity);
-        db.SubmitChanges();
-      }
-    }
-    #endregion
-
-    #region Helpers
-    private void CollectChildTasks(HiveDataContext db, Guid parentTaskId, List<Task> collection) {
-      var tasks = db.Tasks.Where(j => j.ParentTaskId == parentTaskId);
-      foreach (var task in tasks) {
-        collection.Add(task);
-        if (task.IsParentTask)
-          CollectChildTasks(db, task.TaskId, collection);
-      }
-    }
-    #endregion
-  }
-}
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveJanitor.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveJanitor.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveJanitor.cs	(revision 9434)
@@ -37,6 +37,6 @@
     }
 
-    private IHiveDtoDao dao {
-      get { return ServiceLocator.Instance.HiveDtoDao; }
+    private IHiveDao dao {
+      get { return ServiceLocator.Instance.HiveDao; }
     }
 
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveOperationContext.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveOperationContext.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveOperationContext.cs	(revision 9434)
@@ -22,15 +22,13 @@
 using System;
 using System.Collections.ObjectModel;
-using System.Diagnostics;
-using System.IO;
 using System.ServiceModel;
 using System.ServiceModel.Channels;
 using System.ServiceModel.Description;
 using System.ServiceModel.Dispatcher;
-using System.Text;
 using HeuristicLab.Services.Hive.DataAccess;
 
 namespace HeuristicLab.Services.Hive {
   public class HiveOperationContext : IExtension<OperationContext> {
+
     public static HiveOperationContext Current {
       get {
@@ -42,9 +40,5 @@
     public HiveDataContext DataContext {
       get {
-        if (dataContext == null) {
-          dataContext = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString);
-          //dataContext.Log = new DebugWriter();
-        }
-        return dataContext;
+        return dataContext ?? (dataContext = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString));
       }
     }
@@ -67,5 +61,5 @@
     }
 
-    public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState) {
+    public void BeforeSendReply(ref Message reply, object correlationState) {
       OperationContext.Current.Extensions.Remove(HiveOperationContext.Current);
     }
@@ -88,21 +82,3 @@
     }
   }
-
-  internal class DebugWriter : TextWriter {
-    public override Encoding Encoding {
-      get { return Encoding.UTF8; }
-    }
-
-    public override void Write(char value) {
-      Debug.Write(value);
-    }
-
-    public override void Write(string value) {
-      Debug.Write(value);
-    }
-
-    public override void WriteLine(string value) {
-      Debug.WriteLine(value);
-    }
-  }
 }
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 9434)
@@ -39,10 +39,10 @@
   [HiveOperationContextBehavior]
   public class HiveService : IHiveService {
-    private IHiveDtoDao dtoDao {
-      get { return ServiceLocator.Instance.HiveDtoDao; }
-    }
     private IHiveDao dao {
       get { return ServiceLocator.Instance.HiveDao; }
     }
+    private IOptimizedHiveDao optimizedDao {
+      get { return ServiceLocator.Instance.OptimizedHiveDao; }
+    }
     private Access.IRoleVerifier authen {
       get { return ServiceLocator.Instance.RoleVerifier; }
@@ -68,11 +68,17 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        task.Id = dtoDao.AddTask(task);
-        taskData.TaskId = task.Id;
-        taskData.LastUpdate = DateTime.Now;
-        dtoDao.AssignJobToResource(task.Id, resourceIds);
-        dtoDao.AddTaskData(taskData);
-        dtoDao.UpdateTaskState(task.Id, DA.TaskState.Waiting, null, userManager.CurrentUserId, null);
-        return taskData.TaskId;
+        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);
     }
@@ -80,8 +86,6 @@
     public Guid AddChildTask(Guid parentTaskId, Task task, TaskData taskData) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      return trans.UseTransaction(() => {
-        task.ParentTaskId = parentTaskId;
-        return AddTask(task, taskData, dtoDao.GetAssignedResources(parentTaskId).Select(x => x.Id));
-      }, false, true);
+      task.ParentTaskId = parentTaskId;
+      return AddTask(task, taskData, optimizedDao.GetAssignedResourceIds(parentTaskId));
     }
 
@@ -91,5 +95,5 @@
 
       return trans.UseTransaction(() => {
-        return DT.Convert.ToDto(dao.GetTaskById(taskId));
+        return DT.Convert.ToDto(optimizedDao.GetTaskById(taskId));
       }, false, false);
     }
@@ -98,5 +102,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        var tasks = dtoDao.GetTasks(x => true);
+        var tasks = dao.GetTasks(x => true);
         foreach (var task in tasks)
           author.AuthorizeForTask(task.Id, Permission.Read);
@@ -109,5 +113,5 @@
 
       return trans.UseTransaction(() => {
-        var tasks = dtoDao.GetTasks(x => taskIds.Contains(x.TaskId)).Select(x => new LightweightTask(x)).ToArray();
+        var tasks = dao.GetTasks(x => taskIds.Contains(x.TaskId)).Select(x => new LightweightTask(x)).ToArray();
         foreach (var task in tasks)
           author.AuthorizeForTask(task.Id, Permission.Read);
@@ -132,5 +136,5 @@
 
       return trans.UseTransaction(() => {
-        return dao.GetLightweightTasks(jobId).ToArray();
+        return optimizedDao.GetLightweightTasks(jobId).ToArray();
       }, false, true);
     }
@@ -141,5 +145,5 @@
 
       return trans.UseTransaction(() => {
-        return dtoDao.GetLightweightTasksWithoutStateLog(task => task.JobId == jobId).ToArray();
+        return dao.GetLightweightTasksWithoutStateLog(task => task.JobId == jobId).ToArray();
       }, false, false);
     }
@@ -150,5 +154,5 @@
 
       return trans.UseTransaction(() => {
-        return dtoDao.GetTaskData(taskId);
+        return dao.GetTaskData(taskId);
       });
     }
@@ -159,6 +163,6 @@
 
       trans.UseTransaction(() => {
-        var task = dao.GetTaskByDto(taskDto);
-        dao.UpdateTask(task);
+        var task = optimizedDao.GetTaskByDto(taskDto);
+        optimizedDao.UpdateTask(task);
       });
     }
@@ -169,12 +173,12 @@
 
       trans.UseTransaction(() => {
-        var t = dao.GetTaskByDto(task);
-        dao.UpdateTask(t);
-      });
-
-      trans.UseTransaction(() => {
-        var data = dao.GetTaskDataByDto(taskData);
+        var t = optimizedDao.GetTaskByDto(task);
+        optimizedDao.UpdateTask(t);
+      });
+
+      trans.UseTransaction(() => {
+        var data = optimizedDao.GetTaskDataByDto(taskData);
         data.LastUpdate = DateTime.Now;
-        dao.UpdateTaskData(data);
+        optimizedDao.UpdateTaskData(data);
       });
     }
@@ -184,5 +188,5 @@
       author.AuthorizeForTask(taskId, Permission.Full);
       trans.UseTransaction(() => {
-        dtoDao.DeleteTask(taskId);
+        dao.DeleteTask(taskId);
       });
     }
@@ -194,6 +198,6 @@
         var tasks = GetChildTasks(parentTaskId, true, false);
         foreach (var task in tasks) {
-          dtoDao.DeleteTask(task.Id);
-          dtoDao.DeleteTaskData(task.Id);
+          dao.DeleteTask(task.Id);
+          dao.DeleteTaskData(task.Id);
         };
       });
@@ -205,5 +209,5 @@
 
       return trans.UseTransaction(() => {
-        var task = dao.UpdateTaskState(taskId, DT.Convert.ToEntity(taskState), slaveId, userId, exception);
+        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) {
@@ -215,8 +219,8 @@
         } else if (taskState == TaskState.Paused && !task.Command.HasValue) {
           // slave paused and uploaded the task (no user-command) -> set waiting.
-          task = dao.UpdateTaskState(taskId, DA.TaskState.Waiting, slaveId, userId, exception);
-        }
-
-        //dao.UpdateTaskAndPlugins(task); no idea why this is needed
+          task = optimizedDao.UpdateTaskState(taskId, DA.TaskState.Waiting, slaveId, userId, exception);
+        }
+
+        //optimizedDao.UpdateTaskAndPlugins(task); no idea why this is needed
         return DT.Convert.ToDto(task);
       });
@@ -225,5 +229,5 @@
     public IEnumerable<Task> GetTasksByResourceId(Guid resourceId) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
-      var tasks = trans.UseTransaction(() => dtoDao.GetJobsByResourceId(resourceId));
+      var tasks = trans.UseTransaction(() => dao.GetJobsByResourceId(resourceId));
       foreach (var task in tasks)
         author.AuthorizeForTask(task.Id, Permission.Read);
@@ -237,8 +241,8 @@
       author.AuthorizeForTask(taskId, Permission.Full);
       trans.UseTransaction(() => {
-        var task = dtoDao.GetTask(taskId);
+        var task = dao.GetTask(taskId);
         if (task.State == TaskState.Calculating || task.State == TaskState.Transferring) {
           task.Command = Command.Stop;
-          dtoDao.UpdateTask(task);
+          dao.UpdateTask(task);
         } else {
           if (task.State != TaskState.Aborted && task.State != TaskState.Finished && task.State != TaskState.Failed) {
@@ -253,8 +257,8 @@
       author.AuthorizeForTask(taskId, Permission.Full);
       trans.UseTransaction(() => {
-        var job = dtoDao.GetTask(taskId);
+        var job = dao.GetTask(taskId);
         if (job.State == TaskState.Calculating || job.State == TaskState.Transferring) {
           job.Command = Command.Pause;
-          dtoDao.UpdateTask(job);
+          dao.UpdateTask(job);
         } else {
           job = UpdateTaskState(taskId, TaskState.Paused, null, null, string.Empty);
@@ -267,7 +271,7 @@
       author.AuthorizeForTask(taskId, Permission.Full);
       trans.UseTransaction(() => {
-        Task task = dtoDao.UpdateTaskState(taskId, DA.TaskState.Waiting, null, userManager.CurrentUserId, string.Empty);
+        Task task = dao.UpdateTaskState(taskId, DA.TaskState.Waiting, null, userManager.CurrentUserId, string.Empty);
         task.Command = null;
-        dtoDao.UpdateTask(task);
+        dao.UpdateTask(task);
       });
     }
@@ -279,10 +283,10 @@
       author.AuthorizeForJob(id, Permission.Read);
       return trans.UseTransaction(() => {
-        var job = dtoDao.GetJobs(x =>
+        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(dtoDao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
+          job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
           job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
         }
@@ -294,8 +298,8 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        var jobs = dtoDao.GetJobs(x => x.OwnerUserId == userManager.CurrentUserId || x.JobPermissions.Count(hep => hep.Permission != DA.Permission.NotAllowed && hep.GrantedUserId == userManager.CurrentUserId) > 0);
+        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(dtoDao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
+          job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
           job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
         }
@@ -307,7 +311,7 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
       return trans.UseTransaction(() => {
-        var jobs = dtoDao.GetJobs(x => true);
+        var jobs = dao.GetJobs(x => true);
         foreach (var job in jobs) { // no authorization here, since this method is admin-only! (admin is allowed to read all task)
-          job.Permission = DT.Convert.ToDto(dtoDao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
+          job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
           job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
         }
@@ -321,5 +325,5 @@
         jobDto.OwnerUserId = userManager.CurrentUserId;
         jobDto.DateCreated = DateTime.Now;
-        return dtoDao.AddJob(jobDto);
+        return dao.AddJob(jobDto);
       });
     }
@@ -329,5 +333,5 @@
       author.AuthorizeForJob(jobDto.Id, Permission.Full);
       trans.UseTransaction(() => {
-        dtoDao.UpdateJob(jobDto);
+        dao.UpdateJob(jobDto);
       });
     }
@@ -337,5 +341,5 @@
       author.AuthorizeForJob(jobId, Permission.Full);
       trans.UseTransaction(() => {
-        dtoDao.DeleteJob(jobId); // child task will be deleted by db-trigger
+        dao.DeleteJob(jobId); // child task will be deleted by db-trigger
       });
     }
@@ -346,9 +350,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        Job job = dtoDao.GetJob(jobId);
+        Job job = dao.GetJob(jobId);
         if (job == null) throw new FaultException<FaultReason>(new FaultReason("Could not find task with id " + jobId));
-        Permission perm = DT.Convert.ToDto(dtoDao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
+        Permission perm = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
         if (perm != Permission.Full) throw new FaultException<FaultReason>(new FaultReason("Not allowed to grant permissions for this experiment"));
-        dtoDao.SetJobPermission(jobId, userManager.CurrentUserId, grantedUserId, DT.Convert.ToEntity(permission));
+        dao.SetJobPermission(jobId, userManager.CurrentUserId, grantedUserId, DT.Convert.ToEntity(permission));
       });
     }
@@ -357,9 +361,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        Job job = dtoDao.GetJob(jobId);
+        Job job = dao.GetJob(jobId);
         if (job == null) throw new FaultException<FaultReason>(new FaultReason("Could not find task with id " + jobId));
-        DA.Permission perm = dtoDao.GetPermissionForJob(job.Id, userManager.CurrentUserId);
+        DA.Permission perm = dao.GetPermissionForJob(job.Id, userManager.CurrentUserId);
         if (perm != DA.Permission.Full) throw new FaultException<FaultReason>(new FaultReason("Not allowed to grant permissions for this experiment"));
-        dtoDao.SetJobPermission(jobId, userManager.CurrentUserId, grantedUserId, DA.Permission.NotAllowed);
+        dao.SetJobPermission(jobId, userManager.CurrentUserId, grantedUserId, DA.Permission.NotAllowed);
       });
     }
@@ -368,7 +372,7 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        DA.Permission currentUserPermission = dtoDao.GetPermissionForJob(jobId, userManager.CurrentUserId);
+        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 dtoDao.GetJobPermissions(x => x.JobId == jobId);
+        return dao.GetJobPermissions(x => x.JobId == jobId);
       });
     }
@@ -387,12 +391,12 @@
 
       trans.UseTransaction(() => {
-        var slave = dtoDao.GetSlave(slaveInfo.Id);
+        var slave = dao.GetSlave(slaveInfo.Id);
 
         if (slave == null) {
-          var healGroup = dtoDao.GetResources(x => x.Name == "HEAL").First();
+          var healGroup = dao.GetResources(x => x.Name == "HEAL").First();
           if (healGroup != null) {
             slaveInfo.ParentResourceId = healGroup.Id;
           }
-          dtoDao.AddSlave(slaveInfo);
+          dao.AddSlave(slaveInfo);
         } else {
           slave.Name = slaveInfo.Name;
@@ -413,5 +417,5 @@
           // don't update those properties: dbSlave.IsAllowedToCalculate, dbSlave.ParentResourceId 
 
-          dtoDao.UpdateSlave(slave);
+          dao.UpdateSlave(slave);
         }
       });
@@ -421,8 +425,8 @@
       authen.AuthenticateForAnyRole(HiveRoles.Slave);
       trans.UseTransaction(() => {
-        var slave = dtoDao.GetSlave(slaveId);
+        var slave = dao.GetSlave(slaveId);
         if (slave != null) {
           slave.SlaveState = SlaveState.Offline;
-          dtoDao.UpdateSlave(slave);
+          dao.UpdateSlave(slave);
         }
       });
@@ -457,5 +461,5 @@
         plugin.DateCreated = DateTime.Now;
 
-        var existing = dtoDao.GetPlugins(x => x.Hash != null).Where(x => x.Hash.SequenceEqual(plugin.Hash));
+        var existing = dao.GetPlugins(x => x.Hash != null).Where(x => x.Hash.SequenceEqual(plugin.Hash));
         if (existing.Count() > 0) {
           // a plugin already exists.
@@ -463,8 +467,8 @@
         }
 
-        Guid pluginId = dtoDao.AddPlugin(plugin);
+        Guid pluginId = dao.AddPlugin(plugin);
         foreach (PluginData pluginData in pluginDatas) {
           pluginData.PluginId = pluginId;
-          dtoDao.AddPluginData(pluginData);
+          dao.AddPluginData(pluginData);
         }
         return pluginId;
@@ -475,5 +479,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       return trans.UseTransaction(() => {
-        return DT.Convert.ToDto(dao.GetPluginById(pluginId));
+        return DT.Convert.ToDto(optimizedDao.GetPluginById(pluginId));
       });
     }
@@ -482,5 +486,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       return trans.UseTransaction(() => {
-        return dtoDao.GetPlugins(x => x.Hash == hash).FirstOrDefault();
+        return dao.GetPlugins(x => x.Hash == hash).FirstOrDefault();
       });
     }
@@ -491,5 +495,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       return trans.UseTransaction(() => {
-        return dtoDao.GetPlugins(x => x.Hash != null);
+        return dao.GetPlugins(x => x.Hash != null);
       });
     }
@@ -500,5 +504,5 @@
       return trans.UseTransaction(() => {
         foreach (Guid guid in pluginIds) {
-          pluginDatas.AddRange(dtoDao.GetPluginDatas(x => x.PluginId == guid).ToList());
+          pluginDatas.AddRange(dao.GetPluginDatas(x => x.PluginId == guid).ToList());
         }
         return pluginDatas;
@@ -509,5 +513,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       trans.UseTransaction(() => {
-        dtoDao.DeletePlugin(pluginId);
+        dao.DeletePlugin(pluginId);
       });
     }
@@ -518,9 +522,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        Resource resource = dtoDao.GetResource(resourceId);
+        Resource resource = dao.GetResource(resourceId);
         if (resource == null) throw new FaultException<FaultReason>(new FaultReason("Could not find resource with id " + resourceId));
         if (resource.OwnerUserId != userManager.CurrentUserId && !authen.IsInRole(HiveRoles.Administrator)) throw new FaultException<FaultReason>(new FaultReason("Not allowed to grant permission for this resource"));
         foreach (Guid id in grantedUserIds)
-          dtoDao.AddResourcePermission(new ResourcePermission { ResourceId = resourceId, GrantedByUserId = userManager.CurrentUserId, GrantedUserId = id });
+          dao.AddResourcePermission(new ResourcePermission { ResourceId = resourceId, GrantedByUserId = userManager.CurrentUserId, GrantedUserId = id });
       });
     }
@@ -529,9 +533,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        Resource resource = dtoDao.GetResource(resourceId);
+        Resource resource = dao.GetResource(resourceId);
         if (resource == null) throw new FaultException<FaultReason>(new FaultReason("Could not find resource with id " + resourceId));
         if (resource.OwnerUserId != userManager.CurrentUserId && !authen.IsInRole(HiveRoles.Administrator)) throw new FaultException<FaultReason>(new FaultReason("Not allowed to revoke permission for this resource"));
         foreach (Guid id in grantedUserIds)
-          dtoDao.DeleteResourcePermission(resourceId, id);
+          dao.DeleteResourcePermission(resourceId, id);
       });
     }
@@ -540,7 +544,7 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        Resource resource = dtoDao.GetResource(resourceId);
+        Resource resource = dao.GetResource(resourceId);
         if (resource == null) throw new FaultException<FaultReason>(new FaultReason("Could not find resource with id " + resourceId));
-        return dtoDao.GetResourcePermissions(x => x.ResourceId == resourceId);
+        return dao.GetResourcePermissions(x => x.ResourceId == resourceId);
       });
     }
@@ -549,5 +553,5 @@
     #region Resource Methods
     public IEnumerable<Resource> GetChildResources(Guid resourceId) {
-      return trans.UseTransaction(() => { return dtoDao.GetChildResources(resourceId); });
+      return trans.UseTransaction(() => { return dao.GetChildResources(resourceId); });
     }
     #endregion
@@ -557,5 +561,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Slave);
 
-      Slave s = trans.UseTransaction(() => { return dtoDao.GetSlave(slaveId); });
+      Slave s = trans.UseTransaction(() => { return dao.GetSlave(slaveId); });
       if (s != null) {
         return s.HbInterval;
@@ -567,20 +571,20 @@
     public Guid AddSlave(Slave slave) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
-      return trans.UseTransaction(() => dtoDao.AddSlave(slave));
+      return trans.UseTransaction(() => dao.AddSlave(slave));
     }
 
     public Guid AddSlaveGroup(SlaveGroup slaveGroup) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      return trans.UseTransaction(() => dtoDao.AddSlaveGroup(slaveGroup));
+      return trans.UseTransaction(() => dao.AddSlaveGroup(slaveGroup));
     }
 
     public Slave GetSlave(Guid slaveId) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
-      return trans.UseTransaction(() => { return dtoDao.GetSlave(slaveId); });
+      return trans.UseTransaction(() => { return dao.GetSlave(slaveId); });
     }
 
     public SlaveGroup GetSlaveGroup(Guid slaveGroupId) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
-      return trans.UseTransaction(() => { return dtoDao.GetSlaveGroup(slaveGroupId); });
+      return trans.UseTransaction(() => { return dao.GetSlaveGroup(slaveGroupId); });
     }
 
@@ -588,5 +592,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        return dtoDao.GetSlaves(x => true).Where(x => x.OwnerUserId == null
+        return dao.GetSlaves(x => true).Where(x => x.OwnerUserId == null
                                            || x.OwnerUserId == userManager.CurrentUserId
                                            || userManager.VerifyUser(userManager.CurrentUserId, GetResourcePermissions(x.Id).Select(y => y.GrantedUserId).ToList())
@@ -598,5 +602,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        return dtoDao.GetSlaveGroups(x => true).Where(x => x.OwnerUserId == null
+        return dao.GetSlaveGroups(x => true).Where(x => x.OwnerUserId == null
                                                 || x.OwnerUserId == userManager.CurrentUserId
                                                 || userManager.VerifyUser(userManager.CurrentUserId, GetResourcePermissions(x.Id).Select(y => y.GrantedUserId).ToList())
@@ -608,5 +612,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        dtoDao.UpdateSlave(slave);
+        dao.UpdateSlave(slave);
       });
     }
@@ -615,5 +619,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        dtoDao.UpdateSlaveGroup(slaveGroup);
+        dao.UpdateSlaveGroup(slaveGroup);
       });
     }
@@ -623,5 +627,5 @@
       author.AuthorizeForResourceAdministration(slaveId);
       trans.UseTransaction(() => {
-        dtoDao.DeleteSlave(slaveId);
+        dao.DeleteSlave(slaveId);
       });
     }
@@ -631,5 +635,5 @@
       author.AuthorizeForResourceAdministration(slaveGroupId);
       trans.UseTransaction(() => {
-        dtoDao.DeleteSlaveGroup(slaveGroupId);
+        dao.DeleteSlaveGroup(slaveGroupId);
       });
     }
@@ -638,7 +642,7 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
       trans.UseTransaction(() => {
-        var resource = dtoDao.GetResource(resourceId);
+        var resource = dao.GetResource(resourceId);
         resource.ParentResourceId = slaveGroupId;
-        dtoDao.UpdateResource(resource);
+        dao.UpdateResource(resource);
       });
     }
@@ -647,7 +651,7 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
       trans.UseTransaction(() => {
-        var resource = dtoDao.GetResource(resourceId);
+        var resource = dao.GetResource(resourceId);
         resource.ParentResourceId = null;
-        dtoDao.UpdateResource(resource);
+        dao.UpdateResource(resource);
       });
     }
@@ -656,5 +660,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        var resource = dtoDao.GetResources(x => x.Name == resourceName).FirstOrDefault();
+        var resource = dao.GetResources(x => x.Name == resourceName).FirstOrDefault();
         if (resource != null) {
           return resource.Id;
@@ -670,7 +674,7 @@
       bool cleanup = false;
       trans.UseTransaction(() => {
-        DateTime lastCleanup = dtoDao.GetLastCleanup();
+        DateTime lastCleanup = dao.GetLastCleanup();
         if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
-          dtoDao.SetLastCleanup(DateTime.Now);
+          dao.SetLastCleanup(DateTime.Now);
           cleanup = true;
         }
@@ -687,5 +691,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       author.AuthorizeForResourceAdministration(downtime.ResourceId);
-      return trans.UseTransaction(() => dtoDao.AddDowntime(downtime));
+      return trans.UseTransaction(() => dao.AddDowntime(downtime));
     }
 
@@ -695,5 +699,5 @@
       // author.AuthorizeForResource(resourceId);
       trans.UseTransaction(() => {
-        dtoDao.DeleteDowntime(downtimeId);
+        dao.DeleteDowntime(downtimeId);
       });
     }
@@ -703,5 +707,5 @@
       author.AuthorizeForResourceAdministration(downtime.ResourceId);
       trans.UseTransaction(() => {
-        dtoDao.UpdateDowntime(downtime);
+        dao.UpdateDowntime(downtime);
       });
     }
@@ -709,5 +713,5 @@
     public IEnumerable<Downtime> GetDowntimesForResource(Guid resourceId) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      return trans.UseTransaction(() => dtoDao.GetDowntimes(x => x.ResourceId == resourceId));
+      return trans.UseTransaction(() => dao.GetDowntimes(x => x.ResourceId == resourceId));
     }
     #endregion
@@ -732,5 +736,5 @@
     #region UserPriority Methods
     public IEnumerable<UserPriority> GetUserPriorities() {
-      return trans.UseTransaction(() => dtoDao.GetUserPriorities(x => true));
+      return trans.UseTransaction(() => dao.GetUserPriorities(x => true));
     }
     #endregion
@@ -738,5 +742,5 @@
     #region Helper Methods
     private IEnumerable<Task> GetChildTasks(Guid? parentTaskId, bool recursive, bool includeParent) {
-      var tasks = new List<Task>(dtoDao.GetTasks(x => parentTaskId == null ? !x.ParentTaskId.HasValue : x.ParentTaskId.Value == parentTaskId));
+      var tasks = new List<Task>(dao.GetTasks(x => parentTaskId == null ? !x.ParentTaskId.HasValue : x.ParentTaskId.Value == parentTaskId));
 
       if (recursive) {
@@ -755,8 +759,8 @@
     #region Statistics Methods
     public IEnumerable<Statistics> GetStatistics() {
-      return trans.UseTransaction(() => { return dtoDao.GetStatistics(x => true); });
+      return trans.UseTransaction(() => { return dao.GetStatistics(x => true); });
     }
     public IEnumerable<Statistics> GetStatisticsForTimePeriod(DateTime from, DateTime to) {
-      return trans.UseTransaction(() => { return dtoDao.GetStatistics(x => x.Timestamp >= from && x.Timestamp <= to); });
+      return trans.UseTransaction(() => { return dao.GetStatistics(x => x.Timestamp >= from && x.Timestamp <= to); });
     }
     #endregion
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IHiveDao.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IHiveDao.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IHiveDao.cs	(revision 9434)
@@ -20,89 +20,148 @@
 #endregion
 
-
 using System;
 using System.Collections.Generic;
-using System.Linq;
+using System.Linq.Expressions;
 using HeuristicLab.Services.Hive.DataAccess;
 using DT = HeuristicLab.Services.Hive.DataTransfer;
+
 namespace HeuristicLab.Services.Hive {
   public interface IHiveDao {
     #region Task Methods
-    Task GetTaskById(Guid task);
-    Task GetTaskByDto(DT.Task taskDto);
-    Tuple<Task, Guid?> GetTaskByIdAndLastStateLogSlaveId(Guid taskId);
-
-    IEnumerable<TaskInfoForScheduler> GetWaitingTasks(Slave slave);
-    IQueryable<DT.LightweightTask> GetLightweightTasks(Guid jobId);
-
-    void UpdateTask(Task task);
-    Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception);
-
-    bool TaskIsAllowedToBeCalculatedBySlave(Guid taskId, Guid slaveId);
+    DT.Task GetTask(Guid id);
+    IEnumerable<DT.Task> GetTasks(Expression<Func<Task, bool>> predicate);
+    IEnumerable<DT.LightweightTask> GetLightweightTasks(Expression<Func<Task, bool>> predicate);
+    IEnumerable<DT.LightweightTask> GetLightweightTasksWithoutStateLog(Expression<Func<Task, bool>> predicate);
+    Guid AddTask(DT.Task dto);
+    void UpdateTaskAndPlugins(DT.Task dto);
+    void UpdateTaskAndStateLogs(DT.Task dto);
+    void UpdateTask(DT.Task dto);
+    void DeleteTask(Guid id);
+    IEnumerable<TaskInfoForScheduler> GetWaitingTasks(DT.Slave slave);
+    IEnumerable<DT.Task> GetParentTasks(IEnumerable<Guid> resourceIds, int count, bool finished);
+    DT.Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception);
     #endregion
 
     #region TaskData Methods
-    TaskData GetTaskDataByDto(DT.TaskData taskDataDto);
-    void UpdateTaskData(TaskData taskData);
+    DT.TaskData GetTaskData(Guid id);
+    IEnumerable<DT.TaskData> GetTaskDatas(Expression<Func<TaskData, bool>> predicate);
+    Guid AddTaskData(DT.TaskData dto);
+    void UpdateTaskData(DT.TaskData dto);
+    void DeleteTaskData(Guid id);
     #endregion
 
     #region StateLog Methods
-
+    DT.StateLog GetStateLog(Guid id);
+    IEnumerable<DT.StateLog> GetStateLogs(Expression<Func<StateLog, bool>> predicate);
+    Guid AddStateLog(DT.StateLog dto);
+    void UpdateStateLog(DT.StateLog dto);
+    void DeleteStateLog(Guid id);
     #endregion
 
     #region Job Methods
-
+    DT.Job GetJob(Guid id);
+    IEnumerable<DT.Job> GetJobs(Expression<Func<Job, bool>> predicate);
+    IEnumerable<JobInfoForScheduler> GetJobInfoForScheduler(Expression<Func<Job, bool>> predicate);
+    Guid AddJob(DT.Job dto);
+    void UpdateJob(DT.Job dto);
+    void DeleteJob(Guid id);
     #endregion
 
     #region JobPermission Methods
-
+    DT.JobPermission GetJobPermission(Guid jobId, Guid grantedUserId);
+    IEnumerable<DT.JobPermission> GetJobPermissions(Expression<Func<JobPermission, bool>> predicate);
+    void AddJobPermission(DT.JobPermission dto);
+    void UpdateJobPermission(DT.JobPermission dto);
+    void DeleteJobPermission(Guid jobId, Guid grantedUserId);
+    void SetJobPermission(Guid jobId, Guid grantedByUserId, Guid grantedUserId, Permission permission);
     #endregion
 
     #region Plugin Methods
-    Plugin GetPluginById(Guid pluginId);
+    DT.Plugin GetPlugin(Guid id);
+    IEnumerable<DT.Plugin> GetPlugins(Expression<Func<Plugin, bool>> predicate);
+    Guid AddPlugin(DT.Plugin dto);
+    void UpdatePlugin(DT.Plugin dto);
+    void DeletePlugin(Guid id);
     #endregion
 
     #region PluginData Methods
-
+    DT.PluginData GetPluginData(Guid id);
+    IEnumerable<DT.PluginData> GetPluginDatas(Expression<Func<PluginData, bool>> predicate);
+    Guid AddPluginData(DT.PluginData dto);
+    void UpdatePluginData(DT.PluginData dto);
+    void DeletePluginData(Guid id);
     #endregion
 
     #region Slave Methods
-    Slave GetSlaveById(Guid id);
-
-    void UpdateSlave(Slave slave);
-
-    bool SlaveHasToShutdownComputer(Guid slaveId);
-    bool SlaveIsAllowedToCalculate(Guid slaveId);
+    DT.Slave GetSlave(Guid id);
+    IEnumerable<DT.Slave> GetSlaves(Expression<Func<Slave, bool>> predicate);
+    Guid AddSlave(DT.Slave dto);
+    void UpdateSlave(DT.Slave dto);
+    void DeleteSlave(Guid id);
     #endregion
 
     #region SlaveGroup Methods
-
+    DT.SlaveGroup GetSlaveGroup(Guid id);
+    IEnumerable<DT.SlaveGroup> GetSlaveGroups(Expression<Func<SlaveGroup, bool>> predicate);
+    Guid AddSlaveGroup(DT.SlaveGroup dto);
+    void UpdateSlaveGroup(DT.SlaveGroup dto);
+    void DeleteSlaveGroup(Guid id);
     #endregion
 
     #region Resource Methods
-
+    DT.Resource GetResource(Guid id);
+    IEnumerable<DT.Resource> GetResources(Expression<Func<Resource, bool>> predicate);
+    Guid AddResource(DT.Resource dto);
+    void UpdateResource(DT.Resource dto);
+    void DeleteResource(Guid id);
+    void AssignJobToResource(Guid taskId, IEnumerable<Guid> resourceIds);
+    IEnumerable<DT.Resource> GetAssignedResources(Guid jobId);
+    IEnumerable<DT.Resource> GetParentResources(Guid resourceId);
+    IEnumerable<DT.Resource> GetChildResources(Guid resourceId);
+    IEnumerable<DT.Task> GetJobsByResourceId(Guid resourceId);
     #endregion
 
     #region ResourcePermission Methods
-
+    DT.ResourcePermission GetResourcePermission(Guid resourceId, Guid grantedUserId);
+    IEnumerable<DT.ResourcePermission> GetResourcePermissions(Expression<Func<ResourcePermission, bool>> predicate);
+    void AddResourcePermission(DT.ResourcePermission dto);
+    void UpdateResourcePermission(DT.ResourcePermission dto);
+    void DeleteResourcePermission(Guid resourceId, Guid grantedUserId);
     #endregion
 
     #region Authorization Methods
-
+    Permission GetPermissionForTask(Guid taskId, Guid userId);
+    Permission GetPermissionForJob(Guid jobId, Guid userId);
+    Guid GetJobForTask(Guid taskId);
     #endregion
 
     #region Lifecycle Methods
-
+    DateTime GetLastCleanup();
+    void SetLastCleanup(DateTime datetime);
     #endregion
 
     #region Downtime Methods
+    DT.Downtime GetDowntime(Guid id);
+    IEnumerable<DT.Downtime> GetDowntimes(Expression<Func<Downtime, bool>> predicate);
+    Guid AddDowntime(DT.Downtime dto);
+    void UpdateDowntime(DT.Downtime dto);
+    void DeleteDowntime(Guid id);
     #endregion
 
     #region Statistics Methods
-
+    Dictionary<Guid, int> GetWaitingTasksByUser();
+    Dictionary<Guid, int> GetWaitingTasksByUserForResources(List<Guid> resourceIds);
+    Dictionary<Guid, int> GetCalculatingTasksByUser();
+    Dictionary<Guid, int> GetCalculatingTasksByUserForResources(List<Guid> resourceIds);
+    DT.Statistics GetStatistic(Guid id);
+    IEnumerable<DT.Statistics> GetStatistics(Expression<Func<Statistics, bool>> predicate);
+    Guid AddStatistics(DT.Statistics dto);
+    void DeleteStatistics(Guid id);
+    List<DT.UserStatistics> GetUserStatistics();
     #endregion
 
     #region UserPriority Methods
-
+    IEnumerable<DT.UserPriority> GetUserPriorities(Expression<Func<UserPriority, bool>> predicate);
+    void EnqueueUserPriority(DT.UserPriority userPriority);
     #endregion
   }
Index: anches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IHiveDtoDao.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IHiveDtoDao.cs	(revision 9433)
+++ 	(revision )
@@ -1,168 +1,0 @@
-﻿#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2012 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.Expressions;
-using HeuristicLab.Services.Hive.DataAccess;
-using DT = HeuristicLab.Services.Hive.DataTransfer;
-
-namespace HeuristicLab.Services.Hive {
-  public interface IHiveDtoDao {
-    #region Task Methods
-    DT.Task GetTask(Guid id);
-    IEnumerable<DT.Task> GetTasks(Expression<Func<Task, bool>> predicate);
-    IEnumerable<DT.LightweightTask> GetLightweightTasks(Expression<Func<Task, bool>> predicate);
-    IEnumerable<DT.LightweightTask> GetLightweightTasksWithoutStateLog(Expression<Func<Task, bool>> predicate);
-    Guid AddTask(DT.Task dto);
-    void UpdateTaskAndPlugins(DT.Task dto);
-    void UpdateTaskAndStateLogs(DT.Task dto);
-    void UpdateTask(DT.Task dto);
-    void DeleteTask(Guid id);
-    IEnumerable<TaskInfoForScheduler> GetWaitingTasks(DT.Slave slave);
-    IEnumerable<DT.Task> GetParentTasks(IEnumerable<Guid> resourceIds, int count, bool finished);
-    DT.Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception);
-    #endregion
-
-    #region TaskData Methods
-    DT.TaskData GetTaskData(Guid id);
-    IEnumerable<DT.TaskData> GetTaskDatas(Expression<Func<TaskData, bool>> predicate);
-    Guid AddTaskData(DT.TaskData dto);
-    void UpdateTaskData(DT.TaskData dto);
-    void DeleteTaskData(Guid id);
-    #endregion
-
-    #region StateLog Methods
-    DT.StateLog GetStateLog(Guid id);
-    IEnumerable<DT.StateLog> GetStateLogs(Expression<Func<StateLog, bool>> predicate);
-    Guid AddStateLog(DT.StateLog dto);
-    void UpdateStateLog(DT.StateLog dto);
-    void DeleteStateLog(Guid id);
-    #endregion
-
-    #region Job Methods
-    DT.Job GetJob(Guid id);
-    IEnumerable<DT.Job> GetJobs(Expression<Func<Job, bool>> predicate);
-    IEnumerable<JobInfoForScheduler> GetJobInfoForScheduler(Expression<Func<Job, bool>> predicate);
-    Guid AddJob(DT.Job dto);
-    void UpdateJob(DT.Job dto);
-    void DeleteJob(Guid id);
-    #endregion
-
-    #region JobPermission Methods
-    DT.JobPermission GetJobPermission(Guid jobId, Guid grantedUserId);
-    IEnumerable<DT.JobPermission> GetJobPermissions(Expression<Func<JobPermission, bool>> predicate);
-    void AddJobPermission(DT.JobPermission dto);
-    void UpdateJobPermission(DT.JobPermission dto);
-    void DeleteJobPermission(Guid jobId, Guid grantedUserId);
-    void SetJobPermission(Guid jobId, Guid grantedByUserId, Guid grantedUserId, Permission permission);
-    #endregion
-
-    #region Plugin Methods
-    DT.Plugin GetPlugin(Guid id);
-    IEnumerable<DT.Plugin> GetPlugins(Expression<Func<Plugin, bool>> predicate);
-    Guid AddPlugin(DT.Plugin dto);
-    void UpdatePlugin(DT.Plugin dto);
-    void DeletePlugin(Guid id);
-    #endregion
-
-    #region PluginData Methods
-    DT.PluginData GetPluginData(Guid id);
-    IEnumerable<DT.PluginData> GetPluginDatas(Expression<Func<PluginData, bool>> predicate);
-    Guid AddPluginData(DT.PluginData dto);
-    void UpdatePluginData(DT.PluginData dto);
-    void DeletePluginData(Guid id);
-    #endregion
-
-    #region Slave Methods
-    DT.Slave GetSlave(Guid id);
-    IEnumerable<DT.Slave> GetSlaves(Expression<Func<Slave, bool>> predicate);
-    Guid AddSlave(DT.Slave dto);
-    void UpdateSlave(DT.Slave dto);
-    void DeleteSlave(Guid id);
-    #endregion
-
-    #region SlaveGroup Methods
-    DT.SlaveGroup GetSlaveGroup(Guid id);
-    IEnumerable<DT.SlaveGroup> GetSlaveGroups(Expression<Func<SlaveGroup, bool>> predicate);
-    Guid AddSlaveGroup(DT.SlaveGroup dto);
-    void UpdateSlaveGroup(DT.SlaveGroup dto);
-    void DeleteSlaveGroup(Guid id);
-    #endregion
-
-    #region Resource Methods
-    DT.Resource GetResource(Guid id);
-    IEnumerable<DT.Resource> GetResources(Expression<Func<Resource, bool>> predicate);
-    Guid AddResource(DT.Resource dto);
-    void UpdateResource(DT.Resource dto);
-    void DeleteResource(Guid id);
-    void AssignJobToResource(Guid taskId, IEnumerable<Guid> resourceIds);
-    IEnumerable<DT.Resource> GetAssignedResources(Guid jobId);
-    IEnumerable<DT.Resource> GetParentResources(Guid resourceId);
-    IEnumerable<DT.Resource> GetChildResources(Guid resourceId);
-    IEnumerable<DT.Task> GetJobsByResourceId(Guid resourceId);
-    #endregion
-
-    #region ResourcePermission Methods
-    DT.ResourcePermission GetResourcePermission(Guid resourceId, Guid grantedUserId);
-    IEnumerable<DT.ResourcePermission> GetResourcePermissions(Expression<Func<ResourcePermission, bool>> predicate);
-    void AddResourcePermission(DT.ResourcePermission dto);
-    void UpdateResourcePermission(DT.ResourcePermission dto);
-    void DeleteResourcePermission(Guid resourceId, Guid grantedUserId);
-    #endregion
-
-    #region Authorization Methods
-    Permission GetPermissionForTask(Guid taskId, Guid userId);
-    Permission GetPermissionForJob(Guid jobId, Guid userId);
-    Guid GetJobForTask(Guid taskId);
-    #endregion
-
-    #region Lifecycle Methods
-    DateTime GetLastCleanup();
-    void SetLastCleanup(DateTime datetime);
-    #endregion
-
-    #region Downtime Methods
-    DT.Downtime GetDowntime(Guid id);
-    IEnumerable<DT.Downtime> GetDowntimes(Expression<Func<Downtime, bool>> predicate);
-    Guid AddDowntime(DT.Downtime dto);
-    void UpdateDowntime(DT.Downtime dto);
-    void DeleteDowntime(Guid id);
-    #endregion
-
-    #region Statistics Methods
-    Dictionary<Guid, int> GetWaitingTasksByUser();
-    Dictionary<Guid, int> GetWaitingTasksByUserForResources(List<Guid> resourceIds);
-    Dictionary<Guid, int> GetCalculatingTasksByUser();
-    Dictionary<Guid, int> GetCalculatingTasksByUserForResources(List<Guid> resourceIds);
-    DT.Statistics GetStatistic(Guid id);
-    IEnumerable<DT.Statistics> GetStatistics(Expression<Func<Statistics, bool>> predicate);
-    Guid AddStatistics(DT.Statistics dto);
-    void DeleteStatistics(Guid id);
-    List<DT.UserStatistics> GetUserStatistics();
-    #endregion
-
-    #region UserPriority Methods
-    IEnumerable<DT.UserPriority> GetUserPriorities(Expression<Func<UserPriority, bool>> predicate);
-    void EnqueueUserPriority(DT.UserPriority userPriority);
-    #endregion
-  }
-}
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IOptimizedHiveDao.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IOptimizedHiveDao.cs	(revision 9434)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IOptimizedHiveDao.cs	(revision 9434)
@@ -0,0 +1,112 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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;
+using DT = HeuristicLab.Services.Hive.DataTransfer;
+namespace HeuristicLab.Services.Hive {
+  public interface IOptimizedHiveDao {
+    #region Task Methods
+    Task GetTaskById(Guid task);
+    Task GetTaskByDto(DT.Task taskDto);
+    Tuple<Task, Guid?> GetTaskByIdAndLastStateLogSlaveId(Guid taskId);
+
+    IEnumerable<TaskInfoForScheduler> GetWaitingTasks(Slave slave);
+    IQueryable<DT.LightweightTask> GetLightweightTasks(Guid jobId);
+
+    void UpdateTask(Task task);
+    Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception);
+
+    Guid AddTask(Task task);
+    void AssignJobToResource(Guid taskId, IEnumerable<Guid> resourceIds);
+
+    bool TaskIsAllowedToBeCalculatedBySlave(Guid taskId, Guid slaveId);
+    #endregion
+
+    #region TaskData Methods
+    TaskData GetTaskDataByDto(DT.TaskData taskDataDto);
+    void UpdateTaskData(TaskData taskData);
+    #endregion
+
+    #region StateLog Methods
+
+    #endregion
+
+    #region Job Methods
+
+    #endregion
+
+    #region JobPermission Methods
+
+    #endregion
+
+    #region Plugin Methods
+    Plugin GetPluginById(Guid pluginId);
+    #endregion
+
+    #region PluginData Methods
+
+    #endregion
+
+    #region Slave Methods
+    Slave GetSlaveById(Guid id);
+
+    void UpdateSlave(Slave slave);
+
+    bool SlaveHasToShutdownComputer(Guid slaveId);
+    bool SlaveIsAllowedToCalculate(Guid slaveId);
+    #endregion
+
+    #region SlaveGroup Methods
+
+    #endregion
+
+    #region Resource Methods
+    IEnumerable<Guid> GetAssignedResourceIds(Guid jobId);
+    #endregion
+
+    #region ResourcePermission Methods
+
+    #endregion
+
+    #region Authorization Methods
+
+    #endregion
+
+    #region Lifecycle Methods
+
+    #endregion
+
+    #region Downtime Methods
+    #endregion
+
+    #region Statistics Methods
+
+    #endregion
+
+    #region UserPriority Methods
+
+    #endregion
+  }
+}
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs	(revision 9434)
@@ -26,6 +26,6 @@
     Access.IRoleVerifier RoleVerifier { get; }
     IAuthorizationManager AuthorizationManager { get; }
-    IHiveDtoDao HiveDtoDao { get; }
     IHiveDao HiveDao { get; }
+    IOptimizedHiveDao OptimizedHiveDao { get; }
     IEventManager EventManager { get; }
     ITransactionManager TransactionManager { get; }
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs	(revision 9434)
@@ -36,5 +36,5 @@
       if (ServiceLocator.Instance.RoleVerifier.IsInRole(HiveRoles.Slave)) return; // slave-users can access all tasks
 
-      Permission permission = ServiceLocator.Instance.HiveDtoDao.GetPermissionForTask(taskId, ServiceLocator.Instance.UserManager.CurrentUserId);
+      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");
@@ -42,5 +42,5 @@
 
     public void AuthorizeForJob(Guid jobId, DT.Permission requiredPermission) {
-      Permission permission = ServiceLocator.Instance.HiveDtoDao.GetPermissionForJob(jobId, ServiceLocator.Instance.UserManager.CurrentUserId);
+      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");
@@ -48,5 +48,5 @@
 
     public void AuthorizeForResourceAdministration(Guid resourceId) {
-      Resource resource = DT.Convert.ToEntity(ServiceLocator.Instance.HiveDtoDao.GetResource(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");
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/EventManager.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/EventManager.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/EventManager.cs	(revision 9434)
@@ -32,6 +32,6 @@
   /// </summary>
   public class EventManager : IEventManager {
-    private IHiveDtoDao dao {
-      get { return ServiceLocator.Instance.HiveDtoDao; }
+    private IHiveDao dao {
+      get { return ServiceLocator.Instance.HiveDao; }
     }
     private IAuthorizationManager auth {
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs	(revision 9434)
@@ -31,6 +31,6 @@
     private const string MutexName = "HiveTaskSchedulingMutex";
 
-    private IHiveDao dao {
-      get { return ServiceLocator.Instance.HiveDao; }
+    private IOptimizedHiveDao dao {
+      get { return ServiceLocator.Instance.OptimizedHiveDao; }
     }
     private ITaskScheduler taskScheduler {
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/OptimizedHiveDao.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/OptimizedHiveDao.cs	(revision 9434)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/OptimizedHiveDao.cs	(revision 9434)
@@ -0,0 +1,294 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2012 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.Data.Linq;
+using System.Linq;
+using DT = HeuristicLab.Services.Hive.DataTransfer;
+
+namespace HeuristicLab.Services.Hive.DataAccess {
+  public class OptimizedHiveDao : IOptimizedHiveDao {
+    private static HiveDataContext Db { get { return HiveOperationContext.Current.DataContext; } }
+
+    #region Task Methods
+    public Task GetTaskById(Guid taskId) {
+      return GetTaskByIdQuery(Db, taskId).SingleOrDefault();
+    }
+
+    private static readonly Func<HiveDataContext, Guid, IQueryable<Task>> GetTaskByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
+      from t in db.Tasks
+      where t.TaskId == taskId
+      select t
+    );
+
+    public Task GetTaskByDto(DT.Task taskDto) {
+      var task = GetTaskById(taskDto.Id);
+      DT.Convert.ToEntity(taskDto, task);
+      return task;
+    }
+
+    public Tuple<Task, Guid?> GetTaskByIdAndLastStateLogSlaveId(Guid taskId) {
+      return GetTaskByIdAndLastStateLogSlaveIdQuery(Db, taskId).SingleOrDefault();
+    }
+
+    private static readonly Func<HiveDataContext, Guid, IQueryable<Tuple<Task, Guid?>>> GetTaskByIdAndLastStateLogSlaveIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
+       from t in db.Tasks
+       join sl in db.StateLogs on t.TaskId equals sl.TaskId
+       where t.TaskId == taskId
+       orderby sl.DateTime descending
+       group sl by t into logs
+       select new Tuple<Task, Guid?>(logs.Key, logs.First().SlaveId)
+    );
+
+    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}
+    ";
+
+    public IEnumerable<TaskInfoForScheduler> 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 Db.ExecuteQuery<TaskInfoForScheduler>(GetWaitingTasksQueryString, slave.ResourceId, Enum.GetName(typeof(TaskState), TaskState.Waiting), slave.FreeCores, slave.FreeMemory);
+    }
+
+    public IQueryable<DT.LightweightTask> GetLightweightTasks(Guid jobId) {
+      return GetLightweightTasksQuery(Db, jobId);
+    }
+
+    private static readonly Func<HiveDataContext, Guid, IQueryable<DT.LightweightTask>> GetLightweightTasksQuery = CompiledQuery.Compile((HiveDataContext db, Guid jobId) =>
+        from task in db.Tasks
+        where task.JobId == jobId
+        select new DT.LightweightTask {
+          Id = task.TaskId,
+          ExecutionTime = TimeSpan.FromMilliseconds(task.ExecutionTimeMs),
+          ParentTaskId = task.ParentTaskId,
+          StateLog = task.StateLogs.Select(sl => ConvertStateLog(sl)).ToList(),
+          State = ConvertTaskState(task.State),
+          Command = ConvertCommand(task.Command),
+          LastTaskDataUpdate = task.JobData.LastUpdate
+        }
+    );
+
+    private static readonly Func<StateLog, DT.StateLog> ConvertStateLog = sl => DT.Convert.ToDto(sl);
+    private static readonly Func<TaskState, DT.TaskState> ConvertTaskState = ts => DT.Convert.ToDto(ts);
+    private static readonly Func<Command?, DT.Command?> ConvertCommand = c => DT.Convert.ToDto(c);
+
+    public void UpdateTask(Task task) {
+      Db.SubmitChanges();
+    }
+
+    public Task UpdateTaskState(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
+      Db.StateLogs.InsertOnSubmit(new StateLog {
+        TaskId = taskId,
+        State = taskState,
+        SlaveId = slaveId,
+        UserId = userId,
+        Exception = exception,
+        DateTime = DateTime.Now
+      });
+
+      var task = GetTaskById(taskId);
+      task.State = taskState;
+
+      Db.SubmitChanges();
+
+      return task;
+    }
+
+    public Guid AddTask(Task task) {
+      Db.Tasks.InsertOnSubmit(task);
+      Db.SubmitChanges();
+      return task.TaskId;
+    }
+
+    public void AssignJobToResource(Guid taskId, IEnumerable<Guid> resourceIds) {
+      Db.AssignedResources.InsertAllOnSubmit(resourceIds.Select(resourceId => new AssignedResource { TaskId = taskId, ResourceId = resourceId }));
+      Db.SubmitChanges();
+    }
+
+    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}
+    ";
+
+    public bool TaskIsAllowedToBeCalculatedBySlave(Guid taskId, Guid slaveId) {
+      return Db.ExecuteQuery<int>(TaskIsAllowedToBeCalculatedBySlaveQueryString, slaveId, taskId).First() > 0;
+    }
+    #endregion
+
+    #region TaskData Methods
+    public TaskData GetTaskDataById(Guid id) {
+      return GetTaskDataByIdQuery(Db, id).SingleOrDefault();
+    }
+
+    private static readonly Func<HiveDataContext, Guid, IQueryable<TaskData>> GetTaskDataByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid id) =>
+      from t in db.TaskDatas
+      where t.TaskId == id
+      select t
+    );
+
+    public TaskData GetTaskDataByDto(DT.TaskData dto) {
+      var taskData = GetTaskDataById(dto.TaskId);
+      DT.Convert.ToEntity(dto, taskData);
+      return taskData;
+    }
+
+    public void UpdateTaskData(TaskData taskData) {
+      Db.SubmitChanges();
+    }
+    #endregion
+
+    #region StateLog Methods
+
+    #endregion
+
+    #region Job Methods
+
+    #endregion
+
+    #region JobPermission Methods
+
+    #endregion
+
+    #region Plugin Methods
+    public Plugin GetPluginById(Guid pluginId) {
+      return GetPluginByIdQuery(Db, pluginId).SingleOrDefault();
+    }
+
+    private static readonly Func<HiveDataContext, Guid, IQueryable<Plugin>> GetPluginByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid pluginId) =>
+      from p in db.Plugins
+      where p.PluginId == pluginId
+      select p
+    );
+
+    #endregion
+
+    #region PluginData Methods
+
+    #endregion
+
+    #region Slave Methods
+    public Slave GetSlaveById(Guid id) {
+      return GetSlaveByIdQuery(Db, id).SingleOrDefault();
+    }
+
+    private static readonly Func<HiveDataContext, Guid, IQueryable<Slave>> GetSlaveByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid slaveId) =>
+      from s in db.Resources.OfType<Slave>()
+      where s.ResourceId == slaveId
+      select s
+    );
+
+    public void UpdateSlave(Slave slave) {
+      Db.SubmitChanges();
+    }
+
+    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}
+      ";
+
+    public bool SlaveHasToShutdownComputer(Guid slaveId) {
+      return Db.ExecuteQuery<int>(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Shutdown).First() > 0;
+    }
+
+    public bool SlaveIsAllowedToCalculate(Guid slaveId) {
+      return Db.ExecuteQuery<int>(DowntimeQueryString, slaveId, DateTime.Now, DowntimeType.Offline).First() == 0;
+    }
+    #endregion
+
+    #region SlaveGroup Methods
+
+    #endregion
+
+    #region Resource Methods
+    public IEnumerable<Guid> GetAssignedResourceIds(Guid taskId) {
+      return GetAssignedResourceIdsQuery(Db, taskId);
+    }
+
+    private static readonly Func<HiveDataContext, Guid, IQueryable<Guid>> GetAssignedResourceIdsQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
+      from ar in db.AssignedResources
+      where ar.TaskId == taskId
+      select ar.ResourceId
+    );
+    #endregion
+
+    #region ResourcePermission Methods
+
+    #endregion
+
+    #region Authorization Methods
+
+    #endregion
+
+    #region Lifecycle Methods
+
+    #endregion
+
+    #region Downtime Methods
+    #endregion
+
+    #region Statistics Methods
+
+    #endregion
+
+    #region UserPriority Methods
+
+    #endregion
+
+    #region Helpers
+
+    #endregion
+  }
+}
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Scheduler/RoundRobinTaskScheduler.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Scheduler/RoundRobinTaskScheduler.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Scheduler/RoundRobinTaskScheduler.cs	(revision 9434)
@@ -27,6 +27,6 @@
 namespace HeuristicLab.Services.Hive {
   public class RoundRobinTaskScheduler : ITaskScheduler {
-    private IHiveDtoDao dao {
-      get { return ServiceLocator.Instance.HiveDtoDao; }
+    private IHiveDao dao {
+      get { return ServiceLocator.Instance.HiveDao; }
     }
 
Index: /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs
===================================================================
--- /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs	(revision 9433)
+++ /branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs	(revision 9434)
@@ -34,12 +34,4 @@
     }
 
-    private IHiveDtoDao hiveDtoDao;
-    public IHiveDtoDao HiveDtoDao {
-      get {
-        if (hiveDtoDao == null) hiveDtoDao = new HiveDtoDao();
-        return hiveDtoDao;
-      }
-    }
-
     private IHiveDao hiveDao;
     public IHiveDao HiveDao {
@@ -47,4 +39,12 @@
         if (hiveDao == null) hiveDao = new HiveDao();
         return hiveDao;
+      }
+    }
+
+    private IOptimizedHiveDao optimizedHiveDao;
+    public IOptimizedHiveDao OptimizedHiveDao {
+      get {
+        if (optimizedHiveDao == null) optimizedHiveDao = new OptimizedHiveDao();
+        return optimizedHiveDao;
       }
     }
