public boolean overrides(MethodDeclaration sub, MethodDeclaration sup) {
        MethodSymbol overrider = ((MethodDeclarationImpl) sub).sym;
        MethodSymbol overridee = ((MethodDeclarationImpl) sup).sym;
        ClassSymbol origin = (ClassSymbol) overrider.owner;

        return overrider.name == overridee.name &&

               // not reflexive as per JLS
               overrider != overridee &&

               // we don't care if overridee is static, though that wouldn't
               // compile
               !overrider.isStatic() &&

               // overrider, whose declaring type is the origin, must be
               // in a subtype of overridee's type
               env.jctypes.asSuper(origin.type, overridee.owner) != null &&

               // check access and signatures; don't check return types
               overrider.overrides(overridee, origin, env.jctypes, false);
    }