Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidator.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidator.java	(revision 5394)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidator.java	(revision 5395)
@@ -23,5 +23,5 @@
 import java.net.MalformedURLException;
 import java.net.URL;
-import java.util.Collections;
+import java.util.ArrayList;
 import java.util.LinkedHashSet;
 import java.util.LinkedList;
@@ -218,5 +218,6 @@
         final List<CMDIValidatorExtension> exts = config.getExtensions();
         if (exts != null) {
-            this.extensions = new LinkedList<CMDIValidatorExtension>();
+            this.extensions =
+                    new ArrayList<CMDIValidatorExtension>(exts.size());
             for (CMDIValidatorExtension extension : exts) {
                 extension.initalize(processor);
@@ -461,5 +462,5 @@
         private final XsltTransformer schematronValidator;
         private final DocumentBuilder builder;
-        private final ResultImpl result = new ResultImpl();
+        private CMDIValidatorWriteableResult result;
 
 
@@ -610,4 +611,5 @@
             TFileInputStream stream = null;
             try {
+
                 /*
                  * step 0: prepare
@@ -615,5 +617,5 @@
                 logger.debug("validating file '{}' ({} bytes)",
                         file, file.length());
-                result.setFile(file);
+                result = new CMDIValidatorWriteableResultImpl(file);
                 stream = new TFileInputStream(file);
 
@@ -654,12 +656,15 @@
                             "error closing file '" + file + "'", e);
                 } finally {
-                    if (handler != null) {
-                        if (result.isHighestSeverity(Severity.ERROR)) {
-                            handler.onValidationFailure(result);
-                        } else {
-                            handler.onValidationSuccess(result);
+                    if ((result != null) && (handler != null)) {
+                        try {
+                            if (result.isHighestSeverity(Severity.ERROR)) {
+                                handler.onValidationFailure(result);
+                            } else {
+                                handler.onValidationSuccess(result);
+                            }
+                        } finally {
+                            result = null;
                         }
                     }
-                    result.reset();
                 }
             }
@@ -1012,212 +1017,3 @@
     }  // class ShadowCacheGrammarPool
 
-
-    private static final class ResultImpl implements
-            CMDIValidatorWriteableResult {
-        private final List<Message> messages = new LinkedList<Message>();
-        private File file;
-        private Severity highestSeverity;
-
-
-        private ResultImpl() {
-            reset();
-        }
-
-
-        @Override
-        public File getFile() {
-            return file;
-        }
-
-
-        @Override
-        public Severity getHighestSeverity() {
-            return highestSeverity;
-        }
-
-
-        @Override
-        public boolean isHighestSeverity(Severity severity) {
-            if (severity == null) {
-                throw new NullPointerException("severity == null");
-            }
-            return this.highestSeverity.equals(severity);
-        }
-
-
-        @Override
-        public List<Message> getMessages() {
-            if (messages.isEmpty()) {
-                return Collections.emptyList();
-            } else {
-                return Collections.unmodifiableList(messages);
-            }
-        }
-
-
-        @Override
-        public Message getFirstMessage() {
-            return messages.isEmpty() ? null : messages.get(0);
-        }
-
-
-        @Override
-        public Message getFirstMessage(Severity severity) {
-            if (severity == null) {
-                throw new NullPointerException("severity == null");
-            }
-
-            if (!messages.isEmpty()) {
-                for (Message msg : messages) {
-                    if (severity.equals(msg.getSeverity())) {
-                        return msg;
-                    }
-                }
-            }
-            return null;
-        }
-
-
-        @Override
-        public int getMessageCount() {
-            return messages.size();
-        }
-
-
-        @Override
-        public int getMessageCount(Severity severity) {
-            if (severity == null) {
-                throw new NullPointerException("severity == null");
-            }
-
-            int count = 0;
-            if (!messages.isEmpty()) {
-                for (Message msg : messages) {
-                    if (severity.equals(msg.getSeverity())) {
-                        count++;
-                    }
-                }
-            }
-            return count;
-        }
-
-
-        @Override
-        public void reportInfo(int line, int col, String message) {
-            reportInfo(line, col, message, null);
-        }
-
-
-        @Override
-        public void reportInfo(int line, int col, String message,
-                Throwable cause) {
-            messages.add(new MessageImpl(Severity.INFO, line, col, message,
-                    cause));
-        }
-
-
-        @Override
-        public void reportWarning(int line, int col, String message) {
-            reportWarning(line, col, message, null);
-        }
-
-
-        @Override
-        public void reportWarning(int line, int col, String message,
-                Throwable cause) {
-            switch (highestSeverity) {
-            case WARNING:
-                /* FALL-THROUGH */
-            case ERROR:
-                break;
-            default:
-                highestSeverity = Severity.WARNING;
-            }
-            messages.add(new MessageImpl(Severity.WARNING, line, col, message,
-                    cause));
-        }
-
-
-        @Override
-        public void reportError(int line, int col, String message) {
-            reportError(line, col, message, null);
-        }
-
-
-        @Override
-        public void reportError(int line, int col, String message,
-                Throwable cause) {
-            switch (highestSeverity) {
-            case ERROR:
-                break;
-            default:
-                highestSeverity = Severity.ERROR;
-            }
-            messages.add(new MessageImpl(Severity.ERROR, line, col, message,
-                    cause));
-        }
-
-
-        private void setFile(File file) {
-            this.file = file;
-        }
-
-
-        private void reset() {
-            this.messages.clear();
-            this.file = null;
-            this.highestSeverity = Severity.INFO;
-        }
-    } // class ResultImpl
-
-
-    private static final class MessageImpl implements
-            CMDIValidatorResult.Message {
-        private final Severity severity;
-        private final int line;
-        private final int col;
-        private final String message;
-        private final Throwable cause;
-
-
-        private MessageImpl(Severity severity, int line, int col,
-                String message, Throwable cause) {
-            this.severity = severity;
-            this.line     = line;
-            this.col      = col;
-            this.message  = message;
-            this.cause    = cause;
-        }
-
-
-        @Override
-        public Severity getSeverity() {
-            return severity;
-        }
-
-
-        @Override
-        public int getLineNumber() {
-            return line;
-        }
-
-
-        @Override
-        public int getColumnNumber() {
-            return col;
-        }
-
-
-        @Override
-        public String getMessage() {
-            return message;
-        }
-
-
-        @Override
-        public Throwable getCause() {
-            return cause;
-        }
-    } // class MessageImpl
-
 } // class CMDIValidator
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorConfig.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorConfig.java	(revision 5394)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorConfig.java	(revision 5395)
@@ -19,6 +19,6 @@
 import java.io.File;
 import java.io.FileFilter;
+import java.util.ArrayList;
 import java.util.Collections;
-import java.util.LinkedList;
 import java.util.List;
 
@@ -165,5 +165,5 @@
             }
             if (config.extensions == null) {
-                config.extensions = new LinkedList<CMDIValidatorExtension>();
+                config.extensions = new ArrayList<CMDIValidatorExtension>();
             }
             config.extensions.add(extension);
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorResult.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorResult.java	(revision 5394)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorResult.java	(revision 5395)
@@ -28,4 +28,9 @@
                 return "I";
             }
+
+            @Override
+            public int priority() {
+                return 1;
+            }
         },
         WARNING {
@@ -33,4 +38,9 @@
             public String getShortcut() {
                 return "W";
+            }
+
+            @Override
+            public int priority() {
+                return 2;
             }
         },
@@ -40,7 +50,15 @@
                 return "E";
             }
+
+            @Override
+            public int priority() {
+                return 3;
+            }
         };
 
         public abstract String getShortcut();
+
+
+        public abstract int priority();
     } // enum Severity
 
Index: CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorWriteableResultImpl.java
===================================================================
--- CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorWriteableResultImpl.java	(revision 5395)
+++ CMDIValidator/trunk/cmdi-validator-core/src/main/java/eu/clarin/cmdi/validator/CMDIValidatorWriteableResultImpl.java	(revision 5395)
@@ -0,0 +1,200 @@
+package eu.clarin.cmdi.validator;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+final class CMDIValidatorWriteableResultImpl implements CMDIValidatorWriteableResult {
+    private final File file;
+    private List<Message> messages;
+    private Severity highestSeverity = Severity.INFO;
+
+
+    CMDIValidatorWriteableResultImpl(File file) {
+        this.file = file;
+    }
+
+
+    @Override
+    public File getFile() {
+        return file;
+    }
+
+
+    @Override
+    public Severity getHighestSeverity() {
+        return highestSeverity;
+    }
+
+
+    @Override
+    public boolean isHighestSeverity(Severity severity) {
+        if (severity == null) {
+            throw new NullPointerException("severity == null");
+        }
+        return highestSeverity.equals(severity);
+    }
+
+
+    @Override
+    public List<Message> getMessages() {
+        if (messages == null) {
+            return Collections.emptyList();
+        } else {
+            return Collections.unmodifiableList(messages);
+        }
+    }
+
+
+    @Override
+    public Message getFirstMessage() {
+        return (messages != null) ? null : messages.get(0);
+    }
+
+
+    @Override
+    public Message getFirstMessage(Severity severity) {
+        if (severity == null) {
+            throw new NullPointerException("severity == null");
+        }
+
+        if (messages != null) {
+            for (Message msg : messages) {
+                if (severity.equals(msg.getSeverity())) {
+                    return msg;
+                }
+            }
+        }
+        return null;
+    }
+
+
+    @Override
+    public int getMessageCount() {
+        return (messages != null) ? messages.size() : 0;
+    }
+
+
+    @Override
+    public int getMessageCount(Severity severity) {
+        if (severity == null) {
+            throw new NullPointerException("severity == null");
+        }
+
+        int count = 0;
+        if (messages != null) {
+            for (Message msg : messages) {
+                if (severity.equals(msg.getSeverity())) {
+                    count++;
+                }
+            }
+        }
+        return count;
+    }
+
+
+    @Override
+    public void reportInfo(int line, int col, String message) {
+        reportInfo(line, col, message, null);
+    }
+
+
+    @Override
+    public void reportInfo(int line, int col, String message,
+            Throwable cause) {
+        addMessage(Severity.INFO, line, col, message, cause);
+    }
+
+
+    @Override
+    public void reportWarning(int line, int col, String message) {
+        reportWarning(line, col, message, null);
+    }
+
+
+    @Override
+    public void reportWarning(int line, int col, String message,
+            Throwable cause) {
+        addMessage(Severity.WARNING, line, col, message, cause);
+    }
+
+
+    @Override
+    public void reportError(int line, int col, String message) {
+        reportError(line, col, message, null);
+    }
+
+
+    @Override
+    public void reportError(int line, int col, String message,
+            Throwable cause) {
+        addMessage(Severity.ERROR, line, col, message, cause);
+    }
+
+
+    private void addMessage(final Severity severity,
+            final int line,
+            final int col,
+            final String message,
+            final Throwable cause) {
+        if (messages == null) {
+            messages = new ArrayList<Message>(8);
+        }
+        if (severity.priority() > highestSeverity.priority()) {
+            highestSeverity = severity;
+        }
+        messages.add(new MessageImpl(severity, line, col, message, cause));
+    }
+
+
+    private static final class MessageImpl implements
+            CMDIValidatorResult.Message {
+        private final Severity severity;
+        private final int line;
+        private final int col;
+        private final String message;
+        private final Throwable cause;
+
+
+        private MessageImpl(Severity severity, int line, int col,
+                String message, Throwable cause) {
+            this.severity = severity;
+            this.line = line;
+            this.col = col;
+            this.message = message;
+            this.cause = cause;
+        }
+
+
+        @Override
+        public Severity getSeverity() {
+            return severity;
+        }
+
+
+        @Override
+        public int getLineNumber() {
+            return line;
+        }
+
+
+        @Override
+        public int getColumnNumber() {
+            return col;
+        }
+
+
+        @Override
+        public String getMessage() {
+            return message;
+        }
+
+
+        @Override
+        public Throwable getCause() {
+            return cause;
+        }
+    } // class MessageImpl
+
+} // class CMDIValidatorWriteableResultImpl
