@Override
 protected ObjectMapper createMapper(
     String name,
     String fullPath,
     boolean enabled,
     Nested nested,
     Dynamic dynamic,
     ContentPath.Type pathType,
     Map<String, Mapper> mappers,
     @Nullable @IndexSettings Settings settings) {
   assert !nested.isNested();
   FormatDateTimeFormatter[] dates = null;
   if (dynamicDateTimeFormatters == null) {
     dates = new FormatDateTimeFormatter[0];
   } else if (dynamicDateTimeFormatters.isEmpty()) {
     // add the default one
     dates = Defaults.DYNAMIC_DATE_TIME_FORMATTERS;
   } else {
     dates =
         dynamicDateTimeFormatters.toArray(
             new FormatDateTimeFormatter[dynamicDateTimeFormatters.size()]);
   }
   return new RootObjectMapper(
       name,
       enabled,
       dynamic,
       pathType,
       mappers,
       dates,
       dynamicTemplates.toArray(new DynamicTemplate[dynamicTemplates.size()]),
       dateDetection,
       numericDetection,
       settings);
 }
 @Override
 protected void doMerge(ObjectMapper mergeWith, MergeContext mergeContext) {
   RootObjectMapper mergeWithObject = (RootObjectMapper) mergeWith;
   if (!mergeContext.mergeFlags().simulate()) {
     // merge them
     List<DynamicTemplate> mergedTemplates =
         Lists.newArrayList(Arrays.asList(this.dynamicTemplates));
     for (DynamicTemplate template : mergeWithObject.dynamicTemplates) {
       boolean replaced = false;
       for (int i = 0; i < mergedTemplates.size(); i++) {
         if (mergedTemplates.get(i).name().equals(template.name())) {
           mergedTemplates.set(i, template);
           replaced = true;
         }
       }
       if (!replaced) {
         mergedTemplates.add(template);
       }
     }
     this.dynamicTemplates = mergedTemplates.toArray(new DynamicTemplate[mergedTemplates.size()]);
   }
 }