@Override
 public void writeTo(StreamOutput out) throws IOException {
   out.writeString(index.getName()); // uuid will come as part of settings
   out.writeLong(version);
   out.writeByte(state.id());
   writeSettingsToStream(settings, out);
   out.writeVInt(mappings.size());
   for (ObjectCursor<MappingMetaData> cursor : mappings.values()) {
     cursor.value.writeTo(out);
   }
   out.writeVInt(aliases.size());
   for (ObjectCursor<AliasMetaData> cursor : aliases.values()) {
     cursor.value.writeTo(out);
   }
   out.writeVInt(customs.size());
   for (ObjectObjectCursor<String, Custom> cursor : customs) {
     out.writeString(cursor.key);
     cursor.value.writeTo(out);
   }
   out.writeVInt(activeAllocationIds.size());
   for (IntObjectCursor<Set<String>> cursor : activeAllocationIds) {
     out.writeVInt(cursor.key);
     DiffableUtils.StringSetValueSerializer.getInstance().write(cursor.value, out);
   }
 }
    public IndexMetaDataDiff(StreamInput in) throws IOException {
      index = in.readString();
      version = in.readLong();
      state = State.fromId(in.readByte());
      settings = Settings.readSettingsFromStream(in);
      mappings =
          DiffableUtils.readImmutableOpenMapDiff(
              in, DiffableUtils.getStringKeySerializer(), MappingMetaData.PROTO);
      aliases =
          DiffableUtils.readImmutableOpenMapDiff(
              in, DiffableUtils.getStringKeySerializer(), AliasMetaData.PROTO);
      customs =
          DiffableUtils.readImmutableOpenMapDiff(
              in,
              DiffableUtils.getStringKeySerializer(),
              new DiffableUtils.DiffableValueSerializer<String, Custom>() {
                @Override
                public Custom read(StreamInput in, String key) throws IOException {
                  return lookupPrototypeSafe(key).readFrom(in);
                }

                @Override
                public Diff<Custom> readDiff(StreamInput in, String key) throws IOException {
                  return lookupPrototypeSafe(key).readDiffFrom(in);
                }
              });
      activeAllocationIds =
          DiffableUtils.readImmutableOpenIntMapDiff(
              in,
              DiffableUtils.getVIntKeySerializer(),
              DiffableUtils.StringSetValueSerializer.getInstance());
    }
 @Override
 public IndexMetaData readFrom(StreamInput in) throws IOException {
   Builder builder = new Builder(in.readString());
   builder.version(in.readLong());
   builder.state(State.fromId(in.readByte()));
   builder.settings(readSettingsFromStream(in));
   int mappingsSize = in.readVInt();
   for (int i = 0; i < mappingsSize; i++) {
     MappingMetaData mappingMd = MappingMetaData.PROTO.readFrom(in);
     builder.putMapping(mappingMd);
   }
   int aliasesSize = in.readVInt();
   for (int i = 0; i < aliasesSize; i++) {
     AliasMetaData aliasMd = AliasMetaData.Builder.readFrom(in);
     builder.putAlias(aliasMd);
   }
   int customSize = in.readVInt();
   for (int i = 0; i < customSize; i++) {
     String type = in.readString();
     Custom customIndexMetaData = lookupPrototypeSafe(type).readFrom(in);
     builder.putCustom(type, customIndexMetaData);
   }
   int activeAllocationIdsSize = in.readVInt();
   for (int i = 0; i < activeAllocationIdsSize; i++) {
     int key = in.readVInt();
     Set<String> allocationIds =
         DiffableUtils.StringSetValueSerializer.getInstance().read(in, key);
     builder.putActiveAllocationIds(key, allocationIds);
   }
   return builder.build();
 }
 public IndexMetaDataDiff(IndexMetaData before, IndexMetaData after) {
   index = after.index.getName();
   version = after.version;
   state = after.state;
   settings = after.settings;
   mappings =
       DiffableUtils.diff(
           before.mappings, after.mappings, DiffableUtils.getStringKeySerializer());
   aliases =
       DiffableUtils.diff(before.aliases, after.aliases, DiffableUtils.getStringKeySerializer());
   customs =
       DiffableUtils.diff(before.customs, after.customs, DiffableUtils.getStringKeySerializer());
   activeAllocationIds =
       DiffableUtils.diff(
           before.activeAllocationIds,
           after.activeAllocationIds,
           DiffableUtils.getVIntKeySerializer(),
           DiffableUtils.StringSetValueSerializer.getInstance());
 }