public EntityType handleEntityType(TypeElement element) {
        EntityType entityType = typeFactory.getEntityType(element.asType(), true);
        List<? extends Element> elements = element.getEnclosedElements();
        VisitorConfig config = configuration.getConfig(element, elements);
        Set<String> blockedProperties = new HashSet<String>();
        Map<String, TypeMirror> propertyTypes = new HashMap<String, TypeMirror>();
        Map<String, TypeMirror> fixedTypes = new HashMap<String, TypeMirror>();
        Map<String, Annotations> propertyAnnotations = new HashMap<String, Annotations>();

        // constructors
        if (config.visitConstructors()) {
            handleConstructors(entityType, elements);
        }

        // fields
        if (config.visitFieldProperties()) {
            for (VariableElement field : ElementFilter.fieldsIn(elements)) {
                String name = field.getSimpleName().toString();
                if (configuration.isBlockedField(field)) {
                    blockedProperties.add(name);
                } else if (configuration.isValidField(field)) {
                    Annotations annotations = new Annotations();
                    configuration.inspect(field, annotations);
                    annotations.addAnnotation(field.getAnnotation(QueryType.class));
                    annotations.addAnnotation(field.getAnnotation(QueryInit.class));
                    propertyAnnotations.put(name, annotations);
                    propertyTypes.put(name, field.asType());
                    TypeMirror fixedType = configuration.getRealType(field);
                    if (fixedType != null) {
                        fixedTypes.put(name, fixedType);
                    }
                }
            }
        }

        // methods
        if (config.visitMethodProperties()) {
            for (ExecutableElement method : ElementFilter.methodsIn(elements)) {
                String name = method.getSimpleName().toString();
                if (name.startsWith("get") && name.length() > 3 && method.getParameters().isEmpty()) {
                    name = BeanUtils.uncapitalize(name.substring(3));
                } else if (name.startsWith("is") && name.length() > 2 && method.getParameters().isEmpty()) {
                    name = BeanUtils.uncapitalize(name.substring(2));
                } else {
                    continue;
                }

                if (configuration.isBlockedGetter(method)) {
                    blockedProperties.add(name);
                } else if (configuration.isValidGetter(method) && !blockedProperties.contains(name)) {
                    Annotations annotations = propertyAnnotations.get(name);
                    if (annotations == null) {
                        annotations = new Annotations();
                        propertyAnnotations.put(name, annotations);
                    }
                    configuration.inspect(method, annotations);
                    annotations.addAnnotation(method.getAnnotation(QueryType.class));
                    annotations.addAnnotation(method.getAnnotation(QueryInit.class));
                    propertyTypes.put(name, method.getReturnType());
                    TypeMirror fixedType = configuration.getRealType(method);
                    if (fixedType != null) {
                        fixedTypes.put(name, fixedType);
                    }
                }
            }
        }

        // fixed types override property types
        propertyTypes.putAll(fixedTypes);
        for (Map.Entry<String, Annotations> entry : propertyAnnotations.entrySet()) {
            Property property = toProperty(entityType, entry.getKey(), propertyTypes.get(entry.getKey()), entry.getValue());
            if (property != null) {
                entityType.addProperty(property);
            }
        }

        return entityType;
    }
{@code TypeElementHandler} is an APT visitor for entity types

@author tiwe
querydsl-apt/src/main/java/com/querydsl/apt/TypeElementHandler.java