private Type createClassType(DeclaredType declaredType, TypeElement typeElement, boolean deep) {
        // other
        String name = typeElement.getQualifiedName().toString();

        if (name.startsWith("java.")) {
            Iterator<? extends TypeMirror> i = declaredType.getTypeArguments().iterator();

            if (isAssignable(declaredType, mapType)) {
                return createMapType(i, deep);

            } else if (isAssignable(declaredType, listType)) {
                return createCollectionType(Types.LIST, i, deep);

            } else if (isAssignable(declaredType, setType)) {
                return createCollectionType(Types.SET, i, deep);

            } else if (isAssignable(declaredType, collectionType)) {
                return createCollectionType(Types.COLLECTION, i, deep);
            }
        }

        TypeCategory typeCategory = TypeCategory.get(name);

        if (typeCategory != TypeCategory.NUMERIC
                && isAssignable(typeElement.asType(), comparableType)
                && isSubType(typeElement.asType(), numberType)) {
            typeCategory = TypeCategory.NUMERIC;

        } else if (!typeCategory.isSubCategoryOf(TypeCategory.COMPARABLE)
                && isAssignable(typeElement.asType(), comparableType)) {
            typeCategory = TypeCategory.COMPARABLE;

        } else if (typeCategory == TypeCategory.SIMPLE) {
            for (Class<? extends Annotation> entityAnn : entityAnnotations) {
                if (typeElement.getAnnotation(entityAnn) != null) {
                    typeCategory = TypeCategory.ENTITY;
                }
            }
        }

        List<? extends TypeMirror> arguments = declaredType.getTypeArguments();

        // for intersection types etc
        if (name.equals("")) {
            TypeMirror type = objectType;
            if (typeCategory == TypeCategory.COMPARABLE) {
                type = comparableType;
            }
            // find most specific type of superTypes which is a subtype of type
            List<? extends TypeMirror> superTypes = env.getTypeUtils().directSupertypes(declaredType);
            for (TypeMirror superType : superTypes) {
                if (env.getTypeUtils().isSubtype(superType, type)) {
                    type = superType;
                }
            }
            typeElement = (TypeElement) env.getTypeUtils().asElement(type);
            if (type instanceof DeclaredType) {
                arguments = ((DeclaredType) type).getTypeArguments();
            }
        }

        Type type = createType(typeElement, typeCategory, arguments, deep);

        TypeMirror superType = typeElement.getSuperclass();
        TypeElement superTypeElement = null;
        if (superType instanceof DeclaredType) {
            superTypeElement = (TypeElement) ((DeclaredType) superType).asElement();
        }

        // entity type
        for (Class<? extends Annotation> entityAnn : entityAnnotations) {
            if (typeElement.getAnnotation(entityAnn) != null ||
                    (superTypeElement != null && superTypeElement.getAnnotation(entityAnn) != null)) {
                EntityType entityType = new EntityType(type, variableNameFunction);
                typeMappings.register(entityType, queryTypeFactory.create(entityType));
                return entityType;
            }
        }
        return type;
    }
private Type createClassType ( DeclaredType declaredType , TypeElement typeElement , boolean deep ) { String name = typeElement . getQualifiedName ( ) . toString ( ) ; if ( name . startsWith ( "java." ) ) { Iterator < ? extends TypeMirror > i = declaredType . getTypeArguments ( ) . iterator ( ) ; if ( isAssignable ( declaredType , mapType ) ) { return createMapType ( i , deep ) ; } else if ( isAssignable ( declaredType , listType ) ) { return createCollectionType ( Types . LIST , i , deep ) ; } else if ( isAssignable ( declaredType , setType ) ) { return createCollectionType ( Types . SET , i , deep ) ; } else if ( isAssignable ( declaredType , collectionType ) ) { return createCollectionType ( Types . COLLECTION , i , deep ) ; } } TypeCategory typeCategory = TypeCategory . get ( name ) ; if ( typeCategory != TypeCategory . NUMERIC && isAssignable ( typeElement . asType ( ) , comparableType ) && isSubType ( typeElement . asType ( ) , numberType ) ) { typeCategory = TypeCategory . NUMERIC ; } else if ( ! typeCategory . isSubCategoryOf ( TypeCategory . COMPARABLE ) && isAssignable ( typeElement . asType ( ) , comparableType ) ) { typeCategory = TypeCategory . COMPARABLE ; } else if ( typeCategory == TypeCategory . SIMPLE ) { for ( Class < ? extends Annotation > entityAnn : entityAnnotations ) { if ( typeElement . getAnnotation ( entityAnn ) != null ) { typeCategory = TypeCategory . ENTITY ; } } } List < ? extends TypeMirror > arguments = declaredType . getTypeArguments ( ) ; if ( name . equals ( "" ) ) { TypeMirror type = objectType ; if ( typeCategory == TypeCategory . COMPARABLE ) { type = comparableType ; } List < ? extends TypeMirror > superTypes = env . getTypeUtils ( ) . directSupertypes ( declaredType ) ; for ( TypeMirror superType : superTypes ) { if ( env . getTypeUtils ( ) . isSubtype ( superType , type ) ) { type = superType ; } } typeElement = ( TypeElement ) env . getTypeUtils ( ) . asElement ( type ) ; if ( type instanceof DeclaredType ) { arguments = ( ( DeclaredType ) type ) . getTypeArguments ( ) ; } } Type type = createType ( typeElement , typeCategory , arguments , deep ) ; TypeMirror superType = typeElement . getSuperclass ( ) ; TypeElement superTypeElement = null ; if ( superType instanceof DeclaredType ) { superTypeElement = ( TypeElement ) ( ( DeclaredType ) superType ) . asElement ( ) ; } for ( Class < ? extends Annotation > entityAnn : entityAnnotations ) { if ( typeElement . getAnnotation ( entityAnn ) != null || ( superTypeElement != null && superTypeElement . getAnnotation ( entityAnn ) != null ) ) { EntityType entityType = new EntityType ( type , variableNameFunction ) ; typeMappings . register ( entityType , queryTypeFactory . create ( entityType ) ) ; return entityType ; } } return type ; }
TODO : simplify