private void findTypesIn(Object model, Map<String, Type> types) {
        requireNonNull(model);
        requireNonNull(types);

		if (model instanceof HasSupertype) {
			((HasSupertype<?>) model).getSupertype().ifPresent(t -> addType(t, types));
		}
		
		if (model instanceof HasAnnotationUsage) {
			((HasAnnotationUsage<?>) model).getAnnotations().forEach(a -> {
				addType(a.getType(), types);
				a.getValue().ifPresent(v -> findTypesIn(v, types));
				a.getValues().stream()
					.map(Map.Entry::getValue)
					.forEach(v ->  findTypesIn(v, types));
			});
		}
		
		if (model instanceof HasClasses) {
			((HasClasses<?>) model).getClasses().forEach(c -> 
				findTypesIn(c, types)
			);
		}
		
		if (model instanceof HasConstructors) {
			((HasConstructors<?>) model).getConstructors().forEach(c -> 
				findTypesIn(c, types)
			);
		}
		
		if (model instanceof HasFields) {
			((HasFields<?>) model).getFields().forEach(f -> {
				addType(f.getType(), types);
				findTypesIn(f, types);
			});
		}
		
		if (model instanceof HasGenerics) {
			((HasGenerics<?>) model).getGenerics().forEach(g -> 
				g.getUpperBounds().forEach(ub -> 
					addType(ub, types)
				)
			);
		}
		
		if (model instanceof HasImplements) {
			((HasImplements<?>) model).getInterfaces().forEach(i -> 
				addType(i, types)
			);
		}
		
		if (model instanceof HasMethods) {
			((HasMethods<?>) model).getMethods().forEach(m -> {
				addType(m.getType(), types);
				findTypesIn(m, types);
			});
		}
        
        if (model instanceof HasThrows) {
			((HasThrows<?>) model).getExceptions().forEach(e -> 
				addType(e, types)
			);
		}
		
		if (model instanceof HasType) {
			addType(((HasType<?>) model).getType(), types);
		}

		if (model instanceof AnonymousValue) {
			((AnonymousValue) model).getTypeParameters().forEach(e ->
				addType(e, types)
			);
		}

        if (model instanceof HasValues) {
            ((HasValues<?>) model).getValues().forEach(v ->
                findTypesIn(v, types)
            );
        }

		if (model instanceof HasValue) {
            ((HasValue<?>) model).getValue()
                .ifPresent(val -> findTypesIn(val, types));
        }

        if (model instanceof Enum) {
			((Enum) model).getConstants()
				.forEach(ec -> findTypesIn(ec, types));
		}
	}
A recursive method that parses through the model hierarchy of the
specified object and adds all found types to the supplied map. The type
names will be used as keys.

@param model  the model to parse recursively
@param types  the map to add the results to
common-parent/codegen/src/main/java/com/speedment/common/codegen/controller/AutoImports.java