Index: /branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.Console/3.3/JobDataFetcher.cs
===================================================================
--- /branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.Console/3.3/JobDataFetcher.cs	(revision 4268)
+++ /branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Server.Console/3.3/JobDataFetcher.cs	(revision 4269)
@@ -79,10 +79,4 @@
 
     private void DoUpdateRun() {
-      // [chn] Exception occured here: PollStates enumeration changed!
-      // todo: make access to PollStates thread-safe!
-      // * added lock on locker -> didn't help
-      // * made public property PollStates an IEnumerable to be immutable -> didn't help
-      // * using for loop
-
       JobState[] pollStatesCopy = PollStates.ToArray();
       for (int i = 0; i < pollStatesCopy.Length; i++) {
Index: /branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Slave.Core/3.3/Core.cs
===================================================================
--- /branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Slave.Core/3.3/Core.cs	(revision 4268)
+++ /branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Slave.Core/3.3/Core.cs	(revision 4269)
@@ -60,5 +60,5 @@
 
     private WcfService wcfService;
-    private Heartbeat beat;
+    private HeartbeatManager beat;
 
     /// <summary>
@@ -90,5 +90,5 @@
 
       //Initialize the heartbeat
-      beat = new Heartbeat { Interval = new TimeSpan(0, 0, 10) };
+      beat = new HeartbeatManager { Interval = new TimeSpan(0, 0, 10) };
       beat.StartHeartbeat();
 
@@ -197,5 +197,4 @@
           kvp.Value.RequestSnapshot();
         }
-
       }
     }
@@ -293,14 +292,13 @@
         bool sandboxed = false;
         Logger.Debug("Fetching plugins for job " + e.Result.Obj.Id);
-
-        PluginCache.Instance.PreparePlugins(e.Result.Obj.PluginsNeeded);
-
-        PluginCache.Instance.CopyPluginsForJob(e.Result.Obj.PluginsNeeded, e.Result.Obj.Id);
-
-        //        foreach (CachedHivePluginInfoDto plugininfo in PluginCache.Instance.GetPlugins(e.Result.Job.PluginsNeeded))
-        //        files.AddRange(plugininfo.PluginFiles);
-        Logger.Debug("Plugins fetched for job " + e.Result.Obj.Id);
         try {
-          String pluginDir = Path.Combine(PluginCache.PLUGIN_REPO, e.Result.Obj.Id.ToString());
+
+          PluginCache.Instance.PreparePlugins(e.Result.Obj.PluginsNeeded);
+          PluginCache.Instance.CopyPluginsForJob(e.Result.Obj.PluginsNeeded, e.Result.Obj.Id);
+
+          //        foreach (CachedHivePluginInfoDto plugininfo in PluginCache.Instance.GetPlugins(e.Result.Job.PluginsNeeded))
+          //        files.AddRange(plugininfo.PluginFiles);
+          Logger.Debug("Plugins fetched for job " + e.Result.Obj.Id);
+          String pluginDir = Path.Combine(PluginCache.Instance.PluginRepositoryDir, e.Result.Obj.Id.ToString());
 
           AppDomain appDomain = HeuristicLab.PluginInfrastructure.Sandboxing.SandboxManager.CreateAndInitSandbox(pluginDir, null);
@@ -323,4 +321,5 @@
             }
           }
+          beat.InterruptHeartBeatThread();
         }
         catch (Exception exception) {
@@ -348,4 +347,5 @@
         SlaveStatusInfo.JobsProcessed++;
         Logger.Info("Increased ProcessedJobs to:" + SlaveStatusInfo.JobsProcessed);
+        beat.InterruptHeartBeatThread();
       } else {
         Logger.Error("Sending of job " + e.Result.JobId + " failed, job has been wasted. Message: " + e.Result.StatusMessage);
@@ -395,9 +395,9 @@
       //a result within the next few heartbeats      
       //if (!UptimeManager.Instance.CalendarAvailable || UptimeManager.Instance.IsOnline()) {
-        Logger.Info("CalendarAvailable is " + UptimeManager.Instance.CalendarAvailable + " and IsOnline is: " + UptimeManager.Instance.IsAllowedToCalculate());
-        Logger.Info("Setting client online");
-        wcfService.LoginSync(ConfigManager.Instance.GetClientInfo());
-        JobStorageManager.CheckAndSubmitJobsFromDisc();
-        CurrentlyFetching = false;
+      Logger.Info("CalendarAvailable is " + UptimeManager.Instance.CalendarAvailable + " and IsOnline is: " + UptimeManager.Instance.IsAllowedToCalculate());
+      Logger.Info("Setting client online");
+      wcfService.LoginSync(ConfigManager.Instance.GetClientInfo());
+      JobStorageManager.CheckAndSubmitJobsFromDisc();
+      CurrentlyFetching = false;
       //}
     }
@@ -417,4 +417,5 @@
         wcfService.SetCalendarStatus(ConfigManager.Instance.GetClientInfo().Id, CalendarState.NotAllowedToFetch);
       }
+      beat.InterruptHeartBeatThread();
     }
 
Index: anches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Slave.Core/3.3/Heartbeat.cs
===================================================================
--- /branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Slave.Core/3.3/Heartbeat.cs	(revision 4268)
+++ 	(revision )
@@ -1,130 +1,0 @@
-#region License Information
-/* HeuristicLab
- * Copyright (C) 2002-2008 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.Text;
-using System.Timers;
-using HeuristicLab.Hive.Slave.Common;
-using HeuristicLab.Hive.Slave.Communication;
-using System.Diagnostics;
-using HeuristicLab.Hive.Contracts.BusinessObjects;
-using HeuristicLab.Hive.Contracts;
-using HeuristicLab.Hive.Slave.Core.ConfigurationManager;
-using HeuristicLab.Hive.Slave.Communication.ServerService;
-using HeuristicLab.Tracing;
-using System.Threading;
-//using BO = HeuristicLab.Hive.Contracts.BusinessObjects;
-
-namespace HeuristicLab.Hive.Slave.Core {
-  /// <summary>
-  /// Heartbeat class. It sends every x ms a heartbeat to the server and receives a Message
-  /// </summary>
-  public class Heartbeat {
-
-    private bool offline;
-
-    public TimeSpan Interval { get; set; }
-
-    private Thread heartBeatThread;
-
-    private static object locker = new object();
-
-    public Heartbeat() {
-      Interval = new TimeSpan(0,0,10);
-    }
-
-    public Heartbeat(TimeSpan interval) {
-      Interval = interval;
-    }
-
-    private WcfService wcfService;
-
-    private bool abortThreadPending;
-
-    /// <summary>
-    /// Starts the Heartbeat signal.
-    /// </summary>
-    public void StartHeartbeat() {
-      wcfService = WcfService.Instance;
-      wcfService.ProcessHeartBeatCompleted += new EventHandler<ProcessHeartBeatCompletedEventArgs>(wcfService_ProcessHeartBeatCompleted);
-      abortThreadPending = false;
-      heartBeatThread = GetHeartBeatThread();
-      heartBeatThread.Start();
-    }
-
-    private Thread GetHeartBeatThread() {
-      return new Thread(() => {
-        while (!abortThreadPending) {
-          lock (locker) {
-            // check if cwfService is disconnected for any reason (should happen at first heartbeat)
-            // [chn] TODO: Client should always send heartbeats. when calendar disallows he should tell the server he does not want to compute anything
-            if (wcfService.ConnState != NetworkEnum.WcfConnState.Connected) {
-              wcfService.Connect(); // Login happens automatically upon successufl connection
-            }
-            if (!wcfService.LoggedIn) {
-              wcfService.LoginSync(ConfigManager.Instance.GetClientInfo()); // if login faild previously try again
-            }
-
-            if (wcfService.LoggedIn) {
-              SlaveDto info = ConfigManager.Instance.GetClientInfo();
-              
-              HeartBeatData heartBeatData = new HeartBeatData {
-                SlaveId = info.Id,
-                FreeCores = info.NrOfCores - ConfigManager.Instance.GetUsedCores(),
-                FreeMemory = GetFreeMemory(),
-                JobProgress = ConfigManager.Instance.GetProgressOfAllJobs(),
-                IsAllowedToCalculate = UptimeManager.Instance.IsAllowedToCalculate() && UptimeManager.Instance.CalendarAvailable
-              };
-
-              if (!heartBeatData.IsAllowedToCalculate) {
-                // stop all running jobs and send snapshots to server
-                MessageQueue.GetInstance().AddMessage(MessageContainer.MessageType.UptimeLimitDisconnect);
-              }
-
-              Logger.Debug("Sending Heartbeat: " + heartBeatData);
-              wcfService.ProcessHeartBeatAsync(heartBeatData);
-            }
-
-          } // lock
-          Thread.Sleep(Interval);
-        } // while
-        abortThreadPending = false;
-      });
-    }
-
-    private int GetFreeMemory() {
-      PerformanceCounter counter = new PerformanceCounter("Memory", "Available Bytes", true);
-      int mb = (int)(counter.NextValue() / 1024 / 1024);
-      return mb;
-    }
-
-    void wcfService_ProcessHeartBeatCompleted(object sender, ProcessHeartBeatCompletedEventArgs e) {
-      Logger.Debug("Heartbeat Response received");
-      e.Result.ActionRequest.ForEach(mc => MessageQueue.GetInstance().AddMessage(mc));
-    }
-
-    public void StopHeartBeat() {
-      abortThreadPending = true;
-    }
-  }
-}
Index: /branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Slave.Core/3.3/PluginCache.cs
===================================================================
--- /branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Slave.Core/3.3/PluginCache.cs	(revision 4268)
+++ /branches/3.3-HiveMigration/sources/HeuristicLab.Hive/HeuristicLab.Hive.Slave.Core/3.3/PluginCache.cs	(revision 4269)
@@ -9,4 +9,5 @@
 using HeuristicLab.PluginInfrastructure.Manager;
 using HeuristicLab.Tracing;
+using System.Reflection;
 
 namespace HeuristicLab.Hive.Slave.Core {
@@ -15,9 +16,9 @@
     private static PluginCache instance = null;
 
-    public const string PLUGIN_REPO = @"plugins\";
+    public string PluginRepositoryDir { get; set; }
 
     private List<PluginDescription> cachedPlugins = new List<PluginDescription>();
 
-    private PluginManager pm = new PluginManager(PLUGIN_REPO);
+    private PluginManager pm;
 
     public static PluginCache Instance {
@@ -28,18 +29,23 @@
       }
     }
+
     public PluginCache() {
+      PluginRepositoryDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins");
+      
+      this.pm = new PluginManager(PluginRepositoryDir);
       DoUpdateRun();
     }
 
     private void DoUpdateRun() {
+      if (!Directory.Exists(PluginRepositoryDir)) {
+        Directory.CreateDirectory(PluginRepositoryDir);
+      }
       pm.DiscoverAndCheckPlugins();
       cachedPlugins = new List<PluginDescription>(pm.Plugins);
     }
 
-
     [MethodImpl(MethodImplOptions.Synchronized)]
     public bool CopyPluginsForJob(List<HivePluginInfoDto> requests, Guid jobId) {
-
-      String targetDir = PLUGIN_REPO + jobId.ToString() + "\\";
+      String targetDir = Path.Combine(PluginRepositoryDir, jobId.ToString());
 
       if (Directory.Exists(targetDir)) {
@@ -50,12 +56,10 @@
 
       foreach (HivePluginInfoDto requestedPlugin in requests) {
-        PluginDescription pd =
-          cachedPlugins.Where(
-            cp =>
-            cp.Name == requestedPlugin.Name &&
-            cp.Version.Major == requestedPlugin.Version.Major &&
-            cp.Version.Minor == requestedPlugin.Version.Minor &&
-            cp.Version.Revision >= requestedPlugin.Version.Revision).
-            SingleOrDefault();
+        PluginDescription pd = cachedPlugins.Where(cp =>
+          cp.Name == requestedPlugin.Name &&
+          cp.Version.Major == requestedPlugin.Version.Major &&
+          cp.Version.Minor == requestedPlugin.Version.Minor &&
+          cp.Version.Revision >= requestedPlugin.Version.Revision).
+          SingleOrDefault();
         if (pd == null) {
           return false;
@@ -63,5 +67,9 @@
 
         foreach (IPluginFile ipf in pd.Files) {
-          File.Copy(ipf.Name, targetDir + ipf.Name.Split('\\').Last());
+          string x = targetDir + ipf.Name.Split('\\').Last();
+          string y = Path.Combine(targetDir, Path.GetFileName(ipf.Name));
+
+          //File.Copy(ipf.Name, targetDir + ipf.Name.Split('\\').Last());
+          File.Copy(ipf.Name, Path.Combine(targetDir, Path.GetFileName(ipf.Name)));
         }
       }
@@ -113,5 +121,7 @@
         Logger.Debug("creating new files");
         foreach (HivePluginFile pf in updateablePlugin.PluginFiles) {
-          File.WriteAllBytes(PLUGIN_REPO + pf.Name.Split('\\').Last(), pf.BinaryFile);
+          string x = PluginRepositoryDir + pf.Name.Split('\\').Last();
+          string y = Path.Combine(PluginRepositoryDir, Path.GetFileName(pf.Name));
+          File.WriteAllBytes(Path.Combine(PluginRepositoryDir, Path.GetFileName(pf.Name)), pf.BinaryFile);
         }
 
@@ -124,6 +134,7 @@
       try {
         Logger.Debug("unloading...");
-        Directory.Delete(Path.Combine(PLUGIN_REPO, id.ToString()), true);
-      } catch (Exception ex) {
+        Directory.Delete(Path.Combine(PluginRepositoryDir, id.ToString()), true);
+      }
+      catch (Exception ex) {
         Logger.Debug("failed while unloading " + id + " with exception " + ex);
       }
Index: /branches/3.3-HiveMigration/tools/cleanHiveDatabase.sql
===================================================================
--- /branches/3.3-HiveMigration/tools/cleanHiveDatabase.sql	(revision 4268)
+++ /branches/3.3-HiveMigration/tools/cleanHiveDatabase.sql	(revision 4269)
@@ -4,6 +4,6 @@
 DELETE FROM [HeuristicLab.Hive].[dbo].UptimeStatistics
 DELETE FROM [HeuristicLab.Hive].[dbo].UptimeCalendar
-DELETE FROM [HeuristicLab.Hive].[dbo].ClientConfig
-DELETE FROM [HeuristicLab.Hive].[dbo].ClientGroup_Resource
+DELETE FROM [HeuristicLab.Hive].[dbo].SlaveConfig
+DELETE FROM [HeuristicLab.Hive].[dbo].SlaveGroup_Resource
 DELETE FROM [HeuristicLab.Hive].[dbo].[Resource]
 DELETE FROM [HeuristicLab.Hive].[dbo].Job
Index: /branches/3.3-HiveMigration/tools/prepareHiveDatabase.sql
===================================================================
--- /branches/3.3-HiveMigration/tools/prepareHiveDatabase.sql	(revision 4268)
+++ /branches/3.3-HiveMigration/tools/prepareHiveDatabase.sql	(revision 4269)
@@ -6,6 +6,6 @@
 ALTER TABLE dbo.AssignedResources ALTER COLUMN AssignedRessourcesId DROP ROWGUIDCOL;
 ALTER TABLE dbo.Job ALTER COLUMN JobId DROP ROWGUIDCOL;
-ALTER TABLE dbo.ClientConfig ALTER COLUMN ClientConfigId DROP ROWGUIDCOL;
-ALTER TABLE dbo.ClientGroup_Resource ALTER COLUMN ClientGroup_RessourceId DROP ROWGUIDCOL;
+ALTER TABLE dbo.SlaveConfig ALTER COLUMN SlaveConfigId DROP ROWGUIDCOL;
+ALTER TABLE dbo.SlaveGroup_Resource ALTER COLUMN SlaveGroup_RessourceId DROP ROWGUIDCOL;
 ALTER TABLE dbo.PluginInfo ALTER COLUMN PluginId DROP ROWGUIDCOL;
 ALTER TABLE dbo.Project ALTER COLUMN ProjectId DROP ROWGUIDCOL;
@@ -17,6 +17,6 @@
 ALTER TABLE dbo.AssignedResources DROP CONSTRAINT [DF_AssignedResources_AssignedRessourcesId];
 ALTER TABLE dbo.Job DROP CONSTRAINT [DF_Job_JobId];
-ALTER TABLE dbo.ClientConfig DROP CONSTRAINT [DF_ClientConfig_ClientConfigId];
-ALTER TABLE dbo.ClientGroup_Resource DROP CONSTRAINT [DF_ClientGroup_ResourceClientGroup_RessourceId];
+ALTER TABLE dbo.SlaveConfig DROP CONSTRAINT [DF_SlaveConfig_SlaveConfigId];
+ALTER TABLE dbo.SlaveGroup_Resource DROP CONSTRAINT [DF_SlaveGroup_ResourceSlaveGroup_RessourceId];
 ALTER TABLE dbo.PluginInfo DROP CONSTRAINT [DF_PluginInfo_PluginId];
 ALTER TABLE dbo.Project DROP CONSTRAINT [DF_Project_ProjectId];
@@ -34,9 +34,9 @@
 ALTER TABLE dbo.Job WITH NOCHECK ADD CONSTRAINT [DF_Job_JobId] DEFAULT (newid()) FOR JobId;
 
-ALTER TABLE dbo.ClientConfig ALTER COLUMN ClientConfigId ADD ROWGUIDCOL;
-ALTER TABLE dbo.ClientConfig WITH NOCHECK ADD CONSTRAINT [DF_ClientConfig_ClientConfigId] DEFAULT (newid()) FOR ClientConfigId;
+ALTER TABLE dbo.SlaveConfig ALTER COLUMN SlaveConfigId ADD ROWGUIDCOL;
+ALTER TABLE dbo.SlaveConfig WITH NOCHECK ADD CONSTRAINT [DF_SlaveConfig_SlaveConfigId] DEFAULT (newid()) FOR SlaveConfigId;
 
-ALTER TABLE dbo.ClientGroup_Resource ALTER COLUMN ClientGroup_RessourceId ADD ROWGUIDCOL;
-ALTER TABLE dbo.ClientGroup_Resource WITH NOCHECK ADD CONSTRAINT [DF_ClientGroup_Resource_ClientGroup_RessourceId] DEFAULT (newid()) FOR ClientGroup_RessourceId;
+ALTER TABLE dbo.SlaveGroup_Resource ALTER COLUMN SlaveGroup_RessourceId ADD ROWGUIDCOL;
+ALTER TABLE dbo.SlaveGroup_Resource WITH NOCHECK ADD CONSTRAINT [DF_SlaveGroup_Resource_SlaveGroup_RessourceId] DEFAULT (newid()) FOR SlaveGroup_RessourceId;
 
 ALTER TABLE dbo.PluginInfo ALTER COLUMN PluginId ADD ROWGUIDCOL;
