diff --git a/common/resource/dependency-structure.ddf b/common/resource/dependency-structure.ddf
index f0e4e57951078c1f359d4f59f5d7272ee035ef8a..947c4fda309310decff0c9a4347fe89fbabe36ae 100644
--- a/common/resource/dependency-structure.ddf
+++ b/common/resource/dependency-structure.ddf
@@ -1,9 +1,3 @@
-#
-#
-#
-
-#show allResults
-
 {package} = ch.systemsx.cisd.common
 
 [annotation] = ${package}.annotation.*
@@ -34,8 +28,13 @@ check sets [test]
 [utilities] = ${package}.utilities.*
 check sets [utilities]
 
+[user-failure-exception] = ${package}.exceptions.UserFailureException
+check sets [user-failure-exception]
+
 layer layer0 = [annotation] [exceptions] [logging] [test]
 layer layer1 = [utilities] 
 layer layer2 = [config] [db] [parser]
 
-check layeringOf layer0 layer1 layer2 
\ No newline at end of file
+check layeringOf layer0 layer1 layer2
+
+check [parser] independentOf [user-failure-exception] 
\ No newline at end of file
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/AbstractParserObjectFactory.java b/common/source/java/ch/systemsx/cisd/common/parser/AbstractParserObjectFactory.java
index 2fd5c5b13597a1ccc89e928c4347deb9a85d4cdf..7860db55ef1eccc3b65ded0972a6c3ee533940a0 100644
--- a/common/source/java/ch/systemsx/cisd/common/parser/AbstractParserObjectFactory.java
+++ b/common/source/java/ch/systemsx/cisd/common/parser/AbstractParserObjectFactory.java
@@ -19,8 +19,6 @@ package ch.systemsx.cisd.common.parser;
 import java.beans.PropertyDescriptor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
-import java.util.Collection;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
@@ -28,7 +26,6 @@ import java.util.Set;
 import ch.systemsx.cisd.common.converter.Converter;
 import ch.systemsx.cisd.common.converter.ConverterPool;
 import ch.systemsx.cisd.common.exceptions.CheckedExceptionTunnel;
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
 import ch.systemsx.cisd.common.utilities.BeanUtils;
 import ch.systemsx.cisd.common.utilities.ClassUtils;
 
@@ -57,7 +54,7 @@ public abstract class AbstractParserObjectFactory<E> implements IParserObjectFac
     /** The class of object bean we are going to create here. */
     private final Class<E> beanClass;
 
-    protected AbstractParserObjectFactory(Class<E> beanClass, IPropertyMapper propertyMapper)
+    protected AbstractParserObjectFactory(final Class<E> beanClass, final IPropertyMapper propertyMapper)
     {
         assert beanClass != null;
         assert propertyMapper != null;
@@ -81,7 +78,7 @@ public abstract class AbstractParserObjectFactory<E> implements IParserObjectFac
      * If given <var>converter</var>, then it will unregister it.
      * </p>
      */
-    protected final <T> void registerConverter(Class<T> clazz, Converter<T> converter)
+    protected final <T> void registerConverter(final Class<T> clazz, final Converter<T> converter)
     {
         if (converter == null)
         {
@@ -98,17 +95,11 @@ public abstract class AbstractParserObjectFactory<E> implements IParserObjectFac
     }
 
     /** For given property name returns corresponding <code>IPropertyModel</code>. */
-    private final IPropertyModel getPropertyModel(String name)
+    private final IPropertyModel getPropertyModel(final String name)
     {
         return propertyMapper.getProperty(name);
     }
 
-    /** Returns an unmodifiable list of <code>PropertyDescriptor</code>s. */
-    private final Collection<PropertyDescriptor> getPropertyDescriptors()
-    {
-        return Collections.unmodifiableCollection(propertyDescriptors.values());
-    }
-
     /**
      * Checks given <code>IPropertyMapper</code>.
      * <p>
@@ -116,46 +107,33 @@ public abstract class AbstractParserObjectFactory<E> implements IParserObjectFac
      * {@link #propertyDescriptors}.
      * </p>
      */
-    private final void checkPropertyMapper(Class<E> clazz, IPropertyMapper propMapper) throws UserFailureException
+    private final void checkPropertyMapper(final Class<E> clazz, final IPropertyMapper propMapper)
+            throws ParserException
     {
-        assert propertyDescriptors != null;
+        assert propertyDescriptors != null : "Property descriptors can not be null.";
 
-        Set<String> propertyNames = new HashSet<String>(propMapper.getAllPropertyNames());
-        propertyNames.removeAll(propertyDescriptors.keySet());
+        final Set<String> allPropertyNames = propMapper.getAllPropertyNames();
+        final Set<String> propertyNames = new HashSet<String>(allPropertyNames);
+        final Set<String> descriptorNames = propertyDescriptors.keySet();
+        propertyNames.removeAll(descriptorNames);
         if (propertyNames.size() > 0)
         {
-            throw UserFailureException.fromTemplate("The following header columns are not part of '%s': %s", clazz
-                    .getSimpleName(), format(propertyNames));
-        }
-    }
-
-    private final String format(Set<String> set)
-    {
-        final StringBuilder builder = new StringBuilder();
-        for (String s : set)
-        {
-            builder.append("'");
-            builder.append(s);
-            builder.append("', ");
+            throw new UnmatchedPropertiesException(clazz, allPropertyNames, descriptorNames, propertyNames);
         }
-        // Remove trailing ", "
-        builder.setLength(builder.length() - 2);
-        return builder.toString();
     }
 
     /** Whether given field name is mandatory. */
-    private final boolean isMandatory(String fieldName)
+    private final boolean isMandatory(final String fieldName)
     {
         return mandatoryFields.contains(fieldName);
     }
 
-    private String getPropertyValue(final String[] lineTokens, final IPropertyModel propertyModel)
+    private final String getPropertyValue(final String[] lineTokens, final IPropertyModel propertyModel)
     {
-        int column = propertyModel.getColumn();
+        final int column = propertyModel.getColumn();
         if (column >= lineTokens.length)
         {
-            throw UserFailureException.fromTemplate("Not enough tokens are available (index: %d, available: %d)",
-                    column, lineTokens.length);
+            throw new IndexOutOfBoundsException(column, lineTokens);
         }
         return lineTokens[column];
     }
@@ -164,13 +142,12 @@ public abstract class AbstractParserObjectFactory<E> implements IParserObjectFac
     // IParserObjectFactory
     //
 
-    @SuppressWarnings("unchecked")
-    public E createObject(String[] lineTokens)
+    public E createObject(final String[] lineTokens) throws ParserException
     {
         try
         {
-            Object object = beanClass.newInstance();
-            for (PropertyDescriptor descriptor : getPropertyDescriptors())
+            final E object = beanClass.newInstance();
+            for (final PropertyDescriptor descriptor : propertyDescriptors.values())
             {
                 final Method writeMethod = descriptor.getWriteMethod();
                 final IPropertyModel propertyModel = getPropertyModel(descriptor.getName());
@@ -185,11 +162,11 @@ public abstract class AbstractParserObjectFactory<E> implements IParserObjectFac
                     final String fieldName = descriptor.getName();
                     if (isMandatory(fieldName))
                     {
-                        throw UserFailureException.fromTemplate("Field/Property name '%s' is mandatory.", fieldName);
+                        throw new MandatoryPropertyMissingException(beanClass, fieldName);
                     }
                 }
             }
-            return (E) object;
+            return object;
         } catch (IllegalAccessException ex)
         {
             throw new CheckedExceptionTunnel(ex);
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/AlwaysAcceptLineFilter.java b/common/source/java/ch/systemsx/cisd/common/parser/AlwaysAcceptLineFilter.java
index ec6941724319f7080b453379d1a4b4c405a280d2..486f87e97e22cfacbb6db7fcdda40b0c5c2e4f0b 100644
--- a/common/source/java/ch/systemsx/cisd/common/parser/AlwaysAcceptLineFilter.java
+++ b/common/source/java/ch/systemsx/cisd/common/parser/AlwaysAcceptLineFilter.java
@@ -2,16 +2,22 @@ package ch.systemsx.cisd.common.parser;
 
 /**
  * A default line filter that accepts any line.
- *
+ * 
  * @author Christian Ribeaud
  */
 public final class AlwaysAcceptLineFilter implements ILineFilter
 {
     public static final ILineFilter INSTANCE = new AlwaysAcceptLineFilter();
-    
-    private AlwaysAcceptLineFilter() {}
-    
-    public final boolean acceptLine(String line, int lineNumber)
+
+    private AlwaysAcceptLineFilter()
+    {
+    }
+
+    //
+    // ILineFilter
+    //
+
+    public final boolean acceptLine(final String line, final int lineNumber)
     {
         return true;
     }
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/DefaultReaderParser.java b/common/source/java/ch/systemsx/cisd/common/parser/DefaultReaderParser.java
index 80db898cce11dc0256f50fe61500ac626f7fcdca..b4019c4623e70b2eb531cc59a32ac9872fb1a858 100644
--- a/common/source/java/ch/systemsx/cisd/common/parser/DefaultReaderParser.java
+++ b/common/source/java/ch/systemsx/cisd/common/parser/DefaultReaderParser.java
@@ -18,7 +18,6 @@ package ch.systemsx.cisd.common.parser;
 
 import java.io.Reader;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 
 import org.apache.commons.io.IOUtils;
@@ -44,12 +43,12 @@ public class DefaultReaderParser<E> implements IReaderParser<E>
         this(new DefaultLineTokenizer());
     }
 
-    public DefaultReaderParser(ILineTokenizer lineTokenizer)
+    public DefaultReaderParser(final ILineTokenizer lineTokenizer)
     {
         this.lineTokenizer = lineTokenizer;
     }
 
-    protected E createObject(String[] tokens)
+    protected E createObject(final String[] tokens) throws ParserException
     {
         return factory.createObject(tokens);
     }
@@ -60,7 +59,7 @@ public class DefaultReaderParser<E> implements IReaderParser<E>
      * Uses <code>ILineTokenizer</code> to do its job.
      * </p>
      */
-    protected String[] parseLine(int lineNumber, String line)
+    protected String[] parseLine(final int lineNumber, final String line)
     {
         return lineTokenizer.tokenize(line);
     }
@@ -69,32 +68,35 @@ public class DefaultReaderParser<E> implements IReaderParser<E>
     // Parser
     //
 
-    public final List<E> parse(Reader reader)
+    public final List<E> parse(final Reader reader)
     {
         return parse(reader, AlwaysAcceptLineFilter.INSTANCE);
     }
 
-    public final List<E> parse(Reader reader, ILineFilter lineFilter)
+    public final List<E> parse(final Reader reader, final ILineFilter lineFilter) throws ParsingException
     {
         final List<E> elements = new ArrayList<E>();
         synchronized (lineTokenizer)
         {
             lineTokenizer.init();
-            LineIterator lineIterator = IOUtils.lineIterator(reader);
+            final LineIterator lineIterator = IOUtils.lineIterator(reader);
             for (int lineNumber = 0; lineIterator.hasNext(); lineNumber++)
             {
-                String nextLine = lineIterator.nextLine();
+                final String nextLine = lineIterator.nextLine();
                 if (lineFilter.acceptLine(nextLine, lineNumber))
                 {
-                    String[] tokens = parseLine(lineNumber, nextLine);
-                    E object;
+                    final String[] tokens = parseLine(lineNumber, nextLine);
+                    E object = null;
                     try
                     {
                         object = createObject(tokens);
-                    } catch (RuntimeException ex)
+                    } catch (final ParserException parserException)
                     {
-                        throw new ParseException(String.format("Creating an object with following tokens '%s' failed.",
-                                Arrays.asList(tokens)), ex, lineNumber);
+                        throw new ParsingException(parserException, tokens, lineNumber);
+                    } catch (final RuntimeException runtimeException)
+                    {
+                        // This should not happen but...
+                        throw new ParsingException(runtimeException, tokens, lineNumber);
                     }
                     elements.add(object);
                 }
@@ -105,7 +107,7 @@ public class DefaultReaderParser<E> implements IReaderParser<E>
 
     }
 
-    public final void setObjectFactory(IParserObjectFactory<E> factory)
+    public final void setObjectFactory(final IParserObjectFactory<E> factory)
     {
         this.factory = factory;
     }
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/ExcludeEmptyAndCommentLineFilter.java b/common/source/java/ch/systemsx/cisd/common/parser/ExcludeEmptyAndCommentLineFilter.java
index b5b4820236b581b38437d6f853b9ac21145172ee..fc0498aaa583bcfd8d0dcb01ffe4625ebfef0d68 100644
--- a/common/source/java/ch/systemsx/cisd/common/parser/ExcludeEmptyAndCommentLineFilter.java
+++ b/common/source/java/ch/systemsx/cisd/common/parser/ExcludeEmptyAndCommentLineFilter.java
@@ -5,16 +5,22 @@ package ch.systemsx.cisd.common.parser;
  * <p>
  * A comment line starts with '#'.
  * </p>
- *
+ * 
  * @author Christian Ribeaud
  */
 public final class ExcludeEmptyAndCommentLineFilter implements ILineFilter
 {
     public static final ILineFilter INSTANCE = new ExcludeEmptyAndCommentLineFilter();
-    
-    private ExcludeEmptyAndCommentLineFilter() {}
-    
-    public final boolean acceptLine(String line, int lineNumber)
+
+    private ExcludeEmptyAndCommentLineFilter()
+    {
+    }
+
+    //
+    // ILineFilter
+    //
+
+    public final boolean acceptLine(final String line, final int lineNumber)
     {
         final String trimmed = line.trim();
         return trimmed.length() > 0 && trimmed.startsWith("#") == false;
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/IParserObjectFactory.java b/common/source/java/ch/systemsx/cisd/common/parser/IParserObjectFactory.java
index 785dcaa0124c10a2e37ba568f87f5276edb115ef..27eb3b269830b303f8ee23111efb08f5744cce1f 100644
--- a/common/source/java/ch/systemsx/cisd/common/parser/IParserObjectFactory.java
+++ b/common/source/java/ch/systemsx/cisd/common/parser/IParserObjectFactory.java
@@ -16,8 +16,6 @@
 
 package ch.systemsx.cisd.common.parser;
 
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
-
 /**
  * A <code>IParserObjectFactory</code> implementation knows how to deal with given line tokens and convert them into
  * an appropriate <code>Object</code>.
@@ -39,21 +37,22 @@ public interface IParserObjectFactory<E>
      * 
      * @author Christian Ribeaud
      */
-    public final static IParserObjectFactory<String[]> STRING_ARRAY_OBJECT_FACTORY = new IParserObjectFactory<String[]>()
-        {
+    public final static IParserObjectFactory<String[]> STRING_ARRAY_OBJECT_FACTORY =
+            new IParserObjectFactory<String[]>()
+                {
 
-            //
-            // IParserObjectFactory
-            //
+                    //
+                    // IParserObjectFactory
+                    //
 
-            public final String[] createObject(String[] lineTokens)
-            {
-                return lineTokens;
-            }
-        };
+                    public final String[] createObject(final String[] lineTokens) throws ParserException
+                    {
+                        return lineTokens;
+                    }
+                };
 
     /**
      * Parses given text line and returns an appropriate <i>Object</i>.
      */
-    public E createObject(String[] lineTokens) throws UserFailureException;
+    public E createObject(final String[] lineTokens) throws ParserException;
 }
\ No newline at end of file
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/IParserObjectFactoryFactory.java b/common/source/java/ch/systemsx/cisd/common/parser/IParserObjectFactoryFactory.java
index 176010b1456f738342573480c27e37904ac863b4..1a37e2db98018fa2f5da70fb109db3502573f8c9 100644
--- a/common/source/java/ch/systemsx/cisd/common/parser/IParserObjectFactoryFactory.java
+++ b/common/source/java/ch/systemsx/cisd/common/parser/IParserObjectFactoryFactory.java
@@ -26,5 +26,5 @@ public interface IParserObjectFactoryFactory<T>
     /**
      * Creates a new factory for the specified property mapper.
      */
-    public IParserObjectFactory<T> createFactory(final IAliasPropertyMapper propertyMapper);
+    public IParserObjectFactory<T> createFactory(final IAliasPropertyMapper propertyMapper) throws ParserException;
 }
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/IPropertyMapper.java b/common/source/java/ch/systemsx/cisd/common/parser/IPropertyMapper.java
index 1635e02198b0fbfe1592d4c91857a58de7443663..a07d1a7e65128462b1ba4c0d4aa0c5bd253f4242 100644
--- a/common/source/java/ch/systemsx/cisd/common/parser/IPropertyMapper.java
+++ b/common/source/java/ch/systemsx/cisd/common/parser/IPropertyMapper.java
@@ -27,7 +27,7 @@ public interface IPropertyMapper
 {
 
     /** Returns an <code>IPropertyModel</code> for a given property name. */
-    public IPropertyModel getProperty(String name);
+    public IPropertyModel getProperty(final String name);
 
     /**
      * Returns a set of all property names.
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/IReaderParser.java b/common/source/java/ch/systemsx/cisd/common/parser/IReaderParser.java
index 1a84b795b68345bffa4abe3c6de923175ba11482..65325b2538fcd92c97da2724b18712fb1dab2e65 100644
--- a/common/source/java/ch/systemsx/cisd/common/parser/IReaderParser.java
+++ b/common/source/java/ch/systemsx/cisd/common/parser/IReaderParser.java
@@ -38,7 +38,7 @@ public interface IReaderParser<E>
      * @param lineFilter you could define a filter for the lines found in given <code>reader</code>.
      * @return a <code>List</code> of elements.
      */
-    public List<E> parse(Reader reader, ILineFilter lineFilter);
+    public List<E> parse(final Reader reader, final ILineFilter lineFilter) throws ParsingException;
 
     /**
      * Parses given <code>Reader</code>. Encapsulates given <code>Reader</code> in a {@link BufferedReader} for
@@ -49,7 +49,7 @@ public interface IReaderParser<E>
      * 
      * @return a <code>List</code> of elements.
      */
-    public List<E> parse(Reader reader);
+    public List<E> parse(final Reader reader);
 
     /**
      * Sets the <code>IParserObjectFactory</code>.
@@ -57,5 +57,5 @@ public interface IReaderParser<E>
      * Typically, the given <code>factory</code> transforms a line into an element.
      * </p>
      */
-    public void setObjectFactory(IParserObjectFactory<E> factory);
+    public void setObjectFactory(final IParserObjectFactory<E> factory);
 }
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/IndexOutOfBoundsException.java b/common/source/java/ch/systemsx/cisd/common/parser/IndexOutOfBoundsException.java
new file mode 100644
index 0000000000000000000000000000000000000000..5f615b245a461991be80044ed5afe7383b7b35b5
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/parser/IndexOutOfBoundsException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007 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.parser;
+
+/**
+ * A <code>ParserException</code> extension which signalizes a lookup index outside of the currently available tokens.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class IndexOutOfBoundsException extends ParserException
+{
+
+    static final String MESSAGE_FORMAT = "Not enough tokens are available (index: %d, available: %d)";
+
+    private static final long serialVersionUID = 1L;
+
+    private final int column;
+
+    private final String[] lineTokens;
+
+    IndexOutOfBoundsException(final int column, final String[] lineTokens)
+    {
+        super(createMessage(column, lineTokens));
+        this.column = column;
+        this.lineTokens = lineTokens;
+    }
+
+    private final static String createMessage(final int index, final String[] lineTokens)
+    {
+        assert lineTokens != null : "Line tokens can not be null.";
+        return String.format(MESSAGE_FORMAT, index, lineTokens.length);
+    }
+
+    public final int getColumn()
+    {
+        return column;
+    }
+
+    public final String[] getLineTokens()
+    {
+        return lineTokens;
+    }
+
+}
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/MandatoryPropertyMissingException.java b/common/source/java/ch/systemsx/cisd/common/parser/MandatoryPropertyMissingException.java
new file mode 100644
index 0000000000000000000000000000000000000000..6560e3639e2c3f3a46d5bc52e4cab074fe932880
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/parser/MandatoryPropertyMissingException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2007 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.parser;
+
+/**
+ * A <code>ParserException</code> extension which signalizes missing of a mandatory property.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class MandatoryPropertyMissingException extends ParserException
+{
+
+    static final String MESSAGE_FORMAT = "Field/Property name '%s' is mandatory.";
+
+    private static final long serialVersionUID = 1L;
+
+    private final Class<?> beanClass;
+
+    private final String fieldName;
+
+    MandatoryPropertyMissingException(final Class<?> beanClass, final String fieldName)
+    {
+        super(createMessage(fieldName));
+        assert beanClass != null : "Bean class can not be null.";
+        this.beanClass = beanClass;
+        this.fieldName = fieldName;
+    }
+
+    private final static String createMessage(final String fieldName)
+    {
+        assert fieldName != null : "Field name can not be null.";
+        return String.format(MESSAGE_FORMAT, fieldName);
+    }
+
+    public final Class<?> getBeanClass()
+    {
+        return beanClass;
+    }
+
+    public final String getFieldName()
+    {
+        return fieldName;
+    }
+
+}
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/ParseException.java b/common/source/java/ch/systemsx/cisd/common/parser/ParserException.java
similarity index 62%
rename from common/source/java/ch/systemsx/cisd/common/parser/ParseException.java
rename to common/source/java/ch/systemsx/cisd/common/parser/ParserException.java
index f8aa5ea362ed7e7b5ecf5b52536cbc75638f3892..bfebad84f2d3082b0bdd61c6be81e80f07074182 100644
--- a/common/source/java/ch/systemsx/cisd/common/parser/ParseException.java
+++ b/common/source/java/ch/systemsx/cisd/common/parser/ParserException.java
@@ -16,31 +16,25 @@
 
 package ch.systemsx.cisd.common.parser;
 
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
+import ch.systemsx.cisd.common.exceptions.HighLevelException;
 
 /**
- * Signals that an error has been reached unexpectedly while parsing.
+ * A top level exception for the parser.
  * 
  * @author Christian Ribeaud
  */
-public final class ParseException extends UserFailureException
+public class ParserException extends HighLevelException
 {
 
     private static final long serialVersionUID = 1L;
 
-    private final int lineNumber;
-
-    public ParseException(String message, Throwable cause, int lineNumber)
+    public ParserException(final String message, final Throwable cause)
     {
         super(message, cause);
-        this.lineNumber = lineNumber;
     }
 
-    /**
-     * Returns the line where the error was found.
-     */
-    public final int getLineNumber()
+    public ParserException(final String message)
     {
-        return lineNumber;
+        super(message);
     }
 }
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/ParserUtilities.java b/common/source/java/ch/systemsx/cisd/common/parser/ParserUtilities.java
index d35ab1fceaa82f5899b73d4d5625f6f74e596d8b..14983891d65565bc7174572255e8024c81917ec5 100644
--- a/common/source/java/ch/systemsx/cisd/common/parser/ParserUtilities.java
+++ b/common/source/java/ch/systemsx/cisd/common/parser/ParserUtilities.java
@@ -72,7 +72,7 @@ public final class ParserUtilities
      */
     public final static Line getFirstAcceptedLine(final File file, final ILineFilter lineFilter)
     {
-        assert file != null && file.exists();
+        assert file != null && file.exists() : "Given file must not be null and must exist.";
         final ILineFilter filter = lineFilter == null ? AlwaysAcceptLineFilter.INSTANCE : lineFilter;
 
         LineIterator lineIterator = null;
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/ParsingException.java b/common/source/java/ch/systemsx/cisd/common/parser/ParsingException.java
new file mode 100644
index 0000000000000000000000000000000000000000..9c95acbd0df5867e28820a1133b7b101fd9fb05f
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/parser/ParsingException.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 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.parser;
+
+import java.util.Arrays;
+
+import ch.systemsx.cisd.common.exceptions.HighLevelException;
+
+/**
+ * Signals that an error has been reached unexpectedly while parsing.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class ParsingException extends HighLevelException
+{
+
+    static final String MESSAGE_FORMAT = "Creating an object with following tokens '%s' failed.";
+
+    private static final long serialVersionUID = 1L;
+
+    private final int lineNumber;
+
+    private final String[] tokens;
+
+    ParsingException(final RuntimeException cause, final String[] tokens, final int lineNumber)
+    {
+        super(createMessage(tokens), cause);
+        this.lineNumber = lineNumber;
+        this.tokens = tokens;
+    }
+
+    private final static String createMessage(final String[] tokens)
+    {
+        assert tokens != null : "Tokens can not be null.";
+        return String.format(MESSAGE_FORMAT, Arrays.asList(tokens));
+    }
+
+    /**
+     * Returns the line where the error was found.
+     */
+    public final int getLineNumber()
+    {
+        return lineNumber;
+    }
+
+    public final String[] getTokens()
+    {
+        return tokens;
+    }
+}
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/PropertiesParserObjectFactory.java b/common/source/java/ch/systemsx/cisd/common/parser/PropertiesParserObjectFactory.java
deleted file mode 100644
index 8553894ef4163f6f036c9af57b55579f061fd91f..0000000000000000000000000000000000000000
--- a/common/source/java/ch/systemsx/cisd/common/parser/PropertiesParserObjectFactory.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2007 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.parser;
-
-import java.util.Set;
-
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
-
-/**
- * Creates new object by setting its properties.
- * 
- * @author Tomasz Pylak on Oct 26, 2007
- */
-public class PropertiesParserObjectFactory<E> implements IParserObjectFactory<E>
-{
-    /** The <code>IPropertyMapper</code> implementation. */
-    private final IPropertyMapper propertyMapper;
-
-    private final IPropertyObjectFactory<E> objectFactory;
-
-    public PropertiesParserObjectFactory(IPropertyMapper propertyMapper, IPropertyObjectFactory<E> objectFactory)
-    {
-        this.propertyMapper = propertyMapper;
-        this.objectFactory = objectFactory;
-    }
-
-    public E createObject(String[] lineTokens) throws UserFailureException
-    {
-        IPropertiesSetter<E> setter = objectFactory.createObjectSetter();
-        Set<String> propertyNames = propertyMapper.getAllPropertyNames();
-        for (String name : propertyNames)
-        {
-            final IPropertyModel propertyModel = propertyMapper.getProperty(name);
-            String propertyValue = getPropertyValue(lineTokens, propertyModel);
-            setter.setProperty(name, propertyValue);
-        }
-        return setter.getConstructedObject();
-    }
-
-    private String getPropertyValue(final String[] lineTokens, final IPropertyModel propertyModel)
-    {
-        int column = propertyModel.getColumn();
-        if (column >= lineTokens.length)
-        {
-            String name = propertyModel.getName();
-            String mergedTokens = merge(lineTokens);
-            throw UserFailureException.fromTemplate("Value for column '%s' cannot be found in line '%s'", name,
-                    mergedTokens);
-        }
-        return lineTokens[column];
-    }
-
-    private static String merge(String[] lineTokens)
-    {
-        StringBuffer sb = new StringBuffer();
-        for (String col : lineTokens)
-        {
-            sb.append("<");
-            sb.append(col);
-            sb.append("> ");
-        }
-        return sb.toString();
-    }
-
-}
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/TabFileLoader.java b/common/source/java/ch/systemsx/cisd/common/parser/TabFileLoader.java
index 9e250e6a632ace4609cc0594540f834cd509186c..147d718c9acc50532988f6110486fa8b10837c19 100644
--- a/common/source/java/ch/systemsx/cisd/common/parser/TabFileLoader.java
+++ b/common/source/java/ch/systemsx/cisd/common/parser/TabFileLoader.java
@@ -51,23 +51,19 @@ public class TabFileLoader<T>
     /**
      * Loads from the specified tab file a list of objects of type <code>T</code>.
      * 
-     * @throws UserFailureException if the file does not exists, the header line with correct column bean attribute
-     *             names is missing, or a parsing error occurs.
-     * @throws EnvironmentFailureException if a IOException occured.
+     * @throws EnvironmentFailureException if a IOException occurred.
      */
-    public final List<T> load(final File file) throws UserFailureException
+    public List<T> load(final File file)
     {
-        // Just check whether the file exists. Lets <code>FileUtils</code> do the rest.
-        if (file.exists() == false)
-        {
-            throw new UserFailureException("Given file '" + file.getAbsolutePath() + "' does not exist.");
-        }
-        DefaultReaderParser<T> parser = new DefaultReaderParser<T>();
+        assert file != null : "Given file must not be null";
+        assert file.isFile() : "Given file '" + file.getAbsolutePath() + "' is not a file.";
+
+        final DefaultReaderParser<T> parser = new DefaultReaderParser<T>();
         final ParserUtilities.Line headerLine =
                 ParserUtilities.getFirstAcceptedLine(file, ExcludeEmptyAndCommentLineFilter.INSTANCE);
         if (headerLine == null)
         {
-            throw new UserFailureException("No header line found in file '" + file.getAbsolutePath() + "'.");
+            throw new IllegalArgumentException("No header line found in file '" + file.getAbsolutePath() + "'.");
         }
         final HeaderLineFilter lineFilter = new HeaderLineFilter(headerLine.number);
         final String[] tokens = StringUtils.split(headerLine.text, "\t");
@@ -82,15 +78,25 @@ public class TabFileLoader<T>
         } catch (IOException ex)
         {
             throw new EnvironmentFailureException(ex.getMessage());
-        } catch (ParseException ex)
+        } catch (final ParsingException ex)
         {
-            throw UserFailureException.fromTemplate("A problem has occurred while parsing line %d of file '%s' [%s].",
-                    ex.getLineNumber(), file, ex.getCause().getMessage());
+            throwParsingException(ex, file);
+            throw new AssertionError("We should never reach this point.");
         } finally
         {
             IOUtils.closeQuietly(reader);
         }
+    }
 
+    /**
+     * Throws given <var>ex</var> or translates it into another kind of exception.
+     * <p>
+     * Default behavior just throws it.
+     * </p>
+     */
+    protected void throwParsingException(final ParsingException parsingException, final File file)
+    {
+        throw parsingException;
     }
 
     /**
@@ -109,8 +115,8 @@ public class TabFileLoader<T>
         {
             if (unique.add(token.toLowerCase()) == false)
             {
-                throw UserFailureException.fromTemplate("Duplicated column name '%s'.", token);
+                throw new IllegalArgumentException(String.format("Duplicated column name '%s'.", token));
             }
         }
     }
-}
+}
\ No newline at end of file
diff --git a/common/source/java/ch/systemsx/cisd/common/parser/UnmatchedPropertiesException.java b/common/source/java/ch/systemsx/cisd/common/parser/UnmatchedPropertiesException.java
new file mode 100644
index 0000000000000000000000000000000000000000..5b94959bebd81088e661879ed8f686030172337a
--- /dev/null
+++ b/common/source/java/ch/systemsx/cisd/common/parser/UnmatchedPropertiesException.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2007 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.parser;
+
+import java.util.Collections;
+import java.util.Set;
+
+/**
+ * A <code>ParserException</code> extension which signalizes unmatched properties.
+ * 
+ * @author Christian Ribeaud
+ */
+public final class UnmatchedPropertiesException extends ParserException
+{
+
+    static final String MESSAGE_FORMAT = "The following header columns are not part of '%s': %s";
+
+    private static final long serialVersionUID = 1L;
+
+    /** The bean this is set during the parsing process. */
+    private final Class<?> beanClass;
+
+    /** The property names found in the parsed file. */
+    private final Set<String> allPropertyNames;
+
+    /** The property names found in the bean. */
+    private final Set<String> descriptorNames;
+
+    /** The difference of {@link #allPropertyNames} minus {@link #descriptorNames}. */
+    private final Set<String> propertyNames;
+
+    UnmatchedPropertiesException(final Class<?> beanClass, final Set<String> allPropertyNames,
+            final Set<String> descriptorNames, final Set<String> propertyNames)
+    {
+        super(createMessage(beanClass, propertyNames));
+        assert allPropertyNames != null : "All property names can not be null.";
+        assert descriptorNames != null : "Descriptor names can not be null.";
+        this.beanClass = beanClass;
+        this.allPropertyNames = allPropertyNames;
+        this.descriptorNames = descriptorNames;
+        this.propertyNames = propertyNames;
+    }
+
+    private final static String createMessage(final Class<?> beanClass, final Set<String> propertyNames)
+    {
+        assert beanClass != null : "Bean class can not be null.";
+        assert propertyNames != null : "Property names can not be null.";
+        assert propertyNames.size() > 0 : "There is no reason to throw this exception.";
+        return String.format(MESSAGE_FORMAT, beanClass.getSimpleName(), format(propertyNames));
+    }
+
+    private final static String format(final Set<String> set)
+    {
+        final StringBuilder builder = new StringBuilder();
+        for (String s : set)
+        {
+            builder.append("'");
+            builder.append(s);
+            builder.append("', ");
+        }
+        // Remove trailing ", "
+        builder.setLength(builder.length() - 2);
+        return builder.toString();
+    }
+
+    public final Class<?> getBeanClass()
+    {
+        return beanClass;
+    }
+
+    public final Set<String> getAllPropertyNames()
+    {
+        return allPropertyNames;
+    }
+
+    public final Set<String> getDescriptorNames()
+    {
+        return Collections.unmodifiableSet(descriptorNames);
+    }
+
+    public final Set<String> getPropertyNames()
+    {
+        return propertyNames;
+    }
+
+}
diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/parser/AbstractParserObjectFactoryTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/parser/AbstractParserObjectFactoryTest.java
index 23616d625a2813d3fbf91f9ff7fabcd23d297e74..2a90ef6f777258db1c4783ce27eb1f7ae9a7b873 100644
--- a/common/sourceTest/java/ch/systemsx/cisd/common/parser/AbstractParserObjectFactoryTest.java
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/parser/AbstractParserObjectFactoryTest.java
@@ -23,7 +23,6 @@ import org.apache.commons.lang.ArrayUtils;
 import org.testng.annotations.Test;
 
 import ch.systemsx.cisd.common.annotation.Mandatory;
-import ch.systemsx.cisd.common.exceptions.UserFailureException;
 
 /**
  * Test cases for corresponding {@link AbstractParserObjectFactory} class.
@@ -67,9 +66,10 @@ public final class AbstractParserObjectFactoryTest
         {
             new BeanFactory(Bean.class, propertyMapper);
             fail("Following properties '[isnotin]' are not part of 'Bean'.");
-        } catch (UserFailureException ex)
+        } catch (UnmatchedPropertiesException ex)
         {
-            assertEquals("The following header columns are not part of 'Bean': 'isnotin'", ex.getMessage());
+            assertEquals(String.format(UnmatchedPropertiesException.MESSAGE_FORMAT, "Bean", "'isnotin'"), ex
+                    .getMessage());
         }
     }
 
@@ -85,9 +85,9 @@ public final class AbstractParserObjectFactoryTest
                 { "1. experiment" };
             beanFactory.createObject(lineTokens);
             fail("Field/Property name 'name' is mandatory.");
-        } catch (UserFailureException ex)
+        } catch (MandatoryPropertyMissingException ex)
         {
-            assertEquals("Field/Property name 'name' is mandatory.", ex.getMessage());
+            assertEquals(String.format(MandatoryPropertyMissingException.MESSAGE_FORMAT, "name"), ex.getMessage());
         }
     }
 
@@ -108,12 +108,12 @@ public final class AbstractParserObjectFactoryTest
         BeanFactory beanFactory = new BeanFactory(Bean.class, propertyMapper);
         String[] defaultTokens = createDefaultLineTokens();
         String[] lineTokens = (String[]) ArrayUtils.remove(defaultTokens, defaultTokens.length - 1);
-        String msg = String.format("Not enough tokens are available (index: 2, available: 2)", 5, lineTokens.length);
+        String msg = String.format(IndexOutOfBoundsException.MESSAGE_FORMAT, 2, lineTokens.length);
         try
         {
             beanFactory.createObject(lineTokens);
             fail(msg);
-        } catch (UserFailureException ex)
+        } catch (IndexOutOfBoundsException ex)
         {
             assertEquals(msg, ex.getMessage());
         }
diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/parser/DefaultReaderParserTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/parser/DefaultReaderParserTest.java
index 55636f55f3682ff2c6345e9b9cd7b88738e03d45..afb4717ea3ff2e1d9c946b7bf3f07b463b11c216 100644
--- a/common/sourceTest/java/ch/systemsx/cisd/common/parser/DefaultReaderParserTest.java
+++ b/common/sourceTest/java/ch/systemsx/cisd/common/parser/DefaultReaderParserTest.java
@@ -83,7 +83,7 @@ public final class DefaultReaderParserTest
         try
         {
             parser.parse(reader, new HeaderLineFilter(2));
-        } catch (ParseException ex)
+        } catch (ParsingException ex)
         {
             assertEquals(
                     "Creating an object with following tokens '[Christian, Ribeaud, Kapfrain 2/2, Efringen-Kirchen]' failed.",