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