View Javadoc
1   /*
2    *   Copyright (C) Christian Schulte <cs@schulte.it>, 2005-206
3    *   All rights reserved.
4    *
5    *   Redistribution and use in source and binary forms, with or without
6    *   modification, are permitted provided that the following conditions
7    *   are met:
8    *
9    *     o Redistributions of source code must retain the above copyright
10   *       notice, this list of conditions and the following disclaimer.
11   *
12   *     o Redistributions in binary form must reproduce the above copyright
13   *       notice, this list of conditions and the following disclaimer in
14   *       the documentation and/or other materials provided with the
15   *       distribution.
16   *
17   *   THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
18   *   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
19   *   AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20   *   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
21   *   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22   *   NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23   *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24   *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25   *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26   *   THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27   *
28   *   $JOMC: DefaultModelValidator.java 5043 2015-05-27 07:03:39Z schulte $
29   *
30   */
31  package org.jomc.model.modlet;
32  
33  import java.text.MessageFormat;
34  import java.util.Collection;
35  import java.util.Collections;
36  import java.util.HashMap;
37  import java.util.HashSet;
38  import java.util.Iterator;
39  import java.util.Locale;
40  import java.util.Map;
41  import java.util.ResourceBundle;
42  import java.util.Set;
43  import java.util.logging.Level;
44  import javax.xml.bind.JAXBElement;
45  import javax.xml.bind.JAXBException;
46  import javax.xml.bind.util.JAXBSource;
47  import javax.xml.namespace.QName;
48  import javax.xml.transform.Source;
49  import org.jomc.model.Argument;
50  import org.jomc.model.Dependency;
51  import org.jomc.model.Implementation;
52  import org.jomc.model.ImplementationReference;
53  import org.jomc.model.Implementations;
54  import org.jomc.model.Inheritable;
55  import org.jomc.model.InheritanceModel;
56  import org.jomc.model.JavaIdentifier;
57  import org.jomc.model.Message;
58  import org.jomc.model.MessageReference;
59  import org.jomc.model.ModelObject;
60  import org.jomc.model.ModelObjectException;
61  import org.jomc.model.Module;
62  import org.jomc.model.Modules;
63  import org.jomc.model.Multiplicity;
64  import org.jomc.model.ObjectFactory;
65  import org.jomc.model.Property;
66  import org.jomc.model.PropertyReference;
67  import org.jomc.model.Specification;
68  import org.jomc.model.SpecificationReference;
69  import org.jomc.model.Specifications;
70  import org.jomc.model.Text;
71  import org.jomc.modlet.Model;
72  import org.jomc.modlet.ModelContext;
73  import org.jomc.modlet.ModelException;
74  import org.jomc.modlet.ModelValidationReport;
75  import org.jomc.modlet.ModelValidator;
76  import org.jomc.util.ParseException;
77  import org.jomc.util.TokenMgrError;
78  import org.jomc.util.VersionParser;
79  import org.w3c.dom.Element;
80  
81  /**
82   * Default object management and configuration {@code ModelValidator} implementation.
83   *
84   * @author <a href="mailto:cs@schulte.it">Christian Schulte</a>
85   * @version $JOMC: DefaultModelValidator.java 5043 2015-05-27 07:03:39Z schulte $
86   * @see ModelContext#validateModel(org.jomc.modlet.Model)
87   */
88  public class DefaultModelValidator implements ModelValidator
89  {
90  
91      /**
92       * Constant for the name of the model context attribute backing property {@code enabled}.
93       *
94       * @see #validateModel(org.jomc.modlet.ModelContext, org.jomc.modlet.Model)
95       * @see ModelContext#getAttribute(java.lang.String)
96       * @since 1.7
97       */
98      public static final String ENABLED_ATTRIBUTE_NAME = "org.jomc.model.modlet.DefaultModelValidator.enabledAttribute";
99  
100     /**
101      * Constant for the name of the system property controlling property {@code defaultEnabled}.
102      *
103      * @see #isDefaultEnabled()
104      * @since 1.7
105      */
106     private static final String DEFAULT_ENABLED_PROPERTY_NAME =
107         "org.jomc.model.modlet.DefaultModelValidator.defaultEnabled";
108 
109     /**
110      * Default value of the flag indicating the validator is enabled by default.
111      *
112      * @see #isDefaultEnabled()
113      * @since 1.7
114      */
115     private static final Boolean DEFAULT_ENABLED = Boolean.TRUE;
116 
117     /**
118      * Flag indicating the validator is enabled by default.
119      *
120      * @since 1.7
121      */
122     private static volatile Boolean defaultEnabled;
123 
124     /**
125      * Flag indicating the validator is enabled.
126      *
127      * @since 1.7
128      */
129     private Boolean enabled;
130 
131     /**
132      * Constant for the name of the model context attribute backing property {@code validateJava}.
133      *
134      * @see ModelContext#getAttribute(java.lang.String)
135      * @since 1.4
136      */
137     public static final String VALIDATE_JAVA_ATTRIBUTE_NAME =
138         "org.jomc.model.modlet.DefaultModelValidator.validateJavaAttribute";
139 
140     /**
141      * Constant for the name of the system property controlling property {@code defaultValidateJava}.
142      *
143      * @see #isDefaultValidateJava()
144      * @since 1.4
145      */
146     private static final String DEFAULT_VALIDATE_JAVA_PROPERTY_NAME =
147         "org.jomc.model.modlet.DefaultModelValidator.defaultValidateJava";
148 
149     /**
150      * Default value of the flag indicating the validator is performing Java related validation by default.
151      *
152      * @see #isDefaultValidateJava()
153      * @since 1.4
154      */
155     private static final Boolean DEFAULT_VALIDATE_JAVA = Boolean.TRUE;
156 
157     /**
158      * Flag indicating the validator is performing Java related validation by default.
159      *
160      * @since 1.4
161      */
162     private static volatile Boolean defaultValidateJava;
163 
164     /**
165      * Flag indicating the validator is performing Java related validation.
166      *
167      * @since 1.4
168      */
169     private Boolean validateJava;
170 
171     /**
172      * Creates a new {@code DefaultModelValidator} instance.
173      */
174     public DefaultModelValidator()
175     {
176         super();
177     }
178 
179     /**
180      * Gets a flag indicating the validator is enabled by default.
181      * <p>
182      * The default enabled flag is controlled by system property
183      * {@code org.jomc.model.modlet.DefaultModelValidator.defaultEnabled} holding a value indicating the validator is
184      * enabled by default. If that property is not set, the {@code true} default is returned.
185      * </p>
186      *
187      * @return {@code true}, if the validator is enabled by default; {@code false}, if the validator is disabled by
188      * default.
189      *
190      * @see #setDefaultEnabled(java.lang.Boolean)
191      * @since 1.7
192      */
193     public static boolean isDefaultEnabled()
194     {
195         if ( defaultEnabled == null )
196         {
197             defaultEnabled = Boolean.valueOf( System.getProperty( DEFAULT_ENABLED_PROPERTY_NAME,
198                                                                   Boolean.toString( DEFAULT_ENABLED ) ) );
199 
200         }
201 
202         return defaultEnabled;
203     }
204 
205     /**
206      * Sets the flag indicating the validator is enabled by default.
207      *
208      * @param value The new value of the flag indicating the validator is enabled by default or {@code null}.
209      *
210      * @see #isDefaultEnabled()
211      * @since 1.7
212      */
213     public static void setDefaultEnabled( final Boolean value )
214     {
215         defaultEnabled = value;
216     }
217 
218     /**
219      * Gets a flag indicating the validator is enabled.
220      *
221      * @return {@code true}, if the validator is enabled; {@code false}, if the validator is disabled.
222      *
223      * @see #isDefaultEnabled()
224      * @see #setEnabled(java.lang.Boolean)
225      * @since 1.7
226      */
227     public final boolean isEnabled()
228     {
229         if ( this.enabled == null )
230         {
231             this.enabled = isDefaultEnabled();
232         }
233 
234         return this.enabled;
235     }
236 
237     /**
238      * Sets the flag indicating the validator is enabled.
239      *
240      * @param value The new value of the flag indicating the validator is enabled or {@code null}.
241      *
242      * @see #isEnabled()
243      * @since 1.7
244      */
245     public final void setEnabled( final Boolean value )
246     {
247         this.enabled = value;
248     }
249 
250     /**
251      * Gets a flag indicating the validator is performing Java related validation by default.
252      * <p>
253      * The default validate Java flag is controlled by system property
254      * {@code org.jomc.model.modlet.DefaultModelValidator.defaultValidateJava} holding a value indicating the validator
255      * is performing Java related validation by default. If that property is not set, the {@code true} default is
256      * returned.
257      * </p>
258      *
259      * @return {@code true}, if the validator is performing Java related validation by default; {@code false}, if the
260      * validator is not performing Java related validation by default.
261      *
262      * @see #setDefaultValidateJava(java.lang.Boolean)
263      *
264      * @since 1.4
265      */
266     public static boolean isDefaultValidateJava()
267     {
268         if ( defaultValidateJava == null )
269         {
270             defaultValidateJava = Boolean.valueOf( System.getProperty( DEFAULT_VALIDATE_JAVA_PROPERTY_NAME,
271                                                                        Boolean.toString( DEFAULT_VALIDATE_JAVA ) ) );
272 
273         }
274 
275         return defaultValidateJava;
276     }
277 
278     /**
279      * Sets the flag indicating the validator is performing Java related validation by default.
280      *
281      * @param value The new value of the flag indicating the validator is performing Java related validation by default
282      * or {@code null}.
283      *
284      * @see #isDefaultValidateJava()
285      *
286      * @since 1.4
287      */
288     public static void setDefaultValidateJava( final Boolean value )
289     {
290         defaultValidateJava = value;
291     }
292 
293     /**
294      * Gets a flag indicating the validator is performing Java related validation.
295      *
296      * @return {@code true}, if the validator is performing Java related validation; {@code false}, if the the validator
297      * is not performing Java related validation.
298      *
299      * @see #isDefaultValidateJava()
300      * @see #setValidateJava(java.lang.Boolean)
301      *
302      * @since 1.4
303      */
304     public final boolean isValidateJava()
305     {
306         if ( this.validateJava == null )
307         {
308             this.validateJava = isDefaultValidateJava();
309         }
310 
311         return this.validateJava;
312     }
313 
314     /**
315      * Sets the flag indicating the validator is performing Java related validation.
316      *
317      * @param value The new value of the flag indicating the validator is performing Java related validation or
318      * {@code null}.
319      *
320      * @see #isValidateJava()
321      *
322      * @since 1.4
323      */
324     public final void setValidateJava( final Boolean value )
325     {
326         this.validateJava = value;
327     }
328 
329     public ModelValidationReport validateModel( final ModelContext context, final Model model ) throws ModelException
330     {
331         if ( context == null )
332         {
333             throw new NullPointerException( "context" );
334         }
335         if ( model == null )
336         {
337             throw new NullPointerException( "model" );
338         }
339 
340         boolean contextEnabled = this.isEnabled();
341         if ( DEFAULT_ENABLED == contextEnabled
342                  && context.getAttribute( ENABLED_ATTRIBUTE_NAME ) instanceof Boolean )
343         {
344             contextEnabled = (Boolean) context.getAttribute( ENABLED_ATTRIBUTE_NAME );
345         }
346 
347         boolean contextValidateJava = this.isValidateJava();
348         if ( DEFAULT_VALIDATE_JAVA == contextValidateJava
349                  && context.getAttribute( VALIDATE_JAVA_ATTRIBUTE_NAME ) instanceof Boolean )
350         {
351             contextValidateJava = (Boolean) context.getAttribute( VALIDATE_JAVA_ATTRIBUTE_NAME );
352         }
353 
354         try
355         {
356             ModelValidationReport report = new ModelValidationReport();
357 
358             if ( contextEnabled )
359             {
360                 final Source source = new JAXBSource( context.createContext( model.getIdentifier() ),
361                                                       new org.jomc.modlet.ObjectFactory().createModel( model ) );
362 
363                 report = context.validateModel( model.getIdentifier(), source );
364 
365                 final Modules modules = ModelHelper.getModules( model );
366 
367                 if ( modules != null )
368                 {
369                     final ValidationContext validationContext =
370                         new ValidationContext( context, modules, report, contextValidateJava );
371 
372                     assertModulesValid( validationContext );
373                     assertSpecificationsValid( validationContext );
374                     assertImplementationsValid( validationContext );
375                 }
376             }
377             else if ( context.isLoggable( Level.FINER ) )
378             {
379                 context.log( Level.FINER, getMessage( "disabled", this.getClass().getSimpleName(),
380                                                       model.getIdentifier() ), null );
381 
382             }
383 
384             return report;
385         }
386         catch ( final JAXBException e )
387         {
388             String message = getMessage( e );
389             if ( message == null && e.getLinkedException() != null )
390             {
391                 message = getMessage( e.getLinkedException() );
392             }
393 
394             if ( context.isLoggable( Level.FINE ) )
395             {
396                 context.log( Level.FINE, message, e );
397             }
398 
399             throw new ModelException( message, e );
400         }
401     }
402 
403     private static void assertModulesValid( final ValidationContext validationContext )
404     {
405         for ( int i = 0, s0 = validationContext.getModules().getModule().size(); i < s0; i++ )
406         {
407             final Module m = validationContext.getModules().getModule().get( i );
408 
409             if ( m.getImplementations() != null )
410             {
411                 for ( int j = 0, s1 = m.getImplementations().getReference().size(); j < s1; j++ )
412                 {
413                     final ImplementationReference r = m.getImplementations().getReference().get( j );
414                     addDetail( validationContext.getReport(), "MODULE_IMPLEMENTATION_REFERENCE_DECLARATION_CONSTRAINT",
415                                Level.SEVERE, new ObjectFactory().createModule( m ),
416                                "moduleImplementationReferenceDeclarationConstraint", m.getName(), r.getIdentifier() );
417 
418                 }
419             }
420 
421             if ( m.getMessages() != null )
422             {
423                 for ( int j = 0, s1 = m.getMessages().getMessage().size(); j < s1; j++ )
424                 {
425                     final Message msg = m.getMessages().getMessage().get( j );
426 
427                     if ( msg.isFinal() )
428                     {
429                         addDetail( validationContext.getReport(), "MODULE_FINAL_MESSAGE_DECLARATION_CONSTRAINT",
430                                    Level.SEVERE, new ObjectFactory().createModule( m ), "moduleFinalMessageConstraint",
431                                    m.getName(), msg.getName() );
432 
433                     }
434 
435                     if ( msg.isOverride() )
436                     {
437                         addDetail( validationContext.getReport(), "MODULE_OVERRIDE_MESSAGE_DECLARATION_CONSTRAINT",
438                                    Level.SEVERE, new ObjectFactory().createModule( m ),
439                                    "moduleOverrideMessageConstraint", m.getName(), msg.getName() );
440 
441                     }
442 
443                     if ( validationContext.isValidateJava() )
444                     {
445                         try
446                         {
447                             msg.getJavaConstantName();
448                         }
449                         catch ( final ModelObjectException e )
450                         {
451                             final String message = getMessage( e );
452 
453                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
454                             {
455                                 validationContext.getModelContext().log( Level.FINE, message, e );
456                             }
457 
458                             addDetail( validationContext.getReport(),
459                                        "MODULE_MESSAGE_JAVA_CONSTANT_NAME_CONSTRAINT",
460                                        Level.SEVERE, new ObjectFactory().createModule( m ),
461                                        "moduleMessageJavaConstantNameConstraint", m.getName(), msg.getName(),
462                                        message != null && message.length() > 0 ? " " + message : "" );
463 
464                         }
465 
466                         try
467                         {
468                             msg.getJavaGetterMethodName();
469                         }
470                         catch ( final ModelObjectException e )
471                         {
472                             final String message = getMessage( e );
473 
474                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
475                             {
476                                 validationContext.getModelContext().log( Level.FINE, message, e );
477                             }
478 
479                             addDetail( validationContext.getReport(),
480                                        "MODULE_MESSAGE_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
481                                        Level.SEVERE, new ObjectFactory().createModule( m ),
482                                        "moduleMessageJavaGetterMethodNameConstraint", m.getName(), msg.getName(),
483                                        message != null && message.length() > 0 ? " " + message : "" );
484 
485                         }
486 
487                         try
488                         {
489                             msg.getJavaSetterMethodName();
490                         }
491                         catch ( final ModelObjectException e )
492                         {
493                             final String message = getMessage( e );
494 
495                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
496                             {
497                                 validationContext.getModelContext().log( Level.FINE, message, e );
498                             }
499 
500                             addDetail( validationContext.getReport(),
501                                        "MODULE_MESSAGE_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
502                                        Level.SEVERE, new ObjectFactory().createModule( m ),
503                                        "moduleMessageJavaSetterMethodNameConstraint", m.getName(), msg.getName(),
504                                        message != null && message.length() > 0 ? " " + message : "" );
505 
506                         }
507 
508                         try
509                         {
510                             msg.getJavaVariableName();
511                         }
512                         catch ( final ModelObjectException e )
513                         {
514                             final String message = getMessage( e );
515 
516                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
517                             {
518                                 validationContext.getModelContext().log( Level.FINE, message, e );
519                             }
520 
521                             addDetail( validationContext.getReport(),
522                                        "MODULE_MESSAGE_JAVA_VARIABLE_NAME_CONSTRAINT",
523                                        Level.SEVERE, new ObjectFactory().createModule( m ),
524                                        "moduleMessageJavaVariableNameConstraint", m.getName(), msg.getName(),
525                                        message != null && message.length() > 0 ? " " + message : "" );
526 
527                         }
528                     }
529 
530                     if ( msg.getTemplate() != null )
531                     {
532                         for ( int k = 0, s2 = msg.getTemplate().getText().size(); k < s2; k++ )
533                         {
534                             final Text t = msg.getTemplate().getText().get( k );
535 
536                             try
537                             {
538                                 t.getMimeType();
539                             }
540                             catch ( final ModelObjectException e )
541                             {
542                                 final String message = getMessage( e );
543 
544                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
545                                 {
546                                     validationContext.getModelContext().log( Level.FINE, message, e );
547                                 }
548 
549                                 addDetail( validationContext.getReport(),
550                                            "MODULE_MESSAGE_TEMPLATE_MIME_TYPE_CONSTRAINT",
551                                            Level.SEVERE, new ObjectFactory().createModule( m ),
552                                            "moduleMessageTemplateMimeTypeConstraint", m.getName(), msg.getName(),
553                                            t.getLanguage(),
554                                            message != null && message.length() > 0 ? " " + message : "" );
555 
556                             }
557 
558                             if ( validationContext.isValidateJava() )
559                             {
560                                 try
561                                 {
562                                     new MessageFormat( t.getValue(), new Locale( t.getLanguage() ) );
563                                 }
564                                 catch ( final IllegalArgumentException e )
565                                 {
566                                     final String message = getMessage( e );
567 
568                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
569                                     {
570                                         validationContext.getModelContext().log( Level.FINE, message, e );
571                                     }
572 
573                                     addDetail( validationContext.getReport(), "MODULE_MESSAGE_TEMPLATE_CONSTRAINT",
574                                                Level.SEVERE, new ObjectFactory().createModule( m ),
575                                                "moduleMessageTemplateConstraint", m.getName(), msg.getName(),
576                                                t.getValue(),
577                                                message != null && message.length() > 0 ? " " + message : "" );
578 
579                                 }
580                             }
581                         }
582                     }
583 
584                     if ( msg.getArguments() != null )
585                     {
586                         final Map<JavaIdentifier, Argument> javaVariableNames =
587                             new HashMap<JavaIdentifier, Argument>( msg.getArguments().getArgument().size() );
588 
589                         for ( int k = 0, s2 = msg.getArguments().getArgument().size(); k < s2; k++ )
590                         {
591                             final Argument a = msg.getArguments().getArgument( k );
592 
593                             if ( validationContext.isValidateJava() )
594                             {
595                                 try
596                                 {
597                                     a.getJavaTypeName();
598                                 }
599                                 catch ( final ModelObjectException e )
600                                 {
601                                     final String message = getMessage( e );
602 
603                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
604                                     {
605                                         validationContext.getModelContext().log( Level.FINE, message, e );
606                                     }
607 
608                                     addDetail( validationContext.getReport(),
609                                                "MODULE_MESSAGE_ARGUMENT_JAVA_TYPE_NAME_CONSTRAINT",
610                                                Level.SEVERE, new ObjectFactory().createModule( m ),
611                                                "moduleMessageArgumentJavaTypeNameConstraint", m.getName(),
612                                                msg.getName(), a.getIndex(),
613                                                message != null && message.length() > 0 ? " " + message : "" );
614 
615                                 }
616 
617                                 try
618                                 {
619                                     final JavaIdentifier javaIdentifier = a.getJavaVariableName();
620 
621                                     if ( javaVariableNames.containsKey( javaIdentifier ) )
622                                     {
623                                         addDetail( validationContext.getReport(),
624                                                    "MODULE_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
625                                                    Level.SEVERE, new ObjectFactory().createModule( m ),
626                                                    "moduleMessageArgumentJavaVariableNameUniquenessConstraint",
627                                                    m.getName(), msg.getName(), a.getName(),
628                                                    javaIdentifier, javaVariableNames.get( javaIdentifier ).getName() );
629 
630                                     }
631                                     else
632                                     {
633                                         javaVariableNames.put( javaIdentifier, a );
634                                     }
635                                 }
636                                 catch ( final ModelObjectException e )
637                                 {
638                                     final String message = getMessage( e );
639 
640                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
641                                     {
642                                         validationContext.getModelContext().log( Level.FINE, message, e );
643                                     }
644 
645                                     addDetail( validationContext.getReport(),
646                                                "MODULE_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_CONSTRAINT",
647                                                Level.SEVERE, new ObjectFactory().createModule( m ),
648                                                "moduleMessageArgumentJavaVariableNameConstraint", m.getName(),
649                                                msg.getName(), a.getIndex(),
650                                                message != null && message.length() > 0 ? " " + message : "" );
651 
652                                 }
653                             }
654                         }
655                     }
656                 }
657 
658                 for ( int j = 0, s1 = m.getMessages().getReference().size(); j < s1; j++ )
659                 {
660                     final MessageReference r = m.getMessages().getReference().get( j );
661                     addDetail( validationContext.getReport(), "MODULE_MESSAGE_REFERENCE_DECLARATION_CONSTRAINT",
662                                Level.SEVERE, new ObjectFactory().createModule( m ),
663                                "moduleMessageReferenceDeclarationConstraint", m.getName(), r.getName() );
664 
665                 }
666             }
667 
668             if ( m.getProperties() != null )
669             {
670                 for ( int j = 0, s1 = m.getProperties().getProperty().size(); j < s1; j++ )
671                 {
672                     final Property p = m.getProperties().getProperty().get( j );
673 
674                     if ( p.isFinal() )
675                     {
676                         addDetail( validationContext.getReport(), "MODULE_FINAL_PROPERTY_DECLARATION_CONSTRAINT",
677                                    Level.SEVERE, new ObjectFactory().createModule( m ), "moduleFinalPropertyConstraint",
678                                    m.getName(), p.getName() );
679 
680                     }
681 
682                     if ( p.isOverride() )
683                     {
684                         addDetail( validationContext.getReport(), "MODULE_OVERRIDE_PROPERTY_DECLARATION_CONSTRAINT",
685                                    Level.SEVERE, new ObjectFactory().createModule( m ),
686                                    "moduleOverridePropertyConstraint", m.getName(), p.getName() );
687 
688                     }
689 
690                     if ( p.getValue() != null && p.getAny() != null )
691                     {
692                         addDetail( validationContext.getReport(), "MODULE_PROPERTY_VALUE_CONSTRAINT", Level.SEVERE,
693                                    new ObjectFactory().createModule( m ), "modulePropertyValueConstraint", m.getName(),
694                                    p.getName() );
695 
696                     }
697 
698                     if ( p.getAny() != null && p.getType() == null )
699                     {
700                         addDetail( validationContext.getReport(), "MODULE_PROPERTY_TYPE_CONSTRAINT", Level.SEVERE,
701                                    new ObjectFactory().createModule( m ), "modulePropertyTypeConstraint", m.getName(),
702                                    p.getName() );
703 
704                     }
705 
706                     if ( validationContext.isValidateJava() )
707                     {
708                         try
709                         {
710                             p.getJavaConstantName();
711                         }
712                         catch ( final ModelObjectException e )
713                         {
714                             final String message = getMessage( e );
715 
716                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
717                             {
718                                 validationContext.getModelContext().log( Level.FINE, message, e );
719                             }
720 
721                             addDetail( validationContext.getReport(),
722                                        "MODULE_PROPERTY_JAVA_CONSTANT_NAME_CONSTRAINT",
723                                        Level.SEVERE, new ObjectFactory().createModule( m ),
724                                        "modulePropertyJavaConstantNameConstraint", m.getName(), p.getName(),
725                                        message != null && message.length() > 0 ? " " + message : "" );
726 
727                         }
728 
729                         try
730                         {
731                             p.getJavaGetterMethodName();
732                         }
733                         catch ( final ModelObjectException e )
734                         {
735                             final String message = getMessage( e );
736 
737                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
738                             {
739                                 validationContext.getModelContext().log( Level.FINE, message, e );
740                             }
741 
742                             addDetail( validationContext.getReport(),
743                                        "MODULE_PROPERTY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
744                                        Level.SEVERE, new ObjectFactory().createModule( m ),
745                                        "modulePropertyJavaGetterMethodNameConstraint", m.getName(), p.getName(),
746                                        message != null && message.length() > 0 ? " " + message : "" );
747 
748                         }
749 
750                         try
751                         {
752                             p.getJavaSetterMethodName();
753                         }
754                         catch ( final ModelObjectException e )
755                         {
756                             final String message = getMessage( e );
757 
758                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
759                             {
760                                 validationContext.getModelContext().log( Level.FINE, message, e );
761                             }
762 
763                             addDetail( validationContext.getReport(),
764                                        "MODULE_PROPERTY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
765                                        Level.SEVERE, new ObjectFactory().createModule( m ),
766                                        "modulePropertyJavaSetterMethodNameConstraint", m.getName(), p.getName(),
767                                        message != null && message.length() > 0 ? " " + message : "" );
768 
769                         }
770 
771                         try
772                         {
773                             p.getJavaTypeName();
774                         }
775                         catch ( final ModelObjectException e )
776                         {
777                             final String message = getMessage( e );
778 
779                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
780                             {
781                                 validationContext.getModelContext().log( Level.FINE, message, e );
782                             }
783 
784                             addDetail( validationContext.getReport(),
785                                        "MODULE_PROPERTY_JAVA_TYPE_NAME_CONSTRAINT",
786                                        Level.SEVERE, new ObjectFactory().createModule( m ),
787                                        "modulePropertyJavaTypeNameConstraint", m.getName(), p.getName(),
788                                        message != null && message.length() > 0 ? " " + message : "" );
789 
790                         }
791 
792                         try
793                         {
794                             p.getJavaVariableName();
795                         }
796                         catch ( final ModelObjectException e )
797                         {
798                             final String message = getMessage( e );
799 
800                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
801                             {
802                                 validationContext.getModelContext().log( Level.FINE, message, e );
803                             }
804 
805                             addDetail( validationContext.getReport(),
806                                        "MODULE_PROPERTY_JAVA_VARIABLE_NAME_CONSTRAINT",
807                                        Level.SEVERE, new ObjectFactory().createModule( m ),
808                                        "modulePropertyJavaVariableNameConstraint", m.getName(), p.getName(),
809                                        message != null && message.length() > 0 ? " " + message : "" );
810 
811                         }
812 
813                         try
814                         {
815                             p.getJavaValue( validationContext.getModelContext().getClassLoader() );
816                         }
817                         catch ( final ModelObjectException e )
818                         {
819                             final String message = getMessage( e );
820 
821                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
822                             {
823                                 validationContext.getModelContext().log( Level.FINE, message, e );
824                             }
825 
826                             addDetail( validationContext.getReport(), "MODULE_PROPERTY_JAVA_VALUE_CONSTRAINT",
827                                        Level.SEVERE, new ObjectFactory().createModule( m ),
828                                        "modulePropertyJavaValueConstraint", m.getName(), p.getName(),
829                                        message != null && message.length() > 0 ? " " + message : "" );
830 
831                         }
832                     }
833                 }
834 
835                 for ( int j = 0, s1 = m.getProperties().getReference().size(); j < s1; j++ )
836                 {
837                     final PropertyReference r = m.getProperties().getReference().get( j );
838                     addDetail( validationContext.getReport(), "MODULE_PROPERTY_REFERENCE_DECLARATION_CONSTRAINT",
839                                Level.SEVERE, new ObjectFactory().createModule( m ),
840                                "modulePropertyReferenceDeclarationConstraint", m.getName(), r.getName() );
841 
842                 }
843             }
844 
845             if ( m.getSpecifications() != null )
846             {
847                 for ( int j = 0, s1 = m.getSpecifications().getReference().size(); j < s1; j++ )
848                 {
849                     final SpecificationReference r = m.getSpecifications().getReference().get( j );
850                     addDetail( validationContext.getReport(), "MODULE_SPECIFICATION_REFERENCE_DECLARATION_CONSTRAINT",
851                                Level.SEVERE, new ObjectFactory().createModule( m ),
852                                "moduleSpecificationReferenceDeclarationConstraint", m.getName(), r.getIdentifier() );
853 
854                 }
855             }
856         }
857     }
858 
859     private static void assertImplementationsValid( final ValidationContext validationContext )
860     {
861         final Implementations implementations = validationContext.getAllImplementations();
862 
863         if ( implementations != null )
864         {
865             final Map<String, Implementation> implementationClassDeclarations = new HashMap<String, Implementation>();
866             final Map<String, Implementation> implementationJavaClassDeclarations =
867                 new HashMap<String, Implementation>();
868 
869             for ( int i = 0, s0 = implementations.getImplementation().size(); i < s0; i++ )
870             {
871                 final Implementation impl = implementations.getImplementation().get( i );
872                 final InheritanceModel imodel = validationContext.getInheritanceModel();
873                 final Module moduleOfImpl = validationContext.getModuleOfImplementation( impl.getIdentifier() );
874                 final Set<InheritanceModel.Node<ImplementationReference>> cyclicImplementationReferenceNodes =
875                     imodel.getCycleNodes( impl.getIdentifier() );
876 
877                 for ( final InheritanceModel.Node<ImplementationReference> node : cyclicImplementationReferenceNodes )
878                 {
879                     addDetail( validationContext.getReport(), "IMPLEMENTATION_INHERITANCE_CYCLE_CONSTRAINT",
880                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
881                                "implementationInheritanceCycleConstraint", impl.getIdentifier(),
882                                moduleOfImpl.getName(), getNodePathString( node ) );
883 
884                 }
885 
886                 if ( validationContext.isValidateJava() )
887                 {
888                     try
889                     {
890                         impl.getJavaTypeName();
891                     }
892                     catch ( final ModelObjectException e )
893                     {
894                         final String message = getMessage( e );
895 
896                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
897                         {
898                             validationContext.getModelContext().log( Level.FINE, message, e );
899                         }
900 
901                         addDetail( validationContext.getReport(),
902                                    "IMPLEMENTATION_JAVA_TYPE_NAME_CONSTRAINT",
903                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
904                                    "implementationJavaTypeNameConstraint", impl.getIdentifier(),
905                                    moduleOfImpl.getName(), impl.getClazz(),
906                                    message != null && message.length() > 0 ? " " + message : "" );
907 
908                     }
909                 }
910 
911                 if ( impl.isClassDeclaration() )
912                 {
913                     if ( impl.getClazz() == null )
914                     {
915                         addDetail( validationContext.getReport(), "IMPLEMENTATION_CLASS_CONSTRAINT", Level.SEVERE,
916                                    new ObjectFactory().createImplementation( impl ), "implementationClassConstraint",
917                                    impl.getIdentifier(), moduleOfImpl.getName() );
918 
919                     }
920                     else
921                     {
922                         final Implementation prev = implementationClassDeclarations.get( impl.getClazz() );
923 
924                         if ( prev != null && !prev.getIdentifier().equals( impl.getIdentifier() ) )
925                         {
926                             final Module moduleOfPrev =
927                                 validationContext.getModuleOfImplementation( prev.getIdentifier() );
928 
929                             addDetail( validationContext.getReport(), "IMPLEMENTATION_CLASS_DECLARATION_CONSTRAINT",
930                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
931                                        "implementationClassDeclarationConstraint", impl.getIdentifier(),
932                                        moduleOfImpl.getName(), impl.getClazz(), prev.getIdentifier(),
933                                        moduleOfPrev.getName() );
934 
935                         }
936                         else
937                         {
938                             implementationClassDeclarations.put( impl.getClazz(), impl );
939                         }
940 
941                         if ( validationContext.isValidateJava() )
942                         {
943                             try
944                             {
945                                 final Implementation java =
946                                     implementationJavaClassDeclarations.get( impl.getJavaTypeName().getClassName() );
947 
948                                 if ( java != null && !java.getIdentifier().equals( impl.getIdentifier() ) )
949                                 {
950                                     final Module moduleOfJava =
951                                         validationContext.getModuleOfImplementation( java.getIdentifier() );
952 
953                                     addDetail( validationContext.getReport(),
954                                                "IMPLEMENTATION_JAVA_CLASS_DECLARATION_CONSTRAINT",
955                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
956                                                "implementationJavaClassDeclarationConstraint", impl.getIdentifier(),
957                                                moduleOfImpl.getName(), impl.getJavaTypeName().getClassName(),
958                                                java.getIdentifier(), moduleOfJava.getName() );
959 
960                                 }
961                                 else
962                                 {
963                                     implementationJavaClassDeclarations.put( impl.getJavaTypeName().getClassName(),
964                                                                              impl );
965 
966                                 }
967                             }
968                             catch ( final ModelObjectException e )
969                             {
970                                 // Already validated above.
971                             }
972                         }
973                     }
974                 }
975 
976                 if ( impl.isAbstract() && impl.getLocation() != null )
977                 {
978                     addDetail( validationContext.getReport(), "IMPLEMENTATION_ABSTRACT_LOCATION_DECLARATION_CONSTRAINT",
979                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
980                                "implementationAbstractLocationDeclarationConstraint", impl.getIdentifier(),
981                                moduleOfImpl.getName(), impl.getLocation() );
982 
983                 }
984 
985                 if ( impl.getDependencies() != null )
986                 {
987                     for ( int j = 0, s1 = impl.getDependencies().getDependency().size(); j < s1; j++ )
988                     {
989                         final Dependency d = impl.getDependencies().getDependency().get( j );
990 
991                         final Set<InheritanceModel.Node<Dependency>> effDependencies =
992                             imodel.getDependencyNodes( impl.getIdentifier(), d.getName() );
993 
994                         for ( final InheritanceModel.Node<Dependency> effDependency : effDependencies )
995                         {
996                             final Set<InheritanceModel.Node<Dependency>> overriddenDependencies =
997                                 modifiableSet( effDependency.getOverriddenNodes() );
998 
999                             if ( d.isOverride() && effDependency.getOverriddenNodes().isEmpty() )
1000                             {
1001                                 addDetail( validationContext.getReport(),
1002                                            "IMPLEMENTATION_DEPENDENCY_OVERRIDE_CONSTRAINT",
1003                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1004                                            "implementationDependencyOverrideConstraint", impl.getIdentifier(),
1005                                            moduleOfImpl.getName(), d.getName() );
1006 
1007                             }
1008 
1009                             if ( !( d.isOverride() || overriddenDependencies.isEmpty() ) )
1010                             {
1011                                 for ( final InheritanceModel.Node<Dependency> overriddenDependency
1012                                           : overriddenDependencies )
1013                                 {
1014                                     Implementation overriddenImplementation = overriddenDependency.getImplementation();
1015                                     if ( overriddenDependency.getClassDeclaration() != null )
1016                                     {
1017                                         overriddenImplementation = overriddenDependency.getClassDeclaration();
1018                                     }
1019 
1020                                     final Module moduleOfDependency =
1021                                         validationContext.getModuleOfImplementation(
1022                                             overriddenImplementation.getIdentifier() );
1023 
1024                                     addDetail( validationContext.getReport(),
1025                                                "IMPLEMENTATION_DEPENDENCY_OVERRIDE_WARNING",
1026                                                Level.WARNING, new ObjectFactory().createImplementation( impl ),
1027                                                "implementationDependencyOverrideWarning", impl.getIdentifier(),
1028                                                moduleOfImpl.getName(), d.getName(),
1029                                                overriddenImplementation.getIdentifier(),
1030                                                moduleOfDependency.getName(),
1031                                                getNodePathString( overriddenDependency ) );
1032 
1033                                 }
1034                             }
1035 
1036                             retainFinalNodes( overriddenDependencies );
1037 
1038                             for ( final InheritanceModel.Node<Dependency> overriddenDependency : overriddenDependencies )
1039                             {
1040                                 Implementation overriddenImplementation = overriddenDependency.getImplementation();
1041                                 if ( overriddenDependency.getClassDeclaration() != null )
1042                                 {
1043                                     overriddenImplementation = overriddenDependency.getClassDeclaration();
1044                                 }
1045 
1046                                 final Module moduleOfDependency =
1047                                     validationContext.getModuleOfImplementation(
1048                                         overriddenImplementation.getIdentifier() );
1049 
1050                                 addDetail( validationContext.getReport(),
1051                                            "IMPLEMENTATION_DEPENDENCY_INHERITANCE_CONSTRAINT", Level.SEVERE,
1052                                            new ObjectFactory().createImplementation( impl ),
1053                                            "implementationDependencyFinalConstraint", impl.getIdentifier(),
1054                                            moduleOfImpl.getName(), d.getName(),
1055                                            overriddenImplementation.getIdentifier(),
1056                                            moduleOfDependency.getName(),
1057                                            getNodePathString( overriddenDependency ) );
1058 
1059                             }
1060                         }
1061 
1062                         if ( validationContext.isValidateJava() )
1063                         {
1064                             try
1065                             {
1066                                 d.getJavaConstantName();
1067                             }
1068                             catch ( final ModelObjectException e )
1069                             {
1070                                 final String message = getMessage( e );
1071 
1072                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1073                                 {
1074                                     validationContext.getModelContext().log( Level.FINE, message, e );
1075                                 }
1076 
1077                                 addDetail( validationContext.getReport(),
1078                                            "IMPLEMENTATION_DEPENDENCY_JAVA_CONSTANT_NAME_CONSTRAINT",
1079                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1080                                            "implementationDependencyJavaConstantNameConstraint", impl.getIdentifier(),
1081                                            moduleOfImpl.getName(), d.getName(),
1082                                            message != null && message.length() > 0 ? " " + message : "" );
1083 
1084                             }
1085 
1086                             try
1087                             {
1088                                 d.getJavaGetterMethodName();
1089                             }
1090                             catch ( final ModelObjectException e )
1091                             {
1092                                 final String message = getMessage( e );
1093 
1094                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1095                                 {
1096                                     validationContext.getModelContext().log( Level.FINE, message, e );
1097                                 }
1098 
1099                                 addDetail( validationContext.getReport(),
1100                                            "IMPLEMENTATION_DEPENDENCY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
1101                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1102                                            "implementationDependencyJavaGetterMethodNameConstraint",
1103                                            impl.getIdentifier(), moduleOfImpl.getName(), d.getName(),
1104                                            message != null && message.length() > 0 ? " " + message : "" );
1105 
1106                             }
1107 
1108                             try
1109                             {
1110                                 d.getJavaSetterMethodName();
1111                             }
1112                             catch ( final ModelObjectException e )
1113                             {
1114                                 final String message = getMessage( e );
1115 
1116                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1117                                 {
1118                                     validationContext.getModelContext().log( Level.FINE, message, e );
1119                                 }
1120 
1121                                 addDetail( validationContext.getReport(),
1122                                            "IMPLEMENTATION_DEPENDENCY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
1123                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1124                                            "implementationDependencyJavaSetterMethodNameConstraint",
1125                                            impl.getIdentifier(), moduleOfImpl.getName(), d.getName(),
1126                                            message != null && message.length() > 0 ? " " + message : "" );
1127 
1128                             }
1129 
1130                             try
1131                             {
1132                                 d.getJavaVariableName();
1133                             }
1134                             catch ( final ModelObjectException e )
1135                             {
1136                                 final String message = getMessage( e );
1137 
1138                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1139                                 {
1140                                     validationContext.getModelContext().log( Level.FINE, message, e );
1141                                 }
1142 
1143                                 addDetail( validationContext.getReport(),
1144                                            "IMPLEMENTATION_DEPENDENCY_JAVA_VARIABLE_NAME_CONSTRAINT",
1145                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1146                                            "implementationDependencyJavaVariableNameConstraint",
1147                                            impl.getIdentifier(), moduleOfImpl.getName(), d.getName(),
1148                                            message != null && message.length() > 0 ? " " + message : "" );
1149 
1150                             }
1151                         }
1152 
1153                         assertDependencyValid( validationContext, impl, d );
1154                     }
1155                 }
1156 
1157                 if ( impl.getImplementations() != null )
1158                 {
1159                     final Set<String> effImplementationReferences =
1160                         imodel.getImplementationReferenceIdentifiers( impl.getIdentifier() );
1161 
1162                     for ( final String effImplementationReference : effImplementationReferences )
1163                     {
1164                         final Implementation ancestorImplementation =
1165                             validationContext.getImplementation( effImplementationReference );
1166 
1167                         if ( ancestorImplementation != null && ancestorImplementation.isFinal() )
1168                         {
1169                             final Module moduleOfFinal =
1170                                 validationContext.getModuleOfImplementation( ancestorImplementation.getIdentifier() );
1171 
1172                             addDetail( validationContext.getReport(),
1173                                        "IMPLEMENTATION_IMPLEMENTATION_INHERITANCE_CONSTRAINT", Level.SEVERE,
1174                                        new ObjectFactory().createImplementation( impl ),
1175                                        "implementationFinalImplementationConstraint", impl.getIdentifier(),
1176                                        moduleOfImpl.getName(), ancestorImplementation.getIdentifier(),
1177                                        moduleOfFinal.getName() );
1178 
1179                         }
1180                     }
1181 
1182                     for ( int j = 0, s1 = impl.getImplementations().getImplementation().size(); j < s1; j++ )
1183                     {
1184                         final Implementation pi = impl.getImplementations().getImplementation().get( j );
1185 
1186                         addDetail( validationContext.getReport(),
1187                                    "IMPLEMENTATION_IMPLEMENTATION_DECLARATION_CONSTRAINT", Level.SEVERE,
1188                                    new ObjectFactory().createImplementation( impl ),
1189                                    "implementationImplementationDeclarationConstraint", impl.getIdentifier(),
1190                                    moduleOfImpl.getName(), pi.getIdentifier() );
1191 
1192                     }
1193 
1194                     for ( int j = 0, s1 = impl.getImplementations().getReference().size(); j < s1; j++ )
1195                     {
1196                         final ImplementationReference r = impl.getImplementations().getReference().get( j );
1197 
1198                         final Set<InheritanceModel.Node<ImplementationReference>> effReferences =
1199                             imodel.getImplementationReferenceNodes( impl.getIdentifier(), r.getIdentifier() );
1200 
1201                         for ( final InheritanceModel.Node<ImplementationReference> effReference : effReferences )
1202                         {
1203                             final Set<InheritanceModel.Node<ImplementationReference>> overriddenReferences =
1204                                 modifiableSet( effReference.getOverriddenNodes() );
1205 
1206                             if ( r.isOverride() && overriddenReferences.isEmpty() )
1207                             {
1208                                 addDetail( validationContext.getReport(),
1209                                            "IMPLEMENTATION_IMPLEMENTATION_OVERRIDE_CONSTRAINT", Level.SEVERE,
1210                                            new ObjectFactory().createImplementation( impl ),
1211                                            "implementationImplementationOverrideConstraint", impl.getIdentifier(),
1212                                            moduleOfImpl.getName(), r.getIdentifier() );
1213 
1214                             }
1215 
1216                             if ( !( r.isOverride() || overriddenReferences.isEmpty() ) )
1217                             {
1218                                 for ( final InheritanceModel.Node<ImplementationReference> overriddenReference
1219                                           : overriddenReferences )
1220                                 {
1221                                     Implementation overriddenImplementation = overriddenReference.getImplementation();
1222                                     if ( overriddenReference.getClassDeclaration() != null )
1223                                     {
1224                                         overriddenImplementation = overriddenReference.getClassDeclaration();
1225                                     }
1226 
1227                                     final Module moduleOfReference =
1228                                         validationContext.getModuleOfImplementation(
1229                                             overriddenImplementation.getIdentifier() );
1230 
1231                                     addDetail( validationContext.getReport(),
1232                                                "IMPLEMENTATION_IMPLEMENTATION_REFERENCE_OVERRIDE_WARNING",
1233                                                Level.WARNING, new ObjectFactory().createImplementation( impl ),
1234                                                "implementationImplementationOverrideWarning", impl.getIdentifier(),
1235                                                moduleOfImpl.getName(), r.getIdentifier(),
1236                                                overriddenImplementation.getIdentifier(),
1237                                                moduleOfReference.getName(),
1238                                                getNodePathString( overriddenReference ) );
1239 
1240                                 }
1241                             }
1242 
1243                             retainFinalNodes( overriddenReferences );
1244 
1245                             for ( final InheritanceModel.Node<ImplementationReference> overriddenReference
1246                                       : overriddenReferences )
1247                             {
1248                                 Implementation overriddenImplementation = overriddenReference.getImplementation();
1249                                 if ( overriddenReference.getClassDeclaration() != null )
1250                                 {
1251                                     overriddenImplementation = overriddenReference.getClassDeclaration();
1252                                 }
1253 
1254                                 final Module moduleOfReference =
1255                                     validationContext.getModuleOfImplementation(
1256                                         overriddenImplementation.getIdentifier() );
1257 
1258                                 addDetail( validationContext.getReport(),
1259                                            "IMPLEMENTATION_IMPLEMENTATION_REFERENCE_INHERITANCE_CONSTRAINT",
1260                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1261                                            "implementationFinalImplementatioReferenceConstraint", impl.getIdentifier(),
1262                                            moduleOfImpl.getName(), r.getIdentifier(),
1263                                            overriddenImplementation.getIdentifier(),
1264                                            moduleOfReference.getName(), getNodePathString( overriddenReference ) );
1265 
1266                             }
1267                         }
1268                     }
1269                 }
1270 
1271                 if ( impl.getMessages() != null )
1272                 {
1273                     for ( int j = 0, s1 = impl.getMessages().getMessage().size(); j < s1; j++ )
1274                     {
1275                         final Message m = impl.getMessages().getMessage().get( j );
1276 
1277                         if ( impl.getMessages().getReference( m.getName() ) != null )
1278                         {
1279                             addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGES_UNIQUENESS_CONSTRAINT",
1280                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1281                                        "implementationMessagesUniquenessConstraint", impl.getIdentifier(),
1282                                        moduleOfImpl.getName(), m.getName() );
1283 
1284                         }
1285 
1286                         if ( validationContext.isValidateJava() )
1287                         {
1288                             try
1289                             {
1290                                 m.getJavaConstantName();
1291                             }
1292                             catch ( final ModelObjectException e )
1293                             {
1294                                 final String message = getMessage( e );
1295 
1296                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1297                                 {
1298                                     validationContext.getModelContext().log( Level.FINE, message, e );
1299                                 }
1300 
1301                                 addDetail( validationContext.getReport(),
1302                                            "IMPLEMENTATION_MESSAGE_JAVA_CONSTANT_NAME_CONSTRAINT", Level.SEVERE,
1303                                            new ObjectFactory().createImplementation( impl ),
1304                                            "implementationMessageJavaConstantNameConstraint", impl.getIdentifier(),
1305                                            moduleOfImpl.getName(), m.getName(),
1306                                            message != null && message.length() > 0 ? " " + message : "" );
1307 
1308                             }
1309 
1310                             try
1311                             {
1312                                 m.getJavaGetterMethodName();
1313                             }
1314                             catch ( final ModelObjectException e )
1315                             {
1316                                 final String message = getMessage( e );
1317 
1318                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1319                                 {
1320                                     validationContext.getModelContext().log( Level.FINE, message, e );
1321                                 }
1322 
1323                                 addDetail( validationContext.getReport(),
1324                                            "IMPLEMENTATION_MESSAGE_JAVA_GETTER_METHOD_NAME_CONSTRAINT", Level.SEVERE,
1325                                            new ObjectFactory().createImplementation( impl ),
1326                                            "implementationMessageJavaGetterMethodNameConstraint", impl.getIdentifier(),
1327                                            moduleOfImpl.getName(), m.getName(),
1328                                            message != null && message.length() > 0 ? " " + message : "" );
1329 
1330                             }
1331 
1332                             try
1333                             {
1334                                 m.getJavaSetterMethodName();
1335                             }
1336                             catch ( final ModelObjectException e )
1337                             {
1338                                 final String message = getMessage( e );
1339 
1340                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1341                                 {
1342                                     validationContext.getModelContext().log( Level.FINE, message, e );
1343                                 }
1344 
1345                                 addDetail( validationContext.getReport(),
1346                                            "IMPLEMENTATION_MESSAGE_JAVA_SETTER_METHOD_NAME_CONSTRAINT", Level.SEVERE,
1347                                            new ObjectFactory().createImplementation( impl ),
1348                                            "implementationMessageJavaSetterMethodNameConstraint", impl.getIdentifier(),
1349                                            moduleOfImpl.getName(), m.getName(),
1350                                            message != null && message.length() > 0 ? " " + message : "" );
1351 
1352                             }
1353 
1354                             try
1355                             {
1356                                 m.getJavaVariableName();
1357                             }
1358                             catch ( final ModelObjectException e )
1359                             {
1360                                 final String message = getMessage( e );
1361 
1362                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1363                                 {
1364                                     validationContext.getModelContext().log( Level.FINE, message, e );
1365                                 }
1366 
1367                                 addDetail( validationContext.getReport(),
1368                                            "IMPLEMENTATION_MESSAGE_JAVA_VARIABLE_NAME_CONSTRAINT", Level.SEVERE,
1369                                            new ObjectFactory().createImplementation( impl ),
1370                                            "implementationMessageJavaVariableNameConstraint", impl.getIdentifier(),
1371                                            moduleOfImpl.getName(), m.getName(),
1372                                            message != null && message.length() > 0 ? " " + message : "" );
1373 
1374                             }
1375                         }
1376 
1377                         if ( m.getTemplate() != null )
1378                         {
1379                             for ( int k = 0, s2 = m.getTemplate().getText().size(); k < s2; k++ )
1380                             {
1381                                 final Text t = m.getTemplate().getText().get( k );
1382 
1383                                 try
1384                                 {
1385                                     t.getMimeType();
1386                                 }
1387                                 catch ( final ModelObjectException e )
1388                                 {
1389                                     final String message = getMessage( e );
1390 
1391                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1392                                     {
1393                                         validationContext.getModelContext().log( Level.FINE, message, e );
1394                                     }
1395 
1396                                     addDetail( validationContext.getReport(),
1397                                                "IMPLEMENTATION_MESSAGE_TEMPLATE_MIME_TYPE_CONSTRAINT", Level.SEVERE,
1398                                                new ObjectFactory().createImplementation( impl ),
1399                                                "implementationMessageTemplateMimeTypeConstraint", impl.getIdentifier(),
1400                                                moduleOfImpl.getName(), m.getName(), t.getLanguage(),
1401                                                message != null && message.length() > 0 ? " " + message : "" );
1402 
1403                                 }
1404 
1405                                 if ( validationContext.isValidateJava() )
1406                                 {
1407                                     try
1408                                     {
1409                                         new MessageFormat( t.getValue(), new Locale( t.getLanguage() ) );
1410                                     }
1411                                     catch ( final IllegalArgumentException e )
1412                                     {
1413                                         final String message = getMessage( e );
1414 
1415                                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1416                                         {
1417                                             validationContext.getModelContext().log( Level.FINE, message, e );
1418                                         }
1419 
1420                                         addDetail( validationContext.getReport(),
1421                                                    "IMPLEMENTATION_MESSAGE_TEMPLATE_CONSTRAINT", Level.SEVERE,
1422                                                    new ObjectFactory().createImplementation( impl ),
1423                                                    "implementationMessageTemplateConstraint", impl.getIdentifier(),
1424                                                    moduleOfImpl.getName(), m.getName(), t.getLanguage(),
1425                                                    message != null && message.length() > 0 ? " " + message : "" );
1426 
1427                                     }
1428                                 }
1429                             }
1430                         }
1431 
1432                         final Set<InheritanceModel.Node<Message>> effMessages =
1433                             imodel.getMessageNodes( impl.getIdentifier(), m.getName() );
1434 
1435                         for ( final InheritanceModel.Node<Message> effMessage : effMessages )
1436                         {
1437                             final Set<InheritanceModel.Node<Message>> overriddenMessages =
1438                                 modifiableSet( effMessage.getOverriddenNodes() );
1439 
1440                             if ( m.isOverride() && overriddenMessages.isEmpty() )
1441                             {
1442                                 addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_CONSTRAINT",
1443                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1444                                            "implementationMessageOverrideConstraint", impl.getIdentifier(),
1445                                            moduleOfImpl.getName(), m.getName() );
1446 
1447                             }
1448 
1449                             if ( !( m.isOverride() || overriddenMessages.isEmpty() ) )
1450                             {
1451                                 for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
1452                                 {
1453                                     Implementation overriddenImplementation = overriddenMessage.getImplementation();
1454                                     if ( overriddenMessage.getClassDeclaration() != null )
1455                                     {
1456                                         overriddenImplementation = overriddenMessage.getClassDeclaration();
1457                                     }
1458 
1459                                     final Module moduleOfMessage =
1460                                         validationContext.getModuleOfImplementation(
1461                                             overriddenImplementation.getIdentifier() );
1462 
1463                                     addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_WARNING",
1464                                                Level.WARNING, new ObjectFactory().createImplementation( impl ),
1465                                                "implementationMessageOverrideWarning", impl.getIdentifier(),
1466                                                moduleOfImpl.getName(), m.getName(),
1467                                                overriddenImplementation.getIdentifier(),
1468                                                moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
1469 
1470                                 }
1471                             }
1472 
1473                             retainFinalNodes( overriddenMessages );
1474 
1475                             for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
1476                             {
1477                                 Implementation overriddenImplementation = overriddenMessage.getImplementation();
1478                                 if ( overriddenMessage.getClassDeclaration() != null )
1479                                 {
1480                                     overriddenImplementation = overriddenMessage.getClassDeclaration();
1481                                 }
1482 
1483                                 final Module moduleOfMessage = validationContext.getModuleOfImplementation(
1484                                     overriddenImplementation.getIdentifier() );
1485 
1486                                 addDetail( validationContext.getReport(),
1487                                            "IMPLEMENTATION_MESSAGE_INHERITANCE_CONSTRAINT",
1488                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1489                                            "implementationMessageFinalConstraint", impl.getIdentifier(),
1490                                            moduleOfImpl.getName(), m.getName(),
1491                                            overriddenImplementation.getIdentifier(),
1492                                            moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
1493 
1494                             }
1495                         }
1496 
1497                         if ( m.getArguments() != null )
1498                         {
1499                             final Map<JavaIdentifier, Argument> javaVariableNames =
1500                                 new HashMap<JavaIdentifier, Argument>( m.getArguments().getArgument().size() );
1501 
1502                             for ( int k = 0, s2 = m.getArguments().getArgument().size(); k < s2; k++ )
1503                             {
1504                                 final Argument a = m.getArguments().getArgument().get( k );
1505 
1506                                 if ( validationContext.isValidateJava() )
1507                                 {
1508                                     try
1509                                     {
1510                                         a.getJavaTypeName();
1511                                     }
1512                                     catch ( final ModelObjectException e )
1513                                     {
1514                                         final String message = getMessage( e );
1515 
1516                                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1517                                         {
1518                                             validationContext.getModelContext().log( Level.FINE, message, e );
1519                                         }
1520 
1521                                         addDetail( validationContext.getReport(),
1522                                                    "IMPLEMENTATION_MESSAGE_ARGUMENT_JAVA_TYPE_NAME_CONSTRAINT",
1523                                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1524                                                    "implementationMessageArgumentJavaTypeNameConstraint",
1525                                                    impl.getIdentifier(), moduleOfImpl.getName(), m.getName(),
1526                                                    a.getName(),
1527                                                    message != null && message.length() > 0 ? " " + message : "" );
1528 
1529                                     }
1530 
1531                                     try
1532                                     {
1533                                         final JavaIdentifier javaIdentifier = a.getJavaVariableName();
1534 
1535                                         if ( javaVariableNames.containsKey( javaIdentifier ) )
1536                                         {
1537                                             addDetail( validationContext.getReport(),
1538                                                        "IMPLEMENTATION_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
1539                                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1540                                                        "implementationMessageArgumentJavaVariableNameUniquenessConstraint",
1541                                                        impl.getIdentifier(), moduleOfImpl.getName(), m.getName(),
1542                                                        a.getName(), javaIdentifier,
1543                                                        javaVariableNames.get( javaIdentifier ).getName() );
1544 
1545                                         }
1546                                         else
1547                                         {
1548                                             javaVariableNames.put( javaIdentifier, a );
1549                                         }
1550                                     }
1551                                     catch ( final ModelObjectException e )
1552                                     {
1553                                         final String message = getMessage( e );
1554 
1555                                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1556                                         {
1557                                             validationContext.getModelContext().log( Level.FINE, message, e );
1558                                         }
1559 
1560                                         addDetail( validationContext.getReport(),
1561                                                    "IMPLEMENTATION_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_CONSTRAINT",
1562                                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1563                                                    "implementationMessageArgumentJavaVariableNameConstraint",
1564                                                    impl.getIdentifier(), moduleOfImpl.getName(), m.getName(),
1565                                                    a.getIndex(),
1566                                                    message != null && message.length() > 0 ? " " + message : "" );
1567 
1568                                     }
1569                                 }
1570                             }
1571                         }
1572                     }
1573 
1574                     for ( int j = 0, s1 = impl.getMessages().getReference().size(); j < s1; j++ )
1575                     {
1576                         final MessageReference r = impl.getMessages().getReference().get( j );
1577 
1578                         final Set<InheritanceModel.Node<Message>> effMessages =
1579                             imodel.getMessageNodes( impl.getIdentifier(), r.getName() );
1580 
1581                         for ( final InheritanceModel.Node<Message> effMessage : effMessages )
1582                         {
1583                             final Set<InheritanceModel.Node<Message>> overriddenMessages =
1584                                 modifiableSet( effMessage.getOverriddenNodes() );
1585 
1586                             if ( r.isOverride() && overriddenMessages.isEmpty() )
1587                             {
1588                                 addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_CONSTRAINT",
1589                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1590                                            "implementationMessageOverrideConstraint", impl.getIdentifier(),
1591                                            moduleOfImpl.getName(), r.getName() );
1592 
1593                             }
1594 
1595                             if ( !( r.isOverride() || overriddenMessages.isEmpty() ) )
1596                             {
1597                                 for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
1598                                 {
1599                                     Implementation overriddenImplementation = overriddenMessage.getImplementation();
1600                                     if ( overriddenMessage.getClassDeclaration() != null )
1601                                     {
1602                                         overriddenImplementation = overriddenMessage.getClassDeclaration();
1603                                     }
1604 
1605                                     final Module moduleOfMessage =
1606                                         validationContext.getModuleOfImplementation(
1607                                             overriddenImplementation.getIdentifier() );
1608 
1609                                     addDetail( validationContext.getReport(), "IMPLEMENTATION_MESSAGE_OVERRIDE_WARNING",
1610                                                Level.WARNING, new ObjectFactory().createImplementation( impl ),
1611                                                "implementationMessageOverrideWarning", impl.getIdentifier(),
1612                                                moduleOfImpl.getName(), r.getName(),
1613                                                overriddenImplementation.getIdentifier(),
1614                                                moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
1615 
1616                                 }
1617                             }
1618 
1619                             retainFinalNodes( overriddenMessages );
1620 
1621                             for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
1622                             {
1623                                 Implementation overriddenImplementation = overriddenMessage.getImplementation();
1624                                 if ( overriddenMessage.getClassDeclaration() != null )
1625                                 {
1626                                     overriddenImplementation = overriddenMessage.getClassDeclaration();
1627                                 }
1628 
1629                                 final Module moduleOfMessage =
1630                                     validationContext.getModuleOfImplementation(
1631                                         overriddenImplementation.getIdentifier() );
1632 
1633                                 addDetail( validationContext.getReport(),
1634                                            "IMPLEMENTATION_MESSAGE_INHERITANCE_CONSTRAINT",
1635                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1636                                            "implementationMessageFinalConstraint", impl.getIdentifier(),
1637                                            moduleOfImpl.getName(), r.getName(),
1638                                            overriddenImplementation.getIdentifier(),
1639                                            moduleOfMessage.getName(), getNodePathString( overriddenMessage ) );
1640 
1641                             }
1642                         }
1643                     }
1644                 }
1645 
1646                 if ( impl.getProperties() != null )
1647                 {
1648                     for ( int j = 0, s1 = impl.getProperties().getProperty().size(); j < s1; j++ )
1649                     {
1650                         final Property p = impl.getProperties().getProperty().get( j );
1651 
1652                         if ( impl.getProperties().getReference( p.getName() ) != null )
1653                         {
1654                             addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTIES_UNIQUENESS_CONSTRAINT",
1655                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1656                                        "implementationPropertiesUniquenessConstraint", impl.getIdentifier(),
1657                                        moduleOfImpl.getName(), p.getName() );
1658 
1659                         }
1660 
1661                         if ( p.getValue() != null && p.getAny() != null )
1662                         {
1663                             addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_VALUE_CONSTRAINT",
1664                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1665                                        "implementationPropertyValueConstraint", impl.getIdentifier(),
1666                                        moduleOfImpl.getName(), p.getName() );
1667 
1668                         }
1669 
1670                         if ( p.getAny() != null && p.getType() == null )
1671                         {
1672                             addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_TYPE_CONSTRAINT",
1673                                        Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1674                                        "implementationPropertyTypeConstraint", impl.getIdentifier(),
1675                                        moduleOfImpl.getName(), p.getName() );
1676 
1677                         }
1678 
1679                         if ( validationContext.isValidateJava() )
1680                         {
1681                             try
1682                             {
1683                                 p.getJavaConstantName();
1684                             }
1685                             catch ( final ModelObjectException e )
1686                             {
1687                                 final String message = getMessage( e );
1688 
1689                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1690                                 {
1691                                     validationContext.getModelContext().log( Level.FINE, message, e );
1692                                 }
1693 
1694                                 addDetail( validationContext.getReport(),
1695                                            "IMPLEMENTATION_PROPERTY_JAVA_CONSTANT_NAME_CONSTRAINT",
1696                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1697                                            "implementationPropertyJavaConstantNameConstraint", impl.getIdentifier(),
1698                                            moduleOfImpl.getName(), p.getName(),
1699                                            message != null && message.length() > 0 ? " " + message : "" );
1700 
1701                             }
1702 
1703                             try
1704                             {
1705                                 p.getJavaGetterMethodName();
1706                             }
1707                             catch ( final ModelObjectException e )
1708                             {
1709                                 final String message = getMessage( e );
1710 
1711                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1712                                 {
1713                                     validationContext.getModelContext().log( Level.FINE, message, e );
1714                                 }
1715 
1716                                 addDetail( validationContext.getReport(),
1717                                            "IMPLEMENTATION_PROPERTY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
1718                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1719                                            "implementationPropertyJavaGetterMethodNameConstraint", impl.getIdentifier(),
1720                                            moduleOfImpl.getName(), p.getName(),
1721                                            message != null && message.length() > 0 ? " " + message : "" );
1722 
1723                             }
1724 
1725                             try
1726                             {
1727                                 p.getJavaSetterMethodName();
1728                             }
1729                             catch ( final ModelObjectException e )
1730                             {
1731                                 final String message = getMessage( e );
1732 
1733                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1734                                 {
1735                                     validationContext.getModelContext().log( Level.FINE, message, e );
1736                                 }
1737 
1738                                 addDetail( validationContext.getReport(),
1739                                            "IMPLEMENTATION_PROPERTY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
1740                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1741                                            "implementationPropertyJavaSetterMethodNameConstraint", impl.getIdentifier(),
1742                                            moduleOfImpl.getName(), p.getName(),
1743                                            message != null && message.length() > 0 ? " " + message : "" );
1744 
1745                             }
1746 
1747                             try
1748                             {
1749                                 p.getJavaTypeName();
1750                             }
1751                             catch ( final ModelObjectException e )
1752                             {
1753                                 final String message = getMessage( e );
1754 
1755                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1756                                 {
1757                                     validationContext.getModelContext().log( Level.FINE, message, e );
1758                                 }
1759 
1760                                 addDetail( validationContext.getReport(),
1761                                            "IMPLEMENTATION_PROPERTY_JAVA_TYPE_NAME_CONSTRAINT",
1762                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1763                                            "implementationPropertyJavaTypeNameConstraint", impl.getIdentifier(),
1764                                            moduleOfImpl.getName(), p.getName(),
1765                                            message != null && message.length() > 0 ? " " + message : "" );
1766 
1767                             }
1768 
1769                             try
1770                             {
1771                                 p.getJavaVariableName();
1772                             }
1773                             catch ( final ModelObjectException e )
1774                             {
1775                                 final String message = getMessage( e );
1776 
1777                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1778                                 {
1779                                     validationContext.getModelContext().log( Level.FINE, message, e );
1780                                 }
1781 
1782                                 addDetail( validationContext.getReport(),
1783                                            "IMPLEMENTATION_PROPERTY_JAVA_VARIABLE_NAME_CONSTRAINT",
1784                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1785                                            "implementationPropertyJavaVariableNameConstraint", impl.getIdentifier(),
1786                                            moduleOfImpl.getName(), p.getName(),
1787                                            message != null && message.length() > 0 ? " " + message : "" );
1788 
1789                             }
1790 
1791                             try
1792                             {
1793                                 p.getJavaValue( validationContext.getModelContext().getClassLoader() );
1794                             }
1795                             catch ( final ModelObjectException e )
1796                             {
1797                                 final String message = getMessage( e );
1798 
1799                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
1800                                 {
1801                                     validationContext.getModelContext().log( Level.FINE, message, e );
1802                                 }
1803 
1804                                 addDetail( validationContext.getReport(),
1805                                            "IMPLEMENTATION_PROPERTY_JAVA_VALUE_CONSTRAINT",
1806                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1807                                            "implementationPropertyJavaValueConstraint", impl.getIdentifier(),
1808                                            moduleOfImpl.getName(), p.getName(),
1809                                            message != null && message.length() > 0 ? " " + message : "" );
1810 
1811                             }
1812                         }
1813 
1814                         final Set<InheritanceModel.Node<Property>> effProperties =
1815                             imodel.getPropertyNodes( impl.getIdentifier(), p.getName() );
1816 
1817                         for ( final InheritanceModel.Node<Property> effProperty : effProperties )
1818                         {
1819                             final Set<InheritanceModel.Node<Property>> overriddenProperties =
1820                                 modifiableSet( effProperty.getOverriddenNodes() );
1821 
1822                             if ( p.isOverride() && overriddenProperties.isEmpty() )
1823                             {
1824                                 addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_OVERRIDE_CONSTRAINT",
1825                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1826                                            "implementationPropertyOverrideConstraint", impl.getIdentifier(),
1827                                            moduleOfImpl.getName(), p.getName() );
1828 
1829                             }
1830 
1831                             if ( !( p.isOverride() || overriddenProperties.isEmpty() ) )
1832                             {
1833                                 for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
1834                                 {
1835                                     if ( overriddenProperty.getSpecification() != null )
1836                                     {
1837                                         final Module moduleOfProperty =
1838                                             validationContext.getModuleOfSpecification(
1839                                                 overriddenProperty.getSpecification().getIdentifier() );
1840 
1841                                         addDetail( validationContext.getReport(),
1842                                                    "IMPLEMENTATION_PROPERTY_OVERRIDE_WARNING", Level.WARNING,
1843                                                    new ObjectFactory().createImplementation( impl ),
1844                                                    "implementationSpecificationPropertyOverrideWarning",
1845                                                    impl.getIdentifier(), moduleOfImpl.getName(), p.getName(),
1846                                                    overriddenProperty.getSpecification().getIdentifier(),
1847                                                    moduleOfProperty.getName(),
1848                                                    getNodePathString( overriddenProperty ) );
1849 
1850                                     }
1851                                     else
1852                                     {
1853                                         Implementation overriddenImplementation =
1854                                             overriddenProperty.getImplementation();
1855 
1856                                         if ( overriddenProperty.getClassDeclaration() != null )
1857                                         {
1858                                             overriddenImplementation = overriddenProperty.getClassDeclaration();
1859                                         }
1860 
1861                                         final Module moduleOfProperty =
1862                                             validationContext.getModuleOfImplementation(
1863                                                 overriddenImplementation.getIdentifier() );
1864 
1865                                         addDetail( validationContext.getReport(),
1866                                                    "IMPLEMENTATION_PROPERTY_OVERRIDE_WARNING", Level.WARNING,
1867                                                    new ObjectFactory().createImplementation( impl ),
1868                                                    "implementationPropertyOverrideWarning", impl.getIdentifier(),
1869                                                    moduleOfImpl.getName(), p.getName(),
1870                                                    overriddenImplementation.getIdentifier(),
1871                                                    moduleOfProperty.getName(),
1872                                                    getNodePathString( overriddenProperty ) );
1873 
1874                                     }
1875                                 }
1876                             }
1877 
1878                             retainFinalNodes( overriddenProperties );
1879 
1880                             for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
1881                             {
1882                                 Implementation overriddenImplementation = overriddenProperty.getImplementation();
1883                                 if ( overriddenProperty.getClassDeclaration() != null )
1884                                 {
1885                                     overriddenImplementation = overriddenProperty.getClassDeclaration();
1886                                 }
1887 
1888                                 final Module moduleOfProperty =
1889                                     validationContext.getModuleOfImplementation(
1890                                         overriddenImplementation.getIdentifier() );
1891 
1892                                 addDetail( validationContext.getReport(),
1893                                            "IMPLEMENTATION_PROPERTY_INHERITANCE_CONSTRAINT",
1894                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1895                                            "implementationPropertyFinalConstraint", impl.getIdentifier(),
1896                                            moduleOfImpl.getName(), p.getName(),
1897                                            overriddenImplementation.getIdentifier(),
1898                                            moduleOfProperty.getName(), getNodePathString( overriddenProperty ) );
1899 
1900                             }
1901                         }
1902                     }
1903 
1904                     for ( int j = 0, s1 = impl.getProperties().getReference().size(); j < s1; j++ )
1905                     {
1906                         final PropertyReference r = impl.getProperties().getReference().get( j );
1907 
1908                         final Set<InheritanceModel.Node<Property>> effProperties =
1909                             imodel.getPropertyNodes( impl.getIdentifier(), r.getName() );
1910 
1911                         for ( final InheritanceModel.Node<Property> effProperty : effProperties )
1912                         {
1913                             final Set<InheritanceModel.Node<Property>> overriddenProperties =
1914                                 modifiableSet( effProperty.getOverriddenNodes() );
1915 
1916                             if ( r.isOverride() && overriddenProperties.isEmpty() )
1917                             {
1918                                 addDetail( validationContext.getReport(), "IMPLEMENTATION_PROPERTY_OVERRIDE_CONSTRAINT",
1919                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1920                                            "implementationPropertyOverrideConstraint", impl.getIdentifier(),
1921                                            moduleOfImpl.getName(), r.getName() );
1922 
1923                             }
1924 
1925                             if ( !( r.isOverride() || overriddenProperties.isEmpty() ) )
1926                             {
1927                                 for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
1928                                 {
1929                                     Implementation overriddenImplementation = overriddenProperty.getImplementation();
1930                                     if ( overriddenProperty.getClassDeclaration() != null )
1931                                     {
1932                                         overriddenImplementation = overriddenProperty.getClassDeclaration();
1933                                     }
1934 
1935                                     final Module moduleOfProperty =
1936                                         validationContext.getModuleOfImplementation(
1937                                             overriddenImplementation.getIdentifier() );
1938 
1939                                     addDetail( validationContext.getReport(),
1940                                                "IMPLEMENTATION_PROPERTY_OVERRIDE_WARNING", Level.WARNING,
1941                                                new ObjectFactory().createImplementation( impl ),
1942                                                "implementationPropertyOverrideWarning", impl.getIdentifier(),
1943                                                moduleOfImpl.getName(), r.getName(),
1944                                                overriddenImplementation.getIdentifier(),
1945                                                moduleOfProperty.getName(), getNodePathString( overriddenProperty ) );
1946 
1947                                 }
1948                             }
1949 
1950                             retainFinalNodes( overriddenProperties );
1951 
1952                             for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
1953                             {
1954                                 Implementation overriddenImplementation = overriddenProperty.getImplementation();
1955                                 if ( overriddenProperty.getClassDeclaration() != null )
1956                                 {
1957                                     overriddenImplementation = overriddenProperty.getClassDeclaration();
1958                                 }
1959 
1960                                 final Module moduleOfProperty =
1961                                     validationContext.getModuleOfImplementation(
1962                                         overriddenImplementation.getIdentifier() );
1963 
1964                                 addDetail( validationContext.getReport(),
1965                                            "IMPLEMENTATION_PROPERTY_INHERITANCE_CONSTRAINT",
1966                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1967                                            "implementationPropertyFinalConstraint", impl.getIdentifier(),
1968                                            moduleOfImpl.getName(), r.getName(),
1969                                            overriddenImplementation.getIdentifier(),
1970                                            moduleOfProperty.getName(), getNodePathString( overriddenProperty ) );
1971 
1972                             }
1973                         }
1974                     }
1975                 }
1976 
1977                 if ( impl.getSpecifications() != null )
1978                 {
1979                     for ( int j = 0, s1 = impl.getSpecifications().getSpecification().size(); j < s1; j++ )
1980                     {
1981                         final Specification s = impl.getSpecifications().getSpecification().get( j );
1982 
1983                         addDetail( validationContext.getReport(), "IMPLEMENTATION_SPECIFICATION_DECLARATION_CONSTRAINT",
1984                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
1985                                    "implementationSpecificationDeclarationConstraint", impl.getIdentifier(),
1986                                    moduleOfImpl.getName(), s.getIdentifier() );
1987 
1988                     }
1989 
1990                     for ( int j = 0, s1 = impl.getSpecifications().getReference().size(); j < s1; j++ )
1991                     {
1992                         final SpecificationReference r = impl.getSpecifications().getReference().get( j );
1993 
1994                         final Set<InheritanceModel.Node<SpecificationReference>> effReferences =
1995                             imodel.getSpecificationReferenceNodes( impl.getIdentifier(), r.getIdentifier() );
1996 
1997                         for ( final InheritanceModel.Node<SpecificationReference> effReference : effReferences )
1998                         {
1999                             final Set<InheritanceModel.Node<SpecificationReference>> overriddenReferences =
2000                                 modifiableSet( effReference.getOverriddenNodes() );
2001 
2002                             if ( r.isOverride() && overriddenReferences.isEmpty() )
2003                             {
2004                                 addDetail( validationContext.getReport(),
2005                                            "IMPLEMENTATION_SPECIFICATION_OVERRIDE_CONSTRAINT", Level.SEVERE,
2006                                            new ObjectFactory().createImplementation( impl ),
2007                                            "implementationSpecificationOverrideConstraint", impl.getIdentifier(),
2008                                            moduleOfImpl.getName(), r.getIdentifier() );
2009 
2010                             }
2011 
2012                             if ( !( r.isOverride() || overriddenReferences.isEmpty() ) )
2013                             {
2014                                 for ( final InheritanceModel.Node<SpecificationReference> overriddenReference
2015                                           : overriddenReferences )
2016                                 {
2017                                     Implementation overriddenImplementation = overriddenReference.getImplementation();
2018                                     if ( overriddenReference.getClassDeclaration() != null )
2019                                     {
2020                                         overriddenImplementation = overriddenReference.getClassDeclaration();
2021                                     }
2022 
2023                                     final Module moduleOfReference =
2024                                         validationContext.getModuleOfImplementation(
2025                                             overriddenImplementation.getIdentifier() );
2026 
2027                                     addDetail( validationContext.getReport(),
2028                                                "IMPLEMENTATION_SPECIFICATION_REFERENCE_OVERRIDE_WARNING",
2029                                                Level.WARNING, new ObjectFactory().createImplementation( impl ),
2030                                                "implementationSpecificationOverrideWarning", impl.getIdentifier(),
2031                                                moduleOfImpl.getName(), r.getIdentifier(),
2032                                                overriddenImplementation.getIdentifier(),
2033                                                moduleOfReference.getName(), getNodePathString( overriddenReference ) );
2034 
2035                                 }
2036                             }
2037 
2038                             retainFinalNodes( overriddenReferences );
2039 
2040                             for ( final InheritanceModel.Node<SpecificationReference> overriddenReference
2041                                       : overriddenReferences )
2042                             {
2043                                 Implementation overriddenImplementation = overriddenReference.getImplementation();
2044                                 if ( overriddenReference.getClassDeclaration() != null )
2045                                 {
2046                                     overriddenImplementation = overriddenReference.getClassDeclaration();
2047                                 }
2048 
2049                                 final Module moduleOfReference =
2050                                     validationContext.getModuleOfImplementation(
2051                                         overriddenImplementation.getIdentifier() );
2052 
2053                                 addDetail( validationContext.getReport(),
2054                                            "IMPLEMENTATION_SPECIFICATION_INHERITANCE_CONSTRAINT", Level.SEVERE,
2055                                            new ObjectFactory().createImplementation( impl ),
2056                                            "implementationSpecificationFinalConstraint", impl.getIdentifier(),
2057                                            moduleOfImpl.getName(), r.getIdentifier(),
2058                                            overriddenImplementation.getIdentifier(),
2059                                            moduleOfReference.getName(), getNodePathString( overriddenReference ) );
2060 
2061                             }
2062                         }
2063                     }
2064                 }
2065 
2066                 if ( !impl.getAny().isEmpty() )
2067                 {
2068                     for ( int j = 0, s1 = impl.getAny().size(); j < s1; j++ )
2069                     {
2070                         final Object any = impl.getAny().get( j );
2071 
2072                         if ( any instanceof JAXBElement<?> )
2073                         {
2074                             final JAXBElement<?> jaxbElement = (JAXBElement<?>) any;
2075                             boolean overrideNode = false;
2076 
2077                             if ( jaxbElement.getValue() instanceof Inheritable )
2078                             {
2079                                 overrideNode = ( (Inheritable) jaxbElement.getValue() ).isOverride();
2080                             }
2081 
2082                             final Set<InheritanceModel.Node<JAXBElement<?>>> effElements =
2083                                 imodel.getJaxbElementNodes( impl.getIdentifier(), jaxbElement.getName() );
2084 
2085                             for ( final InheritanceModel.Node<JAXBElement<?>> effElement : effElements )
2086                             {
2087                                 final Set<InheritanceModel.Node<JAXBElement<?>>> overriddenElements =
2088                                     modifiableSet( effElement.getOverriddenNodes() );
2089 
2090                                 if ( overrideNode && overriddenElements.isEmpty() )
2091                                 {
2092                                     addDetail( validationContext.getReport(),
2093                                                "IMPLEMENTATION_JAXB_ELEMENT_OVERRIDE_CONSTRAINT",
2094                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2095                                                "implementationJaxbElementOverrideConstraint", impl.getIdentifier(),
2096                                                moduleOfImpl.getName(), jaxbElement.getName().toString() );
2097 
2098                                 }
2099 
2100                                 if ( !( overrideNode || overriddenElements.isEmpty() ) )
2101                                 {
2102                                     for ( final InheritanceModel.Node<JAXBElement<?>> overriddenElement
2103                                               : overriddenElements )
2104                                     {
2105                                         Implementation overriddenImplementation = overriddenElement.getImplementation();
2106                                         if ( overriddenElement.getClassDeclaration() != null )
2107                                         {
2108                                             overriddenImplementation = overriddenElement.getClassDeclaration();
2109                                         }
2110 
2111                                         final Module moduleOfElement =
2112                                             validationContext.getModuleOfImplementation(
2113                                                 overriddenElement.getImplementation().getIdentifier() );
2114 
2115                                         addDetail( validationContext.getReport(),
2116                                                    "IMPLEMENTATION_JAXB_ELEMENT_OVERRIDE_WARNING",
2117                                                    Level.WARNING, new ObjectFactory().createImplementation( impl ),
2118                                                    "implementationJaxbElementOverrideWarning", impl.getIdentifier(),
2119                                                    moduleOfImpl.getName(), jaxbElement.getName().toString(),
2120                                                    overriddenImplementation.getIdentifier(),
2121                                                    moduleOfElement.getName(), getNodePathString( overriddenElement ) );
2122 
2123                                     }
2124                                 }
2125 
2126                                 retainFinalNodes( overriddenElements );
2127 
2128                                 for ( final InheritanceModel.Node<JAXBElement<?>> overriddenElement : overriddenElements )
2129                                 {
2130                                     Implementation overriddenImplementation = overriddenElement.getImplementation();
2131                                     if ( overriddenElement.getClassDeclaration() != null )
2132                                     {
2133                                         overriddenImplementation = overriddenElement.getClassDeclaration();
2134                                     }
2135 
2136                                     final Module moduleOfElement =
2137                                         validationContext.getModuleOfImplementation(
2138                                             overriddenImplementation.getIdentifier() );
2139 
2140                                     addDetail( validationContext.getReport(),
2141                                                "IMPLEMENTATION_JAXB_ELEMENT_INHERITANCE_CONSTRAINT",
2142                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2143                                                "implementationJaxbElementFinalConstraint", impl.getIdentifier(),
2144                                                moduleOfImpl.getName(), jaxbElement.getName().toString(),
2145                                                overriddenImplementation.getIdentifier(),
2146                                                moduleOfElement.getName(), getNodePathString( overriddenElement ) );
2147 
2148                                 }
2149                             }
2150                         }
2151                     }
2152                 }
2153 
2154                 final Set<String> dependencyNames = imodel.getDependencyNames( impl.getIdentifier() );
2155 
2156                 final Map<JavaIdentifier, InheritanceModel.Node<Dependency>> dependencyJavaConstantNames =
2157                     new HashMap<JavaIdentifier, InheritanceModel.Node<Dependency>>( dependencyNames.size() );
2158 
2159                 final Map<JavaIdentifier, InheritanceModel.Node<Dependency>> dependencyJavaGetterMethodNames =
2160                     new HashMap<JavaIdentifier, InheritanceModel.Node<Dependency>>( dependencyNames.size() );
2161 
2162                 final Map<JavaIdentifier, InheritanceModel.Node<Dependency>> dependencyJavaSetterMethodNames =
2163                     new HashMap<JavaIdentifier, InheritanceModel.Node<Dependency>>( dependencyNames.size() );
2164 
2165                 final Map<JavaIdentifier, InheritanceModel.Node<Dependency>> dependencyJavaVariableNames =
2166                     new HashMap<JavaIdentifier, InheritanceModel.Node<Dependency>>( dependencyNames.size() );
2167 
2168                 for ( final String dependencyName : dependencyNames )
2169                 {
2170                     final Set<InheritanceModel.Node<Dependency>> dependencyNodes =
2171                         imodel.getDependencyNodes( impl.getIdentifier(), dependencyName );
2172 
2173                     if ( dependencyNodes.size() > 1 )
2174                     {
2175                         addDetail( validationContext.getReport(),
2176                                    "IMPLEMENTATION_DEPENDENCY_MULTIPLE_INHERITANCE_CONSTRAINT",
2177                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2178                                    "implementationMultipleInheritanceDependencyConstraint", impl.getIdentifier(),
2179                                    moduleOfImpl.getName(), dependencyName, getNodeListPathString( dependencyNodes ) );
2180 
2181                     }
2182 
2183                     if ( validationContext.isValidateJava() )
2184                     {
2185                         for ( final InheritanceModel.Node<Dependency> node : dependencyNodes )
2186                         {
2187                             try
2188                             {
2189                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaConstantName();
2190                                 final InheritanceModel.Node<Dependency> existingNode =
2191                                     dependencyJavaConstantNames.get( javaIdentifier );
2192 
2193                                 if ( existingNode != null )
2194                                 {
2195                                     addDetail( validationContext.getReport(),
2196                                                "IMPLEMENTATION_DEPENDENCY_JAVA_CONSTANT_NAME_UNIQUENESS_CONSTRAINT",
2197                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2198                                                "implementationDependencyJavaConstantNameUniquenessConstraint",
2199                                                impl.getIdentifier(), moduleOfImpl.getName(), dependencyName,
2200                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2201                                                getNodePathString( existingNode ), javaIdentifier );
2202 
2203                                 }
2204                                 else
2205                                 {
2206                                     dependencyJavaConstantNames.put( javaIdentifier, node );
2207                                 }
2208                             }
2209                             catch ( final ModelObjectException e )
2210                             {
2211                                 // Validated above.
2212                             }
2213 
2214                             try
2215                             {
2216                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaGetterMethodName();
2217                                 final InheritanceModel.Node<Dependency> existingNode =
2218                                     dependencyJavaGetterMethodNames.get( javaIdentifier );
2219 
2220                                 if ( existingNode != null )
2221                                 {
2222                                     addDetail( validationContext.getReport(),
2223                                                "IMPLEMENTATION_DEPENDENCY_JAVA_GETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2224                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2225                                                "implementationDependencyJavaGetterMethodNameUniquenessConstraint",
2226                                                impl.getIdentifier(), moduleOfImpl.getName(), dependencyName,
2227                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2228                                                getNodePathString( existingNode ), javaIdentifier );
2229 
2230                                 }
2231                                 else
2232                                 {
2233                                     dependencyJavaGetterMethodNames.put( javaIdentifier, node );
2234                                 }
2235                             }
2236                             catch ( final ModelObjectException e )
2237                             {
2238                                 // Validated above.
2239                             }
2240 
2241                             try
2242                             {
2243                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2244                                 final InheritanceModel.Node<Dependency> existingNode =
2245                                     dependencyJavaSetterMethodNames.get( javaIdentifier );
2246 
2247                                 if ( existingNode != null )
2248                                 {
2249                                     addDetail( validationContext.getReport(),
2250                                                "IMPLEMENTATION_DEPENDENCY_JAVA_SETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2251                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2252                                                "implementationDependencyJavaSetterMethodNameUniquenessConstraint",
2253                                                impl.getIdentifier(), moduleOfImpl.getName(), dependencyName,
2254                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2255                                                getNodePathString( existingNode ), javaIdentifier );
2256 
2257                                 }
2258                                 else
2259                                 {
2260                                     dependencyJavaSetterMethodNames.put( javaIdentifier, node );
2261                                 }
2262                             }
2263                             catch ( final ModelObjectException e )
2264                             {
2265                                 // Validated above.
2266                             }
2267 
2268                             try
2269                             {
2270                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2271                                 final InheritanceModel.Node<Dependency> existingNode =
2272                                     dependencyJavaVariableNames.get( javaIdentifier );
2273 
2274                                 if ( existingNode != null )
2275                                 {
2276                                     addDetail( validationContext.getReport(),
2277                                                "IMPLEMENTATION_DEPENDENCY_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
2278                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2279                                                "implementationDependencyJavaVariableNameUniquenessConstraint",
2280                                                impl.getIdentifier(), moduleOfImpl.getName(), dependencyName,
2281                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2282                                                getNodePathString( existingNode ), javaIdentifier );
2283 
2284                                 }
2285                                 else
2286                                 {
2287                                     dependencyJavaVariableNames.put( javaIdentifier, node );
2288                                 }
2289                             }
2290                             catch ( final ModelObjectException e )
2291                             {
2292                                 // Validated above.
2293                             }
2294                         }
2295                     }
2296                 }
2297 
2298                 final Set<String> messageNames = imodel.getMessageNames( impl.getIdentifier() );
2299 
2300                 final Map<JavaIdentifier, InheritanceModel.Node<Message>> messageJavaConstantNames =
2301                     new HashMap<JavaIdentifier, InheritanceModel.Node<Message>>( messageNames.size() );
2302 
2303                 final Map<JavaIdentifier, InheritanceModel.Node<Message>> messageJavaGetterMethodNames =
2304                     new HashMap<JavaIdentifier, InheritanceModel.Node<Message>>( messageNames.size() );
2305 
2306                 final Map<JavaIdentifier, InheritanceModel.Node<Message>> messageJavaSetterMethodNames =
2307                     new HashMap<JavaIdentifier, InheritanceModel.Node<Message>>( messageNames.size() );
2308 
2309                 final Map<JavaIdentifier, InheritanceModel.Node<Message>> messageJavaVariableNames =
2310                     new HashMap<JavaIdentifier, InheritanceModel.Node<Message>>( messageNames.size() );
2311 
2312                 for ( final String messageName : messageNames )
2313                 {
2314                     final Set<InheritanceModel.Node<Message>> messageNodes =
2315                         imodel.getMessageNodes( impl.getIdentifier(), messageName );
2316 
2317                     if ( messageNodes.size() > 1 )
2318                     {
2319                         addDetail( validationContext.getReport(),
2320                                    "IMPLEMENTATION_MESSAGE_MULTIPLE_INHERITANCE_CONSTRAINT", Level.SEVERE,
2321                                    new ObjectFactory().createImplementation( impl ),
2322                                    "implementationMultipleInheritanceMessageConstraint", impl.getIdentifier(),
2323                                    moduleOfImpl.getName(), messageName, getNodeListPathString( messageNodes ) );
2324 
2325                     }
2326 
2327                     if ( validationContext.isValidateJava() )
2328                     {
2329                         for ( final InheritanceModel.Node<Message> node : messageNodes )
2330                         {
2331                             try
2332                             {
2333                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaConstantName();
2334                                 final InheritanceModel.Node<Message> existingNode =
2335                                     messageJavaConstantNames.get( javaIdentifier );
2336 
2337                                 if ( existingNode != null )
2338                                 {
2339                                     addDetail( validationContext.getReport(),
2340                                                "IMPLEMENTATION_MESSAGE_JAVA_CONSTANT_NAME_UNIQUENESS_CONSTRAINT",
2341                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2342                                                "implementationMessageJavaConstantNameUniquenessConstraint",
2343                                                impl.getIdentifier(), moduleOfImpl.getName(), messageName,
2344                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2345                                                getNodePathString( existingNode ), javaIdentifier );
2346 
2347                                 }
2348                                 else
2349                                 {
2350                                     messageJavaConstantNames.put( javaIdentifier, node );
2351                                 }
2352                             }
2353                             catch ( final ModelObjectException e )
2354                             {
2355                                 // Validated above.
2356                             }
2357 
2358                             try
2359                             {
2360                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaGetterMethodName();
2361                                 final InheritanceModel.Node<Message> existingNode =
2362                                     messageJavaGetterMethodNames.get( javaIdentifier );
2363 
2364                                 if ( existingNode != null )
2365                                 {
2366                                     addDetail( validationContext.getReport(),
2367                                                "IMPLEMENTATION_MESSAGE_JAVA_GETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2368                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2369                                                "implementationMessageJavaGetterMethodNameUniquenessConstraint",
2370                                                impl.getIdentifier(), moduleOfImpl.getName(), messageName,
2371                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2372                                                getNodePathString( existingNode ), javaIdentifier );
2373 
2374                                 }
2375                                 else
2376                                 {
2377                                     messageJavaGetterMethodNames.put( javaIdentifier, node );
2378                                 }
2379                             }
2380                             catch ( final ModelObjectException e )
2381                             {
2382                                 // Validated above.
2383                             }
2384 
2385                             try
2386                             {
2387                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2388                                 final InheritanceModel.Node<Message> existingNode =
2389                                     messageJavaSetterMethodNames.get( javaIdentifier );
2390 
2391                                 if ( existingNode != null )
2392                                 {
2393                                     addDetail( validationContext.getReport(),
2394                                                "IMPLEMENTATION_MESSAGE_JAVA_SETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2395                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2396                                                "implementationMessageJavaSetterMethodNameUniquenessConstraint",
2397                                                impl.getIdentifier(), moduleOfImpl.getName(), messageName,
2398                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2399                                                getNodePathString( existingNode ), javaIdentifier );
2400 
2401                                 }
2402                                 else
2403                                 {
2404                                     messageJavaSetterMethodNames.put( javaIdentifier, node );
2405                                 }
2406                             }
2407                             catch ( final ModelObjectException e )
2408                             {
2409                                 // Validated above.
2410                             }
2411 
2412                             try
2413                             {
2414                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2415                                 final InheritanceModel.Node<Message> existingNode =
2416                                     messageJavaVariableNames.get( javaIdentifier );
2417 
2418                                 if ( existingNode != null )
2419                                 {
2420                                     addDetail( validationContext.getReport(),
2421                                                "IMPLEMENTATION_MESSAGE_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
2422                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2423                                                "implementationMessageJavaVariableNameUniquenessConstraint",
2424                                                impl.getIdentifier(), moduleOfImpl.getName(), messageName,
2425                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2426                                                getNodePathString( existingNode ), javaIdentifier );
2427 
2428                                 }
2429                                 else
2430                                 {
2431                                     messageJavaVariableNames.put( javaIdentifier, node );
2432                                 }
2433                             }
2434                             catch ( final ModelObjectException e )
2435                             {
2436                                 // Validated above.
2437                             }
2438                         }
2439                     }
2440                 }
2441 
2442                 final Set<String> propertyNames = imodel.getPropertyNames( impl.getIdentifier() );
2443 
2444                 final Map<JavaIdentifier, InheritanceModel.Node<Property>> propertyJavaConstantNames =
2445                     new HashMap<JavaIdentifier, InheritanceModel.Node<Property>>( messageNames.size() );
2446 
2447                 final Map<JavaIdentifier, InheritanceModel.Node<Property>> propertyJavaGetterMethodNames =
2448                     new HashMap<JavaIdentifier, InheritanceModel.Node<Property>>( messageNames.size() );
2449 
2450                 final Map<JavaIdentifier, InheritanceModel.Node<Property>> propertyJavaSetterMethodNames =
2451                     new HashMap<JavaIdentifier, InheritanceModel.Node<Property>>( messageNames.size() );
2452 
2453                 final Map<JavaIdentifier, InheritanceModel.Node<Property>> propertyJavaVariableNames =
2454                     new HashMap<JavaIdentifier, InheritanceModel.Node<Property>>( messageNames.size() );
2455 
2456                 for ( final String propertyName : propertyNames )
2457                 {
2458                     final Set<InheritanceModel.Node<Property>> propertyNodes =
2459                         imodel.getPropertyNodes( impl.getIdentifier(), propertyName );
2460 
2461                     if ( propertyNodes.size() > 1 )
2462                     {
2463                         addDetail( validationContext.getReport(),
2464                                    "IMPLEMENTATION_PROPERTY_MULTIPLE_INHERITANCE_CONSTRAINT", Level.SEVERE,
2465                                    new ObjectFactory().createImplementation( impl ),
2466                                    "implementationMultipleInheritancePropertyConstraint", impl.getIdentifier(),
2467                                    moduleOfImpl.getName(), propertyName, getNodeListPathString( propertyNodes ) );
2468 
2469                     }
2470 
2471                     if ( validationContext.isValidateJava() )
2472                     {
2473                         for ( final InheritanceModel.Node<Property> node : propertyNodes )
2474                         {
2475                             try
2476                             {
2477                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaConstantName();
2478                                 final InheritanceModel.Node<Property> existingNode =
2479                                     propertyJavaConstantNames.get( javaIdentifier );
2480 
2481                                 if ( existingNode != null )
2482                                 {
2483                                     addDetail( validationContext.getReport(),
2484                                                "IMPLEMENTATION_PROPERTY_JAVA_CONSTANT_NAME_UNIQUENESS_CONSTRAINT",
2485                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2486                                                "implementationPropertyJavaConstantNameUniquenessConstraint",
2487                                                impl.getIdentifier(), moduleOfImpl.getName(), propertyName,
2488                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2489                                                getNodePathString( existingNode ), javaIdentifier );
2490 
2491                                 }
2492                                 else
2493                                 {
2494                                     propertyJavaConstantNames.put( javaIdentifier, node );
2495                                 }
2496                             }
2497                             catch ( final ModelObjectException e )
2498                             {
2499                                 // Validated above.
2500                             }
2501 
2502                             try
2503                             {
2504                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaGetterMethodName();
2505                                 final InheritanceModel.Node<Property> existingNode =
2506                                     propertyJavaGetterMethodNames.get( javaIdentifier );
2507 
2508                                 if ( existingNode != null )
2509                                 {
2510                                     addDetail( validationContext.getReport(),
2511                                                "IMPLEMENTATION_PROPERTY_JAVA_GETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2512                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2513                                                "implementationPropertyJavaGetterMethodNameUniquenessConstraint",
2514                                                impl.getIdentifier(), moduleOfImpl.getName(), propertyName,
2515                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2516                                                getNodePathString( existingNode ), javaIdentifier );
2517 
2518                                 }
2519                                 else
2520                                 {
2521                                     propertyJavaGetterMethodNames.put( javaIdentifier, node );
2522                                 }
2523                             }
2524                             catch ( final ModelObjectException e )
2525                             {
2526                                 // Validated above.
2527                             }
2528 
2529                             try
2530                             {
2531                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2532                                 final InheritanceModel.Node<Property> existingNode =
2533                                     propertyJavaSetterMethodNames.get( javaIdentifier );
2534 
2535                                 if ( existingNode != null )
2536                                 {
2537                                     addDetail( validationContext.getReport(),
2538                                                "IMPLEMENTATION_PROPERTY_JAVA_SETTER_METHOD_NAME_UNIQUENESS_CONSTRAINT",
2539                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2540                                                "implementationPropertyJavaSetterMethodNameUniquenessConstraint",
2541                                                impl.getIdentifier(), moduleOfImpl.getName(), propertyName,
2542                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2543                                                getNodePathString( existingNode ), javaIdentifier );
2544 
2545                                 }
2546                                 else
2547                                 {
2548                                     propertyJavaSetterMethodNames.put( javaIdentifier, node );
2549                                 }
2550                             }
2551                             catch ( final ModelObjectException e )
2552                             {
2553                                 // Validated above.
2554                             }
2555 
2556                             try
2557                             {
2558                                 final JavaIdentifier javaIdentifier = node.getModelObject().getJavaSetterMethodName();
2559                                 final InheritanceModel.Node<Property> existingNode =
2560                                     propertyJavaVariableNames.get( javaIdentifier );
2561 
2562                                 if ( existingNode != null )
2563                                 {
2564                                     addDetail( validationContext.getReport(),
2565                                                "IMPLEMENTATION_PROPERTY_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
2566                                                Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2567                                                "implementationPropertyJavaVariableNameUniquenessConstraint",
2568                                                impl.getIdentifier(), moduleOfImpl.getName(), propertyName,
2569                                                getNodePathString( node ), existingNode.getModelObject().getName(),
2570                                                getNodePathString( existingNode ), javaIdentifier );
2571 
2572                                 }
2573                                 else
2574                                 {
2575                                     propertyJavaVariableNames.put( javaIdentifier, node );
2576                                 }
2577                             }
2578                             catch ( final ModelObjectException e )
2579                             {
2580                                 // Validated above.
2581                             }
2582                         }
2583                     }
2584                 }
2585 
2586                 final Set<String> specificationReferenceIdentifiers =
2587                     imodel.getSpecificationReferenceIdentifiers( impl.getIdentifier() );
2588 
2589                 for ( final String specificationRefereneIdentifier : specificationReferenceIdentifiers )
2590                 {
2591                     final Set<InheritanceModel.Node<SpecificationReference>> specificationReferenceNodes =
2592                         imodel.getSpecificationReferenceNodes( impl.getIdentifier(), specificationRefereneIdentifier );
2593 
2594                     if ( specificationReferenceNodes.size() > 1 )
2595                     {
2596                         addDetail( validationContext.getReport(),
2597                                    "IMPLEMENTATION_SPECIFICATION_MULTIPLE_INHERITANCE_CONSTRAINT",
2598                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2599                                    "implementationMultipleInheritanceSpecificationConstraint",
2600                                    impl.getIdentifier(), moduleOfImpl.getName(), specificationRefereneIdentifier,
2601                                    getNodeListPathString( specificationReferenceNodes ) );
2602 
2603                     }
2604                 }
2605 
2606                 final Set<QName> xmlElementNames = imodel.getXmlElementNames( impl.getIdentifier() );
2607 
2608                 for ( final QName xmlElementName : xmlElementNames )
2609                 {
2610                     final Set<InheritanceModel.Node<Element>> xmlElementNodes =
2611                         imodel.getXmlElementNodes( impl.getIdentifier(), xmlElementName );
2612 
2613                     if ( xmlElementNodes.size() > 1 )
2614                     {
2615                         addDetail( validationContext.getReport(),
2616                                    "IMPLEMENTATION_XML_ELEMENT_MULTIPLE_INHERITANCE_CONSTRAINT",
2617                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2618                                    "implementationMultipleInheritanceXmlElementConstraint",
2619                                    impl.getIdentifier(), moduleOfImpl.getName(), xmlElementName.toString(),
2620                                    getNodeListPathString( xmlElementNodes ) );
2621 
2622                     }
2623                 }
2624 
2625                 final Set<QName> jaxbElementNames = imodel.getJaxbElementNames( impl.getIdentifier() );
2626 
2627                 for ( final QName jaxbElementName : jaxbElementNames )
2628                 {
2629                     final Set<InheritanceModel.Node<JAXBElement<?>>> jaxbElementNodes =
2630                         imodel.getJaxbElementNodes( impl.getIdentifier(), jaxbElementName );
2631 
2632                     if ( jaxbElementNodes.size() > 1 )
2633                     {
2634                         addDetail( validationContext.getReport(),
2635                                    "IMPLEMENTATION_JAXB_ELEMENT_MULTIPLE_INHERITANCE_CONSTRAINT",
2636                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2637                                    "implementationMultipleInheritanceJaxbElementConstraint",
2638                                    impl.getIdentifier(), moduleOfImpl.getName(), jaxbElementName.toString(),
2639                                    getNodeListPathString( jaxbElementNodes ) );
2640 
2641                     }
2642                 }
2643 
2644                 final Set<String> implementationReferenceIdentifiers =
2645                     imodel.getImplementationReferenceIdentifiers( impl.getIdentifier() );
2646 
2647                 for ( final String implementationReferenceIdentifier : implementationReferenceIdentifiers )
2648                 {
2649                     final Set<InheritanceModel.Node<ImplementationReference>> implementationReferenceNodes =
2650                         imodel.getImplementationReferenceNodes( impl.getIdentifier(),
2651                                                                 implementationReferenceIdentifier );
2652 
2653                     for ( final InheritanceModel.Node<ImplementationReference> node : implementationReferenceNodes )
2654                     {
2655                         final ImplementationReference r = node.getModelObject();
2656 
2657                         final Implementation referenced =
2658                             validationContext.getImplementation( r.getIdentifier() );
2659 
2660                         final Module moduleOfReferenced =
2661                             validationContext.getModuleOfImplementation( referenced.getIdentifier() );
2662 
2663                         if ( r.getVersion() != null && referenced != null )
2664                         {
2665                             if ( referenced.getVersion() == null )
2666                             {
2667                                 addDetail( validationContext.getReport(),
2668                                            "IMPLEMENTATION_IMPLEMENTATION_VERSIONING_CONSTRAINT", Level.SEVERE,
2669                                            new ObjectFactory().createImplementation( impl ),
2670                                            "implementationImplementationVersioningConstraint",
2671                                            impl.getIdentifier(), moduleOfImpl.getName(), r.getIdentifier(),
2672                                            moduleOfReferenced.getName() );
2673 
2674                             }
2675                             else
2676                             {
2677                                 try
2678                                 {
2679                                     if ( VersionParser.compare( r.getVersion(), referenced.getVersion() ) > 0 )
2680                                     {
2681                                         addDetail( validationContext.getReport(),
2682                                                    "IMPLEMENTATION_INHERITANCE_COMPATIBILITY_CONSTRAINT",
2683                                                    Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2684                                                    "implementationInheritanceCompatibilityConstraint",
2685                                                    impl.getIdentifier(), moduleOfImpl.getName(),
2686                                                    referenced.getIdentifier(), moduleOfReferenced.getName(),
2687                                                    r.getVersion(), referenced.getVersion() );
2688 
2689                                     }
2690                                 }
2691                                 catch ( final ParseException ex )
2692                                 {
2693                                     final String message = getMessage( ex );
2694 
2695                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2696                                     {
2697                                         validationContext.getModelContext().log( Level.FINE, message, ex );
2698                                     }
2699 
2700                                     addDetail(
2701                                         validationContext.getReport(),
2702                                         "IMPLEMENTATION_INHERITANCE_COMPATIBILITY_VERSIONING_PARSE_EXCEPTION",
2703                                         Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2704                                         "implementationInheritanceCompatibilityParseException",
2705                                         impl.getIdentifier(), moduleOfImpl.getName(), r.getIdentifier(),
2706                                         moduleOfReferenced.getName(), r.getVersion(),
2707                                         message != null && message.length() > 0 ? " " + message : "" );
2708 
2709                                 }
2710                                 catch ( final TokenMgrError ex )
2711                                 {
2712                                     final String message = getMessage( ex );
2713 
2714                                     if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2715                                     {
2716                                         validationContext.getModelContext().log( Level.FINE, message, ex );
2717                                     }
2718 
2719                                     addDetail(
2720                                         validationContext.getReport(),
2721                                         "IMPLEMENTATION_INHERITANCE_COMPATIBILITY_VERSIONING_TOKEN_MANAGER_ERROR",
2722                                         Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2723                                         "implementationInheritanceCompatiblityVersioningTokenManagerError",
2724                                         impl.getIdentifier(), moduleOfImpl.getName(), r.getIdentifier(),
2725                                         moduleOfReferenced.getName(), r.getVersion(),
2726                                         message != null && message.length() > 0 ? " " + message : "" );
2727 
2728                                 }
2729                             }
2730                         }
2731                     }
2732                 }
2733 
2734                 assertImplementationSpecificationCompatibility( validationContext, impl );
2735             }
2736         }
2737     }
2738 
2739     private static void assertSpecificationsValid( final ValidationContext validationContext )
2740     {
2741         final Specifications specifications = validationContext.getAllSpecifications();
2742         final Map<String, Specification> specificationClassDeclarations = new HashMap<String, Specification>();
2743         final Map<String, Specification> specificationJavaClassDeclarations =
2744             new HashMap<String, Specification>();
2745 
2746         if ( specifications != null )
2747         {
2748             for ( int i = 0, s0 = specifications.getSpecification().size(); i < s0; i++ )
2749             {
2750                 final Specification s = specifications.getSpecification().get( i );
2751                 final Implementations impls = validationContext.getImplementations( s.getIdentifier() );
2752                 final Module moduleOfS = validationContext.getModuleOfSpecification( s.getIdentifier() );
2753 
2754                 if ( validationContext.isValidateJava() )
2755                 {
2756                     try
2757                     {
2758                         s.getJavaTypeName();
2759                     }
2760                     catch ( final ModelObjectException e )
2761                     {
2762                         final String message = getMessage( e );
2763 
2764                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2765                         {
2766                             validationContext.getModelContext().log( Level.FINE, message, e );
2767                         }
2768 
2769                         addDetail( validationContext.getReport(),
2770                                    "SPECIFICATION_JAVA_TYPE_NAME_CONSTRAINT",
2771                                    Level.SEVERE, new ObjectFactory().createSpecification( s ),
2772                                    "specificationJavaTypeNameConstraint", s.getIdentifier(),
2773                                    moduleOfS.getName(), s.getClazz(),
2774                                    message != null && message.length() > 0 ? " " + message : "" );
2775 
2776                     }
2777                 }
2778 
2779                 if ( s.isClassDeclaration() )
2780                 {
2781                     if ( s.getClazz() == null )
2782                     {
2783                         addDetail( validationContext.getReport(), "SPECIFICATION_CLASS_CONSTRAINT", Level.SEVERE,
2784                                    new ObjectFactory().createSpecification( s ), "specificationClassConstraint",
2785                                    s.getIdentifier(), moduleOfS.getName() );
2786 
2787                     }
2788                     else
2789                     {
2790                         final Specification prev = specificationClassDeclarations.get( s.getClazz() );
2791 
2792                         if ( prev != null && !prev.getIdentifier().equals( s.getIdentifier() ) )
2793                         {
2794                             final Module moduleOfPrev =
2795                                 validationContext.getModuleOfSpecification( prev.getIdentifier() );
2796 
2797                             addDetail( validationContext.getReport(), "SPECIFICATION_CLASS_DECLARATION_CONSTRAINT",
2798                                        Level.SEVERE, new ObjectFactory().createSpecification( s ),
2799                                        "specificationClassDeclarationConstraint", s.getIdentifier(),
2800                                        moduleOfS.getName(), s.getClazz(), prev.getIdentifier(),
2801                                        moduleOfPrev.getName() );
2802 
2803                         }
2804                         else
2805                         {
2806                             specificationClassDeclarations.put( s.getClazz(), s );
2807                         }
2808 
2809                         if ( validationContext.isValidateJava() )
2810                         {
2811                             try
2812                             {
2813                                 final Specification java =
2814                                     specificationJavaClassDeclarations.get( s.getJavaTypeName().getClassName() );
2815 
2816                                 if ( java != null && !java.getIdentifier().equals( s.getIdentifier() ) )
2817                                 {
2818                                     final Module moduleOfJava =
2819                                         validationContext.getModuleOfSpecification( java.getIdentifier() );
2820 
2821                                     addDetail( validationContext.getReport(),
2822                                                "SPECIFICATION_JAVA_CLASS_DECLARATION_CONSTRAINT",
2823                                                Level.SEVERE, new ObjectFactory().createSpecification( s ),
2824                                                "specificationJavaClassDeclarationConstraint", s.getIdentifier(),
2825                                                moduleOfS.getName(), s.getJavaTypeName().getClassName(),
2826                                                java.getIdentifier(), moduleOfJava.getName() );
2827 
2828                                 }
2829                                 else
2830                                 {
2831                                     specificationJavaClassDeclarations.put( s.getJavaTypeName().getClassName(), s );
2832                                 }
2833                             }
2834                             catch ( final ModelObjectException e )
2835                             {
2836                                 // Already validated above.
2837                             }
2838                         }
2839                     }
2840                 }
2841 
2842                 if ( impls != null )
2843                 {
2844                     final Map<String, Implementations> map = new HashMap<String, Implementations>();
2845 
2846                     for ( int j = 0, s1 = impls.getImplementation().size(); j < s1; j++ )
2847                     {
2848                         final Implementation impl = impls.getImplementation().get( j );
2849                         Implementations implementations = map.get( impl.getName() );
2850 
2851                         if ( implementations == null )
2852                         {
2853                             implementations = new Implementations();
2854                             map.put( impl.getName(), implementations );
2855                         }
2856 
2857                         implementations.getImplementation().add( impl );
2858                     }
2859 
2860                     for ( final Map.Entry<String, Implementations> e : map.entrySet() )
2861                     {
2862                         if ( e.getValue().getImplementation().size() > 1 )
2863                         {
2864                             for ( int j = 0, s1 = e.getValue().getImplementation().size(); j < s1; j++ )
2865                             {
2866                                 final Implementation impl = e.getValue().getImplementation().get( j );
2867                                 final Module moduleOfImpl =
2868                                     validationContext.getModuleOfImplementation( impl.getIdentifier() );
2869 
2870                                 addDetail( validationContext.getReport(),
2871                                            "SPECIFICATION_IMPLEMENTATION_NAME_UNIQUENESS_CONSTRAINT",
2872                                            Level.SEVERE, new ObjectFactory().createImplementation( impl ),
2873                                            "specificationImplementationNameConstraint", impl.getIdentifier(),
2874                                            moduleOfImpl.getName(), s.getIdentifier(), moduleOfS.getName(),
2875                                            impl.getName() );
2876 
2877                             }
2878                         }
2879                     }
2880 
2881                     if ( s.getMultiplicity() == Multiplicity.ONE && impls.getImplementation().size() > 1 )
2882                     {
2883                         for ( int j = 0, s1 = impls.getImplementation().size(); j < s1; j++ )
2884                         {
2885                             final Implementation impl = impls.getImplementation().get( j );
2886                             final Module moduleOfImpl =
2887                                 validationContext.getModuleOfImplementation( impl.getIdentifier() );
2888 
2889                             addDetail( validationContext.getReport(),
2890                                        "SPECIFICATION_IMPLEMENTATION_MULTIPLICITY_CONSTRAINT", Level.SEVERE,
2891                                        new ObjectFactory().createImplementation( impl ),
2892                                        "specificationMultiplicityConstraint", impl.getIdentifier(),
2893                                        moduleOfImpl.getName(), s.getIdentifier(), moduleOfS.getName(),
2894                                        s.getMultiplicity() );
2895 
2896                         }
2897                     }
2898                 }
2899 
2900                 if ( s.getProperties() != null )
2901                 {
2902                     for ( int j = 0, s1 = s.getProperties().getProperty().size(); j < s1; j++ )
2903                     {
2904                         final Property p = s.getProperties().getProperty().get( j );
2905 
2906                         if ( p.getValue() != null && p.getAny() != null )
2907                         {
2908                             addDetail( validationContext.getReport(), "SPECIFICATION_PROPERTY_VALUE_CONSTRAINT",
2909                                        Level.SEVERE, new ObjectFactory().createSpecification( s ),
2910                                        "specificationPropertyValueConstraint", s.getIdentifier(),
2911                                        moduleOfS.getName(), p.getName() );
2912 
2913                         }
2914 
2915                         if ( p.getAny() != null && p.getType() == null )
2916                         {
2917                             addDetail( validationContext.getReport(), "SPECIFICATION_PROPERTY_TYPE_CONSTRAINT",
2918                                        Level.SEVERE, new ObjectFactory().createSpecification( s ),
2919                                        "specificationPropertyTypeConstraint", s.getIdentifier(),
2920                                        moduleOfS.getName(), p.getName() );
2921 
2922                         }
2923 
2924                         if ( validationContext.isValidateJava() )
2925                         {
2926                             try
2927                             {
2928                                 p.getJavaConstantName();
2929                             }
2930                             catch ( final ModelObjectException e )
2931                             {
2932                                 final String message = getMessage( e );
2933 
2934                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2935                                 {
2936                                     validationContext.getModelContext().log( Level.FINE, message, e );
2937                                 }
2938 
2939                                 addDetail( validationContext.getReport(),
2940                                            "SPECIFICATION_PROPERTY_JAVA_CONSTANT_NAME_CONSTRAINT",
2941                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
2942                                            "specificationPropertyJavaConstantNameConstraint", s.getIdentifier(),
2943                                            moduleOfS.getName(), p.getName(),
2944                                            message != null && message.length() > 0 ? " " + message : "" );
2945 
2946                             }
2947 
2948                             try
2949                             {
2950                                 p.getJavaGetterMethodName();
2951                             }
2952                             catch ( final ModelObjectException e )
2953                             {
2954                                 final String message = getMessage( e );
2955 
2956                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2957                                 {
2958                                     validationContext.getModelContext().log( Level.FINE, message, e );
2959                                 }
2960 
2961                                 addDetail( validationContext.getReport(),
2962                                            "SPECIFICATION_PROPERTY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
2963                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
2964                                            "specificationPropertyJavaGetterMethodNameConstraint", s.getIdentifier(),
2965                                            moduleOfS.getName(), p.getName(),
2966                                            message != null && message.length() > 0 ? " " + message : "" );
2967 
2968                             }
2969 
2970                             try
2971                             {
2972                                 p.getJavaSetterMethodName();
2973                             }
2974                             catch ( final ModelObjectException e )
2975                             {
2976                                 final String message = getMessage( e );
2977 
2978                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
2979                                 {
2980                                     validationContext.getModelContext().log( Level.FINE, message, e );
2981                                 }
2982 
2983                                 addDetail( validationContext.getReport(),
2984                                            "SPECIFICATION_PROPERTY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
2985                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
2986                                            "specificationPropertyJavaSetterMethodNameConstraint", s.getIdentifier(),
2987                                            moduleOfS.getName(), p.getName(),
2988                                            message != null && message.length() > 0 ? " " + message : "" );
2989 
2990                             }
2991 
2992                             try
2993                             {
2994                                 p.getJavaTypeName();
2995                             }
2996                             catch ( final ModelObjectException e )
2997                             {
2998                                 final String message = getMessage( e );
2999 
3000                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3001                                 {
3002                                     validationContext.getModelContext().log( Level.FINE, message, e );
3003                                 }
3004 
3005                                 addDetail( validationContext.getReport(),
3006                                            "SPECIFICATION_PROPERTY_JAVA_TYPE_NAME_CONSTRAINT",
3007                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
3008                                            "specificationPropertyJavaTypeNameConstraint", s.getIdentifier(),
3009                                            moduleOfS.getName(), p.getName(),
3010                                            message != null && message.length() > 0 ? " " + message : "" );
3011 
3012                             }
3013 
3014                             try
3015                             {
3016                                 p.getJavaVariableName();
3017                             }
3018                             catch ( final ModelObjectException e )
3019                             {
3020                                 final String message = getMessage( e );
3021 
3022                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3023                                 {
3024                                     validationContext.getModelContext().log( Level.FINE, message, e );
3025                                 }
3026 
3027                                 addDetail( validationContext.getReport(),
3028                                            "SPECIFICATION_PROPERTY_JAVA_VARIABLE_NAME_CONSTRAINT",
3029                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
3030                                            "specificationPropertyJavaVariableNameConstraint", s.getIdentifier(),
3031                                            moduleOfS.getName(), p.getName(),
3032                                            message != null && message.length() > 0 ? " " + message : "" );
3033 
3034                             }
3035 
3036                             try
3037                             {
3038                                 p.getJavaValue( validationContext.getModelContext().getClassLoader() );
3039                             }
3040                             catch ( final ModelObjectException e )
3041                             {
3042                                 final String message = getMessage( e );
3043 
3044                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3045                                 {
3046                                     validationContext.getModelContext().log( Level.FINE, message, e );
3047                                 }
3048 
3049                                 addDetail( validationContext.getReport(),
3050                                            "SPECIFICATION_PROPERTY_JAVA_VALUE_CONSTRAINT",
3051                                            Level.SEVERE, new ObjectFactory().createSpecification( s ),
3052                                            "specificationPropertyJavaValueConstraint", s.getIdentifier(),
3053                                            moduleOfS.getName(), p.getName(),
3054                                            message != null && message.length() > 0 ? " " + message : "" );
3055 
3056                             }
3057                         }
3058                     }
3059 
3060                     for ( int j = 0, s1 = s.getProperties().getReference().size(); j < s1; j++ )
3061                     {
3062                         final PropertyReference r = s.getProperties().getReference().get( j );
3063 
3064                         addDetail( validationContext.getReport(),
3065                                    "SPECIFICATION_PROPERTY_REFERENCE_DECLARATION_CONSTRAINT", Level.SEVERE,
3066                                    new ObjectFactory().createSpecification( s ),
3067                                    "specificationPropertyReferenceDeclarationConstraint", s.getIdentifier(),
3068                                    moduleOfS.getName(), r.getName() );
3069 
3070                     }
3071                 }
3072             }
3073         }
3074     }
3075 
3076     private static void assertDependencyValid( final ValidationContext validationContext,
3077                                                final Implementation implementation, final Dependency dependency )
3078     {
3079         final Specification s = validationContext.getSpecification( dependency.getIdentifier() );
3080         final Implementations available = validationContext.getImplementations( dependency.getIdentifier() );
3081         final Module moduleOfImpl =
3082             validationContext.getModuleOfImplementation( implementation.getIdentifier() );
3083 
3084         if ( !dependency.isOptional()
3085                  && ( available == null || available.getImplementation().isEmpty()
3086                       || ( dependency.getImplementationName() != null
3087                            && available.getImplementationByName( dependency.getImplementationName() ) == null ) ) )
3088         {
3089             addDetail( validationContext.getReport(), "IMPLEMENTATION_MANDATORY_DEPENDENCY_CONSTRAINT", Level.SEVERE,
3090                        new ObjectFactory().createImplementation( implementation ),
3091                        "implementationMandatoryDependencyConstraint", implementation.getIdentifier(),
3092                        moduleOfImpl.getName(), dependency.getName() );
3093 
3094         }
3095 
3096         if ( s != null )
3097         {
3098             final Module moduleOfS = validationContext.getModuleOfSpecification( s.getIdentifier() );
3099 
3100             if ( s.getClazz() == null )
3101             {
3102                 addDetail( validationContext.getReport(), "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_CLASS_CONSTRAINT",
3103                            Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3104                            "implementationDependencySpecificationClassConstraint", implementation.getIdentifier(),
3105                            moduleOfImpl.getName(), dependency.getName(), dependency.getIdentifier(),
3106                            moduleOfS.getName() );
3107 
3108             }
3109 
3110             if ( dependency.getVersion() != null )
3111             {
3112                 if ( s.getVersion() == null )
3113                 {
3114                     addDetail( validationContext.getReport(),
3115                                "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_VERSIONING_CONSTRAINT", Level.SEVERE,
3116                                new ObjectFactory().createImplementation( implementation ),
3117                                "implementationDependencySpecificationVersioningConstraint",
3118                                implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3119                                s.getIdentifier(), moduleOfS.getName() );
3120 
3121                 }
3122                 else
3123                 {
3124                     try
3125                     {
3126                         if ( VersionParser.compare( dependency.getVersion(), s.getVersion() ) > 0 )
3127                         {
3128                             addDetail( validationContext.getReport(),
3129                                        "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_COMPATIBILITY_CONSTRAINT",
3130                                        Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3131                                        "implementationDependencySpecificationCompatibilityConstraint",
3132                                        implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
3133                                        moduleOfS.getName(), dependency.getVersion(), s.getVersion() );
3134 
3135                         }
3136                     }
3137                     catch ( final ParseException e )
3138                     {
3139                         final String message = getMessage( e );
3140 
3141                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3142                         {
3143                             validationContext.getModelContext().log( Level.FINE, message, e );
3144                         }
3145 
3146                         addDetail( validationContext.getReport(),
3147                                    "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_COMPATIBILITY_VERSIONING_PARSE_EXCEPTION",
3148                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3149                                    "implementationDependencySpecificationCompatibilityParseException",
3150                                    implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
3151                                    moduleOfS.getName(), dependency.getVersion(),
3152                                    message != null && message.length() > 0 ? " " + message : "" );
3153 
3154                     }
3155                     catch ( final TokenMgrError e )
3156                     {
3157                         final String message = getMessage( e );
3158 
3159                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3160                         {
3161                             validationContext.getModelContext().log( Level.FINE, message, e );
3162                         }
3163 
3164                         addDetail( validationContext.getReport(),
3165                                    "IMPLEMENTATION_DEPENDENCY_SPECIFICATION_COMPATIBILITY_VERSIONING_TOKEN_MANAGER_ERROR",
3166                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3167                                    "implementationDependencySpecificationCompatibilityTokenMgrError",
3168                                    implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
3169                                    moduleOfS.getName(), dependency.getVersion(),
3170                                    message != null && message.length() > 0 ? " " + message : "" );
3171 
3172                     }
3173                 }
3174             }
3175 
3176             if ( s.getScope() != null )
3177             {
3178                 if ( dependency.getDependencies() != null )
3179                 {
3180                     for ( int i = 0, s0 = dependency.getDependencies().getDependency().size(); i < s0; i++ )
3181                     {
3182                         final Dependency d = dependency.getDependencies().getDependency().get( i );
3183 
3184                         addDetail( validationContext.getReport(),
3185                                    "IMPLEMENTATION_DEPENDENCY_DEPENDENCIES_OVERRIDE_CONSTRAINT", Level.SEVERE,
3186                                    new ObjectFactory().createImplementation( implementation ),
3187                                    "implementationDependencyDependenciesOverrideConstraint",
3188                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3189                                    d.getName(), s.getIdentifier(), moduleOfS.getName(), s.getScope() );
3190 
3191                     }
3192                 }
3193 
3194                 if ( dependency.getMessages() != null )
3195                 {
3196                     for ( int i = 0, s0 = dependency.getMessages().getMessage().size(); i < s0; i++ )
3197                     {
3198                         final Message m = dependency.getMessages().getMessage().get( i );
3199 
3200                         addDetail( validationContext.getReport(),
3201                                    "IMPLEMENTATION_DEPENDENCY_MESSAGES_OVERRIDE_CONSTRAINT", Level.SEVERE,
3202                                    new ObjectFactory().createImplementation( implementation ),
3203                                    "implementationDependencyMessagesOverrideConstraint", implementation.getIdentifier(),
3204                                    moduleOfImpl.getName(), dependency.getName(), m.getName(), s.getIdentifier(),
3205                                    moduleOfS.getName(), s.getScope() );
3206 
3207                     }
3208                 }
3209 
3210                 if ( dependency.getProperties() != null )
3211                 {
3212                     for ( int i = 0, s0 = dependency.getProperties().getProperty().size(); i < s0; i++ )
3213                     {
3214                         final Property p = dependency.getProperties().getProperty().get( i );
3215                         addDetail( validationContext.getReport(),
3216                                    "IMPLEMENTATION_DEPENDENCY_PROPERTIES_OVERRIDE_CONSTRAINT", Level.SEVERE,
3217                                    new ObjectFactory().createImplementation( implementation ),
3218                                    "implementationDependencyPropertiesOverrideConstraint",
3219                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3220                                    p.getName(), s.getIdentifier(), moduleOfS.getName(), s.getScope() );
3221 
3222                     }
3223                 }
3224             }
3225         }
3226 
3227         if ( dependency.getMessages() != null )
3228         {
3229             for ( int i = 0, s0 = dependency.getMessages().getMessage().size(); i < s0; i++ )
3230             {
3231                 final Message m = dependency.getMessages().getMessage().get( i );
3232 
3233                 if ( validationContext.isValidateJava() )
3234                 {
3235                     try
3236                     {
3237                         m.getJavaConstantName();
3238                     }
3239                     catch ( final ModelObjectException e )
3240                     {
3241                         final String message = getMessage( e );
3242 
3243                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3244                         {
3245                             validationContext.getModelContext().log( Level.FINE, message, e );
3246                         }
3247 
3248                         addDetail( validationContext.getReport(),
3249                                    "IMPLEMENTATION_DEPENDENCY_MESSAGE_JAVA_CONSTANT_NAME_CONSTRAINT", Level.SEVERE,
3250                                    new ObjectFactory().createImplementation( implementation ),
3251                                    "implementationDependencyMessageJavaConstantNameConstraint",
3252                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3253                                    m.getName(), message != null && message.length() > 0 ? " " + message : "" );
3254                     }
3255 
3256                     try
3257                     {
3258                         m.getJavaGetterMethodName();
3259                     }
3260                     catch ( final ModelObjectException e )
3261                     {
3262                         final String message = getMessage( e );
3263 
3264                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3265                         {
3266                             validationContext.getModelContext().log( Level.FINE, message, e );
3267                         }
3268 
3269                         addDetail( validationContext.getReport(),
3270                                    "IMPLEMENTATION_DEPENDENCY_MESSAGE_JAVA_GETTER_METHOD_NAME_CONSTRAINT", Level.SEVERE,
3271                                    new ObjectFactory().createImplementation( implementation ),
3272                                    "implementationDependencyMessageJavaGetterMethodNameConstraint",
3273                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3274                                    m.getName(), message != null && message.length() > 0 ? " " + message : "" );
3275                     }
3276 
3277                     try
3278                     {
3279                         m.getJavaSetterMethodName();
3280                     }
3281                     catch ( final ModelObjectException e )
3282                     {
3283                         final String message = getMessage( e );
3284 
3285                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3286                         {
3287                             validationContext.getModelContext().log( Level.FINE, message, e );
3288                         }
3289 
3290                         addDetail( validationContext.getReport(),
3291                                    "IMPLEMENTATION_DEPENDENCY_MESSAGE_JAVA_SETTER_METHOD_NAME_CONSTRAINT", Level.SEVERE,
3292                                    new ObjectFactory().createImplementation( implementation ),
3293                                    "implementationDependencyMessageJavaSetterMethodNameConstraint",
3294                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3295                                    m.getName(), message != null && message.length() > 0 ? " " + message : "" );
3296                     }
3297 
3298                     try
3299                     {
3300                         m.getJavaVariableName();
3301                     }
3302                     catch ( final ModelObjectException e )
3303                     {
3304                         final String message = getMessage( e );
3305 
3306                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3307                         {
3308                             validationContext.getModelContext().log( Level.FINE, message, e );
3309                         }
3310 
3311                         addDetail( validationContext.getReport(),
3312                                    "IMPLEMENTATION_DEPENDENCY_MESSAGE_JAVA_VARIABLE_NAME_CONSTRAINT", Level.SEVERE,
3313                                    new ObjectFactory().createImplementation( implementation ),
3314                                    "implementationDependencyMessageJavaVariableNameConstraint",
3315                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3316                                    m.getName(), message != null && message.length() > 0 ? " " + message : "" );
3317                     }
3318                 }
3319 
3320                 if ( m.getTemplate() != null )
3321                 {
3322                     for ( int j = 0, s1 = m.getTemplate().getText().size(); j < s1; j++ )
3323                     {
3324                         final Text t = m.getTemplate().getText().get( j );
3325 
3326                         try
3327                         {
3328                             t.getMimeType();
3329                         }
3330                         catch ( final ModelObjectException e )
3331                         {
3332                             final String message = getMessage( e );
3333 
3334                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3335                             {
3336                                 validationContext.getModelContext().log( Level.FINE, message, e );
3337                             }
3338 
3339                             addDetail( validationContext.getReport(),
3340                                        "IMPLEMENTATION_DEPENDENCY_MESSAGE_TEMPLATE_MIME_TYPE_CONSTRAINT", Level.SEVERE,
3341                                        new ObjectFactory().createImplementation( implementation ),
3342                                        "implementationDependencyMessageTemplateMimeTypeConstraint",
3343                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3344                                        m.getName(), t.getLanguage(),
3345                                        message != null && message.length() > 0 ? " " + message : "" );
3346 
3347                         }
3348 
3349                         if ( validationContext.isValidateJava() )
3350                         {
3351                             try
3352                             {
3353                                 new MessageFormat( t.getValue(), new Locale( t.getLanguage() ) );
3354                             }
3355                             catch ( final IllegalArgumentException e )
3356                             {
3357                                 final String message = getMessage( e );
3358 
3359                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3360                                 {
3361                                     validationContext.getModelContext().log( Level.FINE, message, e );
3362                                 }
3363 
3364                                 addDetail( validationContext.getReport(),
3365                                            "IMPLEMENTATION_DEPENDENCY_MESSAGE_TEMPLATE_CONSTRAINT", Level.SEVERE,
3366                                            new ObjectFactory().createImplementation( implementation ),
3367                                            "implementationDependencyMessageTemplateConstraint",
3368                                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3369                                            m.getName(), t.getLanguage(),
3370                                            message != null && message.length() > 0 ? " " + message : "" );
3371 
3372                             }
3373                         }
3374                     }
3375                 }
3376 
3377                 if ( m.getArguments() != null )
3378                 {
3379                     final Map<JavaIdentifier, Argument> javaVariableNames =
3380                         new HashMap<JavaIdentifier, Argument>( m.getArguments().getArgument().size() );
3381 
3382                     for ( int j = 0, s1 = m.getArguments().getArgument().size(); j < s1; j++ )
3383                     {
3384                         final Argument a = m.getArguments().getArgument().get( j );
3385 
3386                         if ( validationContext.isValidateJava() )
3387                         {
3388                             try
3389                             {
3390                                 a.getJavaTypeName();
3391                             }
3392                             catch ( final ModelObjectException e )
3393                             {
3394                                 final String message = getMessage( e );
3395 
3396                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3397                                 {
3398                                     validationContext.getModelContext().log( Level.FINE, message, e );
3399                                 }
3400 
3401                                 addDetail( validationContext.getReport(),
3402                                            "IMPLEMENTATION_DEPENDENCY_MESSAGE_ARGUMENT_JAVA_TYPE_NAME_CONSTRAINT",
3403                                            Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3404                                            "implementationDependencyMessageArgumentJavaTypeNameConstraint",
3405                                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3406                                            m.getName(), a.getName(),
3407                                            message != null && message.length() > 0 ? " " + message : "" );
3408 
3409                             }
3410 
3411                             try
3412                             {
3413                                 final JavaIdentifier javaIdentifier = a.getJavaVariableName();
3414 
3415                                 if ( javaVariableNames.containsKey( javaIdentifier ) )
3416                                 {
3417                                     addDetail( validationContext.getReport(),
3418                                                "IMPLEMENTATION_DEPENDENCY_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_UNIQUENESS_CONSTRAINT",
3419                                                Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3420                                                "implementationDependencyMessageArgumentJavaVariableNameUniquenessConstraint",
3421                                                implementation.getIdentifier(), moduleOfImpl.getName(),
3422                                                dependency.getName(), m.getName(), a.getName(), javaIdentifier,
3423                                                javaVariableNames.get( javaIdentifier ).getName() );
3424 
3425                                 }
3426                                 else
3427                                 {
3428                                     javaVariableNames.put( javaIdentifier, a );
3429                                 }
3430                             }
3431                             catch ( final ModelObjectException e )
3432                             {
3433                                 final String message = getMessage( e );
3434 
3435                                 if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3436                                 {
3437                                     validationContext.getModelContext().log( Level.FINE, message, e );
3438                                 }
3439 
3440                                 addDetail( validationContext.getReport(),
3441                                            "IMPLEMENTATION_DEPENDENCY_MESSAGE_ARGUMENT_JAVA_VARIABLE_NAME_CONSTRAINT",
3442                                            Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3443                                            "implementationDependencyMessageArgumentJavaVariableNameConstraint",
3444                                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3445                                            m.getName(), a.getIndex(),
3446                                            message != null && message.length() > 0 ? " " + message : "" );
3447 
3448                             }
3449                         }
3450                     }
3451                 }
3452             }
3453 
3454             for ( int i = 0, s0 = dependency.getMessages().getReference().size(); i < s0; i++ )
3455             {
3456                 final MessageReference r = dependency.getMessages().getReference().get( i );
3457 
3458                 addDetail( validationContext.getReport(),
3459                            "IMPLEMENTATION_DEPENDENCY_MESSAGE_REFERENCE_DECLARATION_CONSTRAINT", Level.SEVERE,
3460                            new ObjectFactory().createImplementation( implementation ),
3461                            "implementationDependencyMessageReferenceDeclarationConstraint",
3462                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(), r.getName() );
3463 
3464             }
3465         }
3466 
3467         if ( dependency.getProperties() != null )
3468         {
3469             for ( int i = 0, s0 = dependency.getProperties().getProperty().size(); i < s0; i++ )
3470             {
3471                 final Property p = dependency.getProperties().getProperty().get( i );
3472 
3473                 if ( p.getValue() != null && p.getAny() != null )
3474                 {
3475                     addDetail( validationContext.getReport(), "IMPLEMENTATION_DEPENDENCY_PROPERTY_VALUE_CONSTRAINT",
3476                                Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3477                                "implementationDependencyPropertyValueConstraint", implementation.getIdentifier(),
3478                                moduleOfImpl.getName(), dependency.getName(), p.getName() );
3479 
3480                 }
3481 
3482                 if ( p.getAny() != null && p.getType() == null )
3483                 {
3484                     addDetail( validationContext.getReport(), "IMPLEMENTATION_DEPENDENCY_PROPERTY_TYPE_CONSTRAINT",
3485                                Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3486                                "implementationDependencyPropertyTypeConstraint", implementation.getIdentifier(),
3487                                moduleOfImpl.getName(), dependency.getName(), p.getName() );
3488 
3489                 }
3490 
3491                 if ( validationContext.isValidateJava() )
3492                 {
3493                     try
3494                     {
3495                         p.getJavaConstantName();
3496                     }
3497                     catch ( final ModelObjectException e )
3498                     {
3499                         final String message = getMessage( e );
3500 
3501                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3502                         {
3503                             validationContext.getModelContext().log( Level.FINE, message, e );
3504                         }
3505 
3506                         addDetail( validationContext.getReport(),
3507                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_CONSTANT_NAME_CONSTRAINT", Level.SEVERE,
3508                                    new ObjectFactory().createImplementation( implementation ),
3509                                    "implementationDependencyPropertyJavaConstantNameConstraint",
3510                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3511                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3512 
3513                     }
3514 
3515                     try
3516                     {
3517                         p.getJavaGetterMethodName();
3518                     }
3519                     catch ( final ModelObjectException e )
3520                     {
3521                         final String message = getMessage( e );
3522 
3523                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3524                         {
3525                             validationContext.getModelContext().log( Level.FINE, message, e );
3526                         }
3527 
3528                         addDetail( validationContext.getReport(),
3529                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
3530                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3531                                    "implementationDependencyPropertyJavaGetterMethodNameConstraint",
3532                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3533                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3534 
3535                     }
3536 
3537                     try
3538                     {
3539                         p.getJavaSetterMethodName();
3540                     }
3541                     catch ( final ModelObjectException e )
3542                     {
3543                         final String message = getMessage( e );
3544 
3545                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3546                         {
3547                             validationContext.getModelContext().log( Level.FINE, message, e );
3548                         }
3549 
3550                         addDetail( validationContext.getReport(),
3551                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
3552                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3553                                    "implementationDependencyPropertyJavaSetterMethodNameConstraint",
3554                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3555                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3556 
3557                     }
3558 
3559                     try
3560                     {
3561                         p.getJavaTypeName();
3562                     }
3563                     catch ( final ModelObjectException e )
3564                     {
3565                         final String message = getMessage( e );
3566 
3567                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3568                         {
3569                             validationContext.getModelContext().log( Level.FINE, message, e );
3570                         }
3571 
3572                         addDetail( validationContext.getReport(),
3573                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_TYPE_NAME_CONSTRAINT",
3574                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3575                                    "implementationDependencyPropertyJavaTypeNameConstraint",
3576                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3577                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3578 
3579                     }
3580 
3581                     try
3582                     {
3583                         p.getJavaVariableName();
3584                     }
3585                     catch ( final ModelObjectException e )
3586                     {
3587                         final String message = getMessage( e );
3588 
3589                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3590                         {
3591                             validationContext.getModelContext().log( Level.FINE, message, e );
3592                         }
3593 
3594                         addDetail( validationContext.getReport(),
3595                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_VARIABLE_NAME_CONSTRAINT",
3596                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3597                                    "implementationDependencyPropertyJavaVariableNameConstraint",
3598                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3599                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3600 
3601                     }
3602 
3603                     try
3604                     {
3605                         p.getJavaValue( validationContext.getModelContext().getClassLoader() );
3606                     }
3607                     catch ( final ModelObjectException e )
3608                     {
3609                         final String message = getMessage( e );
3610 
3611                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3612                         {
3613                             validationContext.getModelContext().log( Level.FINE, message, e );
3614                         }
3615 
3616                         addDetail( validationContext.getReport(),
3617                                    "IMPLEMENTATION_DEPENDENCY_PROPERTY_JAVA_VALUE_CONSTRAINT", Level.SEVERE,
3618                                    new ObjectFactory().createImplementation( implementation ),
3619                                    "implementationDependencyPropertyJavaValueConstraint",
3620                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3621                                    p.getName(), message != null && message.length() > 0 ? " " + message : "" );
3622 
3623                     }
3624                 }
3625             }
3626 
3627             for ( int i = 0, s0 = dependency.getProperties().getReference().size(); i < s0; i++ )
3628             {
3629                 final PropertyReference r = dependency.getProperties().getReference().get( i );
3630 
3631                 addDetail( validationContext.getReport(),
3632                            "IMPLEMENTATION_DEPENDENCY_PROPERTY_REFERENCE_DECLARATION_CONSTRAINT", Level.SEVERE,
3633                            new ObjectFactory().createImplementation( implementation ),
3634                            "implementationDependencyPropertyReferenceDeclarationConstraint",
3635                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(), r.getName() );
3636 
3637             }
3638         }
3639 
3640         if ( available != null )
3641         {
3642             for ( int i = 0, s0 = available.getImplementation().size(); i < s0; i++ )
3643             {
3644                 final Implementation a = available.getImplementation().get( i );
3645 
3646                 if ( dependency.getImplementationName() != null
3647                          && !dependency.getImplementationName().equals( a.getName() ) )
3648                 {
3649                     continue;
3650                 }
3651 
3652                 final InheritanceModel imodel = validationContext.getInheritanceModel();
3653                 final Module moduleOfA = validationContext.getModuleOfImplementation( a.getIdentifier() );
3654 
3655                 if ( dependency.getDependencies() != null )
3656                 {
3657                     for ( int j = 0, s1 = dependency.getDependencies().getDependency().size(); j < s1; j++ )
3658                     {
3659                         final Dependency override = dependency.getDependencies().getDependency().get( j );
3660 
3661                         final Set<InheritanceModel.Node<Dependency>> effDependencies =
3662                             imodel.getDependencyNodes( a.getIdentifier(), override.getName() );
3663 
3664                         final Set<InheritanceModel.Node<Dependency>> overriddenDependencies =
3665                             modifiableSet( effDependencies );
3666 
3667                         final boolean effectiveDependencyOverridden = !overriddenDependencies.isEmpty();
3668 
3669                         if ( override.isOverride() && overriddenDependencies.isEmpty() )
3670                         {
3671                             addDetail( validationContext.getReport(),
3672                                        "IMPLEMENTATION_DEPENDENCY_OVERRIDE_DEPENDENCY_CONSTRAINT",
3673                                        Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3674                                        "implementationDependencyOverrideDependencyConstraint",
3675                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3676                                        override.getName(), a.getIdentifier(), moduleOfA.getName() );
3677 
3678                         }
3679 
3680                         if ( !( override.isOverride() || overriddenDependencies.isEmpty() ) )
3681                         {
3682                             for ( final InheritanceModel.Node<Dependency> overriddenDependency : overriddenDependencies )
3683                             {
3684                                 addDetail( validationContext.getReport(),
3685                                            "IMPLEMENTATION_DEPENDENCY_OVERRIDE_DEPENDENCY_WARNING",
3686                                            Level.WARNING, new ObjectFactory().createImplementation( implementation ),
3687                                            "implementationDependencyOverrideDependencyWarning",
3688                                            implementation.getIdentifier(), moduleOfImpl.getName(),
3689                                            dependency.getName(), override.getName(), a.getIdentifier(),
3690                                            moduleOfA.getName(), getNodePathString( overriddenDependency ) );
3691 
3692                             }
3693                         }
3694 
3695                         retainFinalNodes( overriddenDependencies );
3696 
3697                         for ( final InheritanceModel.Node<Dependency> overriddenDependency : overriddenDependencies )
3698                         {
3699                             addDetail( validationContext.getReport(),
3700                                        "IMPLEMENTATION_DEPENDENCY_FINAL_DEPENDENCY_CONSTRAINT",
3701                                        Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3702                                        "implementationDependencyFinalDependencyConstraint",
3703                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3704                                        override.getName(), a.getIdentifier(), moduleOfA.getName(),
3705                                        getNodePathString( overriddenDependency ) );
3706 
3707                         }
3708 
3709                         if ( effectiveDependencyOverridden )
3710                         {
3711                             for ( final InheritanceModel.Node<Dependency> node : effDependencies )
3712                             {
3713                                 final Dependency overridden = node.getModelObject();
3714 
3715                                 final Specification overrideSpecification =
3716                                     validationContext.getSpecification( override.getIdentifier() );
3717 
3718                                 final Specification overriddenSpecification =
3719                                     validationContext.getSpecification( overridden.getIdentifier() );
3720 
3721                                 if ( overrideSpecification != null && overriddenSpecification != null )
3722                                 {
3723                                     if ( overrideSpecification.getMultiplicity()
3724                                              != overriddenSpecification.getMultiplicity() )
3725                                     {
3726                                         addDetail( validationContext.getReport(),
3727                                                    "IMPLEMENTATION_DEPENDENCY_MULTIPLICITY_CONSTRAINT",
3728                                                    Level.SEVERE,
3729                                                    new ObjectFactory().createImplementation( implementation ),
3730                                                    "implementationDependencyMultiplicityConstraint",
3731                                                    implementation.getIdentifier(), moduleOfImpl.getName(),
3732                                                    dependency.getName(), overridden.getName(),
3733                                                    a.getIdentifier(), moduleOfA.getName(),
3734                                                    overrideSpecification.getMultiplicity().value(),
3735                                                    overriddenSpecification.getMultiplicity().value() );
3736 
3737                                     }
3738 
3739                                     if ( overrideSpecification.getScope() != null
3740                                              ? !overrideSpecification.getScope().equals(
3741                                             overriddenSpecification.getScope() )
3742                                              : overriddenSpecification.getScope() != null )
3743                                     {
3744                                         addDetail( validationContext.getReport(),
3745                                                    "IMPLEMENTATION_DEPENDENCY_SCOPE_CONSTRAINT", Level.SEVERE,
3746                                                    new ObjectFactory().createImplementation( implementation ),
3747                                                    "implementationDependencyScopeConstraint",
3748                                                    implementation.getIdentifier(), moduleOfImpl.getName(),
3749                                                    dependency.getName(), override.getName(),
3750                                                    a.getIdentifier(), moduleOfA.getName(),
3751                                                    overrideSpecification.getScope() == null
3752                                                        ? "Multiton" : overrideSpecification.getScope(),
3753                                                    overriddenSpecification.getScope() == null
3754                                                        ? "Multiton" : overriddenSpecification.getScope() );
3755 
3756                                     }
3757 
3758                                     if ( overriddenSpecification.getMultiplicity() == Multiplicity.MANY )
3759                                     {
3760                                         if ( override.getImplementationName() == null
3761                                                  && overridden.getImplementationName() != null )
3762                                         {
3763                                             addDetail( validationContext.getReport(),
3764                                                        "IMPLEMENTATION_DEPENDENCY_NO_IMPLEMENTATION_NAME_CONSTRAINT",
3765                                                        Level.SEVERE,
3766                                                        new ObjectFactory().createImplementation( implementation ),
3767                                                        "implementationDependencyNoImplementationNameConstraint",
3768                                                        implementation.getIdentifier(), moduleOfImpl.getName(),
3769                                                        dependency.getName(), override.getName(),
3770                                                        a.getIdentifier(), moduleOfA.getName() );
3771 
3772                                         }
3773 
3774                                         if ( override.getImplementationName() != null
3775                                                  && overridden.getImplementationName() == null )
3776                                         {
3777                                             addDetail( validationContext.getReport(),
3778                                                        "IMPLEMENTATION_DEPENDENCY_IMPLEMENTATION_NAME_CONSTRAINT",
3779                                                        Level.SEVERE,
3780                                                        new ObjectFactory().createImplementation( implementation ),
3781                                                        "implementationDependencyImplementationNameConstraint",
3782                                                        implementation.getIdentifier(), moduleOfImpl.getName(),
3783                                                        dependency.getName(), overridden.getName(),
3784                                                        a.getIdentifier(), moduleOfA.getName(),
3785                                                        override.getImplementationName() );
3786 
3787                                         }
3788                                     }
3789                                 }
3790 
3791                                 if ( override.isOptional() != overridden.isOptional() )
3792                                 {
3793                                     addDetail( validationContext.getReport(),
3794                                                "IMPLEMENTATION_DEPENDENCY_OPTIONALITY_CONSTRAINT", Level.SEVERE,
3795                                                new ObjectFactory().createImplementation( implementation ),
3796                                                "implementationDependencyOptonalityConstraint",
3797                                                implementation.getIdentifier(), moduleOfImpl.getName(),
3798                                                dependency.getName(), overridden.getName(),
3799                                                a.getIdentifier(), moduleOfA.getName() );
3800 
3801                                 }
3802                             }
3803                         }
3804                     }
3805                 }
3806 
3807                 if ( dependency.getMessages() != null )
3808                 {
3809                     for ( int j = 0, s1 = dependency.getMessages().getMessage().size(); j < s1; j++ )
3810                     {
3811                         final Message override = dependency.getMessages().getMessage().get( j );
3812 
3813                         final Set<InheritanceModel.Node<Message>> overriddenMessages =
3814                             modifiableSet( imodel.getMessageNodes( a.getIdentifier(), override.getName() ) );
3815 
3816                         if ( override.isOverride() && overriddenMessages.isEmpty() )
3817                         {
3818                             addDetail( validationContext.getReport(),
3819                                        "IMPLEMENTATION_DEPENDENCY_OVERRIDE_MESSAGE_CONSTRAINT", Level.SEVERE,
3820                                        new ObjectFactory().createImplementation( implementation ),
3821                                        "implementationDependencyOverrideMessageConstraint",
3822                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3823                                        override.getName(), a.getIdentifier(), moduleOfA.getName() );
3824 
3825                         }
3826 
3827                         if ( !( override.isOverride() || overriddenMessages.isEmpty() ) )
3828                         {
3829                             for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
3830                             {
3831                                 addDetail( validationContext.getReport(),
3832                                            "IMPLEMENTATION_DEPENDENCY_OVERRIDE_MESSAGE_WARNING", Level.WARNING,
3833                                            new ObjectFactory().createImplementation( implementation ),
3834                                            "implementationDependencyOverrideMessageWarning",
3835                                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3836                                            override.getName(), a.getIdentifier(), moduleOfA.getName(),
3837                                            getNodePathString( overriddenMessage ) );
3838 
3839                             }
3840                         }
3841 
3842                         retainFinalNodes( overriddenMessages );
3843 
3844                         for ( final InheritanceModel.Node<Message> overriddenMessage : overriddenMessages )
3845                         {
3846                             addDetail( validationContext.getReport(),
3847                                        "IMPLEMENTATION_DEPENDENCY_FINAL_MESSAGE_CONSTRAINT", Level.SEVERE,
3848                                        new ObjectFactory().createImplementation( implementation ),
3849                                        "implementationDependencyFinalMessageConstraint",
3850                                        implementation.getIdentifier(), moduleOfImpl.getName(),
3851                                        dependency.getName(), override.getName(), a.getIdentifier(),
3852                                        moduleOfA.getName(), getNodePathString( overriddenMessage ) );
3853 
3854                         }
3855                     }
3856                 }
3857 
3858                 if ( dependency.getProperties() != null )
3859                 {
3860                     for ( int j = 0, s1 = dependency.getProperties().getProperty().size(); j < s1; j++ )
3861                     {
3862                         final Property override = dependency.getProperties().getProperty().get( j );
3863 
3864                         final Set<InheritanceModel.Node<Property>> overriddenProperties =
3865                             modifiableSet( imodel.getPropertyNodes( a.getIdentifier(), override.getName() ) );
3866 
3867                         if ( override.isOverride() && overriddenProperties.isEmpty() )
3868                         {
3869                             addDetail( validationContext.getReport(),
3870                                        "IMPLEMENTATION_DEPENDENCY_OVERRIDE_PROPERTY_CONSTRAINT", Level.SEVERE,
3871                                        new ObjectFactory().createImplementation( implementation ),
3872                                        "implementationDependencyOverridePropertyConstraint",
3873                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3874                                        override.getName(), a.getIdentifier(), moduleOfA.getName() );
3875 
3876                         }
3877 
3878                         if ( !( override.isOverride() || overriddenProperties.isEmpty() ) )
3879                         {
3880                             for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
3881                             {
3882                                 addDetail( validationContext.getReport(),
3883                                            "IMPLEMENTATION_DEPENDENCY_OVERRIDE_PROPERTY_WARNING", Level.WARNING,
3884                                            new ObjectFactory().createImplementation( implementation ),
3885                                            "implementationDependencyOverridePropertyWarning",
3886                                            implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3887                                            override.getName(), a.getIdentifier(), moduleOfA.getName(),
3888                                            getNodePathString( overriddenProperty ) );
3889 
3890                             }
3891                         }
3892 
3893                         retainFinalNodes( overriddenProperties );
3894 
3895                         for ( final InheritanceModel.Node<Property> overriddenProperty : overriddenProperties )
3896                         {
3897                             addDetail( validationContext.getReport(),
3898                                        "IMPLEMENTATION_DEPENDENCY_FINAL_PROPERTY_CONSTRAINT", Level.SEVERE,
3899                                        new ObjectFactory().createImplementation( implementation ),
3900                                        "implementationDependencyFinalPropertyConstraint",
3901                                        implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3902                                        override.getName(), a.getIdentifier(), moduleOfA.getName(),
3903                                        getNodePathString( overriddenProperty ) );
3904 
3905                         }
3906                     }
3907                 }
3908             }
3909         }
3910 
3911         if ( dependency.getDependencies() != null )
3912         {
3913             for ( int i = 0, s0 = dependency.getDependencies().getDependency().size(); i < s0; i++ )
3914             {
3915                 final Dependency d = dependency.getDependencies().getDependency().get( i );
3916 
3917                 if ( validationContext.isValidateJava() )
3918                 {
3919                     try
3920                     {
3921                         d.getJavaConstantName();
3922                     }
3923                     catch ( final ModelObjectException e )
3924                     {
3925                         final String message = getMessage( e );
3926 
3927                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3928                         {
3929                             validationContext.getModelContext().log( Level.FINE, message, e );
3930                         }
3931 
3932                         addDetail( validationContext.getReport(),
3933                                    "IMPLEMENTATION_DEPENDENCY_DEPENDENCY_JAVA_CONSTANT_NAME_CONSTRAINT", Level.SEVERE,
3934                                    new ObjectFactory().createImplementation( implementation ),
3935                                    "implementationDependencyDependencyJavaConstantNameConstraint",
3936                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3937                                    d.getName(), message != null && message.length() > 0 ? " " + message : "" );
3938 
3939                     }
3940 
3941                     try
3942                     {
3943                         d.getJavaGetterMethodName();
3944                     }
3945                     catch ( final ModelObjectException e )
3946                     {
3947                         final String message = getMessage( e );
3948 
3949                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3950                         {
3951                             validationContext.getModelContext().log( Level.FINE, message, e );
3952                         }
3953 
3954                         addDetail( validationContext.getReport(),
3955                                    "IMPLEMENTATION_DEPENDENCY_DEPENDENCY_JAVA_GETTER_METHOD_NAME_CONSTRAINT",
3956                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3957                                    "implementationDependencyDependencyJavaGetterMethodNameConstraint",
3958                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3959                                    d.getName(), message != null && message.length() > 0 ? " " + message : "" );
3960 
3961                     }
3962 
3963                     try
3964                     {
3965                         d.getJavaSetterMethodName();
3966                     }
3967                     catch ( final ModelObjectException e )
3968                     {
3969                         final String message = getMessage( e );
3970 
3971                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3972                         {
3973                             validationContext.getModelContext().log( Level.FINE, message, e );
3974                         }
3975 
3976                         addDetail( validationContext.getReport(),
3977                                    "IMPLEMENTATION_DEPENDENCY_DEPENDENCY_JAVA_SETTER_METHOD_NAME_CONSTRAINT",
3978                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
3979                                    "implementationDependencyDependencyJavaSetterMethodNameConstraint",
3980                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
3981                                    d.getName(), message != null && message.length() > 0 ? " " + message : "" );
3982 
3983                     }
3984 
3985                     try
3986                     {
3987                         d.getJavaVariableName();
3988                     }
3989                     catch ( final ModelObjectException e )
3990                     {
3991                         final String message = getMessage( e );
3992 
3993                         if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
3994                         {
3995                             validationContext.getModelContext().log( Level.FINE, message, e );
3996                         }
3997 
3998                         addDetail( validationContext.getReport(),
3999                                    "IMPLEMENTATION_DEPENDENCY_DEPENDENCY_JAVA_VARIABLE_NAME_CONSTRAINT",
4000                                    Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
4001                                    "implementationDependencyDependencyJavaVariableNameConstraint",
4002                                    implementation.getIdentifier(), moduleOfImpl.getName(), dependency.getName(),
4003                                    d.getName(), message != null && message.length() > 0 ? " " + message : "" );
4004 
4005                     }
4006                 }
4007 
4008                 assertDependencyValid( validationContext, implementation, d );
4009             }
4010         }
4011     }
4012 
4013     private static void assertImplementationSpecificationCompatibility(
4014         final ValidationContext validationContext, final Implementation implementation )
4015     {
4016         final Specifications specs = validationContext.getSpecifications( implementation.getIdentifier() );
4017         final Module moduleOfImpl =
4018             validationContext.getModuleOfImplementation( implementation.getIdentifier() );
4019 
4020         if ( specs != null )
4021         {
4022             for ( int i = 0, s0 = specs.getReference().size(); i < s0; i++ )
4023             {
4024                 final SpecificationReference r = specs.getReference().get( i );
4025                 final Specification s = specs.getSpecification( r.getIdentifier() );
4026 
4027                 if ( s != null && r.getVersion() != null )
4028                 {
4029                     final Module moduleOfS =
4030                         validationContext.getModuleOfSpecification( s.getIdentifier() );
4031 
4032                     if ( s.getVersion() == null )
4033                     {
4034                         addDetail( validationContext.getReport(),
4035                                    "IMPLEMENTATION_SPECIFICATION_VERSIONING_CONSTRAINT", Level.SEVERE,
4036                                    new ObjectFactory().createImplementation( implementation ),
4037                                    "implementationSpecificationVersioningConstraint", implementation.getIdentifier(),
4038                                    moduleOfImpl.getName(), s.getIdentifier(), moduleOfS.getName() );
4039 
4040                     }
4041                     else
4042                     {
4043                         try
4044                         {
4045                             if ( VersionParser.compare( r.getVersion(), s.getVersion() ) != 0 )
4046                             {
4047                                 addDetail( validationContext.getReport(),
4048                                            "IMPLEMENTATION_SPECIFICATION_COMPATIBILITY_CONSTRAINT", Level.SEVERE,
4049                                            new ObjectFactory().createImplementation( implementation ),
4050                                            "implementationSpecificationCompatibilityConstraint",
4051                                            implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
4052                                            moduleOfS.getName(), r.getVersion(), s.getVersion() );
4053 
4054                             }
4055                         }
4056                         catch ( final ParseException e )
4057                         {
4058                             final String message = getMessage( e );
4059 
4060                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
4061                             {
4062                                 validationContext.getModelContext().log( Level.FINE, message, e );
4063                             }
4064 
4065                             addDetail( validationContext.getReport(),
4066                                        "IMPLEMENTATION_SPECIFICATION_COMPATIBILITY_VERSIONING_PARSE_EXCEPTION",
4067                                        Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
4068                                        "implementationSpecificationCompatibilityVersioningParseException",
4069                                        implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
4070                                        moduleOfS.getName(), r.getVersion(),
4071                                        message != null && message.length() > 0 ? " " + message : "" );
4072 
4073                         }
4074                         catch ( final TokenMgrError e )
4075                         {
4076                             final String message = getMessage( e );
4077 
4078                             if ( validationContext.getModelContext().isLoggable( Level.FINE ) )
4079                             {
4080                                 validationContext.getModelContext().log( Level.FINE, message, e );
4081                             }
4082 
4083                             addDetail( validationContext.getReport(),
4084                                        "IMPLEMENTATION_SPECIFICATION_COMPATIBILITY_VERSIONING_TOKEN_MANAGER_ERROR",
4085                                        Level.SEVERE, new ObjectFactory().createImplementation( implementation ),
4086                                        "implementationSpecificationCompatibilityVersioningTokenManagerError",
4087                                        implementation.getIdentifier(), moduleOfImpl.getName(), s.getIdentifier(),
4088                                        moduleOfS.getName(), r.getVersion(),
4089                                        message != null && message.length() > 0 ? " " + message : "" );
4090 
4091                         }
4092                     }
4093                 }
4094             }
4095         }
4096     }
4097 
4098     private static <T> String getNodePathString( final InheritanceModel.Node<T> node )
4099     {
4100         final StringBuilder b = new StringBuilder( node.getPath().size() * 50 );
4101 
4102         for ( int i = 0, s0 = node.getPath().size(); i < s0; i++ )
4103         {
4104             final InheritanceModel.Node<Implementation> pathNode = node.getPath().get( i );
4105 
4106             if ( pathNode.getClassDeclaration() != null )
4107             {
4108                 b.append( " -> [" ).append( pathNode.getClassDeclaration().getClazz() ).append( "] @ '" ).
4109                     append( pathNode.getImplementation().getIdentifier() ).append( "'" );
4110 
4111             }
4112             if ( pathNode.getSpecification() != null )
4113             {
4114                 b.append( " -> <" ).append( pathNode.getSpecification().getIdentifier() ).append( "> @ '" ).
4115                     append( pathNode.getImplementation().getIdentifier() ).append( "'" );
4116 
4117             }
4118             else
4119             {
4120                 b.append( " -> '" ).append( pathNode.getImplementation().getIdentifier() ).append( "'" );
4121             }
4122         }
4123 
4124         if ( node.getClassDeclaration() != null )
4125         {
4126             b.append( " -> [" ).append( node.getClassDeclaration().getClazz() ).append( "] @ '" ).
4127                 append( node.getImplementation().getIdentifier() ).append( "'" );
4128 
4129         }
4130         if ( node.getSpecification() != null )
4131         {
4132             b.append( " -> <" ).append( node.getSpecification().getIdentifier() ).append( "> @ '" ).
4133                 append( node.getImplementation().getIdentifier() ).append( "'" );
4134 
4135         }
4136 
4137         return b.length() > 0 ? b.substring( " -> ".length() ) : b.toString();
4138     }
4139 
4140     private static <T> String getNodeListPathString( final Collection<? extends InheritanceModel.Node<T>> nodes )
4141     {
4142         final StringBuilder path = new StringBuilder( nodes.size() * 255 );
4143 
4144         for ( final InheritanceModel.Node<T> node : nodes )
4145         {
4146             path.append( ", " ).append( getNodePathString( node ) );
4147         }
4148 
4149         return path.length() > 1 ? path.substring( 2 ) : path.toString();
4150     }
4151 
4152     private static <T> Set<InheritanceModel.Node<T>> retainFinalNodes( final Set<InheritanceModel.Node<T>> set )
4153     {
4154         if ( set != null )
4155         {
4156             for ( final Iterator<InheritanceModel.Node<T>> it = set.iterator(); it.hasNext(); )
4157             {
4158                 if ( !it.next().isFinal() )
4159                 {
4160                     it.remove();
4161                 }
4162             }
4163         }
4164 
4165         return set;
4166     }
4167 
4168     private static void addDetail(
4169         final ModelValidationReport report, final String identifier, final Level level,
4170         final JAXBElement<? extends ModelObject> element, final String messageKey, final Object... messageArguments )
4171     {
4172         report.getDetails().add( new ModelValidationReport.Detail(
4173             identifier, level, getMessage( messageKey, messageArguments ), element ) );
4174 
4175     }
4176 
4177     private static <T> Set<T> modifiableSet( final Collection<? extends T> col )
4178     {
4179         Set<T> set = Collections.emptySet();
4180 
4181         if ( col != null )
4182         {
4183             set = new HashSet<T>( col );
4184         }
4185 
4186         return set;
4187     }
4188 
4189     private static String getMessage( final String key, final Object... messageArguments )
4190     {
4191         return MessageFormat.format( ResourceBundle.getBundle(
4192             DefaultModelValidator.class.getName().replace( '.', '/' ),
4193             Locale.getDefault() ).getString( key ), messageArguments );
4194 
4195     }
4196 
4197     private static String getMessage( final Throwable t )
4198     {
4199         return t != null
4200                    ? t.getMessage() != null && t.getMessage().trim().length() > 0
4201                          ? t.getMessage()
4202                          : getMessage( t.getCause() )
4203                    : null;
4204 
4205     }
4206 
4207     /**
4208      * @since 1.2
4209      */
4210     private static final class ValidationContext
4211     {
4212 
4213         private final ModelContext modelContext;
4214 
4215         private final Modules modules;
4216 
4217         private final ModelValidationReport report;
4218 
4219         private final InheritanceModel inheritanceModel;
4220 
4221         private final boolean validateJava;
4222 
4223         private final Specifications allSpecifications;
4224 
4225         private final Implementations allImplementations;
4226 
4227         private final Map<String, Specification> specifications = new HashMap<String, Specification>();
4228 
4229         private final Map<String, Specifications> specificationsByImplementation =
4230             new HashMap<String, Specifications>();
4231 
4232         private final Map<String, Module> modulesOfSpecifications = new HashMap<String, Module>();
4233 
4234         private final Map<String, Implementation> implementations = new HashMap<String, Implementation>();
4235 
4236         private final Map<String, Implementations> implementationsBySpecification =
4237             new HashMap<String, Implementations>();
4238 
4239         private final Map<String, Module> modulesOfImplementations = new HashMap<String, Module>();
4240 
4241         private ValidationContext( final ModelContext modelContext, final Modules modules,
4242                                    final ModelValidationReport report, final boolean validateJava )
4243         {
4244             super();
4245             this.modelContext = modelContext;
4246             this.modules = modules;
4247             this.report = report;
4248             this.inheritanceModel = new InheritanceModel( modules );
4249             this.validateJava = validateJava;
4250             this.allImplementations = modules.getImplementations();
4251             this.allSpecifications = modules.getSpecifications();
4252 
4253             if ( this.allSpecifications != null )
4254             {
4255                 for ( final Specification s : this.allSpecifications.getSpecification() )
4256                 {
4257                     this.specifications.put( s.getIdentifier(), s );
4258                     this.implementationsBySpecification.put(
4259                         s.getIdentifier(), modules.getImplementations( s.getIdentifier() ) );
4260 
4261                     this.modulesOfSpecifications.put(
4262                         s.getIdentifier(), modules.getModuleOfSpecification( s.getIdentifier() ) );
4263 
4264                 }
4265             }
4266 
4267             if ( this.allImplementations != null )
4268             {
4269                 for ( final Implementation i : this.allImplementations.getImplementation() )
4270                 {
4271                     this.implementations.put( i.getIdentifier(), i );
4272                     this.specificationsByImplementation.put(
4273                         i.getIdentifier(), modules.getSpecifications( i.getIdentifier() ) );
4274 
4275                     this.modulesOfImplementations.put(
4276                         i.getIdentifier(), modules.getModuleOfImplementation( i.getIdentifier() ) );
4277                 }
4278             }
4279         }
4280 
4281         private ModelContext getModelContext()
4282         {
4283             return modelContext;
4284         }
4285 
4286         private Modules getModules()
4287         {
4288             return modules;
4289         }
4290 
4291         private ModelValidationReport getReport()
4292         {
4293             return report;
4294         }
4295 
4296         private InheritanceModel getInheritanceModel()
4297         {
4298             return this.inheritanceModel;
4299         }
4300 
4301         private boolean isValidateJava()
4302         {
4303             return this.validateJava;
4304         }
4305 
4306         private Specifications getAllSpecifications()
4307         {
4308             return this.allSpecifications;
4309         }
4310 
4311         private Implementations getAllImplementations()
4312         {
4313             return this.allImplementations;
4314         }
4315 
4316         private Specification getSpecification( final String identifier )
4317         {
4318             return this.specifications.get( identifier );
4319         }
4320 
4321         private Specifications getSpecifications( final String implementation )
4322         {
4323             return this.specificationsByImplementation.get( implementation );
4324         }
4325 
4326         private Implementation getImplementation( final String identifier )
4327         {
4328             return this.implementations.get( identifier );
4329         }
4330 
4331         private Implementations getImplementations( final String specification )
4332         {
4333             return this.implementationsBySpecification.get( specification );
4334         }
4335 
4336         private Module getModuleOfSpecification( final String identifier )
4337         {
4338             return this.modulesOfSpecifications.get( identifier );
4339         }
4340 
4341         private Module getModuleOfImplementation( final String identifier )
4342         {
4343             return this.modulesOfImplementations.get( identifier );
4344         }
4345 
4346     }
4347 
4348 }