Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveClient.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveClient.cs	(revision 6373)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveClient.cs	(revision 6381)
@@ -225,5 +225,5 @@
 
           foreach (HiveJob hiveJob in refreshableHiveExperiment.HiveExperiment.HiveJobs) {
-            UploadJobWithChildren(refreshableHiveExperiment.HiveExperiment.Progress, service, hiveJob, null, resourceIds, ref jobCount, totalJobCount, configFilePlugin.Id, refreshableHiveExperiment.HiveExperiment.UseLocalPlugins, refreshableHiveExperiment.HiveExperiment.Id, refreshableHiveExperiment.Log);
+            UploadJobWithChildren(refreshableHiveExperiment.HiveExperiment.Progress, service, hiveJob, null, resourceIds, ref jobCount, totalJobCount, configFilePlugin.Id, refreshableHiveExperiment.HiveExperiment.UseLocalPlugins, refreshableHiveExperiment.HiveExperiment.Id, refreshableHiveExperiment.Log, refreshableHiveExperiment.HiveExperiment.IsPrivileged);
           }
 
@@ -257,5 +257,5 @@
     /// <param name="parentHiveJob">shall be null if its the root job</param>
     /// <param name="groups"></param>
-    private void UploadJobWithChildren(IProgress progress, IHiveService service, HiveJob hiveJob, HiveJob parentHiveJob, IEnumerable<Guid> groups, ref int jobCount, int totalJobCount, Guid configPluginId, bool useLocalPlugins, Guid hiveExperimentId, ILog log) {
+    private void UploadJobWithChildren(IProgress progress, IHiveService service, HiveJob hiveJob, HiveJob parentHiveJob, IEnumerable<Guid> groups, ref int jobCount, int totalJobCount, Guid configPluginId, bool useLocalPlugins, Guid hiveExperimentId, ILog log, bool isPrivileged) {
       jobCount++;
       progress.Status = string.Format("Serializing job {0} of {1}", jobCount, totalJobCount);
@@ -263,6 +263,5 @@
       List<IPluginDescription> plugins;
 
-      if (hiveJob.ItemJob.ComputeInParallel &&
-        (hiveJob.ItemJob.Item is Optimization.Experiment || hiveJob.ItemJob.Item is Optimization.BatchRun)) {
+      if (hiveJob.ItemJob.ComputeInParallel && (hiveJob.ItemJob.Item is Optimization.Experiment || hiveJob.ItemJob.Item is Optimization.BatchRun)) {
         hiveJob.Job.IsParentJob = true;
         hiveJob.Job.FinishWhenChildJobsFinished = true;
@@ -279,4 +278,5 @@
       hiveJob.Job.PluginsNeededIds.Add(configPluginId);
       hiveJob.Job.HiveExperimentId = hiveExperimentId;
+      hiveJob.Job.IsPrivileged = isPrivileged;
 
       progress.Status = string.Format("Uploading job {0} of {1} ({2} kb, {3} objects)", jobCount, totalJobCount, jobData.Data.Count() / 1024, hiveJob.ItemJob.GetObjectGraphObjects().Count());
@@ -293,5 +293,5 @@
 
       foreach (HiveJob child in hiveJob.ChildHiveJobs) {
-        UploadJobWithChildren(progress, service, child, hiveJob, groups, ref jobCount, totalJobCount, configPluginId, useLocalPlugins, hiveExperimentId, log);
+        UploadJobWithChildren(progress, service, child, hiveJob, groups, ref jobCount, totalJobCount, configPluginId, useLocalPlugins, hiveExperimentId, log, isPrivileged);
       }
     }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveJobs/EngineHiveJob.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveJobs/EngineHiveJob.cs	(revision 6373)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveJobs/EngineHiveJob.cs	(revision 6381)
@@ -56,10 +56,10 @@
 
       // clone operation and remove unnecessary scopes; don't do this earlier to avoid memory problems
-      lock (locker) {
+      //lock (locker) {
         ((IAtomicOperation)ItemJob.InitialOperation).Scope.Parent = parentScopeClone;
         ItemJob.InitialOperation = (IOperation)ItemJob.InitialOperation.Clone();
         ((IAtomicOperation)ItemJob.InitialOperation).Scope.ClearParentScopes();
         jobData.Data = PersistenceUtil.Serialize(ItemJob, out usedTypes);
-      }
+      //}
 
       // add type objects from object graph to work around ticket #1527
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveJobs/HiveJob.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveJobs/HiveJob.cs	(revision 6373)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveJobs/HiveJob.cs	(revision 6381)
@@ -25,4 +25,5 @@
 using System.Drawing;
 using System.Linq;
+using System.Threading;
 using HeuristicLab.Collections;
 using HeuristicLab.Common;
@@ -37,4 +38,5 @@
   public class HiveJob : NamedItem, IItemTree<HiveJob> {
     protected static object locker = new object();
+    protected ReaderWriterLockSlim childHiveJobsLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion);
 
     public override Image ItemImage {
@@ -109,5 +111,11 @@
     protected ItemList<HiveJob> childHiveJobs;
     public virtual ReadOnlyItemList<HiveJob> ChildHiveJobs {
-      get { return childHiveJobs.AsReadOnly(); }
+      get {
+        childHiveJobsLock.EnterReadLock();
+        try {
+          return childHiveJobs.AsReadOnly();
+        }
+        finally { childHiveJobsLock.ExitReadLock(); }
+      }
     }
 
@@ -117,8 +125,5 @@
     #region Constructors and Cloning
     public HiveJob() {
-      this.Job = new Job() {
-        CoresNeeded = 1,
-        MemoryNeeded = 0
-      };
+      this.Job = new Job() { CoresNeeded = 1, MemoryNeeded = 0 };
       job.State = JobState.Offline;
       this.childHiveJobs = new ItemList<HiveJob>();
@@ -152,5 +157,9 @@
       this.Job = cloner.Clone(original.job);
       this.ItemJob = cloner.Clone(original.ItemJob);
-      this.childHiveJobs = cloner.Clone(original.childHiveJobs);
+      original.childHiveJobsLock.EnterReadLock();
+      try {
+        this.childHiveJobs = cloner.Clone(original.childHiveJobs);
+      }
+      finally { original.childHiveJobsLock.ExitReadLock(); }
       this.syncJobsWithOptimizers = original.syncJobsWithOptimizers;
       this.isFinishedJobDownloaded = original.isFinishedJobDownloaded;
@@ -198,5 +207,9 @@
 
     public virtual void AddChildHiveJob(HiveJob hiveJob) {
-      this.childHiveJobs.Add(hiveJob);
+      childHiveJobsLock.EnterWriteLock();
+      try {
+        this.childHiveJobs.Add(hiveJob);
+      }
+      finally { childHiveJobsLock.ExitWriteLock(); }
     }
 
@@ -237,12 +250,6 @@
       IEnumerable<Type> usedTypes;
       byte[] jobByteArray = PersistenceUtil.Serialize(this.ItemJob, out usedTypes);
-
-      JobData jobData = new JobData() {
-        JobId = job.Id,
-        Data = jobByteArray
-      };
-
+      JobData jobData = new JobData() { JobId = job.Id, Data = jobByteArray };
       PluginUtil.CollectDeclaringPlugins(plugins, usedTypes);
-
       return jobData;
     }
@@ -295,21 +302,29 @@
     /// </summary>
     public IEnumerable<HiveJob> GetAllHiveJobs() {
-      var jobs = new List<HiveJob>();
-      jobs.Add(this);
-      foreach (HiveJob child in this.ChildHiveJobs) {
-        jobs.AddRange(child.GetAllHiveJobs());
-      }
-      return jobs;
+      childHiveJobsLock.EnterReadLock();
+      try {
+        var jobs = new List<HiveJob>();
+        jobs.Add(this);
+        foreach (HiveJob child in this.childHiveJobs) {
+          jobs.AddRange(child.GetAllHiveJobs());
+        }
+        return jobs;
+      }
+      finally { childHiveJobsLock.ExitReadLock(); }
     }
 
     public HiveJob GetParentByJobId(Guid jobId) {
-      if (this.ChildHiveJobs.SingleOrDefault(j => j.job.Id == jobId) != null)
-        return this;
-      foreach (HiveJob child in this.childHiveJobs) {
-        HiveJob result = child.GetParentByJobId(jobId);
-        if (result != null)
-          return result;
-      }
-      return null;
+      childHiveJobsLock.EnterReadLock();
+      try {
+        if (this.ChildHiveJobs.SingleOrDefault(j => j.job.Id == jobId) != null)
+          return this;
+        foreach (HiveJob child in this.childHiveJobs) {
+          HiveJob result = child.GetParentByJobId(jobId);
+          if (result != null)
+            return result;
+        }
+        return null;
+      }
+      finally { childHiveJobsLock.ExitWriteLock(); }
     }
 
@@ -321,9 +336,13 @@
         return this;
       } else {
-        foreach (HiveJob child in this.ChildHiveJobs) {
-          HiveJob result = child.GetHiveJobByJobId(jobId);
-          if (result != null)
-            return result;
-        }
+        childHiveJobsLock.EnterReadLock();
+        try {
+          foreach (HiveJob child in this.childHiveJobs) {
+            HiveJob result = child.GetHiveJobByJobId(jobId);
+            if (result != null)
+              return result;
+          }
+        }
+        finally { childHiveJobsLock.ExitReadLock(); }
       }
       return null;
@@ -331,15 +350,19 @@
 
     public void RemoveByJobId(Guid jobId) {
-      IEnumerable<HiveJob> jobs = ChildHiveJobs.Where(j => j.Job.Id == jobId).ToList(); // if Guid.Empty needs to be removed, there could be more than one with this jobId
-      foreach (HiveJob j in jobs) {
-        this.childHiveJobs.Remove(j);
-      }
-      foreach (HiveJob child in ChildHiveJobs) {
-        child.RemoveByJobId(jobId);
-      }
+      childHiveJobsLock.EnterWriteLock();
+      try {
+        IEnumerable<HiveJob> jobs = childHiveJobs.Where(j => j.Job.Id == jobId).ToList();
+        foreach (HiveJob j in jobs) {
+          this.childHiveJobs.Remove(j);
+        }
+        foreach (HiveJob child in childHiveJobs) {
+          child.RemoveByJobId(jobId);
+        }
+      }
+      finally { childHiveJobsLock.ExitWriteLock(); }
     }
 
     public IEnumerable<IItemTree<HiveJob>> GetChildItems() {
-      return this.childHiveJobs;
+      return this.ChildHiveJobs;
     }
 
@@ -371,7 +394,11 @@
     public void Pause() {
       if (this.Job.IsParentJob) {
-        foreach (var child in ChildHiveJobs) {
-          ServiceLocator.Instance.CallHiveService(s => s.PauseJob(child.job.Id));
-        }
+        childHiveJobsLock.EnterReadLock();
+        try {
+          foreach (var child in childHiveJobs) {
+            ServiceLocator.Instance.CallHiveService(s => s.PauseJob(child.job.Id));
+          }
+        }
+        finally { childHiveJobsLock.ExitReadLock(); }
       } else {
         ServiceLocator.Instance.CallHiveService(s => s.PauseJob(this.job.Id));
@@ -381,7 +408,11 @@
     public void Stop() {
       if (this.Job.IsParentJob) {
-        foreach (var child in ChildHiveJobs) {
-          ServiceLocator.Instance.CallHiveService(s => s.StopJob(child.job.Id));
-        }
+        childHiveJobsLock.EnterReadLock();
+        try {
+          foreach (var child in childHiveJobs) {
+            ServiceLocator.Instance.CallHiveService(s => s.StopJob(child.job.Id));
+          }
+        }
+        finally { childHiveJobsLock.ExitReadLock(); }
       } else {
         ServiceLocator.Instance.CallHiveService(s => s.StopJob(this.job.Id));
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveJobs/OptimizerHiveJob.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveJobs/OptimizerHiveJob.cs	(revision 6373)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/HiveJobs/OptimizerHiveJob.cs	(revision 6381)
@@ -129,35 +129,51 @@
     private void Optimizers_ItemsAdded(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
       if (syncJobsWithOptimizers && this.ItemJob.ComputeInParallel) {
-        foreach (var item in e.Items) {
-          if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
-            this.childHiveJobs.Add(new OptimizerHiveJob(item.Value));
-          }
-        }
+        childHiveJobsLock.EnterWriteLock();
+        try {
+          foreach (var item in e.Items) {
+            if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
+              this.childHiveJobs.Add(new OptimizerHiveJob(item.Value));
+            }
+          }
+        }
+        finally { childHiveJobsLock.ExitWriteLock(); }
       }
     }
     private void Optimizers_ItemsReplaced(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
       if (syncJobsWithOptimizers && this.ItemJob.ComputeInParallel) {
-        foreach (var item in e.OldItems) {
-          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
-        }
-        foreach (var item in e.Items) {
-          if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
-            this.childHiveJobs.Add(new OptimizerHiveJob(item.Value));
-          }
-        }
+        childHiveJobsLock.EnterWriteLock();
+        try {
+          foreach (var item in e.OldItems) {
+            this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
+          }
+          foreach (var item in e.Items) {
+            if (GetChildByOptimizer(item.Value) == null && item.Value.Name != "Placeholder") {
+              this.childHiveJobs.Add(new OptimizerHiveJob(item.Value));
+            }
+          }
+        }
+        finally { childHiveJobsLock.ExitWriteLock(); }
       }
     }
     private void Optimizers_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
       if (syncJobsWithOptimizers && this.ItemJob.ComputeInParallel) {
-        foreach (var item in e.Items) {
-          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
-        }
+        childHiveJobsLock.EnterWriteLock();
+        try {
+          foreach (var item in e.Items) {
+            this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
+          }
+        }
+        finally { childHiveJobsLock.ExitWriteLock(); }
       }
     }
     private void Optimizers_CollectionReset(object sender, CollectionItemsChangedEventArgs<IndexedItem<IOptimizer>> e) {
       if (syncJobsWithOptimizers && this.ItemJob.ComputeInParallel) {
-        foreach (var item in e.Items) {
-          this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
-        }
+        childHiveJobsLock.EnterWriteLock();
+        try {
+          foreach (var item in e.Items) {
+            this.childHiveJobs.Remove(this.GetChildByOptimizer(item.Value));
+          }
+        }
+        finally { childHiveJobsLock.ExitWriteLock(); }
       }
     }
@@ -182,9 +198,13 @@
 
       OptimizerHiveJob child = (OptimizerHiveJob)this.ChildHiveJobs.Single(j => j.Job.Id == childJobId);
-      if (!optimizerJob.ComputeInParallel) {
-        child.syncJobsWithOptimizers = false;
-        child.ItemJob = optimizerJob;
-        child.syncJobsWithOptimizers = true;
-      }
+      childHiveJobsLock.EnterReadLock();
+      try {
+        if (!optimizerJob.ComputeInParallel) {
+          child.syncJobsWithOptimizers = false;
+          child.ItemJob = optimizerJob;
+          child.syncJobsWithOptimizers = true;
+        }
+      }
+      finally { childHiveJobsLock.ExitReadLock(); }
       syncJobsWithOptimizers = true;
     }
@@ -243,7 +263,11 @@
         }
       }
-      foreach (OptimizerHiveJob child in childHiveJobs) {
-        child.SetIndexInParentOptimizerList(this);
-      }
+      childHiveJobsLock.EnterReadLock();
+      try {
+        foreach (OptimizerHiveJob child in childHiveJobs) {
+          child.SetIndexInParentOptimizerList(this);
+        }
+      }
+      finally { childHiveJobsLock.ExitReadLock(); }
     }
 
@@ -302,28 +326,31 @@
       }
 
-      JobData jobData = new JobData() {
-        JobId = job.Id,
-        Data = jobByteArray
-      };
-
+      JobData jobData = new JobData() { JobId = job.Id, Data = jobByteArray };
       PluginUtil.CollectDeclaringPlugins(plugins, usedTypes);
-
       return jobData;
     }
 
     public OptimizerHiveJob GetChildByOptimizerJob(OptimizerJob optimizerJob) {
-      foreach (OptimizerHiveJob child in ChildHiveJobs) {
-        if (child.ItemJob == optimizerJob)
-          return child;
-      }
-      return null;
+      childHiveJobsLock.EnterReadLock();
+      try {
+        foreach (OptimizerHiveJob child in childHiveJobs) {
+          if (child.ItemJob == optimizerJob)
+            return child;
+        }
+        return null;
+      }
+      finally { childHiveJobsLock.ExitReadLock(); }
     }
 
     public HiveJob<OptimizerJob> GetChildByOptimizer(IOptimizer optimizer) {
-      foreach (OptimizerHiveJob child in ChildHiveJobs) {
-        if (child.ItemJob.Item == optimizer)
-          return child;
-      }
-      return null;
+      childHiveJobsLock.EnterReadLock();
+      try {
+        foreach (OptimizerHiveJob child in childHiveJobs) {
+          if (child.ItemJob.Item == optimizer)
+            return child;
+        }
+        return null;
+      }
+      finally { childHiveJobsLock.ExitReadLock(); }
     }
 
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/Jobs/ItemJob.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/Jobs/ItemJob.cs	(revision 6373)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/Jobs/ItemJob.cs	(revision 6381)
@@ -31,5 +31,5 @@
   [Item("Item Job", "Represents a executable hive job which contains a HeuristicLab Item.")]
   [StorableClass]
-  public abstract class ItemJob : DeepCloneable, IJob {
+  public abstract class ItemJob : NamedItem, IJob {
     public virtual bool IsParallelizable {
       get { return true; }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/Jobs/OptimizerJob.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/Jobs/OptimizerJob.cs	(revision 6373)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/Jobs/OptimizerJob.cs	(revision 6381)
@@ -86,5 +86,4 @@
 
     #region IJob Members
-
     public override ExecutionState ExecutionState {
       get { return Item.ExecutionState; }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/RefreshableHiveExperiment.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/RefreshableHiveExperiment.cs	(revision 6373)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/RefreshableHiveExperiment.cs	(revision 6381)
@@ -395,5 +395,5 @@
 
     public override string ToString() {
-      return HiveExperiment.ToString();
+      return string.Format("{0} {1}", HiveExperiment.DateCreated.ToString("MM.dd.yyyy HH:mm"), HiveExperiment.ToString());
     }
   }
Index: branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveExperiment.cs
===================================================================
--- branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveExperiment.cs	(revision 6373)
+++ branches/HeuristicLab.Hive-3.4/sources/HeuristicLab.Clients.Hive/3.4/ServiceClients/HiveExperiment.cs	(revision 6381)
@@ -33,4 +33,10 @@
       get { return useLocalPlugins; }
       set { useLocalPlugins = value; }
+    }
+
+    private bool isPrivileged;
+    public bool IsPrivileged {
+      get { return isPrivileged; }
+      set { isPrivileged = value; }
     }
 
@@ -89,4 +95,5 @@
       this.ResourceNames = "HEAL";
       this.HiveJobs = new ItemCollection<HiveJob>();
+      this.DateCreated = DateTime.Now;
     }
 
@@ -103,4 +110,5 @@
       this.UseLocalPlugins = original.UseLocalPlugins;
       this.ExecutionTime = original.ExecutionTime;
+      this.IsPrivileged = original.IsPrivileged;
     }
     public override IDeepCloneable Clone(Cloner cloner) {
