Index: /branches/HeuristicLab.Hive-3.3/sources/HeuristicLab.Hive/HeuristicLab.Hive 3.3.sln
===================================================================
--- /branches/HeuristicLab.Hive-3.3/sources/HeuristicLab.Hive/HeuristicLab.Hive 3.3.sln	(revision 5267)
+++ /branches/HeuristicLab.Hive-3.3/sources/HeuristicLab.Hive/HeuristicLab.Hive 3.3.sln	(revision 5268)
@@ -29,5 +29,5 @@
 		ConfigMerger.exe = ConfigMerger.exe
 		HeuristicLab 3.3.vsmdi = HeuristicLab 3.3.vsmdi
-		HeuristicLab.Hive 3.32.vsmdi = HeuristicLab.Hive 3.32.vsmdi
+		HeuristicLab.Hive 3.33.vsmdi = HeuristicLab.Hive 3.33.vsmdi
 		LocalTestRun.testrunconfig = LocalTestRun.testrunconfig
 		PreBuildEvent.cmd = PreBuildEvent.cmd
@@ -108,5 +108,5 @@
 Global
 	GlobalSection(TestCaseManagementSettings) = postSolution
-		CategoryFile = HeuristicLab.Hive 3.32.vsmdi
+		CategoryFile = HeuristicLab.Hive 3.33.vsmdi
 	EndGlobalSection
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
Index: /branches/HeuristicLab.Hive-3.3/sources/HeuristicLab.Hive/HeuristicLab.HiveEngine/3.3/HiveEngine.cs
===================================================================
--- /branches/HeuristicLab.Hive-3.3/sources/HeuristicLab.Hive/HeuristicLab.HiveEngine/3.3/HiveEngine.cs	(revision 5267)
+++ /branches/HeuristicLab.Hive-3.3/sources/HeuristicLab.Hive/HeuristicLab.HiveEngine/3.3/HiveEngine.cs	(revision 5268)
@@ -67,4 +67,9 @@
           coll = (OperationCollection)next;
           if (coll.Parallel) {
+            // clone the parent scope here and reuse it for each operation. otherwise for each job the whole scope-tree first needs to be copied and then cleaned, which causes a lot of work for the Garbage Collector
+            IScope parentScopeClone = (IScope)((IAtomicOperation)coll.First()).Scope.Parent.Clone();
+            parentScopeClone.SubScopes.Clear();
+            parentScopeClone.ClearParentScopes();
+
             OperationJob[] jobs = new OperationJob[coll.Count];
             for (int i = 0; i < coll.Count; i++) {
@@ -72,5 +77,5 @@
             }
 
-            IScope[] scopes = ExecuteOnHive(jobs, cancellationToken);
+            IScope[] scopes = ExecuteOnHive(jobs, parentScopeClone, cancellationToken);
 
             for (int i = 0; i < coll.Count; i++) {
@@ -136,5 +141,5 @@
     /// </summary>
     /// <param name="jobs"></param>
-    private IScope[] ExecuteOnHive(OperationJob[] jobs, CancellationToken cancellationToken) {
+    private IScope[] ExecuteOnHive(OperationJob[] jobs, IScope parentScopeClone, CancellationToken cancellationToken) {
       LogMessage(string.Format("Executing {0} operations on the hive.", jobs.Length));
       IScope[] scopes = new Scope[jobs.Length];
@@ -160,5 +165,5 @@
 
           uploadTasks.Add(Task.Factory.StartNew<JobDto>((keyValuePairObj) => {
-            return UploadJob(pluginsNeeded, keyValuePairObj, cancellationToken);
+            return UploadJob(pluginsNeeded, keyValuePairObj, parentScopeClone, cancellationToken);
           }, new KeyValuePair<int, OperationJob>(i, job), cancellationToken));
         }
@@ -198,23 +203,28 @@
 
           Thread.Sleep(10000);
-          using (Disposable<IClientFacade> service = ServiceLocator.Instance.ClientFacadePool.GetService()) {
-            results = service.Obj.GetJobResults(remainingJobIds).Obj;
-          }
-          var jobsFinished = results.Where(j => j.State == JobState.Finished || j.State == JobState.Failed || j.State == JobState.Aborted);
-          finishedCount += jobsFinished.Count();
-          var totalExecutionTime = TimeSpan.FromMilliseconds(results.Select(j => j.ExecutionTime).Union(executionTimes).Select(e => e.TotalMilliseconds).Sum());
-          LogMessage(string.Format("Results polled. Jobs finished: {0}/{1}, TotalExecutionTime: {2}", finishedCount, jobs.Length, totalExecutionTime));
-          foreach (var result in jobsFinished) {
-            if (result.State == JobState.Finished) {
-              downloadTasks.Add(Task.Factory.StartNew<OperationJob>((jobIdObj) => {
-                return DownloadJob(jobIndices, jobIdObj, cancellationToken);
-              }, result.Id, cancellationToken));
-            } else if (result.State == JobState.Aborted) {
-              LogMessage(string.Format("Job #{0} aborted (id: {1})", jobIndices[result.Id] + 1, result.Id));
-            } else if (result.State == JobState.Failed) {
-              LogMessage(string.Format("Job {0} failed (id: {1}): {2}", jobIndices[result.Id] + 1, result.Id, result.Exception));
-            }
-            remainingJobIds.Remove(result.Id);
-            executionTimes.Add(result.ExecutionTime);
+          try {
+            using (Disposable<IClientFacade> service = ServiceLocator.Instance.ClientFacadePool.GetService()) {
+              results = service.Obj.GetJobResults(remainingJobIds).Obj;
+            }
+            var jobsFinished = results.Where(j => j.State == JobState.Finished || j.State == JobState.Failed || j.State == JobState.Aborted);
+            finishedCount += jobsFinished.Count();
+            var totalExecutionTime = TimeSpan.FromMilliseconds(results.Select(j => j.ExecutionTime).Union(executionTimes).Select(e => e.TotalMilliseconds).Sum());
+            LogMessage(string.Format("Results polled. Jobs finished: {0}/{1}, TotalExecutionTime: {2}", finishedCount, jobs.Length, totalExecutionTime));
+            foreach (var result in jobsFinished) {
+              if (result.State == JobState.Finished) {
+                downloadTasks.Add(Task.Factory.StartNew<OperationJob>((jobIdObj) => {
+                  return DownloadJob(jobIndices, jobIdObj, cancellationToken);
+                }, result.Id, cancellationToken));
+              } else if (result.State == JobState.Aborted) {
+                LogMessage(string.Format("Job #{0} aborted (id: {1})", jobIndices[result.Id] + 1, result.Id));
+              } else if (result.State == JobState.Failed) {
+                LogMessage(string.Format("Job {0} failed (id: {1}): {2}", jobIndices[result.Id] + 1, result.Id, result.Exception));
+              }
+              remainingJobIds.Remove(result.Id);
+              executionTimes.Add(result.ExecutionTime);
+            }
+          }
+          catch (Exception e) {
+            LogException(e);
           }
         }
@@ -254,5 +264,5 @@
 
     private static object locker = new object();
-    private JobDto UploadJob(List<HivePluginInfoDto> pluginsNeeded, object keyValuePairObj, CancellationToken cancellationToken) {
+    private JobDto UploadJob(List<HivePluginInfoDto> pluginsNeeded, object keyValuePairObj, IScope parentScopeClone, CancellationToken cancellationToken) {
       var keyValuePair = (KeyValuePair<int, OperationJob>)keyValuePairObj;
       var groups = ResourceIds.Split(';');
@@ -272,4 +282,5 @@
       // clone operation and remove unnecessary scopes; don't do this earlier to avoid memory problems
       lock (locker) {
+        ((IAtomicOperation)keyValuePair.Value.Operation).Scope.Parent = parentScopeClone;
         keyValuePair.Value.Operation = (IOperation)keyValuePair.Value.Operation.Clone();
         if (keyValuePair.Value.Operation is IAtomicOperation)
