diff --git a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/AnyLNValidator.java b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/AnyLNValidator.java
index 5534900a9b43179ca7519c8ce33773cdef2d1dfa..0dc3cd0b69ec9bec5ffae221c5f0bb91b5a865d1 100644
--- a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/AnyLNValidator.java
+++ b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/AnyLNValidator.java
@@ -20,6 +20,11 @@ package fr.centralesupelec.edf.riseclipse.iec61850.scl.validator;
 
 import java.util.HashMap;
 import java.util.HashSet;
+
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.DiagnosticChain;
+
 import fr.centralesupelec.edf.riseclipse.iec61850.nsd.AbstractLNClass;
 import fr.centralesupelec.edf.riseclipse.iec61850.nsd.DataObject;
 import fr.centralesupelec.edf.riseclipse.iec61850.nsd.LNClass;
@@ -60,78 +65,103 @@ public class AnyLNValidator {
         }
     }
 
-    public boolean validateLN( AnyLN ln ) {
+    public boolean validateLN( AnyLN ln, DiagnosticChain diagnostics ) {
+        boolean res = true;
+
         HashSet< String > checkedDO = new HashSet<>();
 
         for( DOI doi : ln.getDOI() ) {
             AbstractRiseClipseConsole.getConsole().verbose( "validateDOI( " + doi.getName() + " )" );
 
             // Test if DOI is a possible DOI in this LN
-            if( !this.doMap.containsKey( doi.getName() ) ) {
-                AbstractRiseClipseConsole.getConsole()
-                        .error( "DO " + doi.getName() + " not found in LNClass " + ln.getLnClass() );
-                return false;
+            if( ! this.doMap.containsKey( doi.getName() ) ) {
+                diagnostics.add( new BasicDiagnostic(
+                        Diagnostic.ERROR,
+                        RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                        0,
+                        "DO " + doi.getName() + " not found in LNClass " + ln.getLnClass(),
+                        new Object[] { ln } ));
+                continue;
             }
 
             // Control of DOI presence in LN  
             String presCond = this.doMap.get( doi.getName() ).getPresCond();
-            this.updateCompulsory( doi.getName(), presCond, checkedDO );
+            this.updateCompulsory( doi, presCond, checkedDO, diagnostics );
 
             // Validation of DOI content
-            if( ! validateDOI( doi ) ) {
-                return false;
+            if( ! validateDOI( doi, diagnostics ) ) {
+                res = false;
             }
 
         }
 
         // Verify all necessary DOI were present
-        if( !this.doMap.entrySet().stream()
-                .map( x -> checkCompulsory( x.getKey(), x.getValue().getPresCond(), checkedDO ))
+        if( ! this.doMap.entrySet().stream()
+                .map( x -> checkCompulsory( ln, x.getKey(), x.getValue().getPresCond(), checkedDO, diagnostics ))
                 .reduce( ( a, b ) -> a && b ).get() ) {
-            AbstractRiseClipseConsole.getConsole()
-                    .error( "LN does not contain all mandatory DO from class " + ln.getLnClass() );
-            return false;
+            diagnostics.add( new BasicDiagnostic(
+                    Diagnostic.ERROR,
+                    RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                    0,
+                    "LN does not contain all mandatory DO from class " + ln.getLnClass(),
+                    new Object[] { ln } ));
+            res = false;
         }
-        return true;
+        return res;
     }
 
-    public boolean checkCompulsory( String name, String presCond, HashSet< String > checked ) {
+    public boolean checkCompulsory( AnyLN ln, String name, String presCond, HashSet< String > checkedDO, DiagnosticChain diagnostics ) {
         switch( presCond ) {
         case "M":
-            if( ! checked.contains( name ) ) {
-                AbstractRiseClipseConsole.getConsole().error( "DO " + name + " is missing" );
+            if( ! checkedDO.contains( name ) ) {
+                diagnostics.add( new BasicDiagnostic(
+                        Diagnostic.ERROR,
+                        RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                        0,
+                        "DO " + name + " is missing",
+                        new Object[] { ln } ));
                 return false;
             }
         }
         return true;
     }
 
-    public boolean updateCompulsory( String name, String presCond, HashSet< String > checked ) {
+    public boolean updateCompulsory( DOI doi, String presCond, HashSet< String > checkedDO, DiagnosticChain diagnostics ) {
         switch( presCond ) {
         case "M":
         case "O":
-            if( checked.contains( name )) {
-                AbstractRiseClipseConsole.getConsole().error( "DO " + name + " cannot appear more than once" );
+            if( checkedDO.contains( doi.getName() )) {
+                diagnostics.add( new BasicDiagnostic(
+                        Diagnostic.ERROR,
+                        RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                        0,
+                        "DO " + doi + " cannot appear more than once",
+                        new Object[] { doi } ));
                 return false;
             }
             else {
-                checked.add( name );
+                checkedDO.add( doi.getName() );
                 break;
             }
         case "F":
-            AbstractRiseClipseConsole.getConsole().error( "DO " + name + " is forbidden" );
+            diagnostics.add( new BasicDiagnostic(
+                    Diagnostic.ERROR,
+                    RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                    0,
+                    "DO " + doi + " is forbidden",
+                    new Object[] { doi } ));
             return false;
         }
         return true;
     }
 
-    public boolean validateDOI( DOI doi ) {
+    public boolean validateDOI( DOI doi, DiagnosticChain diagnostics ) {
 
         AbstractRiseClipseConsole.getConsole().verbose( "found DO " + doi.getName() + " in LNClass " + this.lnClass );
 
         // DOIValidator validates DOI content
         String cdc = this.doMap.get( doi.getName() ).getRefersToCDC().getName();
-        return cdcMap.get( cdc ).validateDOI( doi );
+        return cdcMap.get( cdc ).validateDOI( doi, diagnostics );
     }
 
 }
diff --git a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/DOIValidator.java b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/DOIValidator.java
index a8820c45bd779bdd2e261d6206e7332c9046d973..9b17fba0a2cecceb36c4d18e73f9d6be5ec93a50 100644
--- a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/DOIValidator.java
+++ b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/DOIValidator.java
@@ -20,6 +20,11 @@ package fr.centralesupelec.edf.riseclipse.iec61850.scl.validator;
 
 import java.util.HashMap;
 import java.util.HashSet;
+
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
+import org.eclipse.emf.common.util.DiagnosticChain;
+
 import fr.centralesupelec.edf.riseclipse.iec61850.nsd.CDC;
 import fr.centralesupelec.edf.riseclipse.iec61850.nsd.DataAttribute;
 import fr.centralesupelec.edf.riseclipse.iec61850.scl.DAI;
@@ -40,7 +45,8 @@ public class DOIValidator {
         }
     }
 
-    public boolean validateDOI( DOI doi ) {
+    public boolean validateDOI( DOI doi, DiagnosticChain diagnostics ) {
+        boolean res = true;
         HashSet< String > checkedDA = new HashSet<>();
 
         for( DAI dai : doi.getDAI() ) {
@@ -48,62 +54,87 @@ public class DOIValidator {
 
             // Test if DAI is a possible DAI in this DOI
             if( ! this.daMap.containsKey( dai.getName() ) ) {
-                AbstractRiseClipseConsole.getConsole().error( "DA " + dai.getName() + " not found in CDC " + this.cdc );
-                return false;
+                diagnostics.add( new BasicDiagnostic(
+                        Diagnostic.ERROR,
+                        RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                        0,
+                        "DA " + dai.getName() + " not found in CDC",
+                        new Object[] { doi, cdc } ));
+                res = false;
+                continue;
             }
 
             // Control of DAI presence in DOI
-            String presCond = this.daMap.get( dai.getName() ).getPresCond();
-            this.updateCompulsory( dai.getName(), presCond, checkedDA );
+            this.updateCompulsory( dai, checkedDA, diagnostics );
 
             // Validation of DAI content
-            if( ! validateDAI( dai ) ) {
-                return false;
+            if( ! validateDAI( dai, diagnostics ) ) {
+                res = false;
             }
 
         }
 
         // Verify all necessary DAI were present
-        if( ! this.daMap.entrySet().stream()
-                .map( x -> checkCompulsory( x.getKey(), x.getValue().getPresCond(), checkedDA ) )
+        if( ! this.daMap.values().stream()
+                .map( x -> checkCompulsory( x, checkedDA, diagnostics ) )
                 .reduce( ( a, b ) -> a && b ).get() ) {
-            AbstractRiseClipseConsole.getConsole().error( "DO does not contain all mandatory DA from CDC " + this.cdc );
-            return false;
+            diagnostics.add( new BasicDiagnostic(
+                    Diagnostic.ERROR,
+                    RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                    0,
+                    "DO does not contain all mandatory DA from CDC ",
+                    new Object[] { doi, cdc } ));
+            res = false;
         }
-        return true;
+        return res;
     }
 
-    public boolean checkCompulsory( String name, String presCond, HashSet< String > checked ) {
-        switch( presCond ) {
+    public boolean checkCompulsory( DataAttribute da, HashSet< String > checked, DiagnosticChain diagnostics ) {
+        switch( da.getPresCond() ) {
         case "M":
-            if( !checked.contains( name ) ) {
-                AbstractRiseClipseConsole.getConsole().error( "DA " + name + " is missing" );
+            if( ! checked.contains( da.getName() )) {
+                diagnostics.add( new BasicDiagnostic(
+                        Diagnostic.ERROR,
+                        RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                        0,
+                        "DA " + da.getName() + " not found in CDC",
+                        new Object[] { da } ));
                 return false;
             }
         }
         return true;
     }
 
-    public boolean updateCompulsory( String name, String presCond, HashSet< String > checked ) {
-        switch( presCond ) {
+    public boolean updateCompulsory( DAI dai, HashSet< String > checked, DiagnosticChain diagnostics ) {
+        switch( this.daMap.get( dai.getName() ).getPresCond() ) {
         case "M":
         case "O":
-            if( checked.contains( name ) ) {
-                AbstractRiseClipseConsole.getConsole().error( "DA " + name + " cannot appear more than once" );
+            if( checked.contains( dai.getName() ) ) {
+                diagnostics.add( new BasicDiagnostic(
+                        Diagnostic.ERROR,
+                        RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                        0,
+                        "DA " + dai.getName() + " cannot appear more than once",
+                        new Object[] { dai } ));
                 return false;
             }
             else {
-                checked.add( name );
+                checked.add( dai.getName() );
                 break;
             }
         case "F":
-            AbstractRiseClipseConsole.getConsole().error( "DA " + name + " is forbidden" );
+            diagnostics.add( new BasicDiagnostic(
+                    Diagnostic.ERROR,
+                    RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                    0,
+                    "DA " + dai.getName() + " is forbidden",
+                    new Object[] { dai } ));
             return false;
         }
         return true;
     }
 
-    public boolean validateDAI( DAI dai ) {
+    public boolean validateDAI( DAI dai, DiagnosticChain diagnostics ) {
 
         AbstractRiseClipseConsole.getConsole().verbose( "found DA " + dai.getName() + " in CDC " + this.cdc );
 
@@ -111,10 +142,14 @@ public class DOIValidator {
         DataAttribute da = this.daMap.get( dai.getName() );
         if( da.getTypeKind().getName().equals( "BASIC" ) ) {
             for( Val val : dai.getVal() ) {
-                if( ! validateVal( val.getValue(), da.getType() ) ) {
-                    AbstractRiseClipseConsole.getConsole().error( "Val " + val.getValue() + " of DA " + dai.getName() +
-                            " is not of type " + da.getType() );
-                    return false;
+                if( ! validateVal( val.getValue(), da.getType() )) {
+                    diagnostics.add( new BasicDiagnostic(
+                            Diagnostic.ERROR,
+                            RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                            0,
+                            "Val " + val.getValue() + " of DA " + dai.getName() + " is not of type " + da.getType(),
+                            new Object[] { dai, val } ));
+                     return false;
                 }
                 AbstractRiseClipseConsole.getConsole().verbose( "Val " + val.getValue() + " of DA " + dai.getName() +
                         " is of type " + da.getType() );
diff --git a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NsdEObjectValidator.java b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NsdEObjectValidator.java
index 712346692c1a3a881b9a27eb22fa68736f86fd57..6f1c803483866dfaeb26c97fd301254eaca5ff88 100644
--- a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NsdEObjectValidator.java
+++ b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/NsdEObjectValidator.java
@@ -20,6 +20,9 @@ package fr.centralesupelec.edf.riseclipse.iec61850.scl.validator;
 
 import java.util.HashMap;
 import java.util.Map;
+
+import org.eclipse.emf.common.util.BasicDiagnostic;
+import org.eclipse.emf.common.util.Diagnostic;
 import org.eclipse.emf.common.util.DiagnosticChain;
 import org.eclipse.emf.ecore.EClass;
 import org.eclipse.emf.ecore.EDataType;
@@ -50,7 +53,7 @@ public class NsdEObjectValidator implements EValidator {
 
     private HashMap< String, AnyLNValidator > generateValidators( LNClass lnClass ) {
         HashMap< String, AnyLNValidator > lnMap = new HashMap<>();
-        lnMap.put( lnClass.getName(), new AnyLNValidator( lnClass ) );
+        lnMap.put( lnClass.getName(), new AnyLNValidator( lnClass ));
         return lnMap;
     }
 
@@ -70,34 +73,40 @@ public class NsdEObjectValidator implements EValidator {
         case "LN0":
         case "LN":
             AnyLN ln = ( AnyLN ) eObject;
-            return validateLN( ln );
+            return validateLN( ln, diagnostics );
         default:
+            AbstractRiseClipseConsole.getConsole().info( "NOT IMPLEMENTED: NSDEObjectValidator.validate( " + eClass.getName() + " )" );
             return false;
         }
     }
 
     @Override
     public boolean validate( EDataType eDataType, Object value, DiagnosticChain diagnostics, Map< Object, Object > context ) {
-        AbstractRiseClipseConsole.getConsole().info( "NOT IMPLEMENTED: NSDEObjectValidator.validate( EDataType ): " + eDataType.getName() );
+        AbstractRiseClipseConsole.getConsole().info( "NOT IMPLEMENTED: NSDEObjectValidator.validate( " + eDataType.getName() +" )" );
 
         // TODO: use nsdResource to validate value
 
         return true;
     }
 
-    public boolean validateLN( AnyLN ln ) {
+    public boolean validateLN( AnyLN ln, DiagnosticChain diagnostics ) {
         AbstractRiseClipseConsole.getConsole().verbose( "" );
         AbstractRiseClipseConsole.getConsole().verbose( "NSDEObjectValidator.validateLN( " + ln.getLnClass() + " )" );
 
-        //LN has valid LNClass
-        if( ! this.lnMap.containsKey( ln.getLnClass() ) ) {
-            AbstractRiseClipseConsole.getConsole().error( "LNClass " + ln.getLnClass() + " not found in NSD files" );
+        // Check that LN has valid LNClass
+        if( ! this.lnMap.containsKey( ln.getLnClass() )) {
+            diagnostics.add( new BasicDiagnostic(
+                    Diagnostic.ERROR,
+                    RiseClipseValidatorSCL.DIAGNOSTIC_SOURCE,
+                    0,
+                    "LNClass " + ln.getLnClass() + " not found in NSD files",
+                    new Object[] { ln } ));
             return false;
         }
         AbstractRiseClipseConsole.getConsole().verbose( "found LNClass " + ln.getLnClass() + " in NSD files" );
 
-        //AnyLNValidator validates LN content
-        return lnMap.get( ln.getLnClass() ).validateLN( ln );
+        // AnyLNValidator validates LN content
+        return lnMap.get( ln.getLnClass() ).validateLN( ln, diagnostics );
     }
 
 }
diff --git a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/RiseClipseValidatorSCL.java b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/RiseClipseValidatorSCL.java
index 20924c0f50eed544d1904815bd1545250ceb7e7e..488ffc6187b1a876cfe614570885816bdf25421c 100644
--- a/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/RiseClipseValidatorSCL.java
+++ b/fr.centralesupelec.edf.riseclipse.iec61850.scl.tools/src/fr/centralesupelec/edf/riseclipse/iec61850/scl/validator/RiseClipseValidatorSCL.java
@@ -27,12 +27,13 @@ import fr.centralesupelec.edf.riseclipse.util.RiseClipseFatalException;
 import fr.centralesupelec.edf.riseclipse.util.TextRiseClipseConsole;
 import fr.centralesupelec.edf.riseclipse.validation.ocl.OCLValidator;
 
-import org.eclipse.emf.ecore.EValidator;
 import org.eclipse.emf.ecore.resource.Resource;
 import org.eclipse.ocl.pivot.validation.ComposedEValidator;
 
 public class RiseClipseValidatorSCL {
 
+    public static final String DIAGNOSTIC_SOURCE = "fr.centralesupelec.edf.riseclipse";
+    
     private static OCLValidator oclValidator;
     private static SclItemProviderAdapterFactory sclAdapter;
     private static SCLModelLoader sclLoader;
@@ -57,6 +58,8 @@ public class RiseClipseValidatorSCL {
         console.setLevel( IRiseClipseConsole.INFO_LEVEL );
         displayLegal( console );
         console.setLevel( IRiseClipseConsole.WARNING_LEVEL );
+        
+        console.doNotDisplayIdenticalMessages();
 
         if( args.length == 0 ) usage( console );