@Override
  public void onTrigger(final ProcessContext context, final ProcessSession session)
      throws ProcessException {
    final List<FlowFile> flowFiles = session.get(50);
    if (flowFiles.isEmpty()) {
      return;
    }

    final ProcessorLog logger = getLogger();
    try {
      if (fileWatcher.checkAndReset()) {
        this.dictionaryTerms = createDictionary(context);
      }
    } catch (final IOException e) {
      logger.error("Unable to reload dictionary due to {}", e);
    }

    final boolean matchAll =
        context.getProperty(MATCHING_CRITERIA).getValue().equals(MATCH_CRITERIA_ALL);

    for (final FlowFile flowFile : flowFiles) {
      final boolean matched =
          matchAll
              ? allMatch(flowFile, attributePattern, dictionaryTerms)
              : anyMatch(flowFile, attributePattern, dictionaryTerms);
      final Relationship relationship = matched ? REL_MATCHED : REL_UNMATCHED;
      session.getProvenanceReporter().route(flowFile, relationship);
      session.transfer(flowFile, relationship);
      logger.info("Transferred {} to {}", new Object[] {flowFile, relationship});
    }
  }
  @Override
  public void onTrigger(final ProcessContext context, final ProcessSession session)
      throws ProcessException {
    final ProcessorLog logger = getLogger();
    final SynchronousFileWatcher fileWatcher = fileWatcherRef.get();
    try {
      if (fileWatcher.checkAndReset()) {
        reloadDictionary(context, true, logger);
      }
    } catch (final IOException e) {
      throw new ProcessException(e);
    }

    Search<byte[]> search = searchRef.get();
    try {
      if (search == null) {
        if (reloadDictionary(context, false, logger)) {
          search = searchRef.get();
        }
      }
    } catch (final IOException e) {
      throw new ProcessException(e);
    }

    if (search == null) {
      return;
    }

    FlowFile flowFile = session.get();
    if (flowFile == null) {
      return;
    }

    final Search<byte[]> finalSearch = search;
    final ObjectHolder<SearchTerm<byte[]>> termRef = new ObjectHolder<>(null);
    termRef.set(null);

    session.read(
        flowFile,
        new InputStreamCallback() {
          @Override
          public void process(final InputStream rawIn) throws IOException {
            try (final InputStream in = new BufferedInputStream(rawIn)) {
              final SearchState<byte[]> searchResult = finalSearch.search(in, false);
              if (searchResult.foundMatch()) {
                termRef.set(searchResult.getResults().keySet().iterator().next());
              }
            }
          }
        });

    final SearchTerm<byte[]> matchingTerm = termRef.get();
    if (matchingTerm == null) {
      logger.info("Routing {} to 'unmatched'", new Object[] {flowFile});
      session.getProvenanceReporter().route(flowFile, REL_NO_MATCH);
      session.transfer(flowFile, REL_NO_MATCH);
    } else {
      final String matchingTermString = matchingTerm.toString(UTF8);
      logger.info(
          "Routing {} to 'matched' because it matched term {}",
          new Object[] {flowFile, matchingTermString});
      flowFile = session.putAttribute(flowFile, MATCH_ATTRIBUTE_KEY, matchingTermString);
      session.getProvenanceReporter().route(flowFile, REL_MATCH);
      session.transfer(flowFile, REL_MATCH);
    }
  }