Index: /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/AuthorizationManager.cs
===================================================================
--- /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/AuthorizationManager.cs	(revision 5028)
+++ /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/AuthorizationManager.cs	(revision 5028)
@@ -0,0 +1,53 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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.Linq;
+using System.Security;
+using System.Web.Security;
+
+namespace HeuristicLab.Services.Hive {
+  public class AuthorizationManager : IAuthorizationManager {
+    private MembershipUser Identity {
+      get { return Membership.GetUser(); }
+    }
+
+    public Guid UserId {
+      get { return (Guid)Identity.ProviderUserKey; }
+    }
+
+    public void AuthorizeJobs(params Guid[] jobIds) {
+      if (!IsAuthorizedForJobs(jobIds)) {
+        throw new SecurityException("User '" + Identity.UserName + "' is not authorized to access job (Id: " + string.Join(", ", jobIds.Select(x => x.ToString()).ToArray()) + ")");
+      }
+    }
+    
+    private bool IsAuthorizedForJobs(params Guid[] jobIds) {
+      return ServiceLocator.Instance.HiveDao.IsUserAuthorizedForJobs(UserId, jobIds);
+    }
+
+    public void Authorize(Guid userId) {
+      if (userId != this.UserId) {
+        throw new SecurityException("User '" + Identity.UserName + "' is not authorized to access object");
+      }
+    }
+  }
+}
Index: /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj
===================================================================
--- /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj	(revision 5028)
+++ /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HeuristicLab.Services.Hive-3.3.csproj	(revision 5028)
@@ -0,0 +1,132 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{CF9DA321-AC1B-4FD3-9EC3-67BC6B861BDE}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>HeuristicLab.Services.Hive</RootNamespace>
+    <AssemblyName>HeuristicLab.Services.Hive-3.3</AssemblyName>
+    <ProjectTypeGuids>{3D9AD99F-2412-4246-B90B-4EAA41C64699};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup>
+    <SignAssembly>true</SignAssembly>
+  </PropertyGroup>
+  <PropertyGroup>
+    <AssemblyOriginatorKeyFile>HeuristicLab.snk</AssemblyOriginatorKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="HeuristicLab.Common-3.3">
+      <HintPath>..\..\..\..\..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Common-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Common.Resources-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Common.Resources-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Core-3.3">
+      <HintPath>..\..\..\..\..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Core-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Persistence-3.3">
+      <HintPath>..\..\..\..\..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Persistence-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.PluginInfrastructure-3.3">
+      <HintPath>..\..\..\..\..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.PluginInfrastructure-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="HeuristicLab.Tracing-3.3, Version=3.3.0.0, Culture=neutral, PublicKeyToken=ba48961d6f65dcec, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\..\..\..\..\..\Program Files\HeuristicLab 3.3\HeuristicLab.Tracing-3.3.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Data.Linq" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.ServiceModel" />
+    <Reference Include="System.Transactions" />
+    <Reference Include="System.Web" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Standalone\HeuristicLabServicesHiveApplication.cs" />
+    <Compile Include="Standalone\MainForm.cs">
+      <SubType>Form</SubType>
+    </Compile>
+    <Compile Include="Standalone\MainForm.Designer.cs">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </Compile>
+    <Compile Include="AuthorizationManager.cs" />
+    <Compile Include="HeuristicLabServicesHivePlugin.cs" />
+    <Compile Include="Hive.cs" />
+    <Compile Include="HiveRoles.cs" />
+    <Compile Include="HiveService.cs" />
+    <Compile Include="Interfaces\IAuthorizationManager.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="ServiceLocator.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\HeuristicLab.Services.Hive.Common\3.3\HeuristicLab.Services.Hive.Common-3.3.csproj">
+      <Project>{14424A16-48D4-445E-80BF-DDF617548BBB}</Project>
+      <Name>HeuristicLab.Services.Hive.Common-3.3</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\HeuristicLab.Services.Hive.DataAccess\3.3\HeuristicLab.Services.Hive.DataAccess-3.3.csproj">
+      <Project>{EC2C8109-6E1E-4C88-9A2B-908CFF2EF4AC}</Project>
+      <Name>HeuristicLab.Services.Hive.DataAccess-3.3</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="HeuristicLab.snk" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Standalone\MainForm.resx">
+      <DependentUpon>MainForm.cs</DependentUpon>
+    </EmbeddedResource>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <ProjectExtensions>
+    <VisualStudio>
+      <FlavorProperties GUID="{3D9AD99F-2412-4246-B90B-4EAA41C64699}">
+        <WcfProjectProperties>
+          <AutoStart>False</AutoStart>
+        </WcfProjectProperties>
+      </FlavorProperties>
+    </VisualStudio>
+  </ProjectExtensions>
+  <PropertyGroup>
+    <PostBuildEvent>set ProjectName=$(ProjectName)
+set TargetPath=$(TargetPath)
+call $(SolutionDir)/CopyAssembly.cmd</PostBuildEvent>
+  </PropertyGroup>
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HeuristicLabServicesHivePlugin.cs
===================================================================
--- /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HeuristicLabServicesHivePlugin.cs	(revision 5028)
+++ /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HeuristicLabServicesHivePlugin.cs	(revision 5028)
@@ -0,0 +1,15 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.PluginInfrastructure;
+
+namespace HeuristicLab.Services.Hive.Server {
+  [Plugin("HeuristicLab.Services.Hive", "3.3")]
+  [PluginFile("HeuristicLab.Services.Hive-3.3.dll", PluginFileType.Assembly)]
+  [PluginDependency("HeuristicLab.Common", "3.3")]
+  [PluginDependency("HeuristicLab.Core", "3.3")]
+  [PluginDependency("HeuristicLab.Persistence", "3.3")]
+  public class HeuristicLabServicesHivePlugin : PluginBase {
+  }
+}
Index: /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/Hive.cs
===================================================================
--- /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/Hive.cs	(revision 5028)
+++ /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/Hive.cs	(revision 5028)
@@ -0,0 +1,207 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Transactions;
+using HeuristicLab.Services.Hive.Common;
+using HeuristicLab.Services.Hive.Common.DataTransfer;
+using HeuristicLab.Tracing;
+
+namespace HeuristicLab.Services.Hive {
+  /// <summary>
+  /// This class holds the state of all recent heartbeats and decides to reschedule jobs and set slaves offline
+  /// </summary>
+  public class Hive {
+    private DataAccess.IHiveDao dao {
+      get { return ServiceLocator.Instance.HiveDao; }
+    }
+    private HeuristicLab.Services.Hive.DataAccess.TransactionManager trans {
+      get { return ServiceLocator.Instance.TransactionManager; }
+    }
+    private IAuthorizationManager auth {
+      get { return ServiceLocator.Instance.AuthorizationManager; }
+    }
+
+    private static object locker = new object();
+    private Dictionary<Guid, DateTime> heartbeats = new Dictionary<Guid, DateTime>();
+
+    // Windows-Forms timer is single threaded, so callbacks will be synchron
+    System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
+
+    /// <summary>
+    /// Contains a list job JobIds which have been sent to a slave, but the slave has not yet sent 
+    /// a jobProgress of the job with a heartbeat, because he has not finished downloading/deserializing it.
+    /// The number value indicates a TimeToLive count that is decremented with each server-heartbeat.
+    /// When the number reaches zero, the jobs is assumed to be lost and is set Offline again.
+    /// </summary>
+    private Dictionary<Guid, int> newlyAssignedJobs = new Dictionary<Guid, int>();
+
+    /// <summary>
+    /// Counts how many jobs are currently beeing transferred.
+    /// </summary>
+    private int jobsCurrentlyTransfering = 0;
+    public int JobsCurrentlyTransferring {
+      get { return jobsCurrentlyTransfering; }
+      set {
+        if (jobsCurrentlyTransfering != value) {
+          jobsCurrentlyTransfering = value;
+          Logger.Info("JobsCurrentlyTransfering: " + jobsCurrentlyTransfering);
+        }
+      }
+    }
+
+    public Hive() {
+      this.timer.Interval = (int)new TimeSpan(0, 0, 10).TotalMilliseconds;
+      this.timer.Tick += new EventHandler(timer_Tick);
+      this.timer.Start();
+      AddAllSlavesToHeartbeats();
+    }
+
+    public void Shutdown() {
+      timer.Stop();
+    }
+
+    /// <summary>
+    // add all slaves to hearbeats-collection and give them some time to say hello (HEARTBEAT_TIMEOUT)
+    // otherwise alls the slaves jobs would be aborted immediately, which is not desirable if the server has just been restarted
+    /// </summary>
+    private void AddAllSlavesToHeartbeats() {
+      lock (locker) {
+        using (trans.OpenTransaction()) {
+          Guid[] slaveIds = dao.GetSlaves(x => true).Select(s => s.Id).ToArray();
+          foreach (Guid slaveId in slaveIds) {
+            if (!heartbeats.ContainsKey(slaveId)) {
+              heartbeats.Add(slaveId, DateTime.Now);
+            }
+          }
+        }
+      }
+    }
+
+    /// <summary>
+    /// This method is supposed to check if slaves are online
+    /// if not -> set them offline and check if they where calculating a job
+    /// </summary>
+    void timer_Tick(object sender, EventArgs e) {
+      lock (locker) {
+        using (trans.OpenTransaction()) {
+          Guid[] slaveIds = dao.GetSlaves(x => true).Select(s => s.Id).ToArray();
+          foreach (Guid slaveId in slaveIds) {
+            if (SlaveTimedOut(slaveId)) {
+              var slave = dao.GetSlave(slaveId);
+              if (slave.SlaveState != SlaveState.Offline) {
+                AbortJobs(slaveId);
+                slave.SlaveState = SlaveState.Offline;
+                dao.UpdateSlave(slave);
+              }
+              heartbeats.Remove(slaveId);
+            }
+          }
+        }
+      }
+    }
+
+    private bool SlaveTimedOut(Guid slaveId) {
+      if (!heartbeats.ContainsKey(slaveId))
+        return true;
+
+      if ((DateTime.Now - heartbeats[slaveId]).TotalSeconds > ApplicationConstants.HeartbeatTimeout) {
+        return true;
+      }
+
+      return false;
+    }
+
+    private void AbortJobs(Guid slaveId) {
+      var jobs = dao.GetJobs(x => x.Slave.ResourceId == slaveId);
+      foreach (var j in jobs) {
+        j.JobState = JobState.Waiting;
+        dao.UpdateJob(j);
+      }
+    }
+
+    /// <summary>
+    /// This method will be called every time a slave sends a heartbeat (-> very often; concurrency is important!)
+    /// </summary>
+    /// <returns>a list of actions the slave should do</returns>
+    public List<MessageContainer> ProcessHeartbeat(Heartbeat heartbeat) {
+      List<MessageContainer> actions = new List<MessageContainer>();
+      Slave slave = dao.GetSlave(heartbeat.SlaveId);
+      if (slave == null) {
+        actions.Add(new MessageContainer(MessageContainer.MessageType.AddSlaveInfo));
+      } else {
+        heartbeats[heartbeat.SlaveId] = DateTime.Now;
+        actions.AddRange(UpdateJobs(heartbeat));
+
+        //check if new Cal must be loaded
+        if (slave.CalendarSyncState == CalendarState.Fetch || slave.CalendarSyncState == CalendarState.ForceFetch) {
+          actions.Add(new MessageContainer(MessageContainer.MessageType.UpdateCalendar));
+        }
+
+        if (this.IsAllowedToSendJobs() && slave.IsAllowedToCalculate && heartbeat.FreeCores > 0) {
+          var availableJobs = dao.GetWaitingJobs(slave);
+          if (availableJobs.Count() > 0) {
+            actions.Add(new MessageContainer(MessageContainer.MessageType.FetchJob));
+          }
+        }
+
+        if (slave.FreeCores != heartbeat.FreeCores ||
+            slave.FreeMemory != heartbeat.FreeMemory ||
+            slave.IsAllowedToCalculate != heartbeat.IsAllowedToCalculate ||
+            slave.SlaveState != (heartbeat.JobProgress.Count > 0 ? SlaveState.Calculating : SlaveState.Idle)) { // only update slave when something changed, to avoid unnecessary updates
+          slave.FreeCores = heartbeat.FreeCores;
+          slave.FreeMemory = heartbeat.FreeMemory;
+          slave.IsAllowedToCalculate = heartbeat.IsAllowedToCalculate;
+          slave.SlaveState = (heartbeat.JobProgress != null && heartbeat.JobProgress.Count > 0) ? SlaveState.Calculating : SlaveState.Idle;
+          dao.UpdateSlave(slave);
+        }
+      }
+      return actions;
+    }
+
+    /// <summary>
+    /// Update the progress of each job
+    /// Checks if all the jobs sent by heartbeat are supposed to be calculated by this slave
+    /// </summary>
+    private IEnumerable<MessageContainer> UpdateJobs(Heartbeat heartbeat) {
+      List<MessageContainer> actions = new List<MessageContainer>();
+
+      if (heartbeat.JobProgress == null)
+        return actions;
+
+      // process the jobProgresses
+      foreach (var jobProgress in heartbeat.JobProgress) {
+        Job curJob = dao.GetJob(jobProgress.Key);
+        if (curJob == null) {
+          // job does not exist in db
+          actions.Add(new MessageContainer(MessageContainer.MessageType.AbortJob, jobProgress.Key));
+          Logger.Error("Job does not exist in DB: " + jobProgress.Key);
+        } else {
+          if (curJob.SlaveId == Guid.Empty || curJob.SlaveId != heartbeat.SlaveId) {
+            // assigned slave does not match heartbeat
+            actions.Add(new MessageContainer(MessageContainer.MessageType.AbortJob, curJob.Id));
+            Logger.Error("The slave " + heartbeat.SlaveId + " is not supposed to calculate Job: " + curJob);
+          } else {
+            // save job execution time
+            curJob.ExecutionTime = jobProgress.Value;
+
+            if (curJob.JobState == JobState.Aborted) {
+              // a request to abort the job has been set
+              actions.Add(new MessageContainer(MessageContainer.MessageType.AbortJob, curJob.Id));
+            }
+            dao.UpdateJob(curJob);
+          }
+        }
+      }
+      return actions;
+    }
+
+    /// <summary>
+    /// Returns true if there are enough resources to send a job
+    /// There should not be too many jobs sent simultaniously
+    /// </summary>
+    private bool IsAllowedToSendJobs() {
+      return JobsCurrentlyTransferring < ApplicationConstants.MaxJobTransferCount;
+    }
+  }
+}
Index: /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HiveRoles.cs
===================================================================
--- /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HiveRoles.cs	(revision 5028)
+++ /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HiveRoles.cs	(revision 5028)
@@ -0,0 +1,29 @@
+﻿#region License Information
+/* HeuristicLab
+ * Copyright (C) 2002-2010 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
+
+
+namespace HeuristicLab.Services.Hive {
+  public static class HiveRoles {
+    public const string Administrator = "Hive Administrator";
+    public const string Slave = "Hive Slave";
+    public const string Client = "Hive Client";
+  }
+}
Index: /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HiveService.cs
===================================================================
--- /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 5028)
+++ /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/HiveService.cs	(revision 5028)
@@ -0,0 +1,317 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.ServiceModel;
+using HeuristicLab.Services.Hive.Common.ServiceContracts;
+using HeuristicLab.Services.Hive.Common.DataTransfer;
+using System.IO;
+using System.Security.Permissions;
+using System.Data.Linq;
+using HeuristicLab.Services.Hive.Common;
+
+namespace HeuristicLab.Services.Hive {
+
+  /// <summary>
+  /// Implementation of the Hive service (interface <see cref="IHiveService"/>).
+  /// </summary>
+  [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
+  public class HiveService : IHiveService {
+    private DataAccess.IHiveDao dao {
+      get { return ServiceLocator.Instance.HiveDao; }
+    }
+    private HeuristicLab.Services.Hive.DataAccess.TransactionManager trans {
+      get { return ServiceLocator.Instance.TransactionManager; }
+    }
+    private IAuthorizationManager auth {
+      get { return ServiceLocator.Instance.AuthorizationManager; }
+    }
+    private Hive hive {
+      get { return ServiceLocator.Instance.Hive; }
+    }
+
+    #region Job Methods
+    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Administrator)]
+    [PrincipalPermission(SecurityAction.Demand, Role = HiveRoles.Client)]
+    public Guid AddJob(Job job, JobData jobData) {
+      using (trans.OpenTransaction()) {
+        jobData.JobId = dao.AddJob(job);
+        dao.AddJobData(jobData);
+        return jobData.JobId;
+      }
+    }
+
+    public Guid AddChildJob(Guid parentJobId, Job job, JobData jobData) {
+      using (trans.OpenTransaction()) {
+        job.ParentJobId = parentJobId;
+        return AddJob(job, jobData);
+      }
+    }
+
+    public Job GetJob(Guid jobId) {
+      return dao.GetJob(jobId);
+    }
+
+    public IEnumerable<Job> GetJobs() {
+      return dao.GetJobs(x => true);
+    }
+
+    public IEnumerable<LightweightJob> GetLightweightJobs(IEnumerable<Guid> jobIds) {
+      return dao.GetJobs(x => jobIds.Contains(x.JobId)).Select(x => new LightweightJob(x)).ToArray();
+    }
+
+    public IEnumerable<LightweightJob> GetLightweightChildJobs(Guid? parentJobId, bool recursive, bool includeParent) {
+      return GetChildJobs(parentJobId, recursive, includeParent).Select(x => new LightweightJob(x)).ToArray();
+    }
+
+    // formerly GetLastSerializedResult
+    public JobData GetJobData(Guid jobId) {
+      return dao.GetJobData(jobId);
+    }
+
+    public Stream GetJobDataStreamed(Guid jobId) {
+      throw new NotImplementedException();
+    }
+
+    public void UpdateJob(Job jobDto, JobData jobDataDto) {
+      using (trans.OpenTransaction()) {
+        dao.UpdateJob(jobDto);
+        dao.UpdateJobData(jobDataDto);
+      }
+    }
+
+    public void UpdateJobDataStreamed(Stream stream) {
+      using (trans.OpenTransaction()) {
+        throw new NotImplementedException();
+      }
+    }
+
+    public void DeleteChildJobs(Guid jobId) {
+      using (trans.OpenTransaction()) {
+        var jobs = GetChildJobs(jobId, true, false);
+        foreach (var job in jobs) {
+          dao.DeleteJob(job.Id);
+          dao.DeleteJobData(job.Id);
+        };
+      }
+    }
+
+    public Job AquireJob(Guid slaveId) {
+      using (trans.OpenTransaction()) {
+        var slave = dao.GetSlave(slaveId);
+        var availableJobs = dao.GetWaitingJobs(slave);
+        var job = availableJobs.FirstOrDefault();
+
+        if (job != null) {
+          job.SlaveId = slaveId;
+          job.JobState = JobState.Calculating;
+        }
+        return job;
+      }
+    }
+    #endregion
+
+    #region Job Control Methods
+    public void AbortJob(Guid jobId) {
+      using (trans.OpenTransaction()) {
+        throw new NotImplementedException();
+      }
+    }
+    public Job PauseJob(Guid jobId) {
+      using (trans.OpenTransaction()) {
+        throw new NotImplementedException();
+      }
+    }
+    #endregion
+
+    #region HiveExperiment Methods
+
+    public HiveExperiment GetHiveExperiment(Guid id) {
+      return dao.GetHiveExperiments(x => x.UserId == auth.UserId && x.HiveExperimentId == id).FirstOrDefault();
+    }
+
+    public IEnumerable<HiveExperiment> GetHiveExperiments() {
+      return dao.GetHiveExperiments(x => x.UserId == auth.UserId);
+    }
+
+    public Guid AddHiveExperiment(HiveExperiment hiveExperimentDto) {
+      using (trans.OpenTransaction()) {
+        hiveExperimentDto.UserId = auth.UserId;
+        return dao.AddHiveExperiment(hiveExperimentDto);
+      }
+    }
+
+    public void UpdateHiveExperiment(HiveExperiment hiveExperimentDto) {
+      using (trans.OpenTransaction()) {
+        dao.UpdateHiveExperiment(hiveExperimentDto);
+      }
+    }
+
+    public void DeleteHiveExperiment(Guid hiveExperimentId) {
+      using (trans.OpenTransaction()) {
+        HiveExperiment he = dao.GetHiveExperiment(hiveExperimentId);
+        if (he.RootJobId.HasValue) {
+          var jobs = GetChildJobs(he.RootJobId.Value, true, true);
+          foreach (var j in jobs) {
+            dao.DeleteJobData(j.Id);
+            dao.DeleteJob(j.Id);
+          }
+        }
+        dao.DeleteHiveExperiment(hiveExperimentId);
+      }
+    }
+    #endregion
+
+    #region Project Methods
+    public Project GetAllProjects() {
+      throw new NotImplementedException();
+    }
+
+    public void CreateProject(Project project) {
+      throw new NotImplementedException();
+    }
+
+    public void ChangeProject(Project project) {
+      throw new NotImplementedException();
+    }
+
+    public void DeleteProject(Guid projectId) {
+      throw new NotImplementedException();
+    }
+
+    public IEnumerable<Job> GetJobsByProject(Guid projectId) {
+      throw new NotImplementedException();
+    }
+    #endregion
+
+    #region Login Methods
+    //public void Login() {
+    //  throw new NotImplementedException();
+    //}
+
+    //public void Login(Slave slave) {
+    //  throw new NotImplementedException();
+    //}
+
+    //public void Logout(Guid clientId) {
+    //  throw new NotImplementedException();
+    //}
+    #endregion
+
+    #region Heartbeat Methods
+    public List<MessageContainer> ProcessHeartbeat(Heartbeat heartbeat) {
+      using (trans.OpenTransaction()) {
+        return hive.ProcessHeartbeat(heartbeat);
+      }
+    }
+    #endregion
+
+    #region Plugin Methods
+    public IEnumerable<PluginData> GetPluginDatas(List<Guid> pluginIds) {
+      throw new NotImplementedException();
+    }
+    public Stream GetStreamedPluginDatas(List<Guid> pluginIds) {
+      throw new NotImplementedException();
+    }
+    public IEnumerable<Plugin> GetAvailablePlugins() {
+      return dao.GetPlugins(x => true);
+    }
+    public Guid AddPlugin(Plugin plugin, List<PluginData> pluginDatas) {
+      using (trans.OpenTransaction()) {
+        Guid pluginId = dao.AddPlugin(plugin);
+        foreach (PluginData pluginData in pluginDatas) {
+          pluginData.PluginId = pluginId;
+          dao.AddPluginData(pluginData);
+        }
+        return pluginId;
+      }
+    }
+    #endregion
+
+    #region Calendar Methods
+    public IEnumerable<Appointment> GetCalendar(Guid clientId) {
+      throw new NotImplementedException();
+    }
+
+    public void SetCalendarStatus(Guid clientId, CalendarState state) {
+      using (trans.OpenTransaction()) {
+        throw new NotImplementedException();
+      }
+    }
+
+    public IEnumerable<Appointment> GetUptimeCalendarForResource(Guid guid) {
+      throw new NotImplementedException();
+    }
+
+    public void SetUptimeCalendarForResource(Guid guid, IEnumerable<Appointment> appointments, bool isForced) {
+      throw new NotImplementedException();
+    }
+    #endregion
+
+    #region Slave Methods
+    public Guid AddSlave(Slave slave) {
+      using (trans.OpenTransaction()) {
+        return dao.AddSlave(slave);
+      }
+    }
+
+    public Guid AddSlaveGroup(SlaveGroup slaveGroup) {
+      using (trans.OpenTransaction()) {
+        return dao.AddSlaveGroup(slaveGroup);
+      }
+    }
+
+    public IEnumerable<Slave> GetSlaves() {
+      return dao.GetSlaves(x => true);
+    }
+
+    public IEnumerable<SlaveGroup> GetSlaveGroups() {
+      return dao.GetSlaveGroups(x => true);
+    }
+
+    public void DeleteSlaveGroup(Guid slaveGroupId) {
+      using (trans.OpenTransaction()) {
+        dao.DeleteSlaveGroup(slaveGroupId);
+      }
+    }
+
+    public void AddResourceToGroup(Guid slaveGroupId, Resource resource) {
+      using (trans.OpenTransaction()) {
+        throw new NotImplementedException();
+      }
+    }
+
+    public void RemoveResourceFromGroup(Guid clientGroupId, Guid resourceId) {
+      using (trans.OpenTransaction()) {
+        throw new NotImplementedException();
+      }
+    }
+
+    public void UpdateSlave(Slave slave) {
+      using (trans.OpenTransaction()) {
+        dao.UpdateSlave(slave);
+      }
+    }
+    #endregion
+
+    #region Helper Methods
+    private IEnumerable<Job> GetChildJobs(Guid? parentJobId, bool recursive, bool includeParent) {
+      var jobs = new List<Job>(dao.GetJobs(x => parentJobId == null ? !x.ParentJobId.HasValue : x.ParentJobId.Value == parentJobId));
+
+      if (includeParent) {
+        jobs.Add(GetJob(parentJobId.Value));
+      }
+
+      if (recursive) {
+        var childs = new List<Job>();
+        foreach (var job in jobs) {
+          childs.AddRange(GetChildJobs(job.Id, recursive, false));
+        }
+        jobs.AddRange(childs);
+      }
+      return jobs;
+    }
+
+    #endregion
+  }
+}
Index: /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs
===================================================================
--- /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs	(revision 5028)
+++ /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/ServiceLocator.cs	(revision 5028)
@@ -0,0 +1,50 @@
+﻿using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using HeuristicLab.Services.Hive.DataAccess;
+
+namespace HeuristicLab.Services.Hive {
+
+  public class ServiceLocator {
+    private static ServiceLocator instance;
+    public static ServiceLocator Instance {
+      get {
+        if (instance == null) instance = new ServiceLocator();
+        return instance;
+      }
+    }
+
+    private IHiveDao hiveDao;
+    public IHiveDao HiveDao {
+      get {
+        if (hiveDao == null) hiveDao = new HiveDao();
+        return hiveDao;
+      }
+    }
+    
+    private TransactionManager transactionManager;
+    public TransactionManager TransactionManager {
+      get {
+        if (transactionManager == null) transactionManager = new TransactionManager();
+        return transactionManager;
+      }
+    }
+
+    private IAuthorizationManager authorizationManager;
+    public IAuthorizationManager AuthorizationManager {
+      get {
+        if (authorizationManager == null) authorizationManager = new AuthorizationManager();
+        return authorizationManager;
+      }
+    }
+
+    private Hive hive;
+    public Hive Hive {
+      get {
+        if (hive == null) hive = new Hive();
+        return hive;
+      }
+    }
+  }
+}
Index: /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/app.config
===================================================================
--- /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/app.config	(revision 5028)
+++ /branches/HeuristicLab.Hive/sources/HeuristicLab.Hive.New/HeuristicLab.Services.Hive/3.3/app.config	(revision 5028)
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+  <system.diagnostics />
+  <connectionStrings>
+    <add name="HeuristicLab.Authentication" connectionString="data source=localhost;Integrated Security=SSPI;Initial Catalog=HeuristicLab.Authentication"/>
+  </connectionStrings>
+
+  <system.web>
+    <membership>
+      <providers>
+        <clear/>
+        <add name="AspNetSqlMembershipProvider" type="System.Web.Security.SqlMembershipProvider" connectionStringName="HeuristicLab.Authentication"
+             enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="false"
+             maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10"
+             applicationName="HeuristicLab.Authentication" />
+      </providers>
+    </membership>
+
+    <roleManager enabled="true">
+      <providers>
+        <clear/>
+        <add name="AspNetSqlRoleProvider" type="System.Web.Security.SqlRoleProvider" connectionStringName="HeuristicLab.Authentication" applicationName="HeuristicLab.Authentication" />
+      </providers>
+    </roleManager>
+  </system.web>
+
+  <system.serviceModel>
+    <diagnostics>
+      <messageLogging logEntireMessage="true" logMalformedMessages="true" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true" maxMessagesToLog="3000" />
+    </diagnostics>
+    <bindings>
+      <wsHttpBinding>
+        <binding name="WSHttpBinding_IHiveService" receiveTimeout="00:10:00"
+          sendTimeout="00:10:00" maxBufferPoolSize="104857600" maxReceivedMessageSize="104857600">
+          <readerQuotas maxStringContentLength="104857600" maxArrayLength="104857600" />
+          <security mode="Message">
+            <transport clientCredentialType="Certificate"/>
+            <message clientCredentialType="UserName" />
+          </security>
+        </binding>
+      </wsHttpBinding>
+    </bindings>
+    <behaviors>
+      <serviceBehaviors>
+        <behavior name="ServiceBehaviour_IHiveService">
+          <serviceMetadata httpGetEnabled="true" httpsGetEnabled="false" />
+          <serviceDebug httpHelpPageEnabled="true" includeExceptionDetailInFaults="true" />
+          <serviceAuthorization principalPermissionMode="UseAspNetRoles" roleProviderName="AspNetSqlRoleProvider" />
+          <serviceCredentials>
+            <serviceCertificate findValue="localhost" x509FindType="FindBySubjectName" />
+            <userNameAuthentication userNamePasswordValidationMode="MembershipProvider" membershipProviderName="AspNetSqlMembershipProvider" />
+          </serviceCredentials>
+          <serviceSecurityAudit auditLogLocation="Application" suppressAuditFailure="false" messageAuthenticationAuditLevel="SuccessOrFailure" />
+          <serviceThrottling maxConcurrentCalls="100" />
+        </behavior>
+      </serviceBehaviors>
+    </behaviors>
+    <services>
+      <service behaviorConfiguration="ServiceBehaviour_IHiveService"
+        name="HeuristicLab.Services.Hive.HiveService">
+        <endpoint address="mex" binding="mexHttpBinding" bindingConfiguration="" name="MexEndpoint" contract="IMetadataExchange" />
+        <endpoint binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IHiveService" name="WSHttpBinding_IHiveService" contract="HeuristicLab.Services.Hive.Common.ServiceContracts.IHiveService" />
+        <host>
+          <baseAddresses>
+            <add baseAddress="http://localhost:9000/Hive-3.3" />
+          </baseAddresses>
+        </host>
+      </service>
+    </services>
+
+  </system.serviceModel>
+
+</configuration>
