@Override
  public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
    builder.startObject(name()).field(Fields.TYPE, CONTENT_TYPE);
    if (indexAnalyzer.name().equals(searchAnalyzer.name())) {
      builder.field(Fields.ANALYZER, indexAnalyzer.name());
    } else {
      builder
          .field(Fields.INDEX_ANALYZER.getPreferredName(), indexAnalyzer.name())
          .field(Fields.SEARCH_ANALYZER.getPreferredName(), searchAnalyzer.name());
    }
    builder.field(Fields.PAYLOADS, this.payloads);
    builder.field(Fields.PRESERVE_SEPARATORS.getPreferredName(), this.preserveSeparators);
    builder.field(
        Fields.PRESERVE_POSITION_INCREMENTS.getPreferredName(), this.preservePositionIncrements);
    builder.field(Fields.MAX_INPUT_LENGTH.getPreferredName(), this.maxInputLength);
    multiFields.toXContent(builder, params);

    if (!contextMapping.isEmpty()) {
      builder.startObject(Fields.CONTEXT);
      for (ContextMapping mapping : contextMapping.values()) {
        builder.value(mapping);
      }
      builder.endObject();
    }

    return builder.endObject();
  }
    @Override
    public Mapper.Builder<?, ?> parse(
        String name, Map<String, Object> node, ParserContext parserContext)
        throws MapperParsingException {
      CompletionFieldMapper.Builder builder = completionField(name);
      for (Iterator<Map.Entry<String, Object>> iterator = node.entrySet().iterator();
          iterator.hasNext(); ) {
        Map.Entry<String, Object> entry = iterator.next();
        String fieldName = entry.getKey();
        Object fieldNode = entry.getValue();
        if (fieldName.equals("type")) {
          continue;
        }
        if (fieldName.equals("analyzer")) {
          NamedAnalyzer analyzer = getNamedAnalyzer(parserContext, fieldNode.toString());
          builder.indexAnalyzer(analyzer);
          builder.searchAnalyzer(analyzer);
          iterator.remove();
        } else if (Fields.INDEX_ANALYZER.match(fieldName)) {
          builder.indexAnalyzer(getNamedAnalyzer(parserContext, fieldNode.toString()));
          iterator.remove();
        } else if (Fields.SEARCH_ANALYZER.match(fieldName)) {
          builder.searchAnalyzer(getNamedAnalyzer(parserContext, fieldNode.toString()));
          iterator.remove();
        } else if (fieldName.equals(Fields.PAYLOADS)) {
          builder.payloads(Boolean.parseBoolean(fieldNode.toString()));
          iterator.remove();
        } else if (Fields.PRESERVE_SEPARATORS.match(fieldName)) {
          builder.preserveSeparators(Boolean.parseBoolean(fieldNode.toString()));
          iterator.remove();
        } else if (Fields.PRESERVE_POSITION_INCREMENTS.match(fieldName)) {
          builder.preservePositionIncrements(Boolean.parseBoolean(fieldNode.toString()));
          iterator.remove();
        } else if (Fields.MAX_INPUT_LENGTH.match(fieldName)) {
          builder.maxInputLength(Integer.parseInt(fieldNode.toString()));
          iterator.remove();
        } else if ("fields".equals(fieldName) || "path".equals(fieldName)) {
          if (parseMultiField(builder, name, parserContext, fieldName, fieldNode)) {
            iterator.remove();
          }
        } else if (fieldName.equals(Fields.CONTEXT)) {
          builder.contextMapping(
              ContextBuilder.loadMappings(fieldNode, parserContext.indexVersionCreated()));
          iterator.remove();
        }
      }

      if (builder.searchAnalyzer == null) {
        builder.searchAnalyzer(parserContext.analysisService().analyzer("simple"));
      }

      if (builder.indexAnalyzer == null) {
        builder.indexAnalyzer(parserContext.analysisService().analyzer("simple"));
      }
      // we are just using this as the default to be wrapped by the CompletionPostingsFormatProvider
      // in the SuggesteFieldMapper ctor
      builder.postingsFormat(parserContext.postingFormatService().get("default"));
      return builder;
    }