Index: /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/RefreshableHiveExperimentView.cs
===================================================================
--- /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/RefreshableHiveExperimentView.cs	(revision 6197)
+++ /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive.Views/3.4/ExperimentManager/RefreshableHiveExperimentView.cs	(revision 6198)
@@ -107,4 +107,5 @@
         calculatingTextBox.Text = "0";
         finishedTextBox.Text = "0";
+        logView.Content = null;
       } else {
         nameTextBox.Text = Content.HiveExperiment.Name;
@@ -117,4 +118,5 @@
         calculatingTextBox.Text = Content.HiveExperiment.CalculatingCount.ToString();
         finishedTextBox.Text = Content.HiveExperiment.FinishedCount.ToString();
+        logView.Content = Content.Log;
       }
       Content_HiveExperimentChanged(this, EventArgs.Empty);
Index: /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/ConcurrentJobDownloader.cs
===================================================================
--- /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/ConcurrentJobDownloader.cs	(revision 6197)
+++ /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/ConcurrentJobDownloader.cs	(revision 6198)
@@ -20,12 +20,12 @@
     }
 
-    public void DownloadJob(Guid jobId, Action<Guid, T, Exception> onFinishedAction) {
-      Task<JobData>.Factory.StartNew((x) => DownloadJob(x), jobId)
+    public void DownloadJob(Job job, Action<Job, T, Exception> onFinishedAction) {
+      Task<JobData>.Factory.StartNew((x) => DownloadJob(x), job.Id)
                                      .ContinueWith((x) => DeserializeJob(x.Result))
-                                     .ContinueWith((x) => OnJobFinished(jobId, x, onFinishedAction), TaskContinuationOptions.ExecuteSynchronously);
+                                     .ContinueWith((x) => OnJobFinished(job, x, onFinishedAction), TaskContinuationOptions.ExecuteSynchronously);
     }
 
-    private void OnJobFinished(Guid jobId, Task<T> task, Action<Guid, T, Exception> onFinishedAction) {
-      onFinishedAction(jobId, task.Result, task.Exception);
+    private void OnJobFinished(Job job, Task<T> task, Action<Job, T, Exception> onFinishedAction) {
+      onFinishedAction(job, task.Result, task.Exception);
     }
 
@@ -46,6 +46,7 @@
     protected T DeserializeJob(JobData jobData) {
       try {
+        if (abort || jobData == null) return null;
         Job job = ServiceLocator.Instance.CallHiveService(s => s.GetJob(jobData.JobId));
-        if (abort || job == null || jobData == null) return null;
+        if (job == null) return null;
         var deserializedJob = PersistenceUtil.Deserialize<T>(jobData.Data);
         jobData.Data = null; // reduce memory consumption.
Index: /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/EngineHiveJob.cs
===================================================================
--- /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/EngineHiveJob.cs	(revision 6197)
+++ /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/EngineHiveJob.cs	(revision 6198)
@@ -22,4 +22,5 @@
 using System;
 using System.Collections.Generic;
+using System.Linq;
 using HeuristicLab.Common;
 using HeuristicLab.Core;
@@ -62,6 +63,10 @@
       }
 
+      // add type objects from object graph to work around ticket #1527
+      var typeObjects = ItemJob.GetObjectGraphObjects().OfType<Type>();
+      usedTypes = new List<Type>(usedTypes).Union(typeObjects);
+
       PluginUtil.CollectDeclaringPlugins(plugins, usedTypes);
-
+      
       return jobData;
     }
Index: /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJob.cs
===================================================================
--- /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJob.cs	(revision 6197)
+++ /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJob.cs	(revision 6198)
@@ -65,5 +65,5 @@
           job = value;
           RegisterJobEvents();
-          itemJobDownloaded = false;
+          IsFinishedJobDownloaded = false;
           OnJobChanged();
           OnToStringChanged();
@@ -87,5 +87,5 @@
           RegisterItemJobEvents();
           OnJobItemChanged();
-          itemJobDownloaded = true;
+          IsFinishedJobDownloaded = true;
         }
       }
@@ -94,8 +94,16 @@
     // job downloaded since last status change
     [Storable]
-    private bool itemJobDownloaded = false;
-    public bool ItemJobDownloaded {
-      get { return itemJobDownloaded; } 
-    }
+    private bool isFinishedJobDownloaded = false;
+    public bool IsFinishedJobDownloaded {
+      get { return isFinishedJobDownloaded; }
+      set {
+        if (value != isFinishedJobDownloaded) {
+          this.isFinishedJobDownloaded = value;
+          OnIsFinishedJobDownloadedChanged();
+        }
+      }
+    }
+
+    public bool IsDownloading { get; set; }
 
     [Storable]
@@ -147,5 +155,5 @@
       this.childHiveJobs = cloner.Clone(original.childHiveJobs);
       this.syncJobsWithOptimizers = original.syncJobsWithOptimizers;
-      this.itemJobDownloaded = original.itemJobDownloaded;
+      this.isFinishedJobDownloaded = original.isFinishedJobDownloaded;
     }
     public override IDeepCloneable Clone(Cloner cloner) {
@@ -210,5 +218,4 @@
         job.StateLog = new List<StateLog>(lightweightJob.StateLog);
         job.Command = lightweightJob.Command;
-        job.LastJobDataUpdate = lightweightJob.LastJobDataUpdate;
 
         OnJobStateChanged();
@@ -262,7 +269,7 @@
     }
 
-    public event EventHandler IsFinishedOptimizerDownloadedChanged;
-    private void OnIsFinishedOptimizerDownloadedChanged() {
-      var handler = IsFinishedOptimizerDownloadedChanged;
+    public event EventHandler IsFinishedJobDownloadedChanged;
+    private void OnIsFinishedJobDownloadedChanged() {
+      var handler = IsFinishedJobDownloadedChanged;
       if (handler != null) handler(this, EventArgs.Empty);
     }
@@ -280,5 +287,5 @@
     private void job_PropertyChanged(object sender, PropertyChangedEventArgs e) {
       if (e.PropertyName == "State") {
-        itemJobDownloaded = false;
+        IsFinishedJobDownloaded = false;
       }
     }
@@ -402,4 +409,5 @@
 
     public virtual void IntegrateChild(ItemJob job, Guid childJobId) { }
+
   }
 
Index: /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJobDownloader.cs
===================================================================
--- /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJobDownloader.cs	(revision 6197)
+++ /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/HiveJobDownloader.cs	(revision 6198)
@@ -59,11 +59,12 @@
     public void StartAsync() {
       foreach (Guid jobId in jobIds) {
-        jobDownloader.DownloadJob(jobId,
-          (id, itemJob, exception) => {
+        Job job = ServiceLocator.Instance.CallHiveService(s => s.GetJob(jobId));
+
+        jobDownloader.DownloadJob(job,
+          (localJob, itemJob, exception) => {
             if (exception != null) {
               throw new ConcurrentJobDownloaderException("Downloading job failed", exception);
             }
-            Job job = ServiceLocator.Instance.CallHiveService(s => s.GetJob(id));
-            if (job != null && itemJob != null) {
+            if (localJob != null && itemJob != null) {
               HiveJob hiveJob;
               if (itemJob is OptimizerJob) {
@@ -72,6 +73,6 @@
                 hiveJob = new HiveJob(itemJob, true);
               }
-              hiveJob.Job = job;
-              this.results.Add(id, hiveJob);
+              hiveJob.Job = localJob;
+              this.results.Add(localJob.Id, hiveJob);
             }
           });
Index: /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/RefreshableHiveExperiment.cs
===================================================================
--- /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/RefreshableHiveExperiment.cs	(revision 6197)
+++ /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ExperimentManager/RefreshableHiveExperiment.cs	(revision 6198)
@@ -95,4 +95,12 @@
     }
 
+    [Storable]
+    private ILog log;
+    public ILog Log {
+      get { return log; }
+      set { log = value; }
+    }
+    
+
     #region Constructors and Cloning
     public RefreshableHiveExperiment() {
@@ -100,4 +108,5 @@
       this.refreshAutomatically = true;
       this.HiveExperiment = new HiveExperiment();
+      this.log = new Log();
     }
     public RefreshableHiveExperiment(HiveExperiment hiveExperiment) {
@@ -105,4 +114,5 @@
       this.refreshAutomatically = true;
       this.HiveExperiment = hiveExperiment;
+      this.log = new Log();
     }
     protected RefreshableHiveExperiment(RefreshableHiveExperiment original, Cloner cloner) {
@@ -112,4 +122,5 @@
       this.IncludeJobs = original.IncludeJobs;
       this.IsControllable = original.IsControllable;
+      this.Log = cloner.Clone(original.Log);
     }
     public IDeepCloneable Clone(Cloner cloner) {
@@ -167,13 +178,23 @@
     private void jobResultPoller_JobResultReceived(object sender, EventArgs<IEnumerable<LightweightJob>> e) {
       foreach (LightweightJob lightweightJob in e.Value) {
-        HiveJob hj = GetHiveJobById(lightweightJob.Id);
-        if (hj != null) {
-          DateTime lastJobDataUpdate = hj.Job.LastJobDataUpdate;
-          hj.UpdateFromLightweightJob(lightweightJob);
-
+        HiveJob hiveJob = GetHiveJobById(lightweightJob.Id);
+        if (hiveJob != null) {
           // lastJobDataUpdate equals DateTime.MinValue right after it was uploaded. When the first results are polled, this value is updated
-          if (lastJobDataUpdate != DateTime.MinValue && lastJobDataUpdate < hj.Job.LastJobDataUpdate) {
-            jobDownloader.DownloadJob(hj.Job.Id, (id, itemJob, exception) => {
+          if (hiveJob.Job.State == JobState.Offline && lightweightJob.State != JobState.Finished && lightweightJob.State != JobState.Failed && lightweightJob.State != JobState.Aborted) {
+            hiveJob.Job.LastJobDataUpdate = lightweightJob.LastJobDataUpdate;
+          }
+
+          hiveJob.UpdateFromLightweightJob(lightweightJob);
+
+          if (!hiveJob.IsFinishedJobDownloaded && !hiveJob.IsDownloading && hiveJob.Job.LastJobDataUpdate < lightweightJob.LastJobDataUpdate) {
+            log.LogMessage(string.Format("Downloading job {0}", lightweightJob.Id));
+            hiveJob.IsDownloading = true;
+            jobDownloader.DownloadJob(hiveJob.Job, (localJob, itemJob, exception) => {
+              log.LogMessage(string.Format("Finished downloading job {0}", localJob.Id));
+              HiveJob localHiveJob = GetHiveJobById(localJob.Id);
+
               if (exception != null) {
+                log.LogException(exception);
+                localHiveJob.IsDownloading = false;
                 throw new ConcurrentJobDownloaderException("Downloading job failed.", exception);
               }
@@ -183,14 +204,18 @@
               } else {
                 // if the job is paused, download but don't integrate into parent optimizer (to avoid Prepare)
-                if (hj.Job.State == JobState.Paused) {
-                  hj.ItemJob = itemJob;
+
+
+                if (localJob.State == JobState.Paused) {
+                  localHiveJob.ItemJob = itemJob;
                 } else {
-                  if (lightweightJob.ParentJobId.HasValue) {
-                    HiveJob parentHiveJob = GetHiveJobById(lightweightJob.ParentJobId.Value);
-                    parentHiveJob.IntegrateChild(itemJob, hj.Job.Id);
+                  if (localJob.ParentJobId.HasValue) {
+                    HiveJob parentHiveJob = GetHiveJobById(localJob.ParentJobId.Value);
+                    parentHiveJob.IntegrateChild(itemJob, localJob.Id);
                   } else {
-                    hj.ItemJob = itemJob;
+                    localHiveJob.ItemJob = itemJob;
                   }
                 }
+                localHiveJob.IsDownloading = false;
+                localHiveJob.Job.LastJobDataUpdate = localJob.LastJobDataUpdate;
               }
             });
@@ -227,5 +252,5 @@
                                                    || j.Job.State == JobState.Aborted
                                                    || j.Job.State == JobState.Failed)
-                                                   && j.ItemJobDownloaded);
+                                                   && j.IsFinishedJobDownloaded);
     }
 
Index: /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/app_services.config
===================================================================
--- /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/app_services.config	(revision 6197)
+++ /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine.Test/app_services.config	(revision 6198)
@@ -36,5 +36,5 @@
     <bindings>
       <wsHttpBinding>
-        <binding name="WSHttpBinding_IUpdate" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="200000000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
+        <binding name="WSHttpBinding_IUpdate" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="200000000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
           <readerQuotas maxDepth="32" maxStringContentLength="32000" maxArrayLength="200000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
           <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
@@ -44,5 +44,5 @@
           </security>
         </binding>
-        <binding name="WSHttpBinding_IAdmin" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="200000000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
+        <binding name="WSHttpBinding_IAdmin" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="200000000" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
           <readerQuotas maxDepth="32" maxStringContentLength="32000" maxArrayLength="200000000" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
           <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
@@ -52,6 +52,6 @@
           </security>
         </binding>
-        <binding name="wsHttpBinding_Hive" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:20:00" sendTimeout="00:20:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
-          <readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="4096" maxNameTableCharCount="16384" />
+        <binding name="wsHttpBinding_IHiveService" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:20:00" sendTimeout="00:20:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true" allowCookies="false">
+          <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
           <reliableSession ordered="true" inactivityTimeout="00:10:00" enabled="false" />
           <security mode="Message">
@@ -73,5 +73,5 @@
         </identity>
       </endpoint>
-      <endpoint address="http://services.heuristiclab.com/Hive-3.4/HiveService.svc" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_Hive" contract="HeuristicLab.Clients.Hive.IHiveService" name="wsHttpBinding_IHiveService">
+      <endpoint address="http://services.heuristiclab.com/Hive-3.4/HiveService.svc" binding="wsHttpBinding" bindingConfiguration="wsHttpBinding_IHiveService" contract="HeuristicLab.Clients.Hive.IHiveService" name="wsHttpBinding_IHiveService">
         <identity>
           <certificate encodedValue="AwAAAAEAAAAUAAAAwK1+2oAmcy/mI2P2QjyiJRh0y60gAAAAAQAAACoCAAAwggImMIIBj6ADAgECAhAIkseQ2EEhgU720qJA61gqMA0GCSqGSIb3DQEBBAUAMCQxIjAgBgNVBAMTGXNlcnZpY2VzLmhldXJpc3RpY2xhYi5jb20wHhcNMTAwNTExMTExNDAyWhcNMzkxMjMxMjM1OTU5WjAkMSIwIAYDVQQDExlzZXJ2aWNlcy5oZXVyaXN0aWNsYWIuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq26Bwmwc7k+4W30qLQ2j+FInEL5BuH6opDY6CSlrtt3xQS/anrhvpbf3QghLDVINzcHkzbPmm/SguG4F85QLB6xO+tJaOvRo0iEK5g3c307vMIru7FJwk/OhplEQ5J1hbDgL3zOJlrWlgtqRVxCtVdF3XroI9BctOt1NkeKv9ewIDAQABo1kwVzBVBgNVHQEETjBMgBCjbgdYd4j5JgUuJ1Wo/GxroSYwJDEiMCAGA1UEAxMZc2VydmljZXMuaGV1cmlzdGljbGFiLmNvbYIQCJLHkNhBIYFO9tKiQOtYKjANBgkqhkiG9w0BAQQFAAOBgQAb/2xk2uQad68shSPl/uixWgvFI8WkxOTBopOLaLtDxwCeZ3mWVHdV9VnixHtThubnEBXAhYOCQSIXWtQuXFWO+gH3YyjTRJY5kTmXyuvBRTn3/so5SrQ7Rdlm9hf6E5YVX3tCjAy7ybUyaDUkQfmH5vmvgvpMzRfsJ1qhnUpJiQ==" />
Index: /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/HiveEngine.cs
===================================================================
--- /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/HiveEngine.cs	(revision 6197)
+++ /branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.HiveEngine/3.4/HiveEngine.cs	(revision 6198)
@@ -261,4 +261,5 @@
           Thread.Sleep(500);
           this.ExecutionTimeOnHive = TimeSpan.FromMilliseconds(hiveExperiments.Sum(x => x.HiveExperiment.ExecutionTime.TotalMilliseconds));
+          cancellationToken.ThrowIfCancellationRequested();
         }
         LogMessage(string.Format("{0} finished (TotalExecutionTime: {1}).", refreshableHiveExperiment.ToString(), refreshableHiveExperiment.HiveExperiment.ExecutionTime));
