private boolean modifyClassfile(CtClass clazz, CtClass metaobject,
                                    CtClass metaclass)
        throws CannotCompileException, NotFoundException
    {
        if (clazz.getAttribute("Reflective") != null)
            return false;       // this is already reflective.
        else
            clazz.setAttribute("Reflective", new byte[0]);

        CtClass mlevel = classPool.get("javassist.tools.reflect.Metalevel");
        boolean addMeta = !clazz.subtypeOf(mlevel);
        if (addMeta)
            clazz.addInterface(mlevel);

        processMethods(clazz, addMeta);
        processFields(clazz);

        CtField f;
        if (addMeta) {
            f = new CtField(classPool.get("javassist.tools.reflect.Metaobject"),
                            metaobjectField, clazz);
            f.setModifiers(Modifier.PROTECTED);
            clazz.addField(f, CtField.Initializer.byNewWithParams(metaobject));

            clazz.addMethod(CtNewMethod.getter(metaobjectGetter, f));
            clazz.addMethod(CtNewMethod.setter(metaobjectSetter, f));
        }

        f = new CtField(classPool.get("javassist.tools.reflect.ClassMetaobject"),
                        classobjectField, clazz);
        f.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
        clazz.addField(f, CtField.Initializer.byNew(metaclass,
                                        new String[] { clazz.getName() }));

        clazz.addMethod(CtNewMethod.getter(classobjectAccessor, f));
        return true;
    }