public void traverse(FieldMapperListener listener) {
   for (RootMapper rootMapper : rootMappersOrdered) {
     if (!rootMapper.includeInObject() && rootMapper instanceof FieldMapper) {
       listener.fieldMapper((FieldMapper) rootMapper);
     }
   }
   rootObjectMapper.traverse(listener);
 }
 public void traverse(ObjectMapperListener listener) {
   rootObjectMapper.traverse(listener);
 }
  public DocumentMapper(
      String index,
      @Nullable Settings indexSettings,
      DocumentMapperParser docMapperParser,
      RootObjectMapper rootObjectMapper,
      ImmutableMap<String, Object> meta,
      NamedAnalyzer indexAnalyzer,
      NamedAnalyzer searchAnalyzer,
      NamedAnalyzer searchQuoteAnalyzer,
      Map<Class<? extends RootMapper>, RootMapper> rootMappers) {
    this.index = index;
    this.indexSettings = indexSettings;
    this.type = rootObjectMapper.name();
    this.docMapperParser = docMapperParser;
    this.meta = meta;
    this.rootObjectMapper = rootObjectMapper;

    this.rootMappers = ImmutableMap.copyOf(rootMappers);
    this.rootMappersOrdered =
        rootMappers.values().toArray(new RootMapper[rootMappers.values().size()]);
    List<RootMapper> rootMappersNotIncludedInObjectLst = newArrayList();
    for (RootMapper rootMapper : rootMappersOrdered) {
      if (!rootMapper.includeInObject()) {
        rootMappersNotIncludedInObjectLst.add(rootMapper);
      }
    }
    this.rootMappersNotIncludedInObject =
        rootMappersNotIncludedInObjectLst.toArray(
            new RootMapper[rootMappersNotIncludedInObjectLst.size()]);

    this.indexAnalyzer = indexAnalyzer;
    this.searchAnalyzer = searchAnalyzer;
    this.searchQuoteAnalyzer = searchQuoteAnalyzer != null ? searchQuoteAnalyzer : searchAnalyzer;

    this.typeFilter = typeMapper().termFilter(type, null);

    if (rootMapper(ParentFieldMapper.class) != null) {
      // mark the routing field mapper as required
      rootMapper(RoutingFieldMapper.class).markAsRequired();
    }

    FieldMapperListener.Aggregator fieldMappersAgg = new FieldMapperListener.Aggregator();
    for (RootMapper rootMapper : rootMappersOrdered) {
      if (rootMapper.includeInObject()) {
        rootObjectMapper.putMapper(rootMapper);
      } else {
        if (rootMapper instanceof FieldMapper) {
          fieldMappersAgg.mappers.add((FieldMapper) rootMapper);
        }
      }
    }

    // now traverse and get all the statically defined ones
    rootObjectMapper.traverse(fieldMappersAgg);

    this.fieldMappers = new DocumentFieldMappers(this, fieldMappersAgg.mappers);

    final Map<String, ObjectMapper> objectMappers = Maps.newHashMap();
    rootObjectMapper.traverse(
        new ObjectMapperListener() {
          @Override
          public void objectMapper(ObjectMapper objectMapper) {
            objectMappers.put(objectMapper.fullPath(), objectMapper);
          }
        });
    this.objectMappers = ImmutableMap.copyOf(objectMappers);
    for (ObjectMapper objectMapper : objectMappers.values()) {
      if (objectMapper.nested().isNested()) {
        hasNestedObjects = true;
      }
    }

    refreshSource();
  }