private void removeObjectAndFieldMappers(DocumentMapper docMapper) {
    // we need to remove those mappers
    MapBuilder<String, FieldMappers> nameFieldMappers = newMapBuilder(this.nameFieldMappers);
    MapBuilder<String, FieldMappers> indexNameFieldMappers =
        newMapBuilder(this.indexNameFieldMappers);
    MapBuilder<String, FieldMappers> fullNameFieldMappers =
        newMapBuilder(this.fullNameFieldMappers);

    for (FieldMapper mapper : docMapper.mappers()) {
      FieldMappers mappers = nameFieldMappers.get(mapper.names().name());
      if (mappers != null) {
        mappers = mappers.remove(mapper);
        if (mappers.isEmpty()) {
          nameFieldMappers.remove(mapper.names().name());
        } else {
          nameFieldMappers.put(mapper.names().name(), mappers);
        }
      }

      mappers = indexNameFieldMappers.get(mapper.names().indexName());
      if (mappers != null) {
        mappers = mappers.remove(mapper);
        if (mappers.isEmpty()) {
          indexNameFieldMappers.remove(mapper.names().indexName());
        } else {
          indexNameFieldMappers.put(mapper.names().indexName(), mappers);
        }
      }

      mappers = fullNameFieldMappers.get(mapper.names().fullName());
      if (mappers != null) {
        mappers = mappers.remove(mapper);
        if (mappers.isEmpty()) {
          fullNameFieldMappers.remove(mapper.names().fullName());
        } else {
          fullNameFieldMappers.put(mapper.names().fullName(), mappers);
        }
      }
    }
    this.nameFieldMappers = nameFieldMappers.map();
    this.indexNameFieldMappers = indexNameFieldMappers.map();
    this.fullNameFieldMappers = fullNameFieldMappers.map();

    MapBuilder<String, ObjectMappers> fullPathObjectMappers =
        newMapBuilder(this.fullPathObjectMappers);
    for (ObjectMapper mapper : docMapper.objectMappers().values()) {
      ObjectMappers mappers = fullPathObjectMappers.get(mapper.fullPath());
      if (mappers != null) {
        mappers = mappers.remove(mapper);
        if (mappers.isEmpty()) {
          fullPathObjectMappers.remove(mapper.fullPath());
        } else {
          fullPathObjectMappers.put(mapper.fullPath(), mappers);
        }
      }
    }

    this.fullPathObjectMappers = fullPathObjectMappers.map();
  }
    public IndexMetaData build() {
      MapBuilder<String, AliasMetaData> tmpAliases = aliases;
      Settings tmpSettings = settings;

      // For backward compatibility
      String[] legacyAliases = settings.getAsArray("index.aliases");
      if (legacyAliases.length > 0) {
        tmpAliases = MapBuilder.newMapBuilder();
        for (String alias : legacyAliases) {
          AliasMetaData aliasMd = AliasMetaData.newAliasMetaDataBuilder(alias).build();
          tmpAliases.put(alias, aliasMd);
        }
        tmpAliases.putAll(aliases.immutableMap());
        // Remove index.aliases from settings once they are migrated to the new data structure
        tmpSettings =
            ImmutableSettings.settingsBuilder().put(settings).putArray("index.aliases").build();
      }

      // update default mapping on the MappingMetaData
      if (mappings.containsKey(MapperService.DEFAULT_MAPPING)) {
        MappingMetaData defaultMapping = mappings.get(MapperService.DEFAULT_MAPPING);
        for (MappingMetaData mappingMetaData : mappings.map().values()) {
          mappingMetaData.updateDefaultMapping(defaultMapping);
        }
      }

      return new IndexMetaData(
          index,
          version,
          state,
          tmpSettings,
          mappings.immutableMap(),
          tmpAliases.immutableMap(),
          customs.immutableMap());
    }
  private void addFieldMappers(FieldMapper[] fieldMappers) {
    synchronized (mutex) {
      MapBuilder<String, FieldMappers> nameFieldMappers = newMapBuilder(this.nameFieldMappers);
      MapBuilder<String, FieldMappers> indexNameFieldMappers =
          newMapBuilder(this.indexNameFieldMappers);
      MapBuilder<String, FieldMappers> fullNameFieldMappers =
          newMapBuilder(this.fullNameFieldMappers);
      for (FieldMapper fieldMapper : fieldMappers) {
        FieldMappers mappers = nameFieldMappers.get(fieldMapper.names().name());
        if (mappers == null) {
          mappers = new FieldMappers(fieldMapper);
        } else {
          mappers = mappers.concat(fieldMapper);
        }
        nameFieldMappers.put(fieldMapper.names().name(), mappers);

        mappers = indexNameFieldMappers.get(fieldMapper.names().indexName());
        if (mappers == null) {
          mappers = new FieldMappers(fieldMapper);
        } else {
          mappers = mappers.concat(fieldMapper);
        }
        indexNameFieldMappers.put(fieldMapper.names().indexName(), mappers);

        mappers = fullNameFieldMappers.get(fieldMapper.names().fullName());
        if (mappers == null) {
          mappers = new FieldMappers(fieldMapper);
        } else {
          mappers = mappers.concat(fieldMapper);
        }
        fullNameFieldMappers.put(fieldMapper.names().fullName(), mappers);
      }

      this.nameFieldMappers = nameFieldMappers.map();
      this.indexNameFieldMappers = indexNameFieldMappers.map();
      this.fullNameFieldMappers = fullNameFieldMappers.map();
    }
  }
 private void addObjectMappers(ObjectMapper[] objectMappers) {
   synchronized (mutex) {
     MapBuilder<String, ObjectMappers> fullPathObjectMappers =
         newMapBuilder(this.fullPathObjectMappers);
     for (ObjectMapper objectMapper : objectMappers) {
       ObjectMappers mappers = fullPathObjectMappers.get(objectMapper.fullPath());
       if (mappers == null) {
         mappers = new ObjectMappers(objectMapper);
       } else {
         mappers = mappers.concat(objectMapper);
       }
       fullPathObjectMappers.put(objectMapper.fullPath(), mappers);
       // update the hasNested flag
       if (objectMapper.nested().isNested()) {
         hasNested = true;
       }
     }
     this.fullPathObjectMappers = fullPathObjectMappers.map();
   }
 }