@Override protected void doProcess(final JCas jCas) throws AnalysisEngineProcessException { Multimap<String, ExtractedRecord> records = HashMultimap.create(); Collection<TemplateRecord> recordAnnotations = JCasUtil.select(jCas, TemplateRecord.class); HashSet<TemplateField> allFields = new HashSet<>(JCasUtil.select(jCas, TemplateField.class)); for (TemplateRecord recordAnnotation : recordAnnotations) { Collection<TemplateField> fieldAnnotations = JCasUtil.selectCovered(TemplateField.class, recordAnnotation); List<TemplateField> recordFieldAnnotations = fieldAnnotations .stream() .filter(f -> recordAnnotation.getSource().equals(f.getSource())) .collect(Collectors.toList()); allFields.removeAll(recordFieldAnnotations); Collection<ExtractedField> fieldValues = makeFieldValues(recordFieldAnnotations); records.put( recordAnnotation.getSource(), new ExtractedRecord(recordAnnotation.getName(), fieldValues)); } Multimap<String, TemplateField> remainingFields = HashMultimap.create(); for (TemplateField templateField : allFields) { remainingFields.put(templateField.getSource(), templateField); } for (String source : remainingFields.keySet()) { records.put(source, new ExtractedRecord(makeFieldValues(remainingFields.get(source)))); } String documentSourceName = SourceUtils.getDocumentSourceBaseName(jCas); writeRecords(jCas, documentSourceName, records.asMap()); }