private void serialize(Serializer serializer, Collection<EntityType> models) {
    for (EntityType model : models) {
      try {
        Type type = conf.getTypeMappings().getPathType(model, model, true);
        String packageName = type.getPackageName();
        String className =
            !packageName.isEmpty()
                ? (packageName + "." + type.getSimpleName())
                : type.getSimpleName();

        // skip if type is excluded class or in excluded package
        if (conf.isExcludedPackage(model.getPackageName())
            || conf.isExcludedClass(model.getFullName())) {
          continue;
        }

        Set<TypeElement> elements = context.typeElements.get(model.getFullName());

        if (elements == null) {
          elements = new HashSet<TypeElement>();
        }
        for (Property property : model.getProperties()) {
          if (property.getType().getCategory() == TypeCategory.CUSTOM) {
            Set<TypeElement> customElements =
                context.typeElements.get(property.getType().getFullName());
            if (customElements != null) {
              elements.addAll(customElements);
            }
          }
        }

        processingEnv
            .getMessager()
            .printMessage(Kind.NOTE, "Generating " + className + " for " + elements);
        JavaFileObject fileObject =
            processingEnv
                .getFiler()
                .createSourceFile(className, elements.toArray(new Element[elements.size()]));
        Writer writer = fileObject.openWriter();
        try {
          SerializerConfig serializerConfig = conf.getSerializerConfig(model);
          serializer.serialize(model, serializerConfig, new JavaWriter(writer));
        } finally {
          if (writer != null) {
            writer.close();
          }
        }

      } catch (IOException e) {
        System.err.println(e.getMessage());
        processingEnv.getMessager().printMessage(Kind.ERROR, e.getMessage());
      }
    }
  }
  protected Set<TypeElement> collectElements() {
    Set<TypeElement> elements = new HashSet<TypeElement>();

    // from delegate methods
    elements.addAll(processDelegateMethods());

    // from class annotations
    for (Class<? extends Annotation> annotation : conf.getEntityAnnotations()) {
      for (Element element : getElements(annotation)) {
        if (element instanceof TypeElement) {
          elements.add((TypeElement) element);
        }
      }
    }

    // from package annotations
    if (conf.getEntitiesAnnotation() != null) {
      for (Element element : getElements(conf.getEntitiesAnnotation())) {
        AnnotationMirror mirror =
            TypeUtils.getAnnotationMirrorOfType(element, conf.getEntitiesAnnotation());
        elements.addAll(TypeUtils.getAnnotationValuesAsElements(mirror, "value"));
      }
    }

    // from embedded annotations
    if (conf.getEmbeddedAnnotation() != null) {
      elements.addAll(getEmbeddedTypes());
    }

    // from embedded
    if (conf.isUnknownAsEmbedded()) {
      elements.addAll(getTypeFromProperties(elements));
    }

    // from annotation less supertypes
    elements.addAll(getAnnotationlessSupertypes(elements));

    // register possible embedded types of non-tracked supertypes
    if (conf.getEmbeddedAnnotation() != null) {
      Class<? extends Annotation> embedded = conf.getEmbeddedAnnotation();
      Set<TypeElement> embeddedElements = new HashSet<TypeElement>();
      for (TypeElement element : elements) {
        TypeMirror superTypeMirror = element.getSuperclass();
        while (superTypeMirror != null) {
          TypeElement superTypeElement =
              (TypeElement) processingEnv.getTypeUtils().asElement(superTypeMirror);
          if (superTypeElement != null) {
            List<? extends Element> enclosed = superTypeElement.getEnclosedElements();
            for (Element child : enclosed) {
              if (child.getAnnotation(embedded) != null) {
                handleEmbeddedType(child, embeddedElements);
              }
            }
            superTypeMirror = superTypeElement.getSuperclass();
            if (superTypeMirror instanceof NoType) {
              superTypeMirror = null;
            }
          } else {
            superTypeMirror = null;
          }
        }
      }

      // register found elements
      for (TypeElement element : embeddedElements) {
        if (!elements.contains(element)) {
          elementHandler.handleEntityType(element);
        }
      }
    }

    return elements;
  }