//public IEnumerable<Type> SubclassesOf(object superclass, string[] packages)
        //{
        //    return Stream.of(packages).filter(this::isValidPackage)
        //            .map(packageName->elements.getPackageElement(packageName))
        //            .flatMap(packageElement->packageElement.getEnclosedElements().stream())
        //            .filter(element->isSubclass(element, superclass))
        //            .map(element->element.asType());

        //    var a = packages.Where(x => IsValidPackage(x)).SelectMany(packageName => _elements.GetMembers()).Where(element => elem)
        //}

        //private bool IsSubclass(Type typeElement, object superclass)
        //{
        //    Type type = _elementstyp((string)superclass)
        //                    .asType();

        //    return ((TypeElement)typeElement).getSuperclass()
        //            .equals(type);
        //}

        //public <T> TypeElement from(final T annotation, final Function<T, Class<?>> retriever)
        //{
        //    try
        //    {
        //        final Class<?> clazz =
        //                retriever.apply(annotation);

        //        return environment.getElementUtils()
        //                .getTypeElement(clazz.getCanonicalName());
        //    }
        //    catch (final MirroredTypeException exception) {
        //        return (TypeElement)environment.getTypeUtils()
        //                .asElement(exception.getTypeMirror());
        //    }
        //}

        //public <T>  List<TypeElement> typesFrom(final T annotation, final Function< T, Class <?>[] > retriever) {
        //        try
        //        {
        //            final Class<?>[] classes =
        //            retriever.apply(annotation);

        //            return Stream.of(classes).map(clazz->environment.getElementUtils()
        //                    .getTypeElement(clazz.getCanonicalName())).collect(Collectors.toList());
        //        }
        //        catch (final MirroredTypesException exception) {
        //            return exception.getTypeMirrors().stream()
        //                    .map(typeMirror-> (TypeElement) environment.getTypeUtils()
        //                            .asElement(typeMirror)).collect(Collectors.toList());
        //        }
        //}

        public static TypeRetriever With(ProcessingEnvironment environment) => new TypeRetriever(environment);
 private TypeRetriever(ProcessingEnvironment environment)
 {
     _environment = environment;
     _elements    = environment.GetElementUtils();
 }