@Override
    public boolean process(
            final Set<? extends TypeElement> annotations,
            final RoundEnvironment roundEnv) {
        if (annotations == null || annotations.isEmpty()) {
            return false;
        }

        // we need the actual TypeElement of the annotation, not just it's name
        final TypeElement annotation = typeElement(ANNOTATION_TYPE);

        // make sure we have the annotation type
        if (annotation == null) {
            // no go for processing
            return false;
        }

        // get all classes that have the annotation
        final Set<? extends Element> annotatedElements =
                roundEnv.getElementsAnnotatedWith(annotation);

        try {
            // we will need to gather the annotated classes that we are
            // going to write to the services registration file
            final Set<String> results = new HashSet<String>(annotatedElements.size());

            for (final Element m : annotatedElements) {

                // we know @Route is a type annotation so casting to TypeElement
                final TypeElement el = (TypeElement) m;

                // check that the class is not abstract since we cant instantiate it if it is
                // and that its of the correct type for our fi.zakar.control.Router
                if (el.getModifiers().contains(Modifier.ABSTRACT) ||
                    !isAssignable(m.asType(), Handler.class)) {
                    // wasn't proper annotation -> go for compilation failure
                    processingEnv.getMessager().printMessage(Kind.ERROR,
                            "@Route annotated classes must be non-abstract and of type " + Handler.class, m);

                }
                else {
                    // we are good to go, gather it up in the results
                    results.add(el.getQualifiedName().toString());
                }
            }

            // write the services to file
            registerControls(results);
        } catch (final IOException ioe) {
            System.out.println("ERROR" + ioe.getMessage());
            processingEnv.getMessager().printMessage(
                    Kind.ERROR,
                    "I/O Error during processing.");

            ioe.printStackTrace();
        }

        return true;
    }