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 9385)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj	(revision 9391)
@@ -138,7 +138,9 @@
     <Compile Include="DataTransfer\UserStatistics.cs" />
     <Compile Include="HiveDao.cs" />
+    <Compile Include="HiveDtoDao.cs" />
     <Compile Include="HiveJanitor.cs" />
     <Compile Include="HiveOperationContext.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 9385)
+++ 	(revision )
@@ -1,1151 +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.Data.Linq;
-using System.Linq;
-using System.Linq.Expressions;
-using DT = HeuristicLab.Services.Hive.DataTransfer;
-
-namespace HeuristicLab.Services.Hive.DataAccess {
-  public class HiveDao : IHiveDao {
-    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 HiveDao() { }
-
-    #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 Task GetTaskDA(Guid id) {
-      var db = HiveOperationContext.Current.DataContext;
-      return GetTaskByIdQuery(db, id).SingleOrDefault();
-    }
-
-    private static Func<HiveDataContext, Guid, IQueryable<Task>> GetTaskByIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid id) =>
-      from t in db.Tasks
-      where t.TaskId == id
-      select t
-    );
-
-    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 UpdateTaskDA(Task task) {
-      var db = HiveOperationContext.Current.DataContext;
-      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 IQueryable<TaskInfoForScheduler> GetWaitingTasksDA(Slave slave) {
-      var db = HiveOperationContext.Current.DataContext;
-
-      var parentResources = GetParentResourcesDA(slave.ResourceId);
-      var resourceIds = parentResources.Select(x => x.ResourceId);
-      //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 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 };
-    }
-
-    /*private static Func<HiveDataContext, Guid, Slave, IQueryable<TaskInfoForScheduler>> GetWaitingTasksQuery = CompiledQuery.Compile((HiveDataContext db, Guid id, Slave slave) =>
-      from ar in db.AssignedResources
-      where ar.ResourceId == id
-          && !(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 }
-    );*/
-
-    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);
-      }
-    }
-
-    public Task UpdateTaskStateDA(Guid taskId, TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
-      var db = HiveOperationContext.Current.DataContext;
-
-      db.StateLogs.InsertOnSubmit(new StateLog {
-        TaskId = taskId,
-        State = taskState,
-        SlaveId = slaveId,
-        UserId = userId,
-        Exception = exception,
-        DateTime = DateTime.Now
-      });
-
-      var task = GetTaskDA(taskId);
-      task.State = taskState;
-
-      db.SubmitChanges();
-
-      return 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 Slave GetSlaveDA(Guid id) {
-      var db = HiveOperationContext.Current.DataContext;
-      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 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 UpdateSlaveDA(Slave slave) {
-      var db = HiveOperationContext.Current.DataContext;
-      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();
-      }
-    }
-
-    public IQueryable<Guid> GetAssignedResourcesIdsDA(Guid taskId) {
-      var db = HiveOperationContext.Current.DataContext;
-      return GetAssignedResourcesIdQuery(db, taskId);
-    }
-
-    private static Func<HiveDataContext, Guid, IQueryable<Guid>> GetAssignedResourcesIdQuery = CompiledQuery.Compile((HiveDataContext db, Guid taskId) =>
-     from ar in db.AssignedResources
-     where ar.TaskId == taskId
-     select ar.ResourceId
-   );
-
-    /// <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();
-      }
-    }
-
-    public IEnumerable<Resource> GetParentResourcesDA(Guid resourceId) {
-      var db = HiveOperationContext.Current.DataContext;
-      var child = db.Resources.Single(r => r.ResourceId == resourceId);
-
-      yield return child;
-      while (child.ParentResource != null) {
-        child = child.ParentResource;
-        yield return child;
-      }
-    }
-
-    public IEnumerable<Guid> GetParentResourcesIDsDA(Guid resourceId) {
-      var db = HiveOperationContext.Current.DataContext;
-      var child = db.Resources.Single(r => r.ResourceId == resourceId);
-
-      yield return resourceId;
-      while (child.ParentResource != null) {
-        child = child.ParentResource;
-        yield return child.ResourceId;
-      }
-    }
-
-    public IQueryable<int> GetNumberOfDowntimesFromParentResourcesAtCurrentTimeDA(Guid resourceId, DowntimeType type) {
-      var db = HiveOperationContext.Current.DataContext;
-
-      var ids = GetParentResourcesIDsDA(resourceId).ToArray();
-
-      return from r in db.Resources
-             where ids.Contains(r.ResourceId)
-             select (from d in db.Downtimes
-                     where d.ResourceId == r.ResourceId && d.DowntimeType == type && (DateTime.Now >= d.StartDate) && (DateTime.Now <= d.EndDate)
-                     select d).Count();
-    }
-
-    /*private static Func<HiveDataContext, Guid, DowntimeType, int> GetNumberOfDowntimesAtCurrentTimeQuery =
-      CompiledQuery.Compile((HiveDataContext db, Guid ids, DowntimeType type) =>
-        (from d in db.Downtimes
-         where d.ResourceId == ids && d.DowntimeType == type && (DateTime.Now >= d.StartDate) && (DateTime.Now <= d.EndDate)
-         select d).Count()
-    );*/
-
-    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/HiveDtoDao.cs
===================================================================
--- branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveDtoDao.cs	(revision 9391)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveDtoDao.cs	(revision 9391)
@@ -0,0 +1,1018 @@
+﻿#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 9385)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveJanitor.cs	(revision 9391)
@@ -37,6 +37,6 @@
     }
 
-    private IHiveDao dao {
-      get { return ServiceLocator.Instance.HiveDao; }
+    private IHiveDtoDao dao {
+      get { return ServiceLocator.Instance.HiveDtoDao; }
     }
 
Index: branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveOperationContext.cs
===================================================================
--- branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveOperationContext.cs	(revision 9385)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveOperationContext.cs	(revision 9391)
@@ -20,7 +20,12 @@
 #endregion
 
+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;
@@ -30,10 +35,5 @@
     public static HiveOperationContext Current {
       get {
-        var context = OperationContext.Current.Extensions.Find<HiveOperationContext>();
-        if (context == null) {
-          context = new HiveOperationContext();
-          OperationContext.Current.Extensions.Add(context);
-        }
-        return context;
+        return OperationContext.Current.Extensions.Find<HiveOperationContext>();
       }
     }
@@ -42,10 +42,38 @@
 
     public void Attach(OperationContext owner) {
-      DataContext = HiveDao.CreateContext();
+      DataContext = new HiveDataContext(Settings.Default.HeuristicLab_Hive_LinqConnectionString);
       //DataContext.Log = new DebugWriter();
     }
 
     public void Detach(OperationContext owner) {
-      // nothing
+      DataContext.Dispose();
+    }
+  }
+
+  public class HiveOperationContextMessageInspector : IDispatchMessageInspector {
+    public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) {
+      OperationContext.Current.Extensions.Add(new HiveOperationContext());
+      return request.Headers.MessageId;
+    }
+
+    public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState) {
+      OperationContext.Current.Extensions.Remove(HiveOperationContext.Current);
+    }
+  }
+
+  public class HiveOperationContextBehaviorAttribute : Attribute, IServiceBehavior {
+    public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase,
+      Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters) {
+    }
+
+    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
+      foreach (ChannelDispatcher cd in serviceHostBase.ChannelDispatchers) {
+        foreach (EndpointDispatcher ed in cd.Endpoints) {
+          ed.DispatchRuntime.MessageInspectors.Add(new HiveOperationContextMessageInspector());
+        }
+      }
+    }
+
+    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) {
     }
   }
Index: branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 9385)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 9391)
@@ -37,5 +37,9 @@
   /// </summary>
   [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IgnoreExtensionDataObject = true)]
+  [HiveOperationContextBehavior]
   public class HiveService : IHiveService {
+    private IHiveDtoDao dtoDao {
+      get { return ServiceLocator.Instance.HiveDtoDao; }
+    }
     private IHiveDao dao {
       get { return ServiceLocator.Instance.HiveDao; }
@@ -64,10 +68,10 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        task.Id = dao.AddTask(task);
+        task.Id = dtoDao.AddTask(task);
         taskData.TaskId = task.Id;
         taskData.LastUpdate = DateTime.Now;
-        dao.AssignJobToResource(task.Id, resourceIds);
-        dao.AddTaskData(taskData);
-        dao.UpdateTaskState(task.Id, DA.TaskState.Waiting, null, userManager.CurrentUserId, null);
+        dtoDao.AssignJobToResource(task.Id, resourceIds);
+        dtoDao.AddTaskData(taskData);
+        dtoDao.UpdateTaskState(task.Id, DA.TaskState.Waiting, null, userManager.CurrentUserId, null);
         return taskData.TaskId;
       }, false, true);
@@ -78,5 +82,5 @@
       return trans.UseTransaction(() => {
         task.ParentTaskId = parentTaskId;
-        return AddTask(task, taskData, dao.GetAssignedResources(parentTaskId).Select(x => x.Id));
+        return AddTask(task, taskData, dtoDao.GetAssignedResources(parentTaskId).Select(x => x.Id));
       }, false, true);
     }
@@ -87,5 +91,5 @@
 
       return trans.UseTransaction(() => {
-        return dao.GetTask(taskId);
+        return dtoDao.GetTask(taskId);
       }, false, false);
     }
@@ -94,5 +98,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        var tasks = dao.GetTasks(x => true);
+        var tasks = dtoDao.GetTasks(x => true);
         foreach (var task in tasks)
           author.AuthorizeForTask(task.Id, Permission.Read);
@@ -105,5 +109,5 @@
 
       return trans.UseTransaction(() => {
-        var tasks = dao.GetTasks(x => taskIds.Contains(x.TaskId)).Select(x => new LightweightTask(x)).ToArray();
+        var tasks = dtoDao.GetTasks(x => taskIds.Contains(x.TaskId)).Select(x => new LightweightTask(x)).ToArray();
         foreach (var task in tasks)
           author.AuthorizeForTask(task.Id, Permission.Read);
@@ -128,5 +132,5 @@
 
       return trans.UseTransaction(() => {
-        return dao.GetLightweightTasks(task => task.JobId == jobId).ToArray();
+        return dtoDao.GetLightweightTasks(task => task.JobId == jobId).ToArray();
       }, false, true);
     }
@@ -137,5 +141,5 @@
 
       return trans.UseTransaction(() => {
-        return dao.GetLightweightTasksWithoutStateLog(task => task.JobId == jobId).ToArray();
+        return dtoDao.GetLightweightTasksWithoutStateLog(task => task.JobId == jobId).ToArray();
       }, false, false);
     }
@@ -146,5 +150,5 @@
 
       return trans.UseTransaction(() => {
-        return dao.GetTaskData(taskId);
+        return dtoDao.GetTaskData(taskId);
       });
     }
@@ -155,5 +159,5 @@
 
       trans.UseTransaction(() => {
-        dao.UpdateTaskAndPlugins(taskDto);
+        dtoDao.UpdateTaskAndPlugins(taskDto);
       });
     }
@@ -163,11 +167,13 @@
       author.AuthorizeForTask(task.Id, Permission.Full);
 
-      trans.UseTransaction(() => {
-        dao.UpdateTaskAndPlugins(task);
-      });
-
-      trans.UseTransaction(() => {
-        taskData.LastUpdate = DateTime.Now;
-        dao.UpdateTaskData(taskData);
+      // what for?
+      /*trans.UseTransaction(() => {
+        dtoDao.UpdateTaskAndPlugins(task);
+      });*/
+
+      trans.UseTransaction(() => {
+        var data = dao.GetTaskDataByDto(taskData);
+        data.LastUpdate = DateTime.Now;
+        dao.UpdateTaskData(data);
       });
     }
@@ -177,5 +183,5 @@
       author.AuthorizeForTask(taskId, Permission.Full);
       trans.UseTransaction(() => {
-        dao.DeleteTask(taskId);
+        dtoDao.DeleteTask(taskId);
       });
     }
@@ -187,6 +193,6 @@
         var tasks = GetChildTasks(parentTaskId, true, false);
         foreach (var task in tasks) {
-          dao.DeleteTask(task.Id);
-          dao.DeleteTaskData(task.Id);
+          dtoDao.DeleteTask(task.Id);
+          dtoDao.DeleteTaskData(task.Id);
         };
       });
@@ -196,20 +202,21 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       author.AuthorizeForTask(taskId, Permission.Full);
-      return trans.UseTransaction(() => {
-        Task task = dao.UpdateTaskState(taskId, DataTransfer.Convert.ToEntity(taskState), slaveId, userId, exception);
-
-        if (task.Command.HasValue && task.Command.Value == Command.Pause && task.State == TaskState.Paused) {
+
+      return trans.UseTransaction(() => {
+        var task = dao.UpdateTaskState(taskId, DT.Convert.ToEntity(taskState), slaveId, userId, exception);
+
+        if (task.Command.HasValue && task.Command.Value == DA.Command.Pause && task.State == DA.TaskState.Paused) {
           task.Command = null;
-        } else if (task.Command.HasValue && task.Command.Value == Command.Abort && task.State == TaskState.Aborted) {
+        } else if (task.Command.HasValue && task.Command.Value == DA.Command.Abort && task.State == DA.TaskState.Aborted) {
           task.Command = null;
-        } else if (task.Command.HasValue && task.Command.Value == Command.Stop && task.State == TaskState.Aborted) {
+        } else if (task.Command.HasValue && task.Command.Value == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
           task.Command = null;
         } else if (taskState == TaskState.Paused && !task.Command.HasValue) {
           // slave paused and uploaded the task (no user-command) -> set waiting.
-          task = dao.UpdateTaskState(taskId, DataTransfer.Convert.ToEntity(TaskState.Waiting), slaveId, userId, exception);
-        }
-
-        dao.UpdateTaskAndPlugins(task);
-        return task;
+          task = dao.UpdateTaskState(taskId, DA.TaskState.Waiting, slaveId, userId, exception);
+        }
+
+        //dtoDao.UpdateTaskAndPluginsDA(task); no idea why this is needed
+        return DT.Convert.ToDto(task);
       });
     }
@@ -217,5 +224,5 @@
     public IEnumerable<Task> GetTasksByResourceId(Guid resourceId) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
-      var tasks = trans.UseTransaction(() => dao.GetJobsByResourceId(resourceId));
+      var tasks = trans.UseTransaction(() => dtoDao.GetJobsByResourceId(resourceId));
       foreach (var task in tasks)
         author.AuthorizeForTask(task.Id, Permission.Read);
@@ -229,8 +236,8 @@
       author.AuthorizeForTask(taskId, Permission.Full);
       trans.UseTransaction(() => {
-        var task = dao.GetTask(taskId);
+        var task = dtoDao.GetTask(taskId);
         if (task.State == TaskState.Calculating || task.State == TaskState.Transferring) {
           task.Command = Command.Stop;
-          dao.UpdateTask(task);
+          dtoDao.UpdateTask(task);
         } else {
           if (task.State != TaskState.Aborted && task.State != TaskState.Finished && task.State != TaskState.Failed) {
@@ -245,8 +252,8 @@
       author.AuthorizeForTask(taskId, Permission.Full);
       trans.UseTransaction(() => {
-        var job = dao.GetTask(taskId);
+        var job = dtoDao.GetTask(taskId);
         if (job.State == TaskState.Calculating || job.State == TaskState.Transferring) {
           job.Command = Command.Pause;
-          dao.UpdateTask(job);
+          dtoDao.UpdateTask(job);
         } else {
           job = UpdateTaskState(taskId, TaskState.Paused, null, null, string.Empty);
@@ -259,7 +266,7 @@
       author.AuthorizeForTask(taskId, Permission.Full);
       trans.UseTransaction(() => {
-        Task task = dao.UpdateTaskState(taskId, DA.TaskState.Waiting, null, userManager.CurrentUserId, string.Empty);
+        Task task = dtoDao.UpdateTaskState(taskId, DA.TaskState.Waiting, null, userManager.CurrentUserId, string.Empty);
         task.Command = null;
-        dao.UpdateTask(task);
+        dtoDao.UpdateTask(task);
       });
     }
@@ -271,10 +278,10 @@
       author.AuthorizeForJob(id, Permission.Read);
       return trans.UseTransaction(() => {
-        var job = dao.GetJobs(x =>
+        var job = dtoDao.GetJobs(x =>
               x.JobId == id
               && (x.OwnerUserId == userManager.CurrentUserId || x.JobPermissions.Count(hep => hep.Permission != DA.Permission.NotAllowed && hep.GrantedUserId == userManager.CurrentUserId) > 0)
             ).FirstOrDefault();
         if (job != null) {
-          job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
+          job.Permission = DT.Convert.ToDto(dtoDao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
           job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
         }
@@ -286,8 +293,8 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        var jobs = dao.GetJobs(x => x.OwnerUserId == userManager.CurrentUserId || x.JobPermissions.Count(hep => hep.Permission != DA.Permission.NotAllowed && hep.GrantedUserId == userManager.CurrentUserId) > 0);
+        var jobs = dtoDao.GetJobs(x => x.OwnerUserId == userManager.CurrentUserId || x.JobPermissions.Count(hep => hep.Permission != DA.Permission.NotAllowed && hep.GrantedUserId == userManager.CurrentUserId) > 0);
         foreach (var job in jobs) {
           author.AuthorizeForJob(job.Id, Permission.Read);
-          job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
+          job.Permission = DT.Convert.ToDto(dtoDao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
           job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
         }
@@ -299,7 +306,7 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
       return trans.UseTransaction(() => {
-        var jobs = dao.GetJobs(x => true);
+        var jobs = dtoDao.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(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
+          job.Permission = DT.Convert.ToDto(dtoDao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
           job.OwnerUsername = userManager.GetUserById(job.OwnerUserId).UserName;
         }
@@ -313,5 +320,5 @@
         jobDto.OwnerUserId = userManager.CurrentUserId;
         jobDto.DateCreated = DateTime.Now;
-        return dao.AddJob(jobDto);
+        return dtoDao.AddJob(jobDto);
       });
     }
@@ -321,5 +328,5 @@
       author.AuthorizeForJob(jobDto.Id, Permission.Full);
       trans.UseTransaction(() => {
-        dao.UpdateJob(jobDto);
+        dtoDao.UpdateJob(jobDto);
       });
     }
@@ -329,5 +336,5 @@
       author.AuthorizeForJob(jobId, Permission.Full);
       trans.UseTransaction(() => {
-        dao.DeleteJob(jobId); // child task will be deleted by db-trigger
+        dtoDao.DeleteJob(jobId); // child task will be deleted by db-trigger
       });
     }
@@ -338,9 +345,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        Job job = dao.GetJob(jobId);
+        Job job = dtoDao.GetJob(jobId);
         if (job == null) throw new FaultException<FaultReason>(new FaultReason("Could not find task with id " + jobId));
-        Permission perm = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
+        Permission perm = DT.Convert.ToDto(dtoDao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
         if (perm != Permission.Full) throw new FaultException<FaultReason>(new FaultReason("Not allowed to grant permissions for this experiment"));
-        dao.SetJobPermission(jobId, userManager.CurrentUserId, grantedUserId, DT.Convert.ToEntity(permission));
+        dtoDao.SetJobPermission(jobId, userManager.CurrentUserId, grantedUserId, DT.Convert.ToEntity(permission));
       });
     }
@@ -349,9 +356,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        Job job = dao.GetJob(jobId);
+        Job job = dtoDao.GetJob(jobId);
         if (job == null) throw new FaultException<FaultReason>(new FaultReason("Could not find task with id " + jobId));
-        DA.Permission perm = dao.GetPermissionForJob(job.Id, userManager.CurrentUserId);
+        DA.Permission perm = dtoDao.GetPermissionForJob(job.Id, userManager.CurrentUserId);
         if (perm != DA.Permission.Full) throw new FaultException<FaultReason>(new FaultReason("Not allowed to grant permissions for this experiment"));
-        dao.SetJobPermission(jobId, userManager.CurrentUserId, grantedUserId, DA.Permission.NotAllowed);
+        dtoDao.SetJobPermission(jobId, userManager.CurrentUserId, grantedUserId, DA.Permission.NotAllowed);
       });
     }
@@ -360,7 +367,7 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        DA.Permission currentUserPermission = dao.GetPermissionForJob(jobId, userManager.CurrentUserId);
+        DA.Permission currentUserPermission = dtoDao.GetPermissionForJob(jobId, userManager.CurrentUserId);
         if (currentUserPermission != DA.Permission.Full) throw new FaultException<FaultReason>(new FaultReason("Not allowed to list permissions for this experiment"));
-        return dao.GetJobPermissions(x => x.JobId == jobId);
+        return dtoDao.GetJobPermissions(x => x.JobId == jobId);
       });
     }
@@ -379,12 +386,12 @@
 
       trans.UseTransaction(() => {
-        var slave = dao.GetSlave(slaveInfo.Id);
+        var slave = dtoDao.GetSlave(slaveInfo.Id);
 
         if (slave == null) {
-          var healGroup = dao.GetResources(x => x.Name == "HEAL").First();
+          var healGroup = dtoDao.GetResources(x => x.Name == "HEAL").First();
           if (healGroup != null) {
             slaveInfo.ParentResourceId = healGroup.Id;
           }
-          dao.AddSlave(slaveInfo);
+          dtoDao.AddSlave(slaveInfo);
         } else {
           slave.Name = slaveInfo.Name;
@@ -405,5 +412,5 @@
           // don't update those properties: dbSlave.IsAllowedToCalculate, dbSlave.ParentResourceId 
 
-          dao.UpdateSlave(slave);
+          dtoDao.UpdateSlave(slave);
         }
       });
@@ -413,8 +420,8 @@
       authen.AuthenticateForAnyRole(HiveRoles.Slave);
       trans.UseTransaction(() => {
-        var slave = dao.GetSlave(slaveId);
+        var slave = dtoDao.GetSlave(slaveId);
         if (slave != null) {
           slave.SlaveState = SlaveState.Offline;
-          dao.UpdateSlave(slave);
+          dtoDao.UpdateSlave(slave);
         }
       });
@@ -449,5 +456,5 @@
         plugin.DateCreated = DateTime.Now;
 
-        var existing = dao.GetPlugins(x => x.Hash != null).Where(x => x.Hash.SequenceEqual(plugin.Hash));
+        var existing = dtoDao.GetPlugins(x => x.Hash != null).Where(x => x.Hash.SequenceEqual(plugin.Hash));
         if (existing.Count() > 0) {
           // a plugin already exists.
@@ -455,8 +462,8 @@
         }
 
-        Guid pluginId = dao.AddPlugin(plugin);
+        Guid pluginId = dtoDao.AddPlugin(plugin);
         foreach (PluginData pluginData in pluginDatas) {
           pluginData.PluginId = pluginId;
-          dao.AddPluginData(pluginData);
+          dtoDao.AddPluginData(pluginData);
         }
         return pluginId;
@@ -467,5 +474,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       return trans.UseTransaction(() => {
-        return dao.GetPlugin(pluginId);
+        return dtoDao.GetPlugin(pluginId);
       });
     }
@@ -474,5 +481,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       return trans.UseTransaction(() => {
-        return dao.GetPlugins(x => x.Hash == hash).FirstOrDefault();
+        return dtoDao.GetPlugins(x => x.Hash == hash).FirstOrDefault();
       });
     }
@@ -483,5 +490,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       return trans.UseTransaction(() => {
-        return dao.GetPlugins(x => x.Hash != null);
+        return dtoDao.GetPlugins(x => x.Hash != null);
       });
     }
@@ -492,5 +499,5 @@
       return trans.UseTransaction(() => {
         foreach (Guid guid in pluginIds) {
-          pluginDatas.AddRange(dao.GetPluginDatas(x => x.PluginId == guid).ToList());
+          pluginDatas.AddRange(dtoDao.GetPluginDatas(x => x.PluginId == guid).ToList());
         }
         return pluginDatas;
@@ -501,5 +508,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       trans.UseTransaction(() => {
-        dao.DeletePlugin(pluginId);
+        dtoDao.DeletePlugin(pluginId);
       });
     }
@@ -510,9 +517,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        Resource resource = dao.GetResource(resourceId);
+        Resource resource = dtoDao.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)
-          dao.AddResourcePermission(new ResourcePermission { ResourceId = resourceId, GrantedByUserId = userManager.CurrentUserId, GrantedUserId = id });
+          dtoDao.AddResourcePermission(new ResourcePermission { ResourceId = resourceId, GrantedByUserId = userManager.CurrentUserId, GrantedUserId = id });
       });
     }
@@ -521,9 +528,9 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        Resource resource = dao.GetResource(resourceId);
+        Resource resource = dtoDao.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)
-          dao.DeleteResourcePermission(resourceId, id);
+          dtoDao.DeleteResourcePermission(resourceId, id);
       });
     }
@@ -532,7 +539,7 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        Resource resource = dao.GetResource(resourceId);
+        Resource resource = dtoDao.GetResource(resourceId);
         if (resource == null) throw new FaultException<FaultReason>(new FaultReason("Could not find resource with id " + resourceId));
-        return dao.GetResourcePermissions(x => x.ResourceId == resourceId);
+        return dtoDao.GetResourcePermissions(x => x.ResourceId == resourceId);
       });
     }
@@ -541,5 +548,5 @@
     #region Resource Methods
     public IEnumerable<Resource> GetChildResources(Guid resourceId) {
-      return trans.UseTransaction(() => { return dao.GetChildResources(resourceId); });
+      return trans.UseTransaction(() => { return dtoDao.GetChildResources(resourceId); });
     }
     #endregion
@@ -549,5 +556,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Slave);
 
-      Slave s = trans.UseTransaction(() => { return dao.GetSlave(slaveId); });
+      Slave s = trans.UseTransaction(() => { return dtoDao.GetSlave(slaveId); });
       if (s != null) {
         return s.HbInterval;
@@ -559,20 +566,20 @@
     public Guid AddSlave(Slave slave) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
-      return trans.UseTransaction(() => dao.AddSlave(slave));
+      return trans.UseTransaction(() => dtoDao.AddSlave(slave));
     }
 
     public Guid AddSlaveGroup(SlaveGroup slaveGroup) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      return trans.UseTransaction(() => dao.AddSlaveGroup(slaveGroup));
+      return trans.UseTransaction(() => dtoDao.AddSlaveGroup(slaveGroup));
     }
 
     public Slave GetSlave(Guid slaveId) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
-      return trans.UseTransaction(() => { return dao.GetSlave(slaveId); });
+      return trans.UseTransaction(() => { return dtoDao.GetSlave(slaveId); });
     }
 
     public SlaveGroup GetSlaveGroup(Guid slaveGroupId) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
-      return trans.UseTransaction(() => { return dao.GetSlaveGroup(slaveGroupId); });
+      return trans.UseTransaction(() => { return dtoDao.GetSlaveGroup(slaveGroupId); });
     }
 
@@ -580,5 +587,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        return dao.GetSlaves(x => true).Where(x => x.OwnerUserId == null
+        return dtoDao.GetSlaves(x => true).Where(x => x.OwnerUserId == null
                                            || x.OwnerUserId == userManager.CurrentUserId
                                            || userManager.VerifyUser(userManager.CurrentUserId, GetResourcePermissions(x.Id).Select(y => y.GrantedUserId).ToList())
@@ -590,5 +597,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        return dao.GetSlaveGroups(x => true).Where(x => x.OwnerUserId == null
+        return dtoDao.GetSlaveGroups(x => true).Where(x => x.OwnerUserId == null
                                                 || x.OwnerUserId == userManager.CurrentUserId
                                                 || userManager.VerifyUser(userManager.CurrentUserId, GetResourcePermissions(x.Id).Select(y => y.GrantedUserId).ToList())
@@ -600,5 +607,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        dao.UpdateSlave(slave);
+        dtoDao.UpdateSlave(slave);
       });
     }
@@ -607,5 +614,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       trans.UseTransaction(() => {
-        dao.UpdateSlaveGroup(slaveGroup);
+        dtoDao.UpdateSlaveGroup(slaveGroup);
       });
     }
@@ -615,5 +622,5 @@
       author.AuthorizeForResourceAdministration(slaveId);
       trans.UseTransaction(() => {
-        dao.DeleteSlave(slaveId);
+        dtoDao.DeleteSlave(slaveId);
       });
     }
@@ -623,5 +630,5 @@
       author.AuthorizeForResourceAdministration(slaveGroupId);
       trans.UseTransaction(() => {
-        dao.DeleteSlaveGroup(slaveGroupId);
+        dtoDao.DeleteSlaveGroup(slaveGroupId);
       });
     }
@@ -630,7 +637,7 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
       trans.UseTransaction(() => {
-        var resource = dao.GetResource(resourceId);
+        var resource = dtoDao.GetResource(resourceId);
         resource.ParentResourceId = slaveGroupId;
-        dao.UpdateResource(resource);
+        dtoDao.UpdateResource(resource);
       });
     }
@@ -639,7 +646,7 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator);
       trans.UseTransaction(() => {
-        var resource = dao.GetResource(resourceId);
+        var resource = dtoDao.GetResource(resourceId);
         resource.ParentResourceId = null;
-        dao.UpdateResource(resource);
+        dtoDao.UpdateResource(resource);
       });
     }
@@ -648,5 +655,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       return trans.UseTransaction(() => {
-        var resource = dao.GetResources(x => x.Name == resourceName).FirstOrDefault();
+        var resource = dtoDao.GetResources(x => x.Name == resourceName).FirstOrDefault();
         if (resource != null) {
           return resource.Id;
@@ -662,7 +669,7 @@
       bool cleanup = false;
       trans.UseTransaction(() => {
-        DateTime lastCleanup = dao.GetLastCleanup();
+        DateTime lastCleanup = dtoDao.GetLastCleanup();
         if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
-          dao.SetLastCleanup(DateTime.Now);
+          dtoDao.SetLastCleanup(DateTime.Now);
           cleanup = true;
         }
@@ -679,5 +686,5 @@
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       author.AuthorizeForResourceAdministration(downtime.ResourceId);
-      return trans.UseTransaction(() => dao.AddDowntime(downtime));
+      return trans.UseTransaction(() => dtoDao.AddDowntime(downtime));
     }
 
@@ -687,5 +694,5 @@
       // author.AuthorizeForResource(resourceId);
       trans.UseTransaction(() => {
-        dao.DeleteDowntime(downtimeId);
+        dtoDao.DeleteDowntime(downtimeId);
       });
     }
@@ -695,5 +702,5 @@
       author.AuthorizeForResourceAdministration(downtime.ResourceId);
       trans.UseTransaction(() => {
-        dao.UpdateDowntime(downtime);
+        dtoDao.UpdateDowntime(downtime);
       });
     }
@@ -701,5 +708,5 @@
     public IEnumerable<Downtime> GetDowntimesForResource(Guid resourceId) {
       authen.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      return trans.UseTransaction(() => dao.GetDowntimes(x => x.ResourceId == resourceId));
+      return trans.UseTransaction(() => dtoDao.GetDowntimes(x => x.ResourceId == resourceId));
     }
     #endregion
@@ -724,5 +731,5 @@
     #region UserPriority Methods
     public IEnumerable<UserPriority> GetUserPriorities() {
-      return trans.UseTransaction(() => dao.GetUserPriorities(x => true));
+      return trans.UseTransaction(() => dtoDao.GetUserPriorities(x => true));
     }
     #endregion
@@ -730,5 +737,5 @@
     #region Helper Methods
     private IEnumerable<Task> GetChildTasks(Guid? parentTaskId, bool recursive, bool includeParent) {
-      var tasks = new List<Task>(dao.GetTasks(x => parentTaskId == null ? !x.ParentTaskId.HasValue : x.ParentTaskId.Value == parentTaskId));
+      var tasks = new List<Task>(dtoDao.GetTasks(x => parentTaskId == null ? !x.ParentTaskId.HasValue : x.ParentTaskId.Value == parentTaskId));
 
       if (recursive) {
@@ -747,8 +754,8 @@
     #region Statistics Methods
     public IEnumerable<Statistics> GetStatistics() {
-      return trans.UseTransaction(() => { return dao.GetStatistics(x => true); });
+      return trans.UseTransaction(() => { return dtoDao.GetStatistics(x => true); });
     }
     public IEnumerable<Statistics> GetStatisticsForTimePeriod(DateTime from, DateTime to) {
-      return trans.UseTransaction(() => { return dao.GetStatistics(x => x.Timestamp >= from && x.Timestamp <= to); });
+      return trans.UseTransaction(() => { return dtoDao.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 9385)
+++ 	(revision )
@@ -1,179 +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 HeuristicLab.Services.Hive.DataAccess;
-using DT = HeuristicLab.Services.Hive.DataTransfer;
-
-namespace HeuristicLab.Services.Hive {
-  public interface IHiveDao {
-    #region Task Methods
-    DT.Task GetTask(Guid id);
-    Task GetTaskDA(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 UpdateTaskDA(Task dto);
-    void DeleteTask(Guid id);
-    IEnumerable<TaskInfoForScheduler> GetWaitingTasks(DT.Slave slave);
-    IQueryable<TaskInfoForScheduler> GetWaitingTasksDA(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);
-    Task UpdateTaskStateDA(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);
-    Slave GetSlaveDA(Guid id);
-    IEnumerable<DT.Slave> GetSlaves(Expression<Func<Slave, bool>> predicate);
-    Guid AddSlave(DT.Slave dto);
-    void UpdateSlave(DT.Slave dto);
-    void UpdateSlaveDA(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);
-    IQueryable<Guid> GetAssignedResourcesIdsDA(Guid taskId);
-    IEnumerable<DT.Resource> GetParentResources(Guid resourceId);
-    IEnumerable<Resource> GetParentResourcesDA(Guid resourceId);
-    IEnumerable<Guid> GetParentResourcesIDsDA(Guid resourceId);
-    IQueryable<int> GetNumberOfDowntimesFromParentResourcesAtCurrentTimeDA(Guid resourceId, DowntimeType type);
-    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/IHiveDtoDao.cs
===================================================================
--- branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IHiveDtoDao.cs	(revision 9391)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IHiveDtoDao.cs	(revision 9391)
@@ -0,0 +1,168 @@
+﻿#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/IServiceLocator.cs
===================================================================
--- branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs	(revision 9385)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Interfaces/IServiceLocator.cs	(revision 9391)
@@ -26,4 +26,5 @@
     Access.IRoleVerifier RoleVerifier { get; }
     IAuthorizationManager AuthorizationManager { get; }
+    IHiveDtoDao HiveDtoDao { get; }
     IHiveDao HiveDao { get; }
     IEventManager EventManager { 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 9385)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/AuthorizationManager.cs	(revision 9391)
@@ -36,5 +36,5 @@
       if (ServiceLocator.Instance.RoleVerifier.IsInRole(HiveRoles.Slave)) return; // slave-users can access all tasks
 
-      Permission permission = ServiceLocator.Instance.HiveDao.GetPermissionForTask(taskId, ServiceLocator.Instance.UserManager.CurrentUserId);
+      Permission permission = ServiceLocator.Instance.HiveDtoDao.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.HiveDao.GetPermissionForJob(jobId, ServiceLocator.Instance.UserManager.CurrentUserId);
+      Permission permission = ServiceLocator.Instance.HiveDtoDao.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.HiveDao.GetResource(resourceId));
+      Resource resource = DT.Convert.ToEntity(ServiceLocator.Instance.HiveDtoDao.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 9385)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/EventManager.cs	(revision 9391)
@@ -32,6 +32,6 @@
   /// </summary>
   public class EventManager : IEventManager {
-    private IHiveDao dao {
-      get { return ServiceLocator.Instance.HiveDao; }
+    private IHiveDtoDao dao {
+      get { return ServiceLocator.Instance.HiveDtoDao; }
     }
     private IAuthorizationManager auth {
@@ -78,5 +78,5 @@
       //we have to find another way to deal with this.  
       //until then the next line is commented out...
-      //stats.UserStatistics = dao.GetUserStatistics();
+      //stats.UserStatistics = dtoDao.GetUserStatistics();
       dao.AddStatistics(stats);
     }
Index: branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs
===================================================================
--- branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs	(revision 9385)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Manager/HeartbeatManager.cs	(revision 9391)
@@ -24,6 +24,6 @@
 using System.Linq;
 using System.Threading;
-using HeuristicLab.Services.Hive.DataTransfer;
-using DA = HeuristicLab.Services.Hive.DataAccess;
+using HeuristicLab.Services.Hive.DataAccess;
+using Heartbeat = HeuristicLab.Services.Hive.DataTransfer.Heartbeat;
 
 namespace HeuristicLab.Services.Hive {
@@ -48,7 +48,7 @@
       List<MessageContainer> actions = new List<MessageContainer>();
 
-      DA.Slave slave = null;
+      Slave slave = null;
       trans.UseTransaction(() => {
-        slave = dao.GetSlaveDA(heartbeat.SlaveId);
+        slave = dao.GetSlaveById(heartbeat.SlaveId);
 
         if (slave == null) {
@@ -67,8 +67,8 @@
           slave.CpuUtilization = heartbeat.CpuUtilization;
           slave.IsAllowedToCalculate = SlaveIsAllowedToCalculate(slave.ResourceId);
-          slave.SlaveState = (heartbeat.JobProgress != null && heartbeat.JobProgress.Count > 0) ? DA.SlaveState.Calculating : DA.SlaveState.Idle;
+          slave.SlaveState = (heartbeat.JobProgress != null && heartbeat.JobProgress.Count > 0) ? SlaveState.Calculating : SlaveState.Idle;
           slave.LastHeartbeat = DateTime.Now;
 
-          dao.UpdateSlaveDA(slave);
+          dao.UpdateSlave(slave);
         }
       });
@@ -86,9 +86,9 @@
             mutexAquired = mutex.WaitOne(Properties.Settings.Default.SchedulingPatience);
             if (!mutexAquired)
-              DA.LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling could not be aquired.");
+              LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling could not be aquired.");
             else {
               trans.UseTransaction(() => {
                 IEnumerable<TaskInfoForScheduler> availableTasks = null;
-                availableTasks = taskScheduler.Schedule(dao.GetWaitingTasksDA(slave).ToArray());
+                availableTasks = taskScheduler.Schedule(dao.GetWaitingTasks(slave).ToArray());
                 if (availableTasks.Any()) {
                   var task = availableTasks.First();
@@ -100,8 +100,8 @@
           }
           catch (AbandonedMutexException) {
-            DA.LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling has been abandoned.");
+            LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager: The mutex used for scheduling has been abandoned.");
           }
           catch (Exception ex) {
-            DA.LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager threw an exception in ProcessHeartbeat: " + ex.ToString());
+            LogFactory.GetLogger(this.GetType().Namespace).Log("HeartbeatManager threw an exception in ProcessHeartbeat: " + ex.ToString());
           }
           finally {
@@ -113,10 +113,10 @@
     }
 
-    private void AssignJob(DA.Slave slave, Guid taskId) {
-      var task = dao.UpdateTaskStateDA(taskId, DataAccess.TaskState.Transferring, slave.ResourceId, null, null);
+    private void AssignJob(Slave slave, Guid taskId) {
+      var task = dao.UpdateTaskState(taskId, DataAccess.TaskState.Transferring, slave.ResourceId, null, null);
 
       // from now on the task has some time to send the next heartbeat (ApplicationConstants.TransferringJobHeartbeatTimeout)
       task.LastHeartbeat = DateTime.Now;
-      dao.UpdateTaskDA(task);
+      dao.UpdateTask(task);
     }
 
@@ -137,9 +137,9 @@
         foreach (var jobProgress in heartbeat.JobProgress) {
           trans.UseTransaction(() => {
-            var curTask = dao.GetTaskDA(jobProgress.Key);
+            var curTask = dao.GetTaskById(jobProgress.Key);
             if (curTask == null) {
               // task does not exist in db
               actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, jobProgress.Key));
-              DA.LogFactory.GetLogger(this.GetType().Namespace).Log("Task on slave " + heartbeat.SlaveId + " does not exist in DB: " + jobProgress.Key);
+              LogFactory.GetLogger(this.GetType().Namespace).Log("Task on slave " + heartbeat.SlaveId + " does not exist in DB: " + jobProgress.Key);
             } else {
               var currentStateLog = curTask.StateLogs.Last();
@@ -147,5 +147,5 @@
                 // assigned slave does not match heartbeat
                 actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.TaskId));
-                DA.LogFactory.GetLogger(this.GetType().Namespace).Log("The slave " + heartbeat.SlaveId + " is not supposed to calculate task: " + curTask);
+                LogFactory.GetLogger(this.GetType().Namespace).Log("The slave " + heartbeat.SlaveId + " is not supposed to calculate task: " + curTask);
               } else if (!TaskIsAllowedToBeCalculatedBySlave(heartbeat.SlaveId, curTask)) {
                 // assigned resources ids of task do not match with slaveId (and parent resourceGroupIds); this might happen when slave is moved to different group
@@ -157,15 +157,15 @@
 
                 switch (curTask.Command) {
-                  case DA.Command.Stop:
+                  case Command.Stop:
                     actions.Add(new MessageContainer(MessageContainer.MessageType.StopTask, curTask.TaskId));
                     break;
-                  case DA.Command.Pause:
+                  case Command.Pause:
                     actions.Add(new MessageContainer(MessageContainer.MessageType.PauseTask, curTask.TaskId));
                     break;
-                  case DA.Command.Abort:
+                  case Command.Abort:
                     actions.Add(new MessageContainer(MessageContainer.MessageType.AbortTask, curTask.TaskId));
                     break;
                 }
-                dao.UpdateTaskDA(curTask);
+                dao.UpdateTask(curTask);
               }
             }
@@ -176,12 +176,12 @@
     }
 
-    private bool TaskIsAllowedToBeCalculatedBySlave(Guid slaveId, DA.Task curTask) {
-      var assignedResourceIds = dao.GetAssignedResourcesIdsDA(curTask.TaskId);
-      var slaveResourceIds = dao.GetParentResourcesIDsDA(slaveId).ToArray();
+    private bool TaskIsAllowedToBeCalculatedBySlave(Guid slaveId, Task curTask) {
+      var assignedResourceIds = dao.GetAssignedResourcesIds(curTask.TaskId);
+      var slaveResourceIds = dao.GetParentResourcesIDs(slaveId).ToArray();
       return assignedResourceIds.Any(r => slaveResourceIds.Contains(r));
     }
 
     private bool SlaveIsAllowedToCalculate(Guid slaveId) {
-      var downtimes = dao.GetNumberOfDowntimesFromParentResourcesAtCurrentTimeDA(slaveId, DA.DowntimeType.Offline);
+      var downtimes = dao.GetNumberOfDowntimesFromParentResourcesAtCurrentTime(slaveId, DowntimeType.Offline);
       // the slave may only calculate if there is no downtime right now. this needs to be checked for every parent resource also
       return downtimes.All(x => x == 0);
@@ -189,5 +189,5 @@
 
     private bool ShutdownSlaveComputer(Guid slaveId) {
-      var downtimes = dao.GetNumberOfDowntimesFromParentResourcesAtCurrentTimeDA(slaveId, DA.DowntimeType.Shutdown);
+      var downtimes = dao.GetNumberOfDowntimesFromParentResourcesAtCurrentTime(slaveId, DowntimeType.Shutdown);
       return downtimes.Any(x => x != 0);
     }
Index: branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Scheduler/RoundRobinTaskScheduler.cs
===================================================================
--- branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Scheduler/RoundRobinTaskScheduler.cs	(revision 9385)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/Scheduler/RoundRobinTaskScheduler.cs	(revision 9391)
@@ -27,6 +27,6 @@
 namespace HeuristicLab.Services.Hive {
   public class RoundRobinTaskScheduler : ITaskScheduler {
-    private IHiveDao dao {
-      get { return ServiceLocator.Instance.HiveDao; }
+    private IHiveDtoDao dao {
+      get { return ServiceLocator.Instance.HiveDtoDao; }
     }
 
Index: branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs
===================================================================
--- branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs	(revision 9385)
+++ branches/HivePerformance/sources/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs	(revision 9391)
@@ -32,4 +32,12 @@
       }
       set { instance = value; }
+    }
+
+    private IHiveDtoDao hiveDtoDao;
+    public IHiveDtoDao HiveDtoDao {
+      get {
+        if (hiveDtoDao == null) hiveDtoDao = new HiveDtoDao();
+        return hiveDtoDao;
+      }
     }
 
