private void exportAnnotationSources(File outputDir, AnnotationType annType, NewDocumentType docType, String packageName) {
        File dirForSources = new File(outputDir, packageName.replaceAll("\\.", "/")+"/annotation/");
        dirForSources.mkdirs();
        String className = className(annType.getName());
        File target = new File(dirForSources, className+".java");
        if (target.lastModified() > newestModifiedTime) {
            getLog().debug("No changes, not updating "+target);
            return;
        }
        try (Writer out = new FileWriter(target)) {
                out.write("package "+packageName+".annotation;\n\n" +
                    "import "+packageName+".ConcreteDocumentFactory;\n" +
                    exportInnerImportsFromDocAndSuperTypes(docType, packageName) +
                    exportImportProvidedAnnotationRefs(annType) +
                    "/**\n" +
                    " *  Generated by vespa-documentgen-plugin, do not edit.\n" +
                    " *  Input annotation type: "+annType.getName()+"\n" +
                    " *  Date: "+new Date()+"\n" +
                    " */\n" +
                    "@com.yahoo.document.Generated\n" +
                    "public "+annTypeModifier(annType)+"class "+className+" extends "+getParentAnnotationType(annType)+" {\n\n");
            if (annType.getDataType() instanceof StructDataType) {
                out.write(ind() + "public "+className+"() {\n" +
                    ind(2) + "setType(new com.yahoo.document.annotation.AnnotationType(\""+annType.getName()+"\", Fields.type));\n" +
                    ind()+"}\n\n");
                StructDataType annStruct = (StructDataType)annType.getDataType();
                StructDataType annStructTmp = new StructDataType("fields"); // Change the type name
                annStructTmp.assign(annStruct);
                Collection<DataType> tmpList = new ArrayList<>();
                tmpList.add(annStructTmp);
                exportStructTypes(tmpList, out, 1, null);
                exportFieldsAndAccessors(className, annStruct.getFieldsThisTypeOnly(), out, 1, false);
                out.write(ind()+"@Override public boolean hasFieldValue() { return true; }\n\n");
                out.write(ind()+"@Override public com.yahoo.document.datatypes.FieldValue getFieldValue() {\n");
                out.write(ind(2)+"com.yahoo.document.datatypes.Struct ret = new Fields();\n");

                for (Field f : annStruct.getFields()) {
                    out.write(
                            ind(2)+"if ("+getter(f.getName()) +"()!=null) {\n" +
                            ind(3)+"com.yahoo.document.Field f = ret.getField(\"" + f.getName() + "\");\n" +
                            ind(3)+"com.yahoo.document.datatypes.FieldValue fv = f.getDataType().createFieldValue(" + getter(f.getName()) + "());\n" +
                            ind(3)+"ret.setFieldValue(f, fv);\n" +
                            ind(2)+"}\n");
                }
                out.write(ind(2)+"return ret;\n");
                out.write(ind()+"}\n\n");

            } else {
                out.write(ind() + "public "+className+"() { setType(new com.yahoo.document.annotation.AnnotationType(\""+annType.getName()+"\")); } \n\n");
                out.write(ind()+"@Override public boolean hasFieldValue() { return false; }\n\n");
                out.write(ind()+"@Override public com.yahoo.document.datatypes.FieldValue getFieldValue() { return null; }\n\n");
            }
            out.write("}\n");
            annotationTypes.put(annType.getName(), packageName+".annotation."+className);
        } catch (IOException e) {
            throw new RuntimeException("Could not export sources for annotation type '"+annType.getName()+"'", e);
        }
    }
\n" +
                    ind()+" * Returns a new Annotation which will be of the correct concrete type.\n" +
                    ind()+"
vespa-documentgen-plugin/src/main/java/com/yahoo/vespa/DocumentGenMojo.java