View Javadoc
1   package org.apache.maven.model.merge;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.ObjectStreamException;
23  import java.util.AbstractList;
24  import java.util.ArrayList;
25  import java.util.Collection;
26  import java.util.HashMap;
27  import java.util.Iterator;
28  import java.util.LinkedHashMap;
29  import java.util.List;
30  import java.util.Map;
31  import java.util.Objects;
32  import java.util.Properties;
33  
34  import org.apache.maven.model.Activation;
35  import org.apache.maven.model.Build;
36  import org.apache.maven.model.BuildBase;
37  import org.apache.maven.model.CiManagement;
38  import org.apache.maven.model.ConfigurationContainer;
39  import org.apache.maven.model.Contributor;
40  import org.apache.maven.model.Dependency;
41  import org.apache.maven.model.DependencyManagement;
42  import org.apache.maven.model.DeploymentRepository;
43  import org.apache.maven.model.Developer;
44  import org.apache.maven.model.DistributionManagement;
45  import org.apache.maven.model.Exclusion;
46  import org.apache.maven.model.Extension;
47  import org.apache.maven.model.FileSet;
48  import org.apache.maven.model.InputLocation;
49  import org.apache.maven.model.IssueManagement;
50  import org.apache.maven.model.License;
51  import org.apache.maven.model.MailingList;
52  import org.apache.maven.model.Model;
53  import org.apache.maven.model.ModelBase;
54  import org.apache.maven.model.Notifier;
55  import org.apache.maven.model.Organization;
56  import org.apache.maven.model.Parent;
57  import org.apache.maven.model.PatternSet;
58  import org.apache.maven.model.Plugin;
59  import org.apache.maven.model.PluginConfiguration;
60  import org.apache.maven.model.PluginContainer;
61  import org.apache.maven.model.PluginExecution;
62  import org.apache.maven.model.PluginManagement;
63  import org.apache.maven.model.Prerequisites;
64  import org.apache.maven.model.Profile;
65  import org.apache.maven.model.Relocation;
66  import org.apache.maven.model.ReportPlugin;
67  import org.apache.maven.model.ReportSet;
68  import org.apache.maven.model.Reporting;
69  import org.apache.maven.model.Repository;
70  import org.apache.maven.model.RepositoryBase;
71  import org.apache.maven.model.RepositoryPolicy;
72  import org.apache.maven.model.Resource;
73  import org.apache.maven.model.Scm;
74  import org.apache.maven.model.Site;
75  import org.codehaus.plexus.util.xml.Xpp3Dom;
76  
77  /**
78   * This is a hand-crafted prototype of the default model merger that should eventually be generated by Modello by a new
79   * Java plugin. Code structure to merge source (read-only) object into the target object is:<ul>
80   * <li><code>merge<i>Classname</i>( <i>Classname</i> target, <i>Classname</i> source, boolean sourceDominant,
81   * Map&lt;Object, Object&gt; context )</code> for each model class</li>
82   * <li><code>merge<i>Classname</i>_<i>FieldName</i>( <i>Classname</i> target, <i>Classname</i> source, boolean
83   * sourceDominant, Map&lt;Object, Object&gt; context )</code> for each field of each model class</li>
84   * <li><code>Object get<i>Classname</i>Key( <i>Classname</i> <i>classname</i> )</code>
85   * for each class that is used in a list</li>
86   * </ul>
87   * Code is written like it could be generated, with default behaviour to be overridden when necessary.
88   * This is particularly the case for <code>Object get<i>Classname</i>Key( <i>Classname</i> <i>classname</i> )</code>
89   * method, which by default return the object itself and is expected to be overridden to calculate better suited key
90   * value.
91   *
92   * @author Benjamin Bentmann
93   */
94  @SuppressWarnings( { "checkstyle:methodname" } )
95  public class ModelMerger
96  {
97  
98      /**
99       * Merges the specified source object into the given target object.
100      *
101      * @param target The target object whose existing contents should be merged with the source, must not be
102      *            <code>null</code>.
103      * @param source The (read-only) source object that should be merged into the target object, may be
104      *            <code>null</code>.
105      * @param sourceDominant A flag indicating whether either the target object or the source object provides the
106      *            dominant data.
107      * @param hints A set of key-value pairs that customized merger implementations can use to carry domain-specific
108      *            information along, may be <code>null</code>.
109      */
110     public void merge( Model target, Model source, boolean sourceDominant, Map<?, ?> hints )
111     {
112         Objects.requireNonNull( target, "target cannot be null" );
113 
114         if ( source == null )
115         {
116             return;
117         }
118 
119         Map<Object, Object> context = new HashMap<>();
120         if ( hints != null )
121         {
122             context.putAll( hints );
123         }
124 
125         mergeModel( target, source, sourceDominant, context );
126     }
127 
128     protected void mergeModel( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
129     {
130         mergeModelBase( target, source, sourceDominant, context );
131 
132         mergeModel_ChildProjectUrlInheritAppendPath( target, source, sourceDominant, context );
133         mergeModel_ModelVersion( target, source, sourceDominant, context );
134         mergeModel_Parent( target, source, sourceDominant, context );
135         mergeModel_GroupId( target, source, sourceDominant, context );
136         mergeModel_ArtifactId( target, source, sourceDominant, context );
137         mergeModel_Version( target, source, sourceDominant, context );
138         mergeModel_Packaging( target, source, sourceDominant, context );
139         mergeModel_Name( target, source, sourceDominant, context );
140         mergeModel_Description( target, source, sourceDominant, context );
141         mergeModel_Url( target, source, sourceDominant, context );
142         mergeModel_InceptionYear( target, source, sourceDominant, context );
143         mergeModel_Organization( target, source, sourceDominant, context );
144         mergeModel_Licenses( target, source, sourceDominant, context );
145         mergeModel_MailingLists( target, source, sourceDominant, context );
146         mergeModel_Developers( target, source, sourceDominant, context );
147         mergeModel_Contributors( target, source, sourceDominant, context );
148         mergeModel_IssueManagement( target, source, sourceDominant, context );
149         mergeModel_Scm( target, source, sourceDominant, context );
150         mergeModel_CiManagement( target, source, sourceDominant, context );
151         mergeModel_Prerequisites( target, source, sourceDominant, context );
152         mergeModel_Build( target, source, sourceDominant, context );
153         mergeModel_Profiles( target, source, sourceDominant, context );
154     }
155 
156     protected void mergeModel_ModelVersion( Model target, Model source, boolean sourceDominant,
157                                             Map<Object, Object> context )
158     {
159         String src = source.getModelVersion();
160         if ( src != null )
161         {
162             if ( sourceDominant || target.getModelVersion() == null )
163             {
164                 target.setModelVersion( src );
165                 target.setLocation( "modelVersion", source.getLocation( "modelVersion" ) );
166             }
167         }
168     }
169 
170     protected void mergeModel_Parent( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
171     {
172         Parent src = source.getParent();
173         if ( src != null )
174         {
175             Parent tgt = target.getParent();
176             if ( tgt == null )
177             {
178                 tgt = new Parent();
179                 tgt.setRelativePath( null );
180                 target.setParent( tgt );
181             }
182             mergeParent( tgt, src, sourceDominant, context );
183         }
184     }
185 
186     protected void mergeModel_GroupId( Model target, Model source, boolean sourceDominant,
187                                        Map<Object, Object> context )
188     {
189         String src = source.getGroupId();
190         if ( src != null )
191         {
192             if ( sourceDominant || target.getGroupId() == null )
193             {
194                 target.setGroupId( src );
195                 target.setLocation( "groupId", source.getLocation( "groupId" ) );
196             }
197         }
198     }
199 
200     protected void mergeModel_ArtifactId( Model target, Model source, boolean sourceDominant,
201                                           Map<Object, Object> context )
202     {
203         String src = source.getArtifactId();
204         if ( src != null )
205         {
206             if ( sourceDominant || target.getArtifactId() == null )
207             {
208                 target.setArtifactId( src );
209                 target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
210             }
211         }
212     }
213 
214     protected void mergeModel_ChildProjectUrlInheritAppendPath( Model target, Model source, boolean sourceDominant,
215                                                                 Map<Object, Object> context )
216     {
217         String src = source.getChildProjectUrlInheritAppendPath();
218         if ( src != null )
219         {
220             if ( sourceDominant || target.getChildProjectUrlInheritAppendPath() == null )
221             {
222                 target.setChildProjectUrlInheritAppendPath( src );
223                 target.setLocation( "child.project.url.inherit.append.path",
224                                     source.getLocation( "child.project.url.inherit.append.path" ) );
225             }
226         }
227     }
228 
229     protected void mergeModel_Version( Model target, Model source, boolean sourceDominant,
230                                        Map<Object, Object> context )
231     {
232         String src = source.getVersion();
233         if ( src != null )
234         {
235             if ( sourceDominant || target.getVersion() == null )
236             {
237                 target.setVersion( src );
238                 target.setLocation( "version", source.getLocation( "version" ) );
239             }
240         }
241     }
242 
243     protected void mergeModel_Packaging( Model target, Model source, boolean sourceDominant,
244                                          Map<Object, Object> context )
245     {
246         String src = source.getPackaging();
247         if ( src != null )
248         {
249             if ( sourceDominant || target.getPackaging() == null )
250             {
251                 target.setPackaging( src );
252                 target.setLocation( "packaging", source.getLocation( "packaging" ) );
253             }
254         }
255     }
256 
257     protected void mergeModel_Name( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
258     {
259         String src = source.getName();
260         if ( src != null )
261         {
262             if ( sourceDominant || target.getName() == null )
263             {
264                 target.setName( src );
265                 target.setLocation( "name", source.getLocation( "name" ) );
266             }
267         }
268     }
269 
270     protected void mergeModel_Description( Model target, Model source, boolean sourceDominant,
271                                            Map<Object, Object> context )
272     {
273         String src = source.getDescription();
274         if ( src != null )
275         {
276             if ( sourceDominant || target.getDescription() == null )
277             {
278                 target.setDescription( src );
279                 target.setLocation( "description", source.getLocation( "description" ) );
280             }
281         }
282     }
283 
284     protected void mergeModel_Url( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
285     {
286         String src = source.getUrl();
287         if ( src != null )
288         {
289             if ( sourceDominant || target.getUrl() == null )
290             {
291                 target.setUrl( src );
292                 target.setLocation( "url", source.getLocation( "url" ) );
293             }
294         }
295     }
296 
297     protected void mergeModel_InceptionYear( Model target, Model source, boolean sourceDominant,
298                                              Map<Object, Object> context )
299     {
300         String src = source.getInceptionYear();
301         if ( src != null )
302         {
303             if ( sourceDominant || target.getInceptionYear() == null )
304             {
305                 target.setInceptionYear( src );
306                 target.setLocation( "inceptionYear", source.getLocation( "inceptionYear" ) );
307             }
308         }
309     }
310 
311     protected void mergeModel_Organization( Model target, Model source, boolean sourceDominant,
312                                             Map<Object, Object> context )
313     {
314         Organization src = source.getOrganization();
315         if ( src != null )
316         {
317             Organization tgt = target.getOrganization();
318             if ( tgt == null )
319             {
320                 tgt = new Organization();
321                 target.setOrganization( tgt );
322             }
323             mergeOrganization( tgt, src, sourceDominant, context );
324         }
325     }
326 
327     protected void mergeModel_Licenses( Model target, Model source, boolean sourceDominant,
328                                         Map<Object, Object> context )
329     {
330         target.setLicenses( merge( target.getLicenses(), source.getLicenses(),
331                                     sourceDominant, new LicenseKeyComputer() ) );
332     }
333 
334     protected void mergeModel_MailingLists( Model target, Model source, boolean sourceDominant,
335                                             Map<Object, Object> context )
336     {
337         target.setMailingLists( merge( target.getMailingLists(), source.getMailingLists(),
338                                        sourceDominant, new MailingListKeyComputer() ) );
339     }
340 
341     protected void mergeModel_Developers( Model target, Model source, boolean sourceDominant,
342                                           Map<Object, Object> context )
343     {
344         target.setDevelopers( merge( target.getDevelopers(), source.getDevelopers(),
345                 sourceDominant, new DeveloperKeyComputer() ) );
346     }
347 
348     protected void mergeModel_Contributors( Model target, Model source, boolean sourceDominant,
349                                             Map<Object, Object> context )
350     {
351         target.setContributors( merge( target.getContributors(), source.getContributors(),
352                 sourceDominant, new ContributorKeyComputer() ) );
353     }
354 
355     protected void mergeModel_IssueManagement( Model target, Model source, boolean sourceDominant,
356                                                Map<Object, Object> context )
357     {
358         IssueManagement src = source.getIssueManagement();
359         if ( src != null )
360         {
361             IssueManagement tgt = target.getIssueManagement();
362             if ( tgt == null )
363             {
364                 tgt = new IssueManagement();
365                 target.setIssueManagement( tgt );
366             }
367             mergeIssueManagement( tgt, src, sourceDominant, context );
368         }
369     }
370 
371     protected void mergeModel_Scm( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
372     {
373         Scm src = source.getScm();
374         if ( src != null )
375         {
376             Scm tgt = target.getScm();
377             if ( tgt == null )
378             {
379                 tgt = new Scm();
380                 tgt.setTag( null );
381                 target.setScm( tgt );
382             }
383             mergeScm( tgt, src, sourceDominant, context );
384         }
385     }
386 
387     protected void mergeModel_CiManagement( Model target, Model source, boolean sourceDominant,
388                                             Map<Object, Object> context )
389     {
390         CiManagement src = source.getCiManagement();
391         if ( src != null )
392         {
393             CiManagement tgt = target.getCiManagement();
394             if ( tgt == null )
395             {
396                 tgt = new CiManagement();
397                 target.setCiManagement( tgt );
398             }
399             mergeCiManagement( tgt, src, sourceDominant, context );
400         }
401     }
402 
403     protected void mergeModel_Prerequisites( Model target, Model source, boolean sourceDominant,
404                                              Map<Object, Object> context )
405     {
406         Prerequisites src = source.getPrerequisites();
407         if ( src != null )
408         {
409             Prerequisites tgt = target.getPrerequisites();
410             if ( tgt == null )
411             {
412                 tgt = new Prerequisites();
413                 tgt.setMaven( null );
414                 target.setPrerequisites( tgt );
415             }
416             mergePrerequisites( tgt, src, sourceDominant, context );
417         }
418     }
419 
420     protected void mergeModel_Build( Model target, Model source, boolean sourceDominant, Map<Object, Object> context )
421     {
422         Build src = source.getBuild();
423         if ( src != null )
424         {
425             Build tgt = target.getBuild();
426             if ( tgt == null )
427             {
428                 tgt = new Build();
429                 target.setBuild( tgt );
430             }
431             mergeBuild( tgt, src, sourceDominant, context );
432         }
433     }
434 
435     protected void mergeModel_Profiles( Model target, Model source, boolean sourceDominant,
436                                         Map<Object, Object> context )
437     {
438         target.setProfiles( merge( target.getProfiles(), source.getProfiles(),
439                 sourceDominant, new ProfileKeyComputer() ) );
440     }
441 
442     protected void mergeModelBase( ModelBase target, ModelBase source, boolean sourceDominant,
443                                    Map<Object, Object> context )
444     {
445         mergeModelBase_DistributionManagement( target, source, sourceDominant, context );
446         mergeModelBase_Modules( target, source, sourceDominant, context );
447         mergeModelBase_Repositories( target, source, sourceDominant, context );
448         mergeModelBase_PluginRepositories( target, source, sourceDominant, context );
449         mergeModelBase_Dependencies( target, source, sourceDominant, context );
450         mergeModelBase_Reporting( target, source, sourceDominant, context );
451         mergeModelBase_DependencyManagement( target, source, sourceDominant, context );
452         mergeModelBase_Properties( target, source, sourceDominant, context );
453     }
454 
455     protected void mergeModelBase_Modules( ModelBase target, ModelBase source, boolean sourceDominant,
456                                            Map<Object, Object> context )
457     {
458         List<String> src = source.getModules();
459         if ( !src.isEmpty() )
460         {
461             List<String> tgt = target.getModules();
462             List<String> merged = new ArrayList<>( tgt.size() + src.size() );
463             merged.addAll( tgt );
464             merged.addAll( src );
465             target.setModules( merged );
466         }
467     }
468 
469     protected void mergeModelBase_Dependencies( ModelBase target, ModelBase source, boolean sourceDominant,
470                                                 Map<Object, Object> context )
471     {
472         target.setDependencies( merge( target.getDependencies(), source.getDependencies(),
473                 sourceDominant, new DependencyKeyComputer() ) );
474     }
475 
476     protected void mergeModelBase_Repositories( ModelBase target, ModelBase source, boolean sourceDominant,
477                                                 Map<Object, Object> context )
478     {
479         target.setRepositories( merge( target.getRepositories(), source.getRepositories(),
480                 sourceDominant, new RepositoryKeyComputer() ) );
481     }
482 
483     protected void mergeModelBase_PluginRepositories( ModelBase target, ModelBase source, boolean sourceDominant,
484                                                       Map<Object, Object> context )
485     {
486         target.setPluginRepositories( merge( target.getPluginRepositories(), source.getPluginRepositories(),
487                 sourceDominant, new RepositoryKeyComputer() ) );
488     }
489 
490     protected void mergeModelBase_DistributionManagement( ModelBase target, ModelBase source, boolean sourceDominant,
491                                                           Map<Object, Object> context )
492     {
493         DistributionManagement src = source.getDistributionManagement();
494         if ( src != null )
495         {
496             DistributionManagement tgt = target.getDistributionManagement();
497             if ( tgt == null )
498             {
499                 tgt = new DistributionManagement();
500                 target.setDistributionManagement( tgt );
501             }
502             mergeDistributionManagement( tgt, src, sourceDominant, context );
503         }
504     }
505 
506     protected void mergeModelBase_Reporting( ModelBase target, ModelBase source, boolean sourceDominant,
507                                              Map<Object, Object> context )
508     {
509         Reporting src = source.getReporting();
510         if ( src != null )
511         {
512             Reporting tgt = target.getReporting();
513             if ( tgt == null )
514             {
515                 tgt = new Reporting();
516                 target.setReporting( tgt );
517             }
518             mergeReporting( tgt, src, sourceDominant, context );
519         }
520     }
521 
522     protected void mergeModelBase_DependencyManagement( ModelBase target, ModelBase source, boolean sourceDominant,
523                                                         Map<Object, Object> context )
524     {
525         DependencyManagement src = source.getDependencyManagement();
526         if ( src != null )
527         {
528             DependencyManagement tgt = target.getDependencyManagement();
529             if ( tgt == null )
530             {
531                 tgt = new DependencyManagement();
532                 target.setDependencyManagement( tgt );
533             }
534             mergeDependencyManagement( tgt, src, sourceDominant, context );
535         }
536     }
537 
538     protected void mergeModelBase_Properties( ModelBase target, ModelBase source, boolean sourceDominant,
539                                               Map<Object, Object> context )
540     {
541         Properties merged = new Properties();
542         if ( sourceDominant )
543         {
544             merged.putAll( target.getProperties() );
545             merged.putAll( source.getProperties() );
546         }
547         else
548         {
549             merged.putAll( source.getProperties() );
550             merged.putAll( target.getProperties() );
551         }
552         target.setProperties( merged );
553         target.setLocation( "properties", InputLocation.merge( target.getLocation( "properties" ),
554                                                                source.getLocation( "properties" ), sourceDominant ) );
555     }
556 
557     protected void mergeDistributionManagement( DistributionManagement target, DistributionManagement source,
558                                                 boolean sourceDominant, Map<Object, Object> context )
559     {
560         mergeDistributionManagement_Repository( target, source, sourceDominant, context );
561         mergeDistributionManagement_SnapshotRepository( target, source, sourceDominant, context );
562         mergeDistributionManagement_Site( target, source, sourceDominant, context );
563         mergeDistributionManagement_Status( target, source, sourceDominant, context );
564         mergeDistributionManagement_DownloadUrl( target, source, sourceDominant, context );
565     }
566 
567     protected void mergeDistributionManagement_Repository( DistributionManagement target,
568                                                            DistributionManagement source, boolean sourceDominant,
569                                                            Map<Object, Object> context )
570     {
571         DeploymentRepository src = source.getRepository();
572         if ( src != null )
573         {
574             DeploymentRepository tgt = target.getRepository();
575             if ( tgt == null )
576             {
577                 tgt = new DeploymentRepository();
578                 target.setRepository( tgt );
579             }
580             mergeDeploymentRepository( tgt, src, sourceDominant, context );
581         }
582     }
583 
584     protected void mergeDistributionManagement_SnapshotRepository( DistributionManagement target,
585                                                                    DistributionManagement source,
586                                                                    boolean sourceDominant,
587                                                                    Map<Object, Object> context )
588     {
589         DeploymentRepository src = source.getSnapshotRepository();
590         if ( src != null )
591         {
592             DeploymentRepository tgt = target.getSnapshotRepository();
593             if ( tgt == null )
594             {
595                 tgt = new DeploymentRepository();
596                 target.setSnapshotRepository( tgt );
597             }
598             mergeDeploymentRepository( tgt, src, sourceDominant, context );
599         }
600     }
601 
602     protected void mergeDistributionManagement_Site( DistributionManagement target, DistributionManagement source,
603                                                      boolean sourceDominant, Map<Object, Object> context )
604     {
605         Site src = source.getSite();
606         if ( src != null )
607         {
608             Site tgt = target.getSite();
609             if ( tgt == null )
610             {
611                 tgt = new Site();
612                 target.setSite( tgt );
613             }
614             mergeSite( tgt, src, sourceDominant, context );
615         }
616     }
617 
618     protected void mergeDistributionManagement_Status( DistributionManagement target, DistributionManagement source,
619                                                        boolean sourceDominant, Map<Object, Object> context )
620     {
621         String src = source.getStatus();
622         if ( src != null )
623         {
624             if ( sourceDominant || target.getStatus() == null )
625             {
626                 target.setStatus( src );
627                 target.setLocation( "status", source.getLocation( "status" ) );
628             }
629         }
630     }
631 
632     protected void mergeDistributionManagement_DownloadUrl( DistributionManagement target,
633                                                             DistributionManagement source, boolean sourceDominant,
634                                                             Map<Object, Object> context )
635     {
636         String src = source.getDownloadUrl();
637         if ( src != null )
638         {
639             if ( sourceDominant || target.getDownloadUrl() == null )
640             {
641                 target.setDownloadUrl( src );
642                 target.setLocation( "downloadUrl", source.getLocation( "downloadUrl" ) );
643             }
644         }
645     }
646 
647     protected void mergeRelocation( Relocation target, Relocation source, boolean sourceDominant,
648                                     Map<Object, Object> context )
649     {
650         mergeRelocation_GroupId( target, source, sourceDominant, context );
651         mergeRelocation_ArtifactId( target, source, sourceDominant, context );
652         mergeRelocation_Version( target, source, sourceDominant, context );
653         mergeRelocation_Message( target, source, sourceDominant, context );
654     }
655 
656     protected void mergeRelocation_GroupId( Relocation target, Relocation source, boolean sourceDominant,
657                                             Map<Object, Object> context )
658     {
659         String src = source.getGroupId();
660         if ( src != null )
661         {
662             if ( sourceDominant || target.getGroupId() == null )
663             {
664                 target.setGroupId( src );
665                 target.setLocation( "groupId", source.getLocation( "groupId" ) );
666             }
667         }
668     }
669 
670     protected void mergeRelocation_ArtifactId( Relocation target, Relocation source, boolean sourceDominant,
671                                                Map<Object, Object> context )
672     {
673         String src = source.getArtifactId();
674         if ( src != null )
675         {
676             if ( sourceDominant || target.getArtifactId() == null )
677             {
678                 target.setArtifactId( src );
679                 target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
680             }
681         }
682     }
683 
684     protected void mergeRelocation_Version( Relocation target, Relocation source, boolean sourceDominant,
685                                             Map<Object, Object> context )
686     {
687         String src = source.getVersion();
688         if ( src != null )
689         {
690             if ( sourceDominant || target.getVersion() == null )
691             {
692                 target.setVersion( src );
693                 target.setLocation( "version", source.getLocation( "version" ) );
694             }
695         }
696     }
697 
698     protected void mergeRelocation_Message( Relocation target, Relocation source, boolean sourceDominant,
699                                             Map<Object, Object> context )
700     {
701         String src = source.getMessage();
702         if ( src != null )
703         {
704             if ( sourceDominant || target.getMessage() == null )
705             {
706                 target.setMessage( src );
707                 target.setLocation( "message", source.getLocation( "message" ) );
708             }
709         }
710     }
711 
712     protected void mergeDeploymentRepository( DeploymentRepository target, DeploymentRepository source,
713                                               boolean sourceDominant, Map<Object, Object> context )
714     {
715         mergeRepository( target, source, sourceDominant, context );
716         mergeDeploymentRepository_UniqueVersion( target, source, sourceDominant, context );
717     }
718 
719     protected void mergeDeploymentRepository_UniqueVersion( DeploymentRepository target, DeploymentRepository source,
720                                                             boolean sourceDominant, Map<Object, Object> context )
721     {
722         if ( sourceDominant )
723         {
724             target.setUniqueVersion( source.isUniqueVersion() );
725             target.setLocation( "uniqueVersion", source.getLocation( "uniqueVersion" ) );
726         }
727     }
728 
729     protected void mergeSite( Site target, Site source, boolean sourceDominant, Map<Object, Object> context )
730     {
731         mergeSite_ChildSiteUrlInheritAppendPath( target, source, sourceDominant, context );
732         mergeSite_Id( target, source, sourceDominant, context );
733         mergeSite_Name( target, source, sourceDominant, context );
734         mergeSite_Url( target, source, sourceDominant, context );
735     }
736 
737     protected void mergeSite_ChildSiteUrlInheritAppendPath( Site target, Site source, boolean sourceDominant,
738                                                             Map<Object, Object> context )
739     {
740         String src = source.getChildSiteUrlInheritAppendPath();
741         if ( src != null )
742         {
743             if ( sourceDominant || target.getChildSiteUrlInheritAppendPath() == null )
744             {
745                 target.setChildSiteUrlInheritAppendPath( src );
746                 target.setLocation( "child.site.url.inherit.append.path",
747                                     source.getLocation( "child.site.url.inherit.append.path" ) );
748             }
749         }
750     }
751 
752     protected void mergeSite_Id( Site target, Site source, boolean sourceDominant, Map<Object, Object> context )
753     {
754         String src = source.getId();
755         if ( src != null )
756         {
757             if ( sourceDominant || target.getId() == null )
758             {
759                 target.setId( src );
760                 target.setLocation( "id", source.getLocation( "id" ) );
761             }
762         }
763     }
764 
765     protected void mergeSite_Name( Site target, Site source, boolean sourceDominant, Map<Object, Object> context )
766     {
767         String src = source.getName();
768         if ( src != null )
769         {
770             if ( sourceDominant || target.getName() == null )
771             {
772                 target.setName( src );
773                 target.setLocation( "name", source.getLocation( "name" ) );
774             }
775         }
776     }
777 
778     protected void mergeSite_Url( Site target, Site source, boolean sourceDominant, Map<Object, Object> context )
779     {
780         String src = source.getUrl();
781         if ( src != null )
782         {
783             if ( sourceDominant || target.getUrl() == null )
784             {
785                 target.setUrl( src );
786                 target.setLocation( "url", source.getLocation( "url" ) );
787             }
788         }
789     }
790 
791     protected void mergeRepository( Repository target, Repository source, boolean sourceDominant,
792                                     Map<Object, Object> context )
793     {
794         mergeRepositoryBase( target, source, sourceDominant, context );
795         mergeRepository_Releases( target, source, sourceDominant, context );
796         mergeRepository_Snapshots( target, source, sourceDominant, context );
797     }
798 
799     protected void mergeRepository_Releases( Repository target, Repository source, boolean sourceDominant,
800                                              Map<Object, Object> context )
801     {
802         RepositoryPolicy src = source.getReleases();
803         if ( src != null )
804         {
805             RepositoryPolicy tgt = target.getReleases();
806             if ( tgt == null )
807             {
808                 tgt = new RepositoryPolicy();
809                 target.setReleases( tgt );
810             }
811             mergeRepositoryPolicy( tgt, src, sourceDominant, context );
812         }
813     }
814 
815     protected void mergeRepository_Snapshots( Repository target, Repository source, boolean sourceDominant,
816                                               Map<Object, Object> context )
817     {
818         RepositoryPolicy src = source.getSnapshots();
819         if ( src != null )
820         {
821             RepositoryPolicy tgt = target.getSnapshots();
822             if ( tgt == null )
823             {
824                 tgt = new RepositoryPolicy();
825                 target.setSnapshots( tgt );
826             }
827             mergeRepositoryPolicy( tgt, src, sourceDominant, context );
828         }
829     }
830 
831     protected void mergeRepositoryBase( RepositoryBase target, RepositoryBase source, boolean sourceDominant,
832                                         Map<Object, Object> context )
833     {
834         mergeRepositoryBase_Id( target, source, sourceDominant, context );
835         mergeRepositoryBase_Name( target, source, sourceDominant, context );
836         mergeRepositoryBase_Url( target, source, sourceDominant, context );
837         mergeRepositoryBase_Layout( target, source, sourceDominant, context );
838     }
839 
840     protected void mergeRepositoryBase_Id( RepositoryBase target, RepositoryBase source, boolean sourceDominant,
841                                            Map<Object, Object> context )
842     {
843         String src = source.getId();
844         if ( src != null )
845         {
846             if ( sourceDominant || target.getId() == null )
847             {
848                 target.setId( src );
849                 target.setLocation( "id", source.getLocation( "id" ) );
850             }
851         }
852     }
853 
854     protected void mergeRepositoryBase_Url( RepositoryBase target, RepositoryBase source, boolean sourceDominant,
855                                             Map<Object, Object> context )
856     {
857         String src = source.getUrl();
858         if ( src != null )
859         {
860             if ( sourceDominant || target.getUrl() == null )
861             {
862                 target.setUrl( src );
863                 target.setLocation( "url", source.getLocation( "url" ) );
864             }
865         }
866     }
867 
868     protected void mergeRepositoryBase_Name( RepositoryBase target, RepositoryBase source, boolean sourceDominant,
869                                              Map<Object, Object> context )
870     {
871         String src = source.getName();
872         if ( src != null )
873         {
874             if ( sourceDominant || target.getName() == null )
875             {
876                 target.setName( src );
877                 target.setLocation( "name", source.getLocation( "name" ) );
878             }
879         }
880     }
881 
882     protected void mergeRepositoryBase_Layout( RepositoryBase target, RepositoryBase source, boolean sourceDominant,
883                                                Map<Object, Object> context )
884     {
885         String src = source.getLayout();
886         if ( src != null )
887         {
888             if ( sourceDominant || target.getLayout() == null )
889             {
890                 target.setLayout( src );
891                 target.setLocation( "layout", source.getLocation( "layout" ) );
892             }
893         }
894     }
895 
896     protected void mergeRepositoryPolicy( RepositoryPolicy target, RepositoryPolicy source, boolean sourceDominant,
897                                           Map<Object, Object> context )
898     {
899         mergeRepositoryPolicy_Enabled( target, source, sourceDominant, context );
900         mergeRepositoryPolicy_UpdatePolicy( target, source, sourceDominant, context );
901         mergeRepositoryPolicy_ChecksumPolicy( target, source, sourceDominant, context );
902     }
903 
904     protected void mergeRepositoryPolicy_Enabled( RepositoryPolicy target, RepositoryPolicy source,
905                                                   boolean sourceDominant, Map<Object, Object> context )
906     {
907         String src = source.getEnabled();
908         if ( src != null )
909         {
910             if ( sourceDominant || target.getEnabled() == null )
911             {
912                 target.setEnabled( src );
913                 target.setLocation( "enabled", source.getLocation( "enabled" ) );
914             }
915         }
916     }
917 
918     protected void mergeRepositoryPolicy_UpdatePolicy( RepositoryPolicy target, RepositoryPolicy source,
919                                                        boolean sourceDominant, Map<Object, Object> context )
920     {
921         String src = source.getUpdatePolicy();
922         if ( src != null )
923         {
924             if ( sourceDominant || target.getUpdatePolicy() == null )
925             {
926                 target.setUpdatePolicy( src );
927                 target.setLocation( "updatePolicy", source.getLocation( "updatePolicy" ) );
928             }
929         }
930     }
931 
932     protected void mergeRepositoryPolicy_ChecksumPolicy( RepositoryPolicy target, RepositoryPolicy source,
933                                                          boolean sourceDominant, Map<Object, Object> context )
934     {
935         String src = source.getChecksumPolicy();
936         if ( src != null )
937         {
938             if ( sourceDominant || target.getChecksumPolicy() == null )
939             {
940                 target.setChecksumPolicy( src );
941                 target.setLocation( "checksumPolicy", source.getLocation( "checksumPolicy" ) );
942             }
943         }
944     }
945 
946     protected void mergeDependency( Dependency target, Dependency source, boolean sourceDominant,
947                                     Map<Object, Object> context )
948     {
949         mergeDependency_GroupId( target, source, sourceDominant, context );
950         mergeDependency_ArtifactId( target, source, sourceDominant, context );
951         mergeDependency_Version( target, source, sourceDominant, context );
952         mergeDependency_Type( target, source, sourceDominant, context );
953         mergeDependency_Classifier( target, source, sourceDominant, context );
954         mergeDependency_Scope( target, source, sourceDominant, context );
955         mergeDependency_SystemPath( target, source, sourceDominant, context );
956         mergeDependency_Optional( target, source, sourceDominant, context );
957         mergeDependency_Exclusions( target, source, sourceDominant, context );
958     }
959 
960     protected void mergeDependency_GroupId( Dependency target, Dependency source, boolean sourceDominant,
961                                             Map<Object, Object> context )
962     {
963         String src = source.getGroupId();
964         if ( src != null )
965         {
966             if ( sourceDominant || target.getGroupId() == null )
967             {
968                 target.setGroupId( src );
969                 target.setLocation( "groupId", source.getLocation( "groupId" ) );
970             }
971         }
972     }
973 
974     protected void mergeDependency_ArtifactId( Dependency target, Dependency source, boolean sourceDominant,
975                                                Map<Object, Object> context )
976     {
977         String src = source.getArtifactId();
978         if ( src != null )
979         {
980             if ( sourceDominant || target.getArtifactId() == null )
981             {
982                 target.setArtifactId( src );
983                 target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
984             }
985         }
986     }
987 
988     protected void mergeDependency_Version( Dependency target, Dependency source, boolean sourceDominant,
989                                             Map<Object, Object> context )
990     {
991         String src = source.getVersion();
992         if ( src != null )
993         {
994             if ( sourceDominant || target.getVersion() == null )
995             {
996                 target.setVersion( src );
997                 target.setLocation( "version", source.getLocation( "version" ) );
998             }
999         }
1000     }
1001 
1002     protected void mergeDependency_Type( Dependency target, Dependency source, boolean sourceDominant,
1003                                          Map<Object, Object> context )
1004     {
1005         String src = source.getType();
1006         if ( src != null )
1007         {
1008             if ( sourceDominant || target.getType() == null )
1009             {
1010                 target.setType( src );
1011                 target.setLocation( "type", source.getLocation( "type" ) );
1012             }
1013         }
1014     }
1015 
1016     protected void mergeDependency_Classifier( Dependency target, Dependency source, boolean sourceDominant,
1017                                                Map<Object, Object> context )
1018     {
1019         String src = source.getClassifier();
1020         if ( src != null )
1021         {
1022             if ( sourceDominant || target.getClassifier() == null )
1023             {
1024                 target.setClassifier( src );
1025                 target.setLocation( "classifier", source.getLocation( "classifier" ) );
1026             }
1027         }
1028     }
1029 
1030     protected void mergeDependency_Scope( Dependency target, Dependency source, boolean sourceDominant,
1031                                           Map<Object, Object> context )
1032     {
1033         String src = source.getScope();
1034         if ( src != null )
1035         {
1036             if ( sourceDominant || target.getScope() == null )
1037             {
1038                 target.setScope( src );
1039                 target.setLocation( "scope", source.getLocation( "scope" ) );
1040             }
1041         }
1042     }
1043 
1044     protected void mergeDependency_SystemPath( Dependency target, Dependency source, boolean sourceDominant,
1045                                                Map<Object, Object> context )
1046     {
1047         String src = source.getSystemPath();
1048         if ( src != null )
1049         {
1050             if ( sourceDominant || target.getSystemPath() == null )
1051             {
1052                 target.setSystemPath( src );
1053                 target.setLocation( "systemPath", source.getLocation( "systemPath" ) );
1054             }
1055         }
1056     }
1057 
1058     protected void mergeDependency_Optional( Dependency target, Dependency source, boolean sourceDominant,
1059                                              Map<Object, Object> context )
1060     {
1061         String src = source.getOptional();
1062         if ( src != null )
1063         {
1064             if ( sourceDominant || target.getOptional() == null )
1065             {
1066                 target.setOptional( src );
1067                 target.setLocation( "optional", source.getLocation( "optional" ) );
1068             }
1069         }
1070     }
1071 
1072     protected void mergeDependency_Exclusions( Dependency target, Dependency source, boolean sourceDominant,
1073                                                Map<Object, Object> context )
1074     {
1075         target.setExclusions( merge( target.getExclusions(), source.getExclusions(),
1076                 sourceDominant, new ExclusionKeyComputer() ) );
1077     }
1078 
1079     protected void mergeExclusion( Exclusion target, Exclusion source, boolean sourceDominant,
1080                                    Map<Object, Object> context )
1081     {
1082         mergeExclusion_GroupId( target, source, sourceDominant, context );
1083         mergeExclusion_ArtifactId( target, source, sourceDominant, context );
1084     }
1085 
1086     protected void mergeExclusion_GroupId( Exclusion target, Exclusion source, boolean sourceDominant,
1087                                            Map<Object, Object> context )
1088     {
1089         String src = source.getGroupId();
1090         if ( src != null )
1091         {
1092             if ( sourceDominant || target.getGroupId() == null )
1093             {
1094                 target.setGroupId( src );
1095                 target.setLocation( "groupId", source.getLocation( "groupId" ) );
1096             }
1097         }
1098     }
1099 
1100     protected void mergeExclusion_ArtifactId( Exclusion target, Exclusion source, boolean sourceDominant,
1101                                               Map<Object, Object> context )
1102     {
1103         String src = source.getArtifactId();
1104         if ( src != null )
1105         {
1106             if ( sourceDominant || target.getArtifactId() == null )
1107             {
1108                 target.setArtifactId( src );
1109                 target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
1110             }
1111         }
1112     }
1113 
1114     protected void mergeReporting( Reporting target, Reporting source, boolean sourceDominant,
1115                                    Map<Object, Object> context )
1116     {
1117         mergeReporting_OutputDirectory( target, source, sourceDominant, context );
1118         mergeReporting_ExcludeDefaults( target, source, sourceDominant, context );
1119         mergeReporting_Plugins( target, source, sourceDominant, context );
1120     }
1121 
1122     protected void mergeReporting_OutputDirectory( Reporting target, Reporting source, boolean sourceDominant,
1123                                                    Map<Object, Object> context )
1124     {
1125         String src = source.getOutputDirectory();
1126         if ( src != null )
1127         {
1128             if ( sourceDominant || target.getOutputDirectory() == null )
1129             {
1130                 target.setOutputDirectory( src );
1131                 target.setLocation( "outputDirectory", source.getLocation( "outputDirectory" ) );
1132             }
1133         }
1134     }
1135 
1136     protected void mergeReporting_ExcludeDefaults( Reporting target, Reporting source, boolean sourceDominant,
1137                                                    Map<Object, Object> context )
1138     {
1139         String src = source.getExcludeDefaults();
1140         if ( src != null )
1141         {
1142             if ( sourceDominant || target.getExcludeDefaults() == null )
1143             {
1144                 target.setExcludeDefaults( src );
1145                 target.setLocation( "excludeDefaults", source.getLocation( "excludeDefaults" ) );
1146             }
1147         }
1148     }
1149 
1150     protected void mergeReporting_Plugins( Reporting target, Reporting source, boolean sourceDominant,
1151                                            Map<Object, Object> context )
1152     {
1153         target.setPlugins( merge( target.getPlugins(), source.getPlugins(),
1154                 sourceDominant, new ReportPluginKeyComputer() ) );
1155     }
1156 
1157     protected void mergeReportPlugin( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
1158                                       Map<Object, Object> context )
1159     {
1160         mergeConfigurationContainer( target, source, sourceDominant, context );
1161         mergeReportPlugin_GroupId( target, source, sourceDominant, context );
1162         mergeReportPlugin_ArtifactId( target, source, sourceDominant, context );
1163         mergeReportPlugin_Version( target, source, sourceDominant, context );
1164         mergeReportPlugin_ReportSets( target, source, sourceDominant, context );
1165     }
1166 
1167     protected void mergeReportPlugin_GroupId( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
1168                                               Map<Object, Object> context )
1169     {
1170         String src = source.getGroupId();
1171         if ( src != null )
1172         {
1173             if ( sourceDominant || target.getGroupId() == null )
1174             {
1175                 target.setGroupId( src );
1176                 target.setLocation( "groupId", source.getLocation( "groupId" ) );
1177             }
1178         }
1179     }
1180 
1181     protected void mergeReportPlugin_ArtifactId( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
1182                                                  Map<Object, Object> context )
1183     {
1184         String src = source.getArtifactId();
1185         if ( src != null )
1186         {
1187             if ( sourceDominant || target.getArtifactId() == null )
1188             {
1189                 target.setArtifactId( src );
1190                 target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
1191             }
1192         }
1193     }
1194 
1195     protected void mergeReportPlugin_Version( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
1196                                               Map<Object, Object> context )
1197     {
1198         String src = source.getVersion();
1199         if ( src != null )
1200         {
1201             if ( sourceDominant || target.getVersion() == null )
1202             {
1203                 target.setVersion( src );
1204                 target.setLocation( "version", source.getLocation( "version" ) );
1205             }
1206         }
1207     }
1208 
1209     protected void mergeReportPlugin_ReportSets( ReportPlugin target, ReportPlugin source, boolean sourceDominant,
1210                                                  Map<Object, Object> context )
1211     {
1212         target.setReportSets( merge( target.getReportSets(), source.getReportSets(),
1213                 sourceDominant, new ReportSetKeyComputer() ) );
1214     }
1215 
1216     protected void mergeReportSet( ReportSet target, ReportSet source, boolean sourceDominant,
1217                                    Map<Object, Object> context )
1218     {
1219         mergeConfigurationContainer( target, source, sourceDominant, context );
1220         mergeReportSet_Id( target, source, sourceDominant, context );
1221         mergeReportSet_Reports( target, source, sourceDominant, context );
1222     }
1223 
1224     protected void mergeReportSet_Id( ReportSet target, ReportSet source, boolean sourceDominant,
1225                                       Map<Object, Object> context )
1226     {
1227         String src = source.getId();
1228         if ( src != null )
1229         {
1230             if ( sourceDominant || target.getId() == null )
1231             {
1232                 target.setId( src );
1233                 target.setLocation( "id", source.getLocation( "id" ) );
1234             }
1235         }
1236     }
1237 
1238     protected void mergeReportSet_Reports( ReportSet target, ReportSet source, boolean sourceDominant,
1239                                            Map<Object, Object> context )
1240     {
1241         List<String> src = source.getReports();
1242         if ( !src.isEmpty() )
1243         {
1244             List<String> tgt = target.getReports();
1245             List<String> merged = new ArrayList<>( tgt.size() + src.size() );
1246             merged.addAll( tgt );
1247             merged.addAll( src );
1248             target.setReports( merged );
1249 
1250             InputLocation sourceLocation = source.getLocation( "reports" );
1251             if ( sourceLocation != null )
1252             {
1253                 InputLocation targetLocation = target.getLocation( "reports" );
1254                 if ( targetLocation == null )
1255                 {
1256                     target.setLocation( "reports", sourceLocation );
1257                 }
1258                 else
1259                 {
1260                     for ( int i = 0; i < src.size(); i++ )
1261                     {
1262                         targetLocation.setLocation( Integer.valueOf( tgt.size() + i ),
1263                                                     sourceLocation.getLocation( Integer.valueOf( i ) ) );
1264                     }
1265                 }
1266             }
1267         }
1268     }
1269 
1270     protected void mergeDependencyManagement( DependencyManagement target, DependencyManagement source,
1271                                               boolean sourceDominant, Map<Object, Object> context )
1272     {
1273         mergeDependencyManagement_Dependencies( target, source, sourceDominant, context );
1274     }
1275 
1276     protected void mergeDependencyManagement_Dependencies( DependencyManagement target, DependencyManagement source,
1277                                                            boolean sourceDominant, Map<Object, Object> context )
1278     {
1279         target.setDependencies( merge( target.getDependencies(), source.getDependencies(),
1280                                        sourceDominant, new DependencyKeyComputer() ) );
1281     }
1282 
1283     protected void mergeParent( Parent target, Parent source, boolean sourceDominant, Map<Object, Object> context )
1284     {
1285         mergeParent_GroupId( target, source, sourceDominant, context );
1286         mergeParent_ArtifactId( target, source, sourceDominant, context );
1287         mergeParent_Version( target, source, sourceDominant, context );
1288         mergeParent_RelativePath( target, source, sourceDominant, context );
1289     }
1290 
1291     protected void mergeParent_GroupId( Parent target, Parent source, boolean sourceDominant,
1292                                         Map<Object, Object> context )
1293     {
1294         String src = source.getGroupId();
1295         if ( src != null )
1296         {
1297             if ( sourceDominant || target.getGroupId() == null )
1298             {
1299                 target.setGroupId( src );
1300                 target.setLocation( "groupId", source.getLocation( "groupId" ) );
1301             }
1302         }
1303     }
1304 
1305     protected void mergeParent_ArtifactId( Parent target, Parent source, boolean sourceDominant,
1306                                            Map<Object, Object> context )
1307     {
1308         String src = source.getArtifactId();
1309         if ( src != null )
1310         {
1311             if ( sourceDominant || target.getArtifactId() == null )
1312             {
1313                 target.setArtifactId( src );
1314                 target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
1315             }
1316         }
1317     }
1318 
1319     protected void mergeParent_Version( Parent target, Parent source, boolean sourceDominant,
1320                                         Map<Object, Object> context )
1321     {
1322         String src = source.getVersion();
1323         if ( src != null )
1324         {
1325             if ( sourceDominant || target.getVersion() == null )
1326             {
1327                 target.setVersion( src );
1328                 target.setLocation( "version", source.getLocation( "version" ) );
1329             }
1330         }
1331     }
1332 
1333     protected void mergeParent_RelativePath( Parent target, Parent source, boolean sourceDominant,
1334                                              Map<Object, Object> context )
1335     {
1336         String src = source.getRelativePath();
1337         if ( src != null )
1338         {
1339             if ( sourceDominant || target.getRelativePath() == null )
1340             {
1341                 target.setRelativePath( src );
1342                 target.setLocation( "relativePath", source.getLocation( "relativePath" ) );
1343             }
1344         }
1345     }
1346 
1347     protected void mergeOrganization( Organization target, Organization source, boolean sourceDominant,
1348                                       Map<Object, Object> context )
1349     {
1350         mergeOrganization_Name( target, source, sourceDominant, context );
1351         mergeOrganization_Url( target, source, sourceDominant, context );
1352     }
1353 
1354     protected void mergeOrganization_Name( Organization target, Organization source, boolean sourceDominant,
1355                                            Map<Object, Object> context )
1356     {
1357         String src = source.getName();
1358         if ( src != null )
1359         {
1360             if ( sourceDominant || target.getName() == null )
1361             {
1362                 target.setName( src );
1363                 target.setLocation( "name", source.getLocation( "name" ) );
1364             }
1365         }
1366     }
1367 
1368     protected void mergeOrganization_Url( Organization target, Organization source, boolean sourceDominant,
1369                                           Map<Object, Object> context )
1370     {
1371         String src = source.getUrl();
1372         if ( src != null )
1373         {
1374             if ( sourceDominant || target.getUrl() == null )
1375             {
1376                 target.setUrl( src );
1377                 target.setLocation( "url", source.getLocation( "url" ) );
1378             }
1379         }
1380     }
1381 
1382     protected void mergeLicense( License target, License source, boolean sourceDominant, Map<Object, Object> context )
1383     {
1384         mergeLicense_Name( target, source, sourceDominant, context );
1385         mergeLicense_Url( target, source, sourceDominant, context );
1386         mergeLicense_Distribution( target, source, sourceDominant, context );
1387         mergeLicense_Comments( target, source, sourceDominant, context );
1388     }
1389 
1390     protected void mergeLicense_Name( License target, License source, boolean sourceDominant,
1391                                       Map<Object, Object> context )
1392     {
1393         String src = source.getName();
1394         if ( src != null )
1395         {
1396             if ( sourceDominant || target.getName() == null )
1397             {
1398                 target.setName( src );
1399                 target.setLocation( "name", source.getLocation( "name" ) );
1400             }
1401         }
1402     }
1403 
1404     protected void mergeLicense_Url( License target, License source, boolean sourceDominant,
1405                                      Map<Object, Object> context )
1406     {
1407         String src = source.getUrl();
1408         if ( src != null )
1409         {
1410             if ( sourceDominant || target.getUrl() == null )
1411             {
1412                 target.setUrl( src );
1413                 target.setLocation( "url", source.getLocation( "url" ) );
1414             }
1415         }
1416     }
1417 
1418     protected void mergeLicense_Distribution( License target, License source, boolean sourceDominant,
1419                                               Map<Object, Object> context )
1420     {
1421         String src = source.getDistribution();
1422         if ( src != null )
1423         {
1424             if ( sourceDominant || target.getDistribution() == null )
1425             {
1426                 target.setDistribution( src );
1427                 target.setLocation( "distribution", source.getLocation( "distribution" ) );
1428             }
1429         }
1430     }
1431 
1432     protected void mergeLicense_Comments( License target, License source, boolean sourceDominant,
1433                                           Map<Object, Object> context )
1434     {
1435         String src = source.getComments();
1436         if ( src != null )
1437         {
1438             if ( sourceDominant || target.getComments() == null )
1439             {
1440                 target.setComments( src );
1441                 target.setLocation( "comments", source.getLocation( "comments" ) );
1442             }
1443         }
1444     }
1445 
1446     protected void mergeMailingList( MailingList target, MailingList source, boolean sourceDominant,
1447                                      Map<Object, Object> context )
1448     {
1449         mergeMailingList_Name( target, source, sourceDominant, context );
1450         mergeMailingList_Subscribe( target, source, sourceDominant, context );
1451         mergeMailingList_Unsubscribe( target, source, sourceDominant, context );
1452         mergeMailingList_Post( target, source, sourceDominant, context );
1453         mergeMailingList_OtherArchives( target, source, sourceDominant, context );
1454     }
1455 
1456     protected void mergeMailingList_Name( MailingList target, MailingList source, boolean sourceDominant,
1457                                           Map<Object, Object> context )
1458     {
1459         String src = source.getName();
1460         if ( src != null )
1461         {
1462             if ( sourceDominant || target.getName() == null )
1463             {
1464                 target.setName( src );
1465                 target.setLocation( "name", source.getLocation( "name" ) );
1466             }
1467         }
1468     }
1469 
1470     protected void mergeMailingList_Subscribe( MailingList target, MailingList source, boolean sourceDominant,
1471                                                Map<Object, Object> context )
1472     {
1473         String src = source.getSubscribe();
1474         if ( src != null )
1475         {
1476             if ( sourceDominant || target.getSubscribe() == null )
1477             {
1478                 target.setSubscribe( src );
1479                 target.setLocation( "subscribe", source.getLocation( "subscribe" ) );
1480             }
1481         }
1482     }
1483 
1484     protected void mergeMailingList_Unsubscribe( MailingList target, MailingList source, boolean sourceDominant,
1485                                                  Map<Object, Object> context )
1486     {
1487         String src = source.getUnsubscribe();
1488         if ( src != null )
1489         {
1490             if ( sourceDominant || target.getUnsubscribe() == null )
1491             {
1492                 target.setUnsubscribe( src );
1493                 target.setLocation( "unsubscribe", source.getLocation( "unsubscribe" ) );
1494             }
1495         }
1496     }
1497 
1498     protected void mergeMailingList_Post( MailingList target, MailingList source, boolean sourceDominant,
1499                                           Map<Object, Object> context )
1500     {
1501         String src = source.getPost();
1502         if ( src != null )
1503         {
1504             if ( sourceDominant || target.getPost() == null )
1505             {
1506                 target.setPost( src );
1507                 target.setLocation( "post", source.getLocation( "post" ) );
1508             }
1509         }
1510     }
1511 
1512     protected void mergeMailingList_Archive( MailingList target, MailingList source, boolean sourceDominant,
1513                                              Map<Object, Object> context )
1514     {
1515         String src = source.getArchive();
1516         if ( src != null )
1517         {
1518             if ( sourceDominant || target.getArchive() == null )
1519             {
1520                 target.setArchive( src );
1521                 target.setLocation( "archive", source.getLocation( "archive" ) );
1522             }
1523         }
1524     }
1525 
1526     protected void mergeMailingList_OtherArchives( MailingList target, MailingList source, boolean sourceDominant,
1527                                                    Map<Object, Object> context )
1528     {
1529         List<String> src = source.getOtherArchives();
1530         if ( !src.isEmpty() )
1531         {
1532             List<String> tgt = target.getOtherArchives();
1533             List<String> merged = new ArrayList<>( tgt.size() + src.size() );
1534             merged.addAll( tgt );
1535             merged.addAll( src );
1536             target.setOtherArchives( merged );
1537         }
1538     }
1539 
1540     protected void mergeDeveloper( Developer target, Developer source, boolean sourceDominant,
1541                                    Map<Object, Object> context )
1542     {
1543         mergeContributor( target, source, sourceDominant, context );
1544         mergeDeveloper_Id( target, source, sourceDominant, context );
1545     }
1546 
1547     protected void mergeDeveloper_Id( Developer target, Developer source, boolean sourceDominant,
1548                                       Map<Object, Object> context )
1549     {
1550         String src = source.getId();
1551         if ( src != null )
1552         {
1553             if ( sourceDominant || target.getId() == null )
1554             {
1555                 target.setId( src );
1556                 target.setLocation( "id", source.getLocation( "id" ) );
1557             }
1558         }
1559     }
1560 
1561     protected void mergeContributor( Contributor target, Contributor source, boolean sourceDominant,
1562                                      Map<Object, Object> context )
1563     {
1564         mergeContributor_Name( target, source, sourceDominant, context );
1565         mergeContributor_Email( target, source, sourceDominant, context );
1566         mergeContributor_Url( target, source, sourceDominant, context );
1567         mergeContributor_Organization( target, source, sourceDominant, context );
1568         mergeContributor_OrganizationUrl( target, source, sourceDominant, context );
1569         mergeContributor_Timezone( target, source, sourceDominant, context );
1570         mergeContributor_Roles( target, source, sourceDominant, context );
1571         mergeContributor_Properties( target, source, sourceDominant, context );
1572     }
1573 
1574     protected void mergeContributor_Name( Contributor target, Contributor source, boolean sourceDominant,
1575                                           Map<Object, Object> context )
1576     {
1577         String src = source.getName();
1578         if ( src != null )
1579         {
1580             if ( sourceDominant || target.getName() == null )
1581             {
1582                 target.setName( src );
1583                 target.setLocation( "name", source.getLocation( "name" ) );
1584             }
1585         }
1586     }
1587 
1588     protected void mergeContributor_Email( Contributor target, Contributor source, boolean sourceDominant,
1589                                            Map<Object, Object> context )
1590     {
1591         String src = source.getEmail();
1592         if ( src != null )
1593         {
1594             if ( sourceDominant || target.getEmail() == null )
1595             {
1596                 target.setEmail( src );
1597                 target.setLocation( "email", source.getLocation( "email" ) );
1598             }
1599         }
1600     }
1601 
1602     protected void mergeContributor_Url( Contributor target, Contributor source, boolean sourceDominant,
1603                                          Map<Object, Object> context )
1604     {
1605         String src = source.getUrl();
1606         if ( src != null )
1607         {
1608             if ( sourceDominant || target.getUrl() == null )
1609             {
1610                 target.setUrl( src );
1611                 target.setLocation( "url", source.getLocation( "url" ) );
1612             }
1613         }
1614     }
1615 
1616     protected void mergeContributor_Organization( Contributor target, Contributor source, boolean sourceDominant,
1617                                                   Map<Object, Object> context )
1618     {
1619         String src = source.getOrganization();
1620         if ( src != null )
1621         {
1622             if ( sourceDominant || target.getOrganization() == null )
1623             {
1624                 target.setOrganization( src );
1625                 target.setLocation( "organization", source.getLocation( "organization" ) );
1626             }
1627         }
1628     }
1629 
1630     protected void mergeContributor_OrganizationUrl( Contributor target, Contributor source, boolean sourceDominant,
1631                                                      Map<Object, Object> context )
1632     {
1633         String src = source.getOrganizationUrl();
1634         if ( src != null )
1635         {
1636             if ( sourceDominant || target.getOrganizationUrl() == null )
1637             {
1638                 target.setOrganizationUrl( src );
1639                 target.setLocation( "organizationUrl", source.getLocation( "organizationUrl" ) );
1640             }
1641         }
1642     }
1643 
1644     protected void mergeContributor_Timezone( Contributor target, Contributor source, boolean sourceDominant,
1645                                               Map<Object, Object> context )
1646     {
1647         String src = source.getTimezone();
1648         if ( src != null )
1649         {
1650             if ( sourceDominant || target.getTimezone() == null )
1651             {
1652                 target.setTimezone( src );
1653                 target.setLocation( "timezone", source.getLocation( "timezone" ) );
1654             }
1655         }
1656     }
1657 
1658     protected void mergeContributor_Roles( Contributor target, Contributor source, boolean sourceDominant,
1659                                            Map<Object, Object> context )
1660     {
1661         List<String> src = source.getRoles();
1662         if ( !src.isEmpty() )
1663         {
1664             List<String> tgt = target.getRoles();
1665             List<String> merged = new ArrayList<>( tgt.size() + src.size() );
1666             merged.addAll( tgt );
1667             merged.addAll( src );
1668             target.setRoles( merged );
1669         }
1670     }
1671 
1672     protected void mergeContributor_Properties( Contributor target, Contributor source, boolean sourceDominant,
1673                                                 Map<Object, Object> context )
1674     {
1675         Properties merged = new Properties();
1676         if ( sourceDominant )
1677         {
1678             merged.putAll( target.getProperties() );
1679             merged.putAll( source.getProperties() );
1680         }
1681         else
1682         {
1683             merged.putAll( source.getProperties() );
1684             merged.putAll( target.getProperties() );
1685         }
1686         target.setProperties( merged );
1687         target.setLocation( "properties", InputLocation.merge( target.getLocation( "properties" ),
1688                                                                source.getLocation( "properties" ), sourceDominant ) );
1689     }
1690 
1691     protected void mergeIssueManagement( IssueManagement target, IssueManagement source, boolean sourceDominant,
1692                                          Map<Object, Object> context )
1693     {
1694         mergeIssueManagement_Url( target, source, sourceDominant, context );
1695         mergeIssueManagement_System( target, source, sourceDominant, context );
1696     }
1697 
1698     protected void mergeIssueManagement_System( IssueManagement target, IssueManagement source, boolean sourceDominant,
1699                                                 Map<Object, Object> context )
1700     {
1701         String src = source.getSystem();
1702         if ( src != null )
1703         {
1704             if ( sourceDominant || target.getSystem() == null )
1705             {
1706                 target.setSystem( src );
1707                 target.setLocation( "system", source.getLocation( "system" ) );
1708             }
1709         }
1710     }
1711 
1712     protected void mergeIssueManagement_Url( IssueManagement target, IssueManagement source, boolean sourceDominant,
1713                                              Map<Object, Object> context )
1714     {
1715         String src = source.getUrl();
1716         if ( src != null )
1717         {
1718             if ( sourceDominant || target.getUrl() == null )
1719             {
1720                 target.setUrl( src );
1721                 target.setLocation( "url", source.getLocation( "url" ) );
1722             }
1723         }
1724     }
1725 
1726     protected void mergeScm( Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context )
1727     {
1728         mergeScm_ChildScmConnectionInheritAppendPath( target, source, sourceDominant, context );
1729         mergeScm_ChildScmDeveloperConnectionInheritAppendPath( target, source, sourceDominant, context );
1730         mergeScm_ChildScmUrlInheritAppendPath( target, source, sourceDominant, context );
1731         mergeScm_Url( target, source, sourceDominant, context );
1732         mergeScm_Connection( target, source, sourceDominant, context );
1733         mergeScm_DeveloperConnection( target, source, sourceDominant, context );
1734         mergeScm_Tag( target, source, sourceDominant, context );
1735     }
1736 
1737     protected void mergeScm_ChildScmConnectionInheritAppendPath( Scm target, Scm source, boolean sourceDominant,
1738                                                                  Map<Object, Object> context )
1739     {
1740         String src = source.getChildScmConnectionInheritAppendPath();
1741         if ( src != null )
1742         {
1743             if ( sourceDominant || target.getChildScmConnectionInheritAppendPath() == null )
1744             {
1745                 target.setChildScmConnectionInheritAppendPath( src );
1746                 target.setLocation( "child.scm.connection.inherit.append.path",
1747                                     source.getLocation( "child.scm.connection.inherit.append.path" ) );
1748             }
1749         }
1750     }
1751 
1752     protected void mergeScm_ChildScmDeveloperConnectionInheritAppendPath( Scm target, Scm source,
1753                                                                           boolean sourceDominant,
1754                                                                           Map<Object, Object> context )
1755     {
1756         String src = source.getChildScmDeveloperConnectionInheritAppendPath();
1757         if ( src != null )
1758         {
1759             if ( sourceDominant || target.getChildScmDeveloperConnectionInheritAppendPath() == null )
1760             {
1761                 target.setChildScmDeveloperConnectionInheritAppendPath( src );
1762                 target.setLocation( "child.scm.developerConnection.inherit.append.path",
1763                                     source.getLocation( "child.scm.developerConnection.inherit.append.path" ) );
1764             }
1765         }
1766     }
1767 
1768     protected void mergeScm_ChildScmUrlInheritAppendPath( Scm target, Scm source, boolean sourceDominant,
1769                                                           Map<Object, Object> context )
1770     {
1771         String src = source.getChildScmUrlInheritAppendPath();
1772         if ( src != null )
1773         {
1774             if ( sourceDominant || target.getChildScmUrlInheritAppendPath() == null )
1775             {
1776                 target.setChildScmUrlInheritAppendPath( src );
1777                 target.setLocation( "child.scm.url.inherit.append.path",
1778                                     source.getLocation( "child.scm.url.inherit.append.path" ) );
1779             }
1780         }
1781     }
1782 
1783     protected void mergeScm_Url( Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context )
1784     {
1785         String src = source.getUrl();
1786         if ( src != null )
1787         {
1788             if ( sourceDominant || target.getUrl() == null )
1789             {
1790                 target.setUrl( src );
1791                 target.setLocation( "url", source.getLocation( "url" ) );
1792             }
1793         }
1794     }
1795 
1796     protected void mergeScm_Connection( Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context )
1797     {
1798         String src = source.getConnection();
1799         if ( src != null )
1800         {
1801             if ( sourceDominant || target.getConnection() == null )
1802             {
1803                 target.setConnection( src );
1804                 target.setLocation( "connection", source.getLocation( "connection" ) );
1805             }
1806         }
1807     }
1808 
1809     protected void mergeScm_DeveloperConnection( Scm target, Scm source, boolean sourceDominant,
1810                                                  Map<Object, Object> context )
1811     {
1812         String src = source.getDeveloperConnection();
1813         if ( src != null )
1814         {
1815             if ( sourceDominant || target.getDeveloperConnection() == null )
1816             {
1817                 target.setDeveloperConnection( src );
1818                 target.setLocation( "developerConnection", source.getLocation( "developerConnection" ) );
1819             }
1820         }
1821     }
1822 
1823     protected void mergeScm_Tag( Scm target, Scm source, boolean sourceDominant, Map<Object, Object> context )
1824     {
1825         String src = source.getTag();
1826         if ( src != null )
1827         {
1828             if ( sourceDominant || target.getTag() == null )
1829             {
1830                 target.setTag( src );
1831                 target.setLocation( "tag", source.getLocation( "tag" ) );
1832             }
1833         }
1834     }
1835 
1836     protected void mergeCiManagement( CiManagement target, CiManagement source, boolean sourceDominant,
1837                                       Map<Object, Object> context )
1838     {
1839         mergeCiManagement_System( target, source, sourceDominant, context );
1840         mergeCiManagement_Url( target, source, sourceDominant, context );
1841         mergeCiManagement_Notifiers( target, source, sourceDominant, context );
1842     }
1843 
1844     protected void mergeCiManagement_System( CiManagement target, CiManagement source, boolean sourceDominant,
1845                                              Map<Object, Object> context )
1846     {
1847         String src = source.getSystem();
1848         if ( src != null )
1849         {
1850             if ( sourceDominant || target.getSystem() == null )
1851             {
1852                 target.setSystem( src );
1853                 target.setLocation( "system", source.getLocation( "system" ) );
1854             }
1855         }
1856     }
1857 
1858     protected void mergeCiManagement_Url( CiManagement target, CiManagement source, boolean sourceDominant,
1859                                           Map<Object, Object> context )
1860     {
1861         String src = source.getUrl();
1862         if ( src != null )
1863         {
1864             if ( sourceDominant || target.getUrl() == null )
1865             {
1866                 target.setUrl( src );
1867                 target.setLocation( "url", source.getLocation( "url" ) );
1868             }
1869         }
1870     }
1871 
1872     protected void mergeCiManagement_Notifiers( CiManagement target, CiManagement source, boolean sourceDominant,
1873                                                 Map<Object, Object> context )
1874     {
1875         target.setNotifiers( merge( target.getNotifiers(), source.getNotifiers(),
1876                                     sourceDominant, new NotifierKeyComputer() ) );
1877     }
1878 
1879     protected void mergeNotifier( Notifier target, Notifier source, boolean sourceDominant,
1880                                   Map<Object, Object> context )
1881     {
1882         mergeNotifier_Type( target, source, sourceDominant, context );
1883         mergeNotifier_Address( target, source, sourceDominant, context );
1884         mergeNotifier_Configuration( target, source, sourceDominant, context );
1885         mergeNotifier_SendOnError( target, source, sourceDominant, context );
1886         mergeNotifier_SendOnFailure( target, source, sourceDominant, context );
1887         mergeNotifier_SendOnSuccess( target, source, sourceDominant, context );
1888         mergeNotifier_SendOnWarning( target, source, sourceDominant, context );
1889     }
1890 
1891     protected void mergeNotifier_Type( Notifier target, Notifier source, boolean sourceDominant,
1892                                        Map<Object, Object> context )
1893     {
1894         String src = source.getType();
1895         if ( src != null )
1896         {
1897             if ( sourceDominant || target.getType() == null )
1898             {
1899                 target.setType( src );
1900             }
1901         }
1902     }
1903 
1904     protected void mergeNotifier_Address( Notifier target, Notifier source, boolean sourceDominant,
1905                                           Map<Object, Object> context )
1906     {
1907         String src = source.getAddress();
1908         if ( src != null )
1909         {
1910             if ( sourceDominant || target.getAddress() == null )
1911             {
1912                 target.setAddress( src );
1913             }
1914         }
1915     }
1916 
1917     protected void mergeNotifier_Configuration( Notifier target, Notifier source, boolean sourceDominant,
1918                                                 Map<Object, Object> context )
1919     {
1920         Properties merged = new Properties();
1921         if ( sourceDominant )
1922         {
1923             merged.putAll( target.getConfiguration() );
1924             merged.putAll( source.getConfiguration() );
1925         }
1926         else
1927         {
1928             merged.putAll( source.getConfiguration() );
1929             merged.putAll( target.getConfiguration() );
1930         }
1931         target.setConfiguration( merged );
1932     }
1933 
1934     protected void mergeNotifier_SendOnError( Notifier target, Notifier source, boolean sourceDominant,
1935                                               Map<Object, Object> context )
1936     {
1937         if ( sourceDominant )
1938         {
1939             target.setSendOnError( source.isSendOnError() );
1940         }
1941     }
1942 
1943     protected void mergeNotifier_SendOnFailure( Notifier target, Notifier source, boolean sourceDominant,
1944                                                 Map<Object, Object> context )
1945     {
1946         if ( sourceDominant )
1947         {
1948             target.setSendOnFailure( source.isSendOnFailure() );
1949         }
1950     }
1951 
1952     protected void mergeNotifier_SendOnSuccess( Notifier target, Notifier source, boolean sourceDominant,
1953                                                 Map<Object, Object> context )
1954     {
1955         if ( sourceDominant )
1956         {
1957             target.setSendOnSuccess( source.isSendOnSuccess() );
1958         }
1959     }
1960 
1961     protected void mergeNotifier_SendOnWarning( Notifier target, Notifier source, boolean sourceDominant,
1962                                                 Map<Object, Object> context )
1963     {
1964         if ( sourceDominant )
1965         {
1966             target.setSendOnWarning( source.isSendOnWarning() );
1967         }
1968     }
1969 
1970     protected void mergePrerequisites( Prerequisites target, Prerequisites source, boolean sourceDominant,
1971                                        Map<Object, Object> context )
1972     {
1973         mergePrerequisites_Maven( target, source, sourceDominant, context );
1974     }
1975 
1976     protected void mergePrerequisites_Maven( Prerequisites target, Prerequisites source, boolean sourceDominant,
1977                                              Map<Object, Object> context )
1978     {
1979         String src = source.getMaven();
1980         if ( src != null )
1981         {
1982             if ( sourceDominant || target.getMaven() == null )
1983             {
1984                 target.setMaven( src );
1985                 target.setLocation( "maven", source.getLocation( "maven" ) );
1986             }
1987         }
1988     }
1989 
1990     protected void mergeBuild( Build target, Build source, boolean sourceDominant, Map<Object, Object> context )
1991     {
1992         mergeBuildBase( target, source, sourceDominant, context );
1993         mergeBuild_SourceDirectory( target, source, sourceDominant, context );
1994         mergeBuild_ScriptSourceDirectory( target, source, sourceDominant, context );
1995         mergeBuild_TestSourceDirectory( target, source, sourceDominant, context );
1996         mergeBuild_OutputDirectory( target, source, sourceDominant, context );
1997         mergeBuild_TestOutputDirectory( target, source, sourceDominant, context );
1998         mergeBuild_Extensions( target, source, sourceDominant, context );
1999     }
2000 
2001     protected void mergeBuild_SourceDirectory( Build target, Build source, boolean sourceDominant,
2002                                                Map<Object, Object> context )
2003     {
2004         String src = source.getSourceDirectory();
2005         if ( src != null )
2006         {
2007             if ( sourceDominant || target.getSourceDirectory() == null )
2008             {
2009                 target.setSourceDirectory( src );
2010                 target.setLocation( "sourceDirectory", source.getLocation( "sourceDirectory" ) );
2011             }
2012         }
2013     }
2014 
2015     protected void mergeBuild_ScriptSourceDirectory( Build target, Build source, boolean sourceDominant,
2016                                                      Map<Object, Object> context )
2017     {
2018         String src = source.getScriptSourceDirectory();
2019         if ( src != null )
2020         {
2021             if ( sourceDominant || target.getScriptSourceDirectory() == null )
2022             {
2023                 target.setScriptSourceDirectory( src );
2024                 target.setLocation( "scriptSourceDirectory", source.getLocation( "scriptSourceDirectory" ) );
2025             }
2026         }
2027     }
2028 
2029     protected void mergeBuild_TestSourceDirectory( Build target, Build source, boolean sourceDominant,
2030                                                    Map<Object, Object> context )
2031     {
2032         String src = source.getTestSourceDirectory();
2033         if ( src != null )
2034         {
2035             if ( sourceDominant || target.getTestSourceDirectory() == null )
2036             {
2037                 target.setTestSourceDirectory( src );
2038                 target.setLocation( "testSourceDirectory", source.getLocation( "testSourceDirectory" ) );
2039             }
2040         }
2041     }
2042 
2043     protected void mergeBuild_OutputDirectory( Build target, Build source, boolean sourceDominant,
2044                                                Map<Object, Object> context )
2045     {
2046         String src = source.getOutputDirectory();
2047         if ( src != null )
2048         {
2049             if ( sourceDominant || target.getOutputDirectory() == null )
2050             {
2051                 target.setOutputDirectory( src );
2052                 target.setLocation( "outputDirectory", source.getLocation( "outputDirectory" ) );
2053             }
2054         }
2055     }
2056 
2057     protected void mergeBuild_TestOutputDirectory( Build target, Build source, boolean sourceDominant,
2058                                                    Map<Object, Object> context )
2059     {
2060         String src = source.getTestOutputDirectory();
2061         if ( src != null )
2062         {
2063             if ( sourceDominant || target.getTestOutputDirectory() == null )
2064             {
2065                 target.setTestOutputDirectory( src );
2066                 target.setLocation( "testOutputDirectory", source.getLocation( "testOutputDirectory" ) );
2067             }
2068         }
2069     }
2070 
2071     protected void mergeBuild_Extensions( Build target, Build source, boolean sourceDominant,
2072                                           Map<Object, Object> context )
2073     {
2074         target.setExtensions( merge( target.getExtensions(), source.getExtensions(),
2075                                      sourceDominant, new ExtensionKeyComputer() ) );
2076     }
2077 
2078     protected void mergeExtension( Extension target, Extension source, boolean sourceDominant,
2079                                    Map<Object, Object> context )
2080     {
2081         mergeExtension_GroupId( target, source, sourceDominant, context );
2082         mergeExtension_ArtifactId( target, source, sourceDominant, context );
2083         mergeExtension_Version( target, source, sourceDominant, context );
2084     }
2085 
2086     protected void mergeExtension_GroupId( Extension target, Extension source, boolean sourceDominant,
2087                                            Map<Object, Object> context )
2088     {
2089         String src = source.getGroupId();
2090         if ( src != null )
2091         {
2092             if ( sourceDominant || target.getGroupId() == null )
2093             {
2094                 target.setGroupId( src );
2095                 target.setLocation( "groupId", source.getLocation( "groupId" ) );
2096             }
2097         }
2098     }
2099 
2100     protected void mergeExtension_ArtifactId( Extension target, Extension source, boolean sourceDominant,
2101                                               Map<Object, Object> context )
2102     {
2103         String src = source.getArtifactId();
2104         if ( src != null )
2105         {
2106             if ( sourceDominant || target.getArtifactId() == null )
2107             {
2108                 target.setArtifactId( src );
2109                 target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
2110             }
2111         }
2112     }
2113 
2114     protected void mergeExtension_Version( Extension target, Extension source, boolean sourceDominant,
2115                                            Map<Object, Object> context )
2116     {
2117         String src = source.getVersion();
2118         if ( src != null )
2119         {
2120             if ( sourceDominant || target.getVersion() == null )
2121             {
2122                 target.setVersion( src );
2123                 target.setLocation( "version", source.getLocation( "version" ) );
2124             }
2125         }
2126     }
2127 
2128     protected void mergeBuildBase( BuildBase target, BuildBase source, boolean sourceDominant,
2129                                    Map<Object, Object> context )
2130     {
2131         mergePluginConfiguration( target, source, sourceDominant, context );
2132         mergeBuildBase_DefaultGoal( target, source, sourceDominant, context );
2133         mergeBuildBase_FinalName( target, source, sourceDominant, context );
2134         mergeBuildBase_Directory( target, source, sourceDominant, context );
2135         mergeBuildBase_Resources( target, source, sourceDominant, context );
2136         mergeBuildBase_TestResources( target, source, sourceDominant, context );
2137         mergeBuildBase_Filters( target, source, sourceDominant, context );
2138     }
2139 
2140     protected void mergeBuildBase_DefaultGoal( BuildBase target, BuildBase source, boolean sourceDominant,
2141                                                Map<Object, Object> context )
2142     {
2143         String src = source.getDefaultGoal();
2144         if ( src != null )
2145         {
2146             if ( sourceDominant || target.getDefaultGoal() == null )
2147             {
2148                 target.setDefaultGoal( src );
2149                 target.setLocation( "defaultGoal", source.getLocation( "defaultGoal" ) );
2150             }
2151         }
2152     }
2153 
2154     protected void mergeBuildBase_Directory( BuildBase target, BuildBase source, boolean sourceDominant,
2155                                              Map<Object, Object> context )
2156     {
2157         String src = source.getDirectory();
2158         if ( src != null )
2159         {
2160             if ( sourceDominant || target.getDirectory() == null )
2161             {
2162                 target.setDirectory( src );
2163                 target.setLocation( "directory", source.getLocation( "directory" ) );
2164             }
2165         }
2166     }
2167 
2168     protected void mergeBuildBase_FinalName( BuildBase target, BuildBase source, boolean sourceDominant,
2169                                              Map<Object, Object> context )
2170     {
2171         String src = source.getFinalName();
2172         if ( src != null )
2173         {
2174             if ( sourceDominant || target.getFinalName() == null )
2175             {
2176                 target.setFinalName( src );
2177                 target.setLocation( "finalName", source.getLocation( "finalName" ) );
2178             }
2179         }
2180     }
2181 
2182     protected void mergeBuildBase_Filters( BuildBase target, BuildBase source, boolean sourceDominant,
2183                                            Map<Object, Object> context )
2184     {
2185         List<String> src = source.getFilters();
2186         if ( !src.isEmpty() )
2187         {
2188             List<String> tgt = target.getFilters();
2189             List<String> merged = new ArrayList<>( tgt.size() + src.size() );
2190             merged.addAll( tgt );
2191             merged.addAll( src );
2192             target.setFilters( merged );
2193         }
2194     }
2195 
2196     protected void mergeBuildBase_Resources( BuildBase target, BuildBase source, boolean sourceDominant,
2197                                              Map<Object, Object> context )
2198     {
2199         target.setResources( merge( target.getResources(), source.getResources(),
2200                                     sourceDominant, new ResourceKeyComputer() ) );
2201     }
2202 
2203     protected void mergeBuildBase_TestResources( BuildBase target, BuildBase source, boolean sourceDominant,
2204                                                  Map<Object, Object> context )
2205     {
2206         target.setTestResources( merge( target.getTestResources(), source.getTestResources(),
2207                                         sourceDominant, new ResourceKeyComputer() ) );
2208     }
2209 
2210     protected void mergePluginConfiguration( PluginConfiguration target, PluginConfiguration source,
2211                                              boolean sourceDominant, Map<Object, Object> context )
2212     {
2213         mergePluginContainer( target, source, sourceDominant, context );
2214         mergePluginConfiguration_PluginManagement( target, source, sourceDominant, context );
2215     }
2216 
2217     protected void mergePluginConfiguration_PluginManagement( PluginConfiguration target, PluginConfiguration source,
2218                                                               boolean sourceDominant, Map<Object, Object> context )
2219     {
2220         PluginManagement src = source.getPluginManagement();
2221         if ( src != null )
2222         {
2223             PluginManagement tgt = target.getPluginManagement();
2224             if ( tgt == null )
2225             {
2226                 tgt = new PluginManagement();
2227                 target.setPluginManagement( tgt );
2228             }
2229             mergePluginManagement( tgt, src, sourceDominant, context );
2230         }
2231     }
2232 
2233     protected void mergePluginContainer( PluginContainer target, PluginContainer source,
2234                                          boolean sourceDominant, Map<Object, Object> context )
2235     {
2236         mergePluginContainer_Plugins( target, source, sourceDominant, context );
2237     }
2238 
2239     protected void mergePluginContainer_Plugins( PluginContainer target, PluginContainer source,
2240                                                  boolean sourceDominant, Map<Object, Object> context )
2241     {
2242         target.setPlugins( merge( target.getPlugins(), source.getPlugins(),
2243                                   sourceDominant, new PluginKeyComputer() ) );
2244     }
2245 
2246     protected void mergePluginManagement( PluginManagement target, PluginManagement source, boolean sourceDominant,
2247                                           Map<Object, Object> context )
2248     {
2249         mergePluginContainer( target, source, sourceDominant, context );
2250     }
2251 
2252     protected void mergePlugin( Plugin target, Plugin source, boolean sourceDominant, Map<Object, Object> context )
2253     {
2254         mergeConfigurationContainer( target, source, sourceDominant, context );
2255         mergePlugin_GroupId( target, source, sourceDominant, context );
2256         mergePlugin_ArtifactId( target, source, sourceDominant, context );
2257         mergePlugin_Version( target, source, sourceDominant, context );
2258         mergePlugin_Extensions( target, source, sourceDominant, context );
2259         mergePlugin_Dependencies( target, source, sourceDominant, context );
2260         mergePlugin_Executions( target, source, sourceDominant, context );
2261     }
2262 
2263     protected void mergePlugin_GroupId( Plugin target, Plugin source, boolean sourceDominant,
2264                                         Map<Object, Object> context )
2265     {
2266         String src = source.getGroupId();
2267         if ( src != null )
2268         {
2269             if ( sourceDominant || target.getGroupId() == null )
2270             {
2271                 target.setGroupId( src );
2272                 target.setLocation( "groupId", source.getLocation( "groupId" ) );
2273             }
2274         }
2275     }
2276 
2277     protected void mergePlugin_ArtifactId( Plugin target, Plugin source, boolean sourceDominant,
2278                                            Map<Object, Object> context )
2279     {
2280         String src = source.getArtifactId();
2281         if ( src != null )
2282         {
2283             if ( sourceDominant || target.getArtifactId() == null )
2284             {
2285                 target.setArtifactId( src );
2286                 target.setLocation( "artifactId", source.getLocation( "artifactId" ) );
2287             }
2288         }
2289     }
2290 
2291     protected void mergePlugin_Version( Plugin target, Plugin source, boolean sourceDominant,
2292                                         Map<Object, Object> context )
2293     {
2294         String src = source.getVersion();
2295         if ( src != null )
2296         {
2297             if ( sourceDominant || target.getVersion() == null )
2298             {
2299                 target.setVersion( src );
2300                 target.setLocation( "version", source.getLocation( "version" ) );
2301             }
2302         }
2303     }
2304 
2305     protected void mergePlugin_Extensions( Plugin target, Plugin source, boolean sourceDominant,
2306                                            Map<Object, Object> context )
2307     {
2308         String src = source.getExtensions();
2309         if ( src != null )
2310         {
2311             if ( sourceDominant || target.getExtensions() == null )
2312             {
2313                 target.setExtensions( src );
2314                 target.setLocation( "extensions", source.getLocation( "extensions" ) );
2315             }
2316         }
2317     }
2318 
2319     protected void mergePlugin_Dependencies( Plugin target, Plugin source, boolean sourceDominant,
2320                                              Map<Object, Object> context )
2321     {
2322         target.setDependencies( merge( target.getDependencies(), source.getDependencies(),
2323                                        sourceDominant, new DependencyKeyComputer() ) );
2324     }
2325 
2326     protected void mergePlugin_Executions( Plugin target, Plugin source, boolean sourceDominant,
2327                                            Map<Object, Object> context )
2328     {
2329         target.setExecutions( merge( target.getExecutions(), source.getExecutions(),
2330                                      sourceDominant, new ExecutionKeyComputer() ) );
2331     }
2332 
2333     protected void mergeConfigurationContainer( ConfigurationContainer target, ConfigurationContainer source,
2334                                                 boolean sourceDominant, Map<Object, Object> context )
2335     {
2336         mergeConfigurationContainer_Inherited( target, source, sourceDominant, context );
2337         mergeConfigurationContainer_Configuration( target, source, sourceDominant, context );
2338     }
2339 
2340     protected void mergeConfigurationContainer_Inherited( ConfigurationContainer target, ConfigurationContainer source,
2341                                                           boolean sourceDominant, Map<Object, Object> context )
2342     {
2343         String src = source.getInherited();
2344         if ( src != null )
2345         {
2346             if ( sourceDominant || target.getInherited() == null )
2347             {
2348                 target.setInherited( src );
2349                 target.setLocation( "inherited", source.getLocation( "inherited" ) );
2350             }
2351         }
2352     }
2353 
2354     protected void mergeConfigurationContainer_Configuration( ConfigurationContainer target,
2355                                                               ConfigurationContainer source, boolean sourceDominant,
2356                                                               Map<Object, Object> context )
2357     {
2358         Xpp3Dom src = (Xpp3Dom) source.getConfiguration();
2359         if ( src != null )
2360         {
2361             Xpp3Dom tgt = (Xpp3Dom) target.getConfiguration();
2362             if ( sourceDominant || tgt == null )
2363             {
2364                 tgt = Xpp3Dom.mergeXpp3Dom( new Xpp3Dom( src ), tgt );
2365             }
2366             else
2367             {
2368                 tgt = Xpp3Dom.mergeXpp3Dom( tgt, src );
2369             }
2370             target.setConfiguration( tgt );
2371         }
2372     }
2373 
2374     protected void mergePluginExecution( PluginExecution target, PluginExecution source, boolean sourceDominant,
2375                                          Map<Object, Object> context )
2376     {
2377         mergeConfigurationContainer( target, source, sourceDominant, context );
2378         mergePluginExecution_Id( target, source, sourceDominant, context );
2379         mergePluginExecution_Phase( target, source, sourceDominant, context );
2380         mergePluginExecution_Goals( target, source, sourceDominant, context );
2381     }
2382 
2383     protected void mergePluginExecution_Id( PluginExecution target, PluginExecution source, boolean sourceDominant,
2384                                             Map<Object, Object> context )
2385     {
2386         String src = source.getId();
2387         if ( src != null )
2388         {
2389             if ( sourceDominant || target.getId() == null )
2390             {
2391                 target.setId( src );
2392                 target.setLocation( "id", source.getLocation( "id" ) );
2393             }
2394         }
2395     }
2396 
2397     protected void mergePluginExecution_Phase( PluginExecution target, PluginExecution source, boolean sourceDominant,
2398                                                Map<Object, Object> context )
2399     {
2400         String src = source.getPhase();
2401         if ( src != null )
2402         {
2403             if ( sourceDominant || target.getPhase() == null )
2404             {
2405                 target.setPhase( src );
2406                 target.setLocation( "phase", source.getLocation( "phase" ) );
2407             }
2408         }
2409     }
2410 
2411     protected void mergePluginExecution_Goals( PluginExecution target, PluginExecution source, boolean sourceDominant,
2412                                                Map<Object, Object> context )
2413     {
2414         List<String> src = source.getGoals();
2415         if ( !src.isEmpty() )
2416         {
2417             List<String> tgt = target.getGoals();
2418             List<String> merged = new ArrayList<>( tgt.size() + src.size() );
2419             merged.addAll( tgt );
2420             merged.addAll( src );
2421             target.setGoals( merged );
2422         }
2423     }
2424 
2425     protected void mergeResource( Resource target, Resource source, boolean sourceDominant,
2426                                   Map<Object, Object> context )
2427     {
2428         mergeFileSet( target, source, sourceDominant, context );
2429         mergeResource_TargetPath( target, source, sourceDominant, context );
2430         mergeResource_Filtering( target, source, sourceDominant, context );
2431         mergeResource_MergeId( target, source, sourceDominant, context );
2432     }
2433 
2434     protected void mergeResource_TargetPath( Resource target, Resource source, boolean sourceDominant,
2435                                              Map<Object, Object> context )
2436     {
2437         String src = source.getTargetPath();
2438         if ( src != null )
2439         {
2440             if ( sourceDominant || target.getTargetPath() == null )
2441             {
2442                 target.setTargetPath( src );
2443                 target.setLocation( "targetPath", source.getLocation( "targetPath" ) );
2444             }
2445         }
2446     }
2447 
2448     protected void mergeResource_Filtering( Resource target, Resource source, boolean sourceDominant,
2449                                             Map<Object, Object> context )
2450     {
2451         String src = source.getFiltering();
2452         if ( src != null )
2453         {
2454             if ( sourceDominant || target.getFiltering() == null )
2455             {
2456                 target.setFiltering( src );
2457                 target.setLocation( "filtering", source.getLocation( "filtering" ) );
2458             }
2459         }
2460     }
2461 
2462     protected void mergeResource_MergeId( Resource target, Resource source, boolean sourceDominant,
2463                                           Map<Object, Object> context )
2464     {
2465         String src = source.getMergeId();
2466         if ( src != null )
2467         {
2468             if ( sourceDominant || target.getMergeId() == null )
2469             {
2470                 target.setMergeId( src );
2471             }
2472         }
2473     }
2474 
2475     protected void mergeFileSet( FileSet target, FileSet source, boolean sourceDominant, Map<Object, Object> context )
2476     {
2477         mergePatternSet( target, source, sourceDominant, context );
2478         mergeFileSet_Directory( target, source, sourceDominant, context );
2479     }
2480 
2481     protected void mergeFileSet_Directory( FileSet target, FileSet source, boolean sourceDominant,
2482                                            Map<Object, Object> context )
2483     {
2484         String src = source.getDirectory();
2485         if ( src != null )
2486         {
2487             if ( sourceDominant || target.getDirectory() == null )
2488             {
2489                 target.setDirectory( src );
2490                 target.setLocation( "directory", source.getLocation( "directory" ) );
2491             }
2492         }
2493     }
2494 
2495     protected void mergePatternSet( PatternSet target, PatternSet source, boolean sourceDominant,
2496                                     Map<Object, Object> context )
2497     {
2498         mergePatternSet_Includes( target, source, sourceDominant, context );
2499         mergePatternSet_Excludes( target, source, sourceDominant, context );
2500     }
2501 
2502     protected void mergePatternSet_Includes( PatternSet target, PatternSet source, boolean sourceDominant,
2503                                              Map<Object, Object> context )
2504     {
2505         List<String> src = source.getIncludes();
2506         if ( !src.isEmpty() )
2507         {
2508             List<String> tgt = target.getIncludes();
2509             List<String> merged = new ArrayList<>( tgt.size() + src.size() );
2510             merged.addAll( tgt );
2511             merged.addAll( src );
2512             target.setIncludes( merged );
2513         }
2514     }
2515 
2516     protected void mergePatternSet_Excludes( PatternSet target, PatternSet source, boolean sourceDominant,
2517                                              Map<Object, Object> context )
2518     {
2519         List<String> src = source.getExcludes();
2520         if ( !src.isEmpty() )
2521         {
2522             List<String> tgt = target.getExcludes();
2523             List<String> merged = new ArrayList<>( tgt.size() + src.size() );
2524             merged.addAll( tgt );
2525             merged.addAll( src );
2526             target.setExcludes( merged );
2527         }
2528     }
2529 
2530     protected void mergeProfile( Profile target, Profile source, boolean sourceDominant, Map<Object, Object> context )
2531     {
2532         mergeModelBase( target, source, sourceDominant, context );
2533         // TODO
2534     }
2535 
2536     protected void mergeActivation( Activation target, Activation source, boolean sourceDominant,
2537                                     Map<Object, Object> context )
2538     {
2539         // TODO
2540     }
2541 
2542     protected Object getDependencyKey( Dependency dependency )
2543     {
2544         return dependency;
2545     }
2546 
2547     protected Object getPluginKey( Plugin plugin )
2548     {
2549         return plugin;
2550     }
2551 
2552     protected Object getPluginExecutionKey( PluginExecution pluginExecution )
2553     {
2554         return pluginExecution;
2555     }
2556 
2557     protected Object getReportPluginKey( ReportPlugin reportPlugin )
2558     {
2559         return reportPlugin;
2560     }
2561 
2562     protected Object getReportSetKey( ReportSet reportSet )
2563     {
2564         return reportSet;
2565     }
2566 
2567     protected Object getLicenseKey( License license )
2568     {
2569         return license;
2570     }
2571 
2572     protected Object getMailingListKey( MailingList mailingList )
2573     {
2574         return mailingList;
2575     }
2576 
2577     protected Object getDeveloperKey( Developer developer )
2578     {
2579         return developer;
2580     }
2581 
2582     protected Object getContributorKey( Contributor contributor )
2583     {
2584         return contributor;
2585     }
2586 
2587     protected Object getProfileKey( Profile profile )
2588     {
2589         return profile;
2590     }
2591 
2592     protected Object getRepositoryKey( Repository repository )
2593     {
2594         return getRepositoryBaseKey( repository );
2595     }
2596 
2597     protected Object getRepositoryBaseKey( RepositoryBase repositoryBase )
2598     {
2599         return repositoryBase;
2600     }
2601 
2602     protected Object getNotifierKey( Notifier notifier )
2603     {
2604         return notifier;
2605     }
2606 
2607     protected Object getResourceKey( Resource resource )
2608     {
2609         return resource;
2610     }
2611 
2612     protected Object getExtensionKey( Extension extension )
2613     {
2614         return extension;
2615     }
2616 
2617     protected Object getExclusionKey( Exclusion exclusion )
2618     {
2619         return exclusion;
2620     }
2621 
2622     /**
2623      * Use to compute keys for data structures
2624      * @param <T>
2625      */
2626     private interface KeyComputer<T>
2627     {
2628         Object key( T t );
2629     }
2630 
2631     /**
2632      * Remapping function
2633      * @param <T>
2634      */
2635     private interface Remapping<T>
2636     {
2637         T merge( T u, T v );
2638     }
2639 
2640     /**
2641      * KeyComputer for Dependency
2642      */
2643     private final class DependencyKeyComputer implements KeyComputer<Dependency>
2644     {
2645         @Override
2646         public Object key( Dependency dependency )
2647         {
2648             return getDependencyKey( dependency );
2649         }
2650     }
2651 
2652     /**
2653      * KeyComputer for License
2654      */
2655     private class LicenseKeyComputer implements KeyComputer<License>
2656     {
2657         @Override
2658         public Object key( License license )
2659         {
2660             return getLicenseKey( license );
2661         }
2662     }
2663 
2664     /**
2665      * KeyComputer for MailingList
2666      */
2667     private class MailingListKeyComputer implements KeyComputer<MailingList>
2668     {
2669         @Override
2670         public Object key( MailingList mailingList )
2671         {
2672             return getMailingListKey( mailingList );
2673         }
2674     }
2675 
2676     /**
2677      * KeyComputer for Developer
2678      */
2679     private class DeveloperKeyComputer implements KeyComputer<Developer>
2680     {
2681         @Override
2682         public Object key( Developer developer )
2683         {
2684             return getDeveloperKey( developer );
2685         }
2686     }
2687 
2688     /**
2689      * KeyComputer for Contributor
2690      */
2691     private class ContributorKeyComputer implements KeyComputer<Contributor>
2692     {
2693         @Override
2694         public Object key( Contributor contributor )
2695         {
2696             return getContributorKey( contributor );
2697         }
2698     }
2699 
2700     /**
2701      * KeyComputer for Profile
2702      */
2703     private class ProfileKeyComputer implements KeyComputer<Profile>
2704     {
2705         @Override
2706         public Object key( Profile profile )
2707         {
2708             return getProfileKey( profile );
2709         }
2710     }
2711 
2712     /**
2713      * KeyComputer for Repository
2714      */
2715     private class RepositoryKeyComputer implements KeyComputer<Repository>
2716     {
2717         @Override
2718         public Object key( Repository repository )
2719         {
2720             return getRepositoryKey( repository );
2721         }
2722     }
2723 
2724     /**
2725      * KeyComputer for ReportPlugin
2726      */
2727     private class ReportPluginKeyComputer implements KeyComputer<ReportPlugin>
2728     {
2729         @Override
2730         public Object key( ReportPlugin plugin )
2731         {
2732             return getReportPluginKey( plugin );
2733         }
2734     }
2735 
2736     /**
2737      * KeyComputer for Plugin
2738      */
2739     private class PluginKeyComputer implements KeyComputer<Plugin>
2740     {
2741         @Override
2742         public Object key( Plugin plugin )
2743         {
2744             return getPluginKey( plugin );
2745         }
2746     }
2747 
2748     /**
2749      * KeyComputer for ReportSet
2750      */
2751     private class ReportSetKeyComputer implements KeyComputer<ReportSet>
2752     {
2753         @Override
2754         public Object key( ReportSet reportSet )
2755         {
2756             return getReportSetKey( reportSet );
2757         }
2758     }
2759 
2760     /**
2761      * KeyComputer for Notifier
2762      */
2763     private class NotifierKeyComputer implements KeyComputer<Notifier>
2764     {
2765         @Override
2766         public Object key( Notifier notifier )
2767         {
2768             return getNotifierKey( notifier );
2769         }
2770     }
2771 
2772     /**
2773      * KeyComputer for Extension
2774      */
2775     private class ExtensionKeyComputer implements KeyComputer<Extension>
2776     {
2777         @Override
2778         public Object key( Extension extension )
2779         {
2780             return getExtensionKey( extension );
2781         }
2782     }
2783 
2784     /**
2785      * KeyComputer for Resource
2786      */
2787     private class ResourceKeyComputer implements KeyComputer<Resource>
2788     {
2789         @Override
2790         public Object key( Resource resource )
2791         {
2792             return getResourceKey( resource );
2793         }
2794     }
2795 
2796     /**
2797      * KeyComputer for PluginExecution
2798      */
2799     private class ExecutionKeyComputer implements KeyComputer<PluginExecution>
2800     {
2801         @Override
2802         public Object key( PluginExecution pluginExecution )
2803         {
2804             return getPluginExecutionKey( pluginExecution );
2805         }
2806     }
2807 
2808     /**
2809      * KeyComputer for Exclusion
2810      */
2811     private class ExclusionKeyComputer implements KeyComputer<Exclusion>
2812     {
2813         @Override
2814         public Object key( Exclusion exclusion )
2815         {
2816             return getExclusionKey( exclusion );
2817         }
2818     }
2819 
2820     /**
2821      * Return the second value if <code>sourceDominant</code> is true, the first one otherwise.
2822      * @param <T>
2823      */
2824     private static class SourceDominant<T> implements Remapping<T>
2825     {
2826         private final boolean sourceDominant;
2827 
2828         SourceDominant( boolean sourceDominant )
2829         {
2830             this.sourceDominant = sourceDominant;
2831         }
2832 
2833         @Override
2834         public T merge( T u, T v )
2835         {
2836             return sourceDominant ? v : u;
2837         }
2838     }
2839 
2840     /**
2841      * Merge two lists
2842      */
2843     private static <T> List<T> merge( List<T> tgt, List<T> src, boolean sourceDominant, KeyComputer<T> computer )
2844     {
2845         return merge( tgt, src, computer, new SourceDominant<T>( sourceDominant ) );
2846     }
2847 
2848     private static <T> List<T> merge( List<T> tgt, List<T> src, KeyComputer<T> computer, Remapping<T> remapping )
2849     {
2850         if ( src.isEmpty() )
2851         {
2852             return tgt;
2853         }
2854 
2855         MergingList<T> list;
2856         if ( tgt instanceof MergingList )
2857         {
2858             list = (MergingList<T>) tgt;
2859         }
2860         else
2861         {
2862             list = new MergingList<>( computer, src.size() + tgt.size() );
2863             list.mergeAll( tgt, new SourceDominant<T>( true ) );
2864         }
2865 
2866         list.mergeAll( src, remapping );
2867         return list;
2868     }
2869 
2870     /**
2871      * Merging list
2872      * @param <V>
2873      */
2874     private static class MergingList<V> extends AbstractList<V> implements java.io.Serializable
2875     {
2876 
2877         private final KeyComputer<V> keyComputer;
2878         private Map<Object, V> map;
2879         private List<V> list;
2880 
2881         MergingList( KeyComputer<V> keyComputer, int initialCapacity )
2882         {
2883             this.map = new LinkedHashMap<>( initialCapacity );
2884             this.keyComputer = keyComputer;
2885         }
2886 
2887         Object writeReplace() throws ObjectStreamException
2888         {
2889             return new ArrayList<>( this );
2890         }
2891 
2892         @Override
2893         public Iterator<V> iterator()
2894         {
2895             if ( map != null )
2896             {
2897                 return map.values().iterator();
2898             }
2899             else
2900             {
2901                 return list.iterator();
2902             }
2903         }
2904 
2905         void mergeAll( Collection<V> vs, Remapping<V> remapping )
2906         {
2907             if ( map == null )
2908             {
2909                 map = new LinkedHashMap<>( list.size() + vs.size() );
2910                 for ( V v : list )
2911                 {
2912                     map.put( keyComputer.key( v ), v );
2913                 }
2914                 list = null;
2915             }
2916             if ( vs instanceof MergingList && ( (MergingList) vs ).map != null )
2917             {
2918                 for ( Map.Entry<Object, V> e : ( (MergingList<V>) vs ).map.entrySet() )
2919                 {
2920                     Object key = e.getKey();
2921                     V oldValue = map.get( key );
2922                     // JDK8: this should be a call to map.merge( key, v, remapping )
2923                     V newValue = ( oldValue == null ) ? e.getValue() : remapping.merge( oldValue, e.getValue() );
2924                     if ( newValue == null )
2925                     {
2926                         remove( key );
2927                     }
2928                     else if ( newValue != oldValue )
2929                     {
2930                         map.put( key, newValue );
2931                     }
2932                 }
2933             }
2934             else
2935             {
2936                 for ( V v : vs )
2937                 {
2938                     Object key = keyComputer.key( v );
2939                     // JDK8: this should be a call to map.merge( key, v, remapping )
2940                     V oldValue = map.get( key );
2941                     V newValue = ( oldValue == null ) ? v : remapping.merge( oldValue, v );
2942                     if ( newValue == null )
2943                     {
2944                         remove( key );
2945                     }
2946                     else
2947                     {
2948                         map.put( key, newValue );
2949                     }
2950                 }
2951             }
2952         }
2953 
2954         @Override
2955         public boolean contains( Object o )
2956         {
2957             if ( map != null )
2958             {
2959                 return map.containsValue( o );
2960             }
2961             else
2962             {
2963                 return list.contains( o );
2964             }
2965         }
2966 
2967         private List<V> asList()
2968         {
2969             if ( list == null )
2970             {
2971                 list = new ArrayList<>( map.values() );
2972                 map = null;
2973             }
2974             return list;
2975         }
2976 
2977         @Override
2978         public void add( int index, V element )
2979         {
2980             asList().add( index, element );
2981         }
2982 
2983         @Override
2984         public V remove( int index )
2985         {
2986             return asList().remove( index );
2987         }
2988 
2989         @Override
2990         public V get( int index )
2991         {
2992             return asList().get( index );
2993         }
2994 
2995         @Override
2996         public int size()
2997         {
2998             if ( map != null )
2999             {
3000                 return map.size();
3001             }
3002             else
3003             {
3004                 return list.size();
3005             }
3006         }
3007     }
3008 }