void writeClass(String ctSymLocation,
                    ClassDescription classDescription,
                    ClassHeaderDescription header,
                    String version) throws IOException {
        List<CPInfo> constantPool = new ArrayList<>();
        constantPool.add(null);
        List<Method> methods = new ArrayList<>();
        for (MethodDescription methDesc : classDescription.methods) {
            if (disjoint(methDesc.versions, version))
                continue;
            Descriptor descriptor = new Descriptor(addString(constantPool, methDesc.descriptor));
            //TODO: LinkedHashMap to avoid param annotations vs. Signature problem in javac's ClassReader:
            Map<String, Attribute> attributesMap = new LinkedHashMap<>();
            addAttributes(methDesc, constantPool, attributesMap);
            Attributes attributes = new Attributes(attributesMap);
            AccessFlags flags = new AccessFlags(methDesc.flags);
            int nameString = addString(constantPool, methDesc.name);
            methods.add(new Method(flags, nameString, descriptor, attributes));
        }
        List<Field> fields = new ArrayList<>();
        for (FieldDescription fieldDesc : classDescription.fields) {
            if (disjoint(fieldDesc.versions, version))
                continue;
            Descriptor descriptor = new Descriptor(addString(constantPool, fieldDesc.descriptor));
            Map<String, Attribute> attributesMap = new HashMap<>();
            addAttributes(fieldDesc, constantPool, attributesMap);
            Attributes attributes = new Attributes(attributesMap);
            AccessFlags flags = new AccessFlags(fieldDesc.flags);
            int nameString = addString(constantPool, fieldDesc.name);
            fields.add(new Field(flags, nameString, descriptor, attributes));
        }
        int currentClass = addClass(constantPool, classDescription.name);
        int superclass = header.extendsAttr != null ? addClass(constantPool, header.extendsAttr) : 0;
        int[] interfaces = new int[header.implementsAttr.size()];
        int i = 0;
        for (String intf : header.implementsAttr) {
            interfaces[i++] = addClass(constantPool, intf);
        }
        AccessFlags flags = new AccessFlags(header.flags);
        Map<String, Attribute> attributesMap = new HashMap<>();
        addAttributes(header, constantPool, attributesMap);
        Attributes attributes = new Attributes(attributesMap);
        ConstantPool cp = new ConstantPool(constantPool.toArray(new CPInfo[constantPool.size()]));
        ClassFile classFile = new ClassFile(0xCAFEBABE,
                Target.DEFAULT.minorVersion,
                Target.DEFAULT.majorVersion,
                cp,
                flags,
                currentClass,
                superclass,
                interfaces,
                fields.toArray(new Field[0]),
                methods.toArray(new Method[0]),
                attributes);

        Path outputClassFile = Paths.get(ctSymLocation, version, classDescription.name + EXTENSION);

        Files.createDirectories(outputClassFile.getParent());

        try (OutputStream out = Files.newOutputStream(outputClassFile)) {
            ClassWriter w = new ClassWriter();

            w.write(classFile, out);
        }
    }
void writeClass ( String ctSymLocation , ClassDescription classDescription , ClassHeaderDescription header , String version ) throws IOException { List < CPInfo > constantPool = new ArrayList < > ( ) ; constantPool . add ( null ) ; List < Method > methods = new ArrayList < > ( ) ; for ( MethodDescription methDesc : classDescription . methods ) { if ( disjoint ( methDesc . versions , version ) ) continue ; Descriptor descriptor = new Descriptor ( addString ( constantPool , methDesc . descriptor ) ) ; Map < String , Attribute > attributesMap = new LinkedHashMap < > ( ) ; addAttributes ( methDesc , constantPool , attributesMap ) ; Attributes attributes = new Attributes ( attributesMap ) ; AccessFlags flags = new AccessFlags ( methDesc . flags ) ; int nameString = addString ( constantPool , methDesc . name ) ; methods . add ( new Method ( flags , nameString , descriptor , attributes ) ) ; } List < Field > fields = new ArrayList < > ( ) ; for ( FieldDescription fieldDesc : classDescription . fields ) { if ( disjoint ( fieldDesc . versions , version ) ) continue ; Descriptor descriptor = new Descriptor ( addString ( constantPool , fieldDesc . descriptor ) ) ; Map < String , Attribute > attributesMap = new HashMap < > ( ) ; addAttributes ( fieldDesc , constantPool , attributesMap ) ; Attributes attributes = new Attributes ( attributesMap ) ; AccessFlags flags = new AccessFlags ( fieldDesc . flags ) ; int nameString = addString ( constantPool , fieldDesc . name ) ; fields . add ( new Field ( flags , nameString , descriptor , attributes ) ) ; } int currentClass = addClass ( constantPool , classDescription . name ) ; int superclass = header . extendsAttr != null ? addClass ( constantPool , header . extendsAttr ) : 0 ; int [ ] interfaces = new int [ header . implementsAttr . size ( ) ] ; int i = 0 ; for ( String intf : header . implementsAttr ) { interfaces [ i ++ ] = addClass ( constantPool , intf ) ; } AccessFlags flags = new AccessFlags ( header . flags ) ; Map < String , Attribute > attributesMap = new HashMap < > ( ) ; addAttributes ( header , constantPool , attributesMap ) ; Attributes attributes = new Attributes ( attributesMap ) ; ConstantPool cp = new ConstantPool ( constantPool . toArray ( new CPInfo [ constantPool . size ( ) ] ) ) ; ClassFile classFile = new ClassFile ( 0xCAFEBABE , Target . DEFAULT . minorVersion , Target . DEFAULT . majorVersion , cp , flags , currentClass , superclass , interfaces , fields . toArray ( new Field [ 0 ] ) , methods . toArray ( new Method [ 0 ] ) , attributes ) ; Path outputClassFile = Paths . get ( ctSymLocation , version , classDescription . name + EXTENSION ) ; Files . createDirectories ( outputClassFile . getParent ( ) ) ; try ( OutputStream out = Files . newOutputStream ( outputClassFile ) ) { ClassWriter w = new ClassWriter ( ) ; w . write ( classFile , out ) ; } }
<editor-fold defaultstate="collapsed" desc="Class Writing">