Index: trunk/sources/HeuristicLab.Core/3.3/Log.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/Log.cs	(revision 11592)
+++ trunk/sources/HeuristicLab.Core/3.3/Log.cs	(revision 11596)
@@ -30,5 +30,5 @@
   [Item("Log", "A log for logging string messages.")]
   [StorableClass]
-  public class Log : Item, ILog, IStorableContent {
+  public sealed class Log : Item, ILog, IStorableContent {
     public string Filename { get; set; }
 
@@ -38,18 +38,18 @@
 
     [Storable]
-    protected IList<string> messages;
-    public virtual IEnumerable<string> Messages {
+    private IList<string> messages;
+    public IEnumerable<string> Messages {
       get { return messages; }
     }
 
     [Storable]
-    protected long maxMessageCount;
-    public virtual long MaxMessageCount {
+    private long maxMessageCount;
+    public long MaxMessageCount {
       get { return maxMessageCount; }
     }
 
     [StorableConstructor]
-    protected Log(bool deserializing) : base(deserializing) { }
-    protected Log(Log original, Cloner cloner)
+    private Log(bool deserializing) : base(deserializing) { }
+    private Log(Log original, Cloner cloner)
       : base(original, cloner) {
       this.messages = new List<string>(original.messages);
@@ -66,9 +66,9 @@
     }
 
-    public virtual void Clear() {
+    public void Clear() {
       messages.Clear();
       OnCleared();
     }
-    public virtual void LogMessage(string message) {
+    public void LogMessage(string message) {
       string s = FormatLogMessage(message);
       messages.Add(s);
@@ -76,5 +76,5 @@
       OnMessageAdded(s);
     }
-    public virtual void LogException(Exception ex) {
+    public void LogException(Exception ex) {
       string s = FormatException(ex);
       messages.Add(s);
@@ -82,23 +82,23 @@
       OnMessageAdded(s);
     }
-    protected virtual void CapMessages() {
+    private void CapMessages() {
       while (maxMessageCount >= 0 && messages.Count > maxMessageCount) {
         messages.RemoveAt(0);
       }
     }
-    protected virtual string FormatLogMessage(string message) {
+    public static string FormatLogMessage(string message) {
       return DateTime.Now.ToString() + "\t" + message;
     }
-    protected virtual string FormatException(Exception ex) {
+    public static string FormatException(Exception ex) {
       return DateTime.Now.ToString() + "\t" + "Exception occurred:" + Environment.NewLine + ErrorHandling.BuildErrorMessage(ex);
     }
 
     public event EventHandler<EventArgs<string>> MessageAdded;
-    protected virtual void OnMessageAdded(string message) {
+    private void OnMessageAdded(string message) {
       EventHandler<EventArgs<string>> handler = MessageAdded;
       if (handler != null) handler(this, new EventArgs<string>(message));
     }
     public event EventHandler Cleared;
-    protected virtual void OnCleared() {
+    private void OnCleared() {
       EventHandler handler = Cleared;
       if (handler != null) handler(this, EventArgs.Empty);
Index: trunk/sources/HeuristicLab.Core/3.3/ThreadSafeLog.cs
===================================================================
--- trunk/sources/HeuristicLab.Core/3.3/ThreadSafeLog.cs	(revision 11592)
+++ trunk/sources/HeuristicLab.Core/3.3/ThreadSafeLog.cs	(revision 11596)
@@ -21,7 +21,6 @@
 
 using System;
+using System.Collections.Concurrent;
 using System.Collections.Generic;
-using System.Linq;
-using System.Threading;
 using HeuristicLab.Common;
 using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
@@ -30,58 +29,78 @@
   [Item("ThreadSafeLog", "A thread-safe log for logging string messages.")]
   [StorableClass]
-  public sealed class ThreadSafeLog : Log {
-    private ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
+  public sealed class ThreadSafeLog : Item, ILog, IStorableContent {
+    public string Filename { get; set; }
+    private ConcurrentQueue<string> messages;
 
-    public override IEnumerable<string> Messages {
-      get {
-        locker.EnterReadLock();
-        try {
-          return messages.ToArray(); // return copy of messages
-        } finally { locker.ExitReadLock(); }
-      }
+    public IEnumerable<string> Messages {
+      get { return messages.ToArray(); }
+    }
+
+    [Storable(Name = "messages")]
+    private IEnumerable<string> StorableMessages {
+      get { return Messages; }
+      set { messages = new ConcurrentQueue<string>(value); }
+    }
+
+    [Storable]
+    private long maxMessageCount;
+    public long MaxMessageCount {
+      get { return maxMessageCount; }
     }
 
     [StorableConstructor]
     private ThreadSafeLog(bool deserializing) : base(deserializing) { }
-    public ThreadSafeLog(long maxMessageCount = -1)
-      : base(maxMessageCount) {
+    private ThreadSafeLog(ThreadSafeLog original, Cloner cloner)
+      : base(original, cloner) {
+      this.messages = new ConcurrentQueue<string>(original.messages);
+      this.maxMessageCount = original.maxMessageCount;
+    }
+    public ThreadSafeLog(long maxMessageCount = int.MaxValue) {
+      this.messages = new ConcurrentQueue<string>();
+      this.maxMessageCount = maxMessageCount;
     }
 
-    private ThreadSafeLog(ThreadSafeLog original, Cloner cloner)
-      : base(original, cloner) { }
-
     public override IDeepCloneable Clone(Cloner cloner) {
-      locker.EnterReadLock();
-      try {
-        return new ThreadSafeLog(this, cloner);
-      } finally { locker.ExitReadLock(); }
+      return new ThreadSafeLog(this, cloner);
     }
 
-    public override void Clear() {
-      locker.EnterWriteLock();
-      try {
-        messages.Clear();
-      } finally { locker.ExitWriteLock(); }
+    public void Clear() {
+      messages = new ConcurrentQueue<string>();
       OnCleared();
     }
 
-    public override void LogMessage(string message) {
-      string s = FormatLogMessage(message);
-      locker.EnterWriteLock();
-      try {
-        messages.Add(s);
-        CapMessages();
-      } finally { locker.ExitWriteLock(); }
+    public void LogMessage(string message) {
+      var s = Log.FormatLogMessage(message);
+      messages.Enqueue(s);
+      CapMessages();
       OnMessageAdded(s);
     }
 
-    public override void LogException(Exception ex) {
-      string s = FormatException(ex);
-      locker.EnterWriteLock();
-      try {
-        messages.Add(s);
-        CapMessages();
-      } finally { locker.ExitWriteLock(); }
+    public void LogException(Exception ex) {
+      var s = Log.FormatException(ex);
+      messages.Enqueue(s);
+      CapMessages();
       OnMessageAdded(s);
+    }
+
+    private readonly object capLock = new object();
+    private void CapMessages() {
+      lock (capLock) {
+        string s;
+        while (messages.Count > maxMessageCount)
+          if (!messages.TryDequeue(out s)) break;
+      }
+    }
+
+    public event EventHandler<EventArgs<string>> MessageAdded;
+    private void OnMessageAdded(string message) {
+      var handler = MessageAdded;
+      if (handler != null) handler(this, new EventArgs<string>(message));
+    }
+
+    public event EventHandler Cleared;
+    private void OnCleared() {
+      var handler = Cleared;
+      if (handler != null) handler(this, EventArgs.Empty);
     }
   }
