Index: branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/NewHiveService.cs
===================================================================
--- branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/NewHiveService.cs	(revision 12584)
+++ branches/HiveStatistics/sources/HeuristicLab.Services.Hive/3.3/NewHiveService.cs	(revision 12691)
@@ -1,8 +1,34 @@
-﻿using System;
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2015 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
+ *
+ * This file is part of HeuristicLab.
+ *
+ * HeuristicLab is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * HeuristicLab is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
+ */
+#endregion
+
+using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Linq;
+using System.Runtime.CompilerServices;
+using System.Security;
+using System.ServiceModel;
 using HeuristicLab.Services.Access;
 using HeuristicLab.Services.Hive.DataAccess.Interfaces;
 using HeuristicLab.Services.Hive.DataTransfer;
+using HeuristicLab.Services.Hive.Manager;
 using HeuristicLab.Services.Hive.ServiceContracts;
 using DA = HeuristicLab.Services.Hive.DataAccess;
@@ -10,4 +36,10 @@
 
 namespace HeuristicLab.Services.Hive {
+  /// <summary>
+  /// Implementation of the Hive service (interface <see cref="IHiveService"/>).
+  /// We need 'IgnoreExtensionDataObject' Attribute for the slave to work. 
+  /// </summary>
+  [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, IgnoreExtensionDataObject = true)]
+  [HiveOperationContextBehavior]
   public class NewHiveService : IHiveService {
     private static readonly DA.TaskState[] CompletedStates = { DA.TaskState.Finished, DA.TaskState.Aborted, DA.TaskState.Failed };
@@ -28,8 +60,16 @@
       get { return ServiceLocator.Instance.AuthorizationManager; }
     }
-
+    private IEventManager EventManager {
+      get { return ServiceLocator.Instance.EventManager; }
+    }
+    private NewHeartbeatManager HeartbeatManager {
+      get { return ServiceLocator.Instance.NewHeartbeatManager; }
+    }
+
+    #region Task Methods
     public Guid AddTask(DT.Task task, DT.TaskData taskData, IEnumerable<Guid> resourceIds) {
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddTask")) {
         var taskDao = pm.TaskDao;
         var stateLogDao = pm.StateLogDao;
@@ -62,5 +102,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       IEnumerable<Guid> resourceIds;
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddChildTask")) {
         var assignedResourceDao = pm.AssignedResourceDao;
         resourceIds = pm.UseTransaction(() => {
@@ -77,5 +118,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetTask")) {
         var taskDao = pm.TaskDao;
         return pm.UseTransaction(() => {
@@ -104,8 +146,10 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetLightweightJobTasks")) {
         var taskDao = pm.TaskDao;
         return pm.UseTransaction(() => {
           return taskDao.GetByJobId(jobId)
+            .ToList()
             .Select(x => new DT.LightweightTask {
               Id = x.TaskId,
@@ -118,5 +162,6 @@
               Command = x.Command.ToDto(),
               LastTaskDataUpdate = x.JobData.LastUpdate
-            });
+            })
+            .ToList();
         }, false, true);
       }
@@ -126,8 +171,10 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
       AuthorizationManager.AuthorizeForJob(jobId, Permission.Read);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetLightweightJobTasksWithoutStateLog")) {
         var taskDao = pm.TaskDao;
         return pm.UseTransaction(() => {
           return taskDao.GetByJobId(jobId)
+            .ToList()
             .Select(x => new DT.LightweightTask {
               Id = x.TaskId,
@@ -138,5 +185,6 @@
               Command = x.Command.ToDto(),
               LastTaskDataUpdate = x.JobData.LastUpdate
-            });
+            })
+            .ToList();
         }, false, true);
       }
@@ -146,5 +194,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Read);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetTaskData")) {
         var taskDataDao = pm.TaskDataDao;
         return pm.UseTransaction(() => taskDataDao.GetById(taskId).ToDto());
@@ -155,5 +204,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateTask")) {
         var taskDao = pm.TaskDao;
         pm.UseTransaction(() => {
@@ -168,5 +218,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskDto.Id, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateTaskData")) {
         var taskDao = pm.TaskDao;
         var taskDataDao = pm.TaskDataDao;
@@ -195,5 +246,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateTaskState")) {
         var taskDao = pm.TaskDao;
         var stateLogDao = pm.StateLogDao;
@@ -206,30 +258,12 @@
       }
     }
-
-    private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
-      var stateLogDao = pm.StateLogDao;
-      var taskStateEntity = taskState.ToEntity();
-      if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
-          || task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
-          || task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
-        task.Command = null;
-      } else if (taskStateEntity == DA.TaskState.Paused) {
-        taskStateEntity = DA.TaskState.Waiting;
-      }
-      stateLogDao.Save(new DA.StateLog {
-        State = taskStateEntity,
-        DateTime = DateTime.Now,
-        TaskId = task.TaskId,
-        UserId = userId,
-        SlaveId = slaveId,
-        Exception = exception
-      });
-      task.State = taskStateEntity;
-    }
-
+    #endregion
+
+    #region Task Control Methods
     public void StopTask(Guid taskId) {
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("StopTask")) {
         var taskDao = pm.TaskDao;
         pm.UseTransaction(() => {
@@ -250,5 +284,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("PauseTask")) {
         var taskDao = pm.TaskDao;
         pm.UseTransaction(() => {
@@ -256,7 +291,6 @@
           if (task.State == DA.TaskState.Calculating || task.State == DA.TaskState.Transferring) {
             task.Command = DA.Command.Pause;
-          } else {
-            UpdateTaskState(pm, task, DT.TaskState.Paused, null, null, string.Empty);
-          }
+          }
+          UpdateTaskState(pm, task, DT.TaskState.Paused, null, null, string.Empty);
           pm.SubmitChanges();
         });
@@ -267,5 +301,6 @@
       RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
       AuthorizationManager.AuthorizeForTask(taskId, Permission.Full);
-      using (var pm = PersistenceManager) {
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("RestartTask")) {
         var taskDao = pm.TaskDao;
         pm.UseTransaction(() => {
@@ -277,13 +312,16 @@
       }
     }
-
-
-    public Job GetJob(Guid id) {
-      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
-      AuthorizationManager.AuthorizeForJob(id, Permission.Read);
-      using (var pm = PersistenceManager) {
+    #endregion
+
+    #region Job Methods
+    public DT.Job GetJob(Guid id) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(id, DT.Permission.Read);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetJob")) {
         var jobDao = pm.JobDao;
         var jobPermissionDao = pm.JobPermissionDao;
         var taskDao = pm.TaskDao;
+        var currentUserId = UserManager.CurrentUserId;
         return pm.UseTransaction(() => {
           var job = jobDao.GetById(id).ToDto();
@@ -301,7 +339,11 @@
               job.FinishedCount = statistics.FinishedCount;
             }
-            // TODO
-            //job.Permission = DT.Convert.ToDto(dao.GetPermissionForJob(job.Id, userManager.CurrentUserId));
             job.OwnerUsername = UserManager.GetUserById(job.OwnerUserId).UserName;
+            if (currentUserId == job.OwnerUserId) {
+              job.Permission = Permission.Full;
+            } else {
+              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
+              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
+            }
           }
           return job;
@@ -310,6 +352,48 @@
     }
 
-    public IEnumerable<Job> GetJobs() {
-      throw new NotImplementedException();
+    public IEnumerable<DT.Job> GetJobs() {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetJobs")) {
+        var jobDao = pm.JobDao;
+        var jobPermissionDao = pm.JobPermissionDao;
+        var taskDao = pm.TaskDao;
+        var currentUserId = UserManager.CurrentUserId;
+        return pm.UseTransaction(() => {
+          var jobs = jobDao.GetAll()
+            .Where(x => x.OwnerUserId == currentUserId
+                     || x.JobPermissions.Count(y => y.Permission != DA.Permission.NotAllowed
+                                                 && y.GrantedUserId == currentUserId) > 0)
+            .Select(x => x.ToDto())
+            .ToList();
+          var statistics = taskDao.GetAll()
+              .GroupBy(x => x.JobId)
+              .Select(x => new {
+                x.Key,
+                TotalCount = x.Count(),
+                CalculatingCount = x.Count(y => y.State == DA.TaskState.Calculating),
+                FinishedCount = x.Count(y => CompletedStates.Contains(y.State))
+              })
+              .ToList();
+          foreach (var job in jobs) {
+            // TODO: improve performance of authorization (batch authorization)
+            AuthorizationManager.AuthorizeForJob(job.Id, DT.Permission.Read);
+            var statistic = statistics.FirstOrDefault(x => x.Key == job.Id);
+            if (statistic != null) {
+              job.JobCount = statistic.TotalCount;
+              job.CalculatingCount = statistic.CalculatingCount;
+              job.FinishedCount = statistic.FinishedCount;
+            }
+            job.OwnerUsername = UserManager.GetUserById(job.OwnerUserId).UserName;
+            if (currentUserId == job.OwnerUserId) {
+              job.Permission = Permission.Full;
+            } else {
+              var jobPermission = jobPermissionDao.GetByJobAndUserId(job.Id, currentUserId);
+              job.Permission = jobPermission == null ? Permission.NotAllowed : jobPermission.Permission.ToDto();
+            }
+          }
+          return jobs;
+        });
+      }
     }
 
@@ -320,45 +404,172 @@
 
     public Guid AddJob(Job jobDto) {
-      throw new NotImplementedException();
-    }
-
-    public void UpdateJob(Job jobDto) {
-      throw new NotImplementedException();
-    }
-
-    public void DeleteJob(Guid JobId) {
-      throw new NotImplementedException();
-    }
-
-    public void GrantPermission(Guid jobId, Guid grantedUserId, Permission permission) {
-      throw new NotImplementedException();
-    }
-
-    public void RevokePermission(Guid hiveExperimentId, Guid grantedUserId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddJob")) {
+        var jobDao = pm.JobDao;
+        return pm.UseTransaction(() => {
+          jobDto.OwnerUserId = UserManager.CurrentUserId;
+          jobDto.DateCreated = DateTime.Now;
+          var job = jobDao.Save(jobDto.ToEntity());
+          pm.SubmitChanges();
+          return job.JobId;
+        });
+      }
+    }
+
+    public void UpdateJob(DT.Job jobDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(jobDto.Id, DT.Permission.Full);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateJob")) {
+        bool exists = true;
+        var jobDao = pm.JobDao;
+        pm.UseTransaction(() => {
+          var job = jobDao.GetById(jobDto.Id);
+          if (job == null) {
+            exists = false;
+            job = new DA.Job();
+          }
+          jobDto.CopyToEntity(job);
+          if (!exists) {
+            jobDao.Save(job);
+          }
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public void DeleteJob(Guid jobId) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(jobId, DT.Permission.Full);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("DeleteJob")) {
+        var jobDao = pm.JobDao;
+        pm.UseTransaction(() => {
+          jobDao.Delete(jobId);
+          pm.SubmitChanges();
+        });
+      }
+    }
+    #endregion
+
+    #region JobPermission Methods
+    public void GrantPermission(Guid jobId, Guid grantedUserId, DT.Permission permission) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GrantPermission")) {
+        var jobPermissionDao = pm.JobPermissionDao;
+        var currentUserId = UserManager.CurrentUserId;
+        pm.UseTransaction(() => {
+          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, permission.ToEntity());
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public void RevokePermission(Guid jobId, Guid grantedUserId) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("RevokePermission")) {
+        var jobPermissionDao = pm.JobPermissionDao;
+        var currentUserId = UserManager.CurrentUserId;
+        pm.UseTransaction(() => {
+          jobPermissionDao.SetJobPermission(jobId, currentUserId, grantedUserId, DA.Permission.NotAllowed);
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public IEnumerable<JobPermission> GetJobPermissions(Guid jobId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForJob(jobId, Permission.Full);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetJobPermissions")) {
+        var jobPermissionDao = pm.JobPermissionDao;
+        return pm.UseTransaction(() => jobPermissionDao.GetByJobId(jobId)
+          .Select(x => x.ToDto())
+          .ToList()
+        );
+      }
     }
 
     public bool IsAllowedPrivileged() {
-      throw new NotImplementedException();
-    }
-
-    public void Hello(Slave slave) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      return RoleVerifier.IsInRole(HiveRoles.IsAllowedPrivileged);
+    }
+    #endregion
+
+    #region Login Methods
+    public void Hello(DT.Slave slaveInfo) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
+      if (UserManager.CurrentUser.UserName != "hiveslave") {
+        slaveInfo.OwnerUserId = UserManager.CurrentUserId;
+      }
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("Hello")) {
+        var slaveDao = pm.SlaveDao;
+        pm.UseTransaction(() => {
+          var slave = slaveDao.GetById(slaveInfo.Id);
+          if (slave == null) {
+            slaveDao.Save(slaveInfo.ToEntity());
+          } else {
+            bool oldIsAllowedToCalculate = slave.IsAllowedToCalculate;
+            Guid? oldParentResourceId = slave.ParentResourceId;
+            slaveInfo.CopyToEntity(slave);
+            slave.IsAllowedToCalculate = oldIsAllowedToCalculate;
+            slave.ParentResourceId = oldParentResourceId;
+            slave.LastHeartbeat = DateTime.Now;
+            slave.SlaveState = DA.SlaveState.Idle;
+          }
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public void GoodBye(Guid slaveId) {
-      throw new NotImplementedException();
-    }
-
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GoodBye")) {
+        var slaveDao = pm.SlaveDao;
+        pm.UseTransaction(() => {
+          var slave = slaveDao.GetById(slaveId);
+          if (slave != null) {
+            slave.SlaveState = DA.SlaveState.Offline;
+            pm.SubmitChanges();
+          }
+        });
+      }
+    }
+    #endregion
+
+    #region Heartbeat Methods
     public List<MessageContainer> Heartbeat(Heartbeat heartbeat) {
-      throw new NotImplementedException();
-    }
-
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
+      List<MessageContainer> result = new List<MessageContainer>();
+      try {
+        using (new PerformanceLogger("ProcessHeartbeat")) {
+          result = HeartbeatManager.ProcessHeartbeat(heartbeat);
+        }
+      }
+      catch (Exception ex) {
+        DA.LogFactory.GetLogger(this.GetType().Namespace).Log(string.Format("Exception processing Heartbeat: {0}", ex));
+      }
+      if (HeuristicLab.Services.Hive.Properties.Settings.Default.TriggerEventManagerInHeartbeat) {
+        TriggerEventManager(false);
+      }
+      return result;
+    }
+    #endregion
+
+    #region Plugin Methods
     public Plugin GetPlugin(Guid pluginId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetPlugin")) {
+        var pluginDao = pm.PluginDao;
+        return pm.UseTransaction(() => pluginDao.GetById(pluginId).ToDto());
+      }
     }
 
@@ -369,13 +580,51 @@
 
     public Guid AddPlugin(Plugin plugin, List<PluginData> pluginData) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddPlugin")) {
+        var pluginDao = pm.PluginDao;
+        plugin.UserId = UserManager.CurrentUserId;
+        plugin.DateCreated = DateTime.Now;
+        return pm.UseTransaction(() => {
+          var pluginEntity = pluginDao.GetByHash(plugin.Hash).SingleOrDefault();
+          if (pluginEntity != null) {
+            throw new FaultException<PluginAlreadyExistsFault>(new PluginAlreadyExistsFault(pluginEntity.PluginId));
+          }
+          pluginEntity = plugin.ToEntity();
+          foreach (var data in pluginData) {
+            data.PluginId = default(Guid);
+            pluginEntity.PluginData.Add(data.ToEntity());
+          }
+          pluginDao.Save(pluginEntity);
+          pm.SubmitChanges();
+          return pluginEntity.PluginId;
+        });
+      }
     }
 
     public IEnumerable<Plugin> GetPlugins() {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetPlugins")) {
+        var pluginDao = pm.PluginDao;
+        return pm.UseTransaction(() => pluginDao.GetAll()
+          .Where(x => x.Hash != null)
+          .Select(x => x.ToDto())
+          .ToList()
+        );
+      }
     }
 
     public IEnumerable<PluginData> GetPluginDatas(List<Guid> pluginIds) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client, HiveRoles.Slave);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetPluginDatas")) {
+        var pluginDataDao = pm.PluginDataDao;
+        return pm.UseTransaction(() => pluginDataDao.GetAll()
+            .Where(x => pluginIds.Contains(x.PluginId))
+            .Select(x => x.ToDto())
+            .ToList()
+        );
+      }
     }
 
@@ -384,32 +633,96 @@
       throw new NotImplementedException();
     }
-
+    #endregion
+
+    #region ResourcePermission Methods
     public void GrantResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GrantResourcePermissions")) {
+        pm.UseTransaction(() => {
+          var resource = AuthorizeForResource(pm, resourceId);
+          var resourcePermissions = resource.ResourcePermissions.ToList();
+          foreach (var id in grantedUserIds) {
+            if (resourcePermissions.All(x => x.GrantedUserId != id)) {
+              resource.ResourcePermissions.Add(new DA.ResourcePermission {
+                GrantedUserId = id,
+                GrantedByUserId = UserManager.CurrentUserId
+              });
+            }
+          }
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public void RevokeResourcePermissions(Guid resourceId, Guid[] grantedUserIds) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("RevokeResourcePermissions")) {
+        var resourcePermissionDao = pm.ResourcePermissionDao;
+        pm.UseTransaction(() => {
+          AuthorizeForResource(pm, resourceId);
+          resourcePermissionDao.DeleteByResourceAndGrantedUserId(resourceId, grantedUserIds);
+        });
+      }
     }
 
     public IEnumerable<ResourcePermission> GetResourcePermissions(Guid resourceId) {
-      throw new NotImplementedException();
-    }
-
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetResourcePermissions")) {
+        var resourcePermissionDao = pm.ResourcePermissionDao;
+        return pm.UseTransaction(() => resourcePermissionDao.GetByResourceId(resourceId)
+          .Select(x => x.ToDto())
+          .ToList()
+        );
+      }
+    }
+    #endregion
+
+    #region Resource Methods
     public IEnumerable<Resource> GetChildResources(Guid resourceId) {
       // unused
       throw new NotImplementedException();
     }
-
-    public Guid AddSlave(Slave slave) {
-      throw new NotImplementedException();
-    }
-
-    public Guid AddSlaveGroup(SlaveGroup slaveGroup) {
-      throw new NotImplementedException();
+    #endregion
+
+    #region Slave Methods
+    public Guid AddSlave(DT.Slave slaveDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddSlave")) {
+        var slaveDao = pm.SlaveDao;
+        return pm.UseTransaction(() => {
+          var slave = slaveDao.Save(slaveDto.ToEntity());
+          pm.SubmitChanges();
+          return slave.ResourceId;
+        });
+      }
+    }
+
+    public Guid AddSlaveGroup(DT.SlaveGroup slaveGroupDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddSlaveGroup")) {
+        var slaveGroupDao = pm.SlaveGroupDao;
+        return pm.UseTransaction(() => {
+          if (slaveGroupDto.Id == Guid.Empty) {
+            slaveGroupDto.Id = Guid.NewGuid();
+          }
+          var slaveGroup = slaveGroupDao.Save(slaveGroupDto.ToEntity());
+          pm.SubmitChanges();
+          return slaveGroup.ResourceId;
+        });
+      }
     }
 
     public Slave GetSlave(Guid slaveId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetSlave")) {
+        var slaveDao = pm.SlaveDao;
+        return pm.UseTransaction(() => slaveDao.GetById(slaveId).ToDto());
+      }
     }
 
@@ -420,37 +733,147 @@
 
     public IEnumerable<Slave> GetSlaves() {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetSlaves")) {
+        var slaveDao = pm.SlaveDao;
+        var resourcePermissionDao = pm.ResourcePermissionDao;
+        var currentUserId = UserManager.CurrentUserId;
+        return pm.UseTransaction(() => {
+          var resourcePermissions = resourcePermissionDao.GetAll();
+          return slaveDao.GetAll()
+            .Where(x => isAdministrator
+              || x.OwnerUserId == null
+              || x.OwnerUserId == currentUserId
+              || UserManager.VerifyUser(currentUserId, resourcePermissions
+                  .Where(y => y.ResourceId == x.ResourceId)
+                  .Select(z => z.GrantedUserId)
+                  .ToList())
+              )
+            .Select(x => x.ToDto())
+            .ToList();
+        });
+      }
     }
 
     public IEnumerable<SlaveGroup> GetSlaveGroups() {
-      throw new NotImplementedException();
-    }
-
-    public void UpdateSlave(Slave slave) {
-      throw new NotImplementedException();
-    }
-
-    public void UpdateSlaveGroup(SlaveGroup slaveGroup) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      bool isAdministrator = RoleVerifier.IsInRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetSlaveGroups")) {
+        var slaveGroupDao = pm.SlaveGroupDao;
+        var resourcePermissionDao = pm.ResourcePermissionDao;
+        var currentUserId = UserManager.CurrentUserId;
+        return pm.UseTransaction(() => {
+          var resourcePermissions = resourcePermissionDao.GetAll();
+          return slaveGroupDao.GetAll()
+            .Where(x => isAdministrator
+              || x.OwnerUserId == null
+              || x.OwnerUserId == currentUserId
+              || UserManager.VerifyUser(currentUserId, resourcePermissions
+                  .Where(y => y.ResourceId == x.ResourceId)
+                  .Select(z => z.GrantedUserId)
+                  .ToList())
+              )
+            .Select(x => x.ToDto())
+            .ToList();
+        });
+      }
+    }
+
+    public void UpdateSlave(DT.Slave slaveDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateSlave")) {
+        var slaveDao = pm.SlaveDao;
+        pm.UseTransaction(() => {
+          var slave = slaveDao.GetById(slaveDto.Id);
+          if (slave != null) {
+            slaveDto.CopyToEntity(slave);
+          } else {
+            slaveDao.Save(slaveDto.ToEntity());
+          }
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public void UpdateSlaveGroup(DT.SlaveGroup slaveGroupDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateSlaveGroup")) {
+        var slaveGroupDao = pm.SlaveGroupDao;
+        pm.UseTransaction(() => {
+          var slaveGroup = slaveGroupDao.GetById(slaveGroupDto.Id);
+          if (slaveGroup != null) {
+            slaveGroupDto.CopyToEntity(slaveGroup);
+          } else {
+            slaveGroupDao.Save(slaveGroupDto.ToEntity());
+          }
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public void DeleteSlave(Guid slaveId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForResourceAdministration(slaveId);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("DeleteSlave")) {
+        var slaveDao = pm.SlaveDao;
+        pm.UseTransaction(() => {
+          slaveDao.Delete(slaveId);
+        });
+      }
     }
 
     public void DeleteSlaveGroup(Guid slaveGroupId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForResourceAdministration(slaveGroupId);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("DeleteSlaveGroup")) {
+        var slaveGroupDao = pm.SlaveGroupDao;
+        pm.UseTransaction(() => {
+          slaveGroupDao.Delete(slaveGroupId);
+        });
+      }
     }
 
     public void AddResourceToGroup(Guid slaveGroupId, Guid resourceId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddResourceToGroup")) {
+        var resourceDao = pm.ResourceDao;
+        pm.UseTransaction(() => {
+          var resource = resourceDao.GetById(resourceId);
+          resource.ParentResourceId = slaveGroupId;
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public void RemoveResourceFromGroup(Guid slaveGroupId, Guid resourceId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("RemoveResourceFromGroup")) {
+        var resourceDao = pm.ResourceDao;
+        pm.UseTransaction(() => {
+          var resource = resourceDao.GetById(resourceId);
+          resource.ParentResourceId = null;
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public Guid GetResourceId(string resourceName) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetResourceId")) {
+        var resourceDao = pm.ResourceDao;
+        return pm.UseTransaction(() => {
+          var resource = resourceDao.GetByName(resourceName);
+          return resource != null ? resource.ResourceId : Guid.Empty;
+        });
+      }
     }
 
@@ -461,40 +884,128 @@
 
     public void TriggerEventManager(bool force) {
-      // private method...
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Slave);
+      // use a serializable transaction here to ensure not two threads execute this simultaniously (mutex-lock would not work since IIS may use multiple AppDomains)
+      bool cleanup;
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("TriggerEventManager")) {
+        cleanup = false;
+        var lifecycleDao = pm.LifecycleDao;
+        pm.UseTransaction(() => {
+          var lastLifecycle = lifecycleDao.GetLastLifecycle();
+          DateTime lastCleanup = lastLifecycle != null ? lastLifecycle.LastCleanup : DateTime.MinValue;
+          if (force || DateTime.Now - lastCleanup > HeuristicLab.Services.Hive.Properties.Settings.Default.CleanupInterval) {
+            lifecycleDao.UpdateLifecycle();
+            cleanup = true;
+            pm.SubmitChanges();
+          }
+        }, true);
+      }
+      if (cleanup) {
+        EventManager.Cleanup();
+      }
     }
 
     public int GetNewHeartbeatInterval(Guid slaveId) {
-      throw new NotImplementedException();
-    }
-
-    public Guid AddDowntime(Downtime downtime) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Slave);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetNewHeartbeatInterval")) {
+        var slaveDao = pm.SlaveDao;
+        return pm.UseTransaction(() => {
+          var slave = slaveDao.GetById(slaveId);
+          if (slave != null) {
+            return slave.HbInterval;
+          }
+          return -1;
+        });
+      }
+    }
+    #endregion
+
+    #region Downtime Methods
+    public Guid AddDowntime(DT.Downtime downtimeDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("AddDowntime")) {
+        var downtimeDao = pm.DowntimeDao;
+        return pm.UseTransaction(() => {
+          var downtime = downtimeDao.Save(downtimeDto.ToEntity());
+          pm.SubmitChanges();
+          return downtime.ResourceId;
+        });
+      }
     }
 
     public void DeleteDowntime(Guid downtimeId) {
-      throw new NotImplementedException();
-    }
-
-    public void UpdateDowntime(Downtime downtime) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("DeleteDowntime")) {
+        var downtimeDao = pm.DowntimeDao;
+        pm.UseTransaction(() => {
+          downtimeDao.Delete(downtimeId);
+          pm.SubmitChanges();
+        });
+      }
+    }
+
+    public void UpdateDowntime(DT.Downtime downtimeDto) {
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      AuthorizationManager.AuthorizeForResourceAdministration(downtimeDto.ResourceId);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("UpdateDowntime")) {
+        var downtimeDao = pm.DowntimeDao;
+        pm.UseTransaction(() => {
+          var downtime = downtimeDao.GetById(downtimeDto.Id);
+          if (downtime != null) {
+            downtimeDto.CopyToEntity(downtime);
+          } else {
+            downtimeDao.Save(downtimeDto.ToEntity());
+          }
+          pm.SubmitChanges();
+        });
+      }
     }
 
     public IEnumerable<Downtime> GetDowntimesForResource(Guid resourceId) {
-      throw new NotImplementedException();
-    }
-
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetDowntimesForResource")) {
+        var downtimeDao = pm.DowntimeDao;
+        return pm.UseTransaction(() => downtimeDao.GetByResourceId(resourceId)
+          .Select(x => x.ToDto())
+          .ToList()
+        );
+      }
+    }
+    #endregion
+
+    #region User Methods
     public string GetUsernameByUserId(Guid userId) {
-      throw new NotImplementedException();
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      var user = UserManager.GetUserById(userId);
+      return user != null ? user.UserName : null;
     }
 
     public Guid GetUserIdByUsername(string username) {
-      throw new NotImplementedException();
-    }
-
+      RoleVerifier.AuthenticateForAnyRole(HiveRoles.Administrator, HiveRoles.Client);
+      var user = ServiceLocator.Instance.UserManager.GetUserByName(username);
+      return user != null ? (Guid?)user.ProviderUserKey ?? Guid.Empty : Guid.Empty;
+    }
+    #endregion
+
+    #region UserPriorities Methods
     public IEnumerable<UserPriority> GetUserPriorities() {
-      throw new NotImplementedException();
-    }
-
+      using (var pm = PersistenceManager)
+      using (new PerformanceLogger("GetUserPriorities")) {
+        var userPriorityDao = pm.UserPriorityDao;
+        return pm.UseTransaction(() => userPriorityDao.GetAll()
+          .Select(x => x.ToDto())
+          .ToList()
+        );
+      }
+    }
+    #endregion
+
+    #region Statistics Methods
     public IEnumerable<Statistics> GetStatistics() {
       // unused
@@ -506,4 +1017,46 @@
       throw new NotImplementedException();
     }
+    #endregion
+
+    #region Private Helper Methods
+    private void UpdateTaskState(IPersistenceManager pm, DA.Task task, DT.TaskState taskState, Guid? slaveId, Guid? userId, string exception) {
+      var stateLogDao = pm.StateLogDao;
+      var taskStateEntity = taskState.ToEntity();
+      if (task.Command == DA.Command.Pause && task.State == DA.TaskState.Paused
+          || task.Command == DA.Command.Abort && task.State == DA.TaskState.Aborted
+          || task.Command == DA.Command.Stop && task.State == DA.TaskState.Aborted) {
+        task.Command = null;
+      } else if (taskStateEntity == DA.TaskState.Paused && task.Command != null) {
+        taskStateEntity = DA.TaskState.Waiting;
+      }
+      stateLogDao.Save(new DA.StateLog {
+        State = taskStateEntity,
+        DateTime = DateTime.Now,
+        TaskId = task.TaskId,
+        UserId = userId,
+        SlaveId = slaveId,
+        Exception = exception
+      });
+      task.State = taskStateEntity;
+    }
+
+    private DA.Resource AuthorizeForResource(IPersistenceManager pm, Guid resourceId) {
+      var resourceDao = pm.ResourceDao;
+      var resource = resourceDao.GetById(resourceId);
+      if (resource == null) throw new SecurityException("Not authorized");
+      if (resource.OwnerUserId != UserManager.CurrentUserId
+          && !RoleVerifier.IsInRole(HiveRoles.Administrator)) {
+        throw new SecurityException("Not authorized");
+      }
+      return resource;
+    }
+
+    [MethodImpl(MethodImplOptions.NoInlining)]
+    public string GetCurrentMethod() {
+      StackTrace st = new StackTrace();
+      StackFrame sf = st.GetFrame(1);
+      return sf.GetMethod().Name;
+    }
+    #endregion
   }
 }
