class MatcherFactoryGenerator extends AbstractProcessor {

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        try {

            if (roundEnv.processingOver()) {
                return false;
            }

            if (annotations.isEmpty()) {
                LOGGER.info("No any annotation found...");
                return false;
            }

            List<Element> fields = new LinkedList<>();

            for (TypeElement annotation : annotations) {
                LOGGER.info(format("Work with %s...", annotation.getQualifiedName()));
                roundEnv.getElementsAnnotatedWith(annotation)
                        .stream()
                        .flatMap(MatcherFactoryGenerator::asFields)
                        .filter(ProcessingPredicates.shouldGenerateMatcher())
                        .forEach(fields::add);
            }

            Map<Element, ClassSpecDescription> classes = groupedClasses(fields);

            LOGGER.info(format("Got %s classes to generate matchers. Writing them...", classes.size()));

            classes.values()
                    .stream()
                    .filter(isEntryWithParentPackageElement())
                    .map(ClassSpecDescription::asJavaFile)
                    .forEach(write(processingEnv));

            LOGGER.info("All classes were successfully processed!");

        } catch (Exception e) {
            LOGGER.log(Level.SEVERE, format("Can't generate matchers, because of: %s", e.getMessage()), e);
        }

        return false;
    }

}