@Override
 public PercolatorFieldMapper build(BuilderContext context) {
   context.path().add(name());
   FieldType fieldType = (FieldType) this.fieldType;
   KeywordFieldMapper extractedTermsField =
       createExtractQueryFieldBuilder(EXTRACTED_TERMS_FIELD_NAME, context);
   fieldType.queryTermsField = extractedTermsField.fieldType();
   KeywordFieldMapper extractionResultField =
       createExtractQueryFieldBuilder(EXTRACTION_RESULT_FIELD_NAME, context);
   fieldType.extractionResultField = extractionResultField.fieldType();
   BinaryFieldMapper queryBuilderField = createQueryBuilderFieldBuilder(context);
   fieldType.queryBuilderField = queryBuilderField.fieldType();
   context.path().remove();
   setupFieldType(context);
   return new PercolatorFieldMapper(
       name(),
       fieldType,
       defaultFieldType,
       context.indexSettings(),
       multiFieldsBuilder.build(this, context),
       copyTo,
       queryShardContext,
       extractedTermsField,
       extractionResultField,
       queryBuilderField);
 }
  @Override
  public FieldMapper updateFieldType(Map<String, MappedFieldType> fullNameToFieldType) {
    PercolatorFieldMapper updated =
        (PercolatorFieldMapper) super.updateFieldType(fullNameToFieldType);
    KeywordFieldMapper queryTermsUpdated =
        (KeywordFieldMapper) queryTermsField.updateFieldType(fullNameToFieldType);
    KeywordFieldMapper extractionResultUpdated =
        (KeywordFieldMapper) extractionResultField.updateFieldType(fullNameToFieldType);
    BinaryFieldMapper queryBuilderUpdated =
        (BinaryFieldMapper) queryBuilderField.updateFieldType(fullNameToFieldType);

    if (updated == this
        && queryTermsUpdated == queryTermsField
        && extractionResultUpdated == extractionResultField
        && queryBuilderUpdated == queryBuilderField) {
      return this;
    }
    if (updated == this) {
      updated = (PercolatorFieldMapper) updated.clone();
    }
    updated.queryTermsField = queryTermsUpdated;
    updated.extractionResultField = extractionResultUpdated;
    updated.queryBuilderField = queryBuilderUpdated;
    return updated;
  }
 void processQuery(Query query, ParseContext context) {
   ParseContext.Document doc = context.doc();
   FieldType pft = (FieldType) this.fieldType();
   QueryAnalyzer.Result result;
   try {
     result = QueryAnalyzer.analyze(query);
   } catch (QueryAnalyzer.UnsupportedQueryException e) {
     doc.add(
         new Field(
             pft.extractionResultField.name(),
             EXTRACTION_FAILED,
             extractionResultField.fieldType()));
     return;
   }
   for (Term term : result.terms) {
     BytesRefBuilder builder = new BytesRefBuilder();
     builder.append(new BytesRef(term.field()));
     builder.append(FIELD_VALUE_SEPARATOR);
     builder.append(term.bytes());
     doc.add(new Field(queryTermsField.name(), builder.toBytesRef(), queryTermsField.fieldType()));
   }
   if (result.verified) {
     doc.add(
         new Field(
             extractionResultField.name(),
             EXTRACTION_COMPLETE,
             extractionResultField.fieldType()));
   } else {
     doc.add(
         new Field(
             extractionResultField.name(), EXTRACTION_PARTIAL, extractionResultField.fieldType()));
   }
 }