protected ClassVisitor createClassVisitor() {
    CompilerConfiguration config = getConfiguration();
    int computeMaxStackAndFrames = ClassWriter.COMPUTE_MAXS;
    if (CompilerConfiguration.isPostJDK7(config.getTargetBytecode())
        || Boolean.TRUE.equals(config.getOptimizationOptions().get("indy"))) {
      computeMaxStackAndFrames += ClassWriter.COMPUTE_FRAMES;
    }
    return new ClassWriter(computeMaxStackAndFrames) {
      private ClassNode getClassNode(String name) {
        // try classes under compilation
        CompileUnit cu = getAST();
        ClassNode cn = cu.getClass(name);
        if (cn != null) return cn;
        // try inner classes
        cn = cu.getGeneratedInnerClass(name);
        if (cn != null) return cn;
        // try class loader classes
        try {
          cn = ClassHelper.make(cu.getClassLoader().loadClass(name, false, true), false);
        } catch (Exception e) {
          throw new GroovyBugError(e);
        }
        return cn;
      }

      private ClassNode getCommonSuperClassNode(ClassNode c, ClassNode d) {
        // adapted from ClassWriter code
        if (c.isDerivedFrom(d)) return d;
        if (d.isDerivedFrom(c)) return c;
        if (c.isInterface() || d.isInterface()) return ClassHelper.OBJECT_TYPE;
        do {
          c = c.getSuperClass();
        } while (c != null && !d.isDerivedFrom(c));
        if (c == null) return ClassHelper.OBJECT_TYPE;
        return c;
      }

      @Override
      protected String getCommonSuperClass(String arg1, String arg2) {
        ClassNode a = getClassNode(arg1.replace('/', '.'));
        ClassNode b = getClassNode(arg2.replace('/', '.'));
        return getCommonSuperClassNode(a, b).getName().replace('.', '/');
      }
    };
  }