diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/concurrent/MessageChannel.java b/common/sourceTest/java/ch/systemsx/cisd/common/concurrent/MessageChannel.java
index 6bdf0999a2d2932d53626dfb69fe5734202abd6b..559b60e72f94b673a4655c23850a6c3937962fb9 100644
--- a/common/sourceTest/java/ch/systemsx/cisd/common/concurrent/MessageChannel.java
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/concurrent/MessageChannel.java
@@ -23,6 +23,9 @@ import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 
+import ch.systemsx.cisd.common.logging.ISimpleLogger;
+import ch.systemsx.cisd.common.logging.LogLevel;
+
 /**
  * Message channel for controlling multiple threads in unit testing. The channel is a
  * {@link BlockingQueue}.
@@ -34,6 +37,10 @@ public class MessageChannel
     private final BlockingQueue<Object> _queue;
 
     private final long _timeOutInMilliSeconds;
+    
+    private String name = "?";
+    
+    private ISimpleLogger logger;
 
     /**
      * Creates an instance with time out 1 second.
@@ -52,6 +59,22 @@ public class MessageChannel
         _queue = new LinkedBlockingQueue<Object>();
     }
 
+    /**
+     * Sets the name of this channel. Will be used if logging is enabled.
+     */
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    /**
+     * Sets an optional logger which log sending and receiving messages.
+     */
+    public void setLogger(ISimpleLogger logger)
+    {
+        this.logger = logger;
+    }
+
     /**
      * Sends specified message. <code>null</code> are not allowed.
      */
@@ -62,6 +85,15 @@ public class MessageChannel
             throw new IllegalArgumentException("Null message not allowed.");
         }
         _queue.offer(message);
+        log("Message '" + message + "' has been sent.");
+    }
+    
+    private void log(String message)
+    {
+        if (logger != null)
+        {
+            logger.log(LogLevel.INFO, "MessageChannel[" + name + "]: " + message);
+        }
     }
 
     /**
@@ -72,14 +104,26 @@ public class MessageChannel
     {
         try
         {
-            assertEquals(expectedMessage,
-                    _queue.poll(_timeOutInMilliSeconds, TimeUnit.MILLISECONDS));
+            assertEquals(expectedMessage, receivesMessage());
         } catch (InterruptedException e)
         {
             // ignored
         }
     }
 
+    private Object receivesMessage() throws InterruptedException
+    {
+        Object message = _queue.poll(_timeOutInMilliSeconds, TimeUnit.MILLISECONDS);
+        if (message == null)
+        {
+            log("No message could be received. Timeout: " + _timeOutInMilliSeconds + " msec");
+        } else
+        {
+            log("Message '" + message + "' has been received.");
+        }
+        return message;
+    }
+
     /**
      * Asserts specified expected message is part of next message to be received. Waits not longer
      * than specified in the constructor.
@@ -88,7 +132,8 @@ public class MessageChannel
     {
         try
         {
-            assertTrue(_queue.poll(_timeOutInMilliSeconds, TimeUnit.MILLISECONDS).toString()
+            Object receivedMessage = receivesMessage();
+            assertTrue("Unexpected message: " + receivedMessage, receivedMessage.toString()
                     .contains(expectedMessagePart.toString()));
         } catch (InterruptedException e)
         {
diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/concurrent/MessageChannelBuilder.java b/common/sourceTest/java/ch/systemsx/cisd/common/concurrent/MessageChannelBuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..c6a0c94908e85b8ede3ff087d1cbbbe602dedee4
--- /dev/null
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/concurrent/MessageChannelBuilder.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2012 ETH Zuerich, CISD
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package ch.systemsx.cisd.common.concurrent;
+
+import org.apache.log4j.Logger;
+
+import ch.systemsx.cisd.common.logging.ISimpleLogger;
+import ch.systemsx.cisd.common.logging.Log4jSimpleLogger;
+
+/**
+ * Builder to build a {@link MessageChannel} object.
+ *
+ * @author Franz-Josef Elmer
+ */
+public class MessageChannelBuilder
+{
+    private final MessageChannel channel;
+    
+    public MessageChannelBuilder()
+    {
+        channel = new MessageChannel();
+    }
+    
+    public MessageChannelBuilder(long timeOutInMilliSeconds)
+    {
+        channel = new MessageChannel(timeOutInMilliSeconds);
+    }
+    
+    public MessageChannelBuilder name(String name)
+    {
+        channel.setName(name);
+        return this;
+    }
+    
+    public MessageChannelBuilder logger(ISimpleLogger logger)
+    {
+        channel.setLogger(logger);
+        return this;
+    }
+    
+    public MessageChannelBuilder logger(Logger logger)
+    {
+        return logger(new Log4jSimpleLogger(logger));
+    }
+    
+    public MessageChannel getChannel()
+    {
+        return channel;
+    }
+}