/**
   * overrides the visitor to find abstract methods that override concrete ones
   *
   * @param obj the context object of the currently parsed method
   */
  @Override
  public void visitMethod(Method obj) {
    if (!obj.isAbstract()) return;

    String methodName = obj.getName();
    String methodSig = obj.getSignature();
    outer:
    for (JavaClass cls : superClasses) {
      Method[] methods = cls.getMethods();
      for (Method m : methods) {
        if (m.isPrivate() || m.isAbstract()) continue;
        if (methodName.equals(m.getName()) && methodSig.equals(m.getSignature())) {
          BugInstance bug =
              new BugInstance(this, BugType.AOM_ABSTRACT_OVERRIDDEN_METHOD.name(), NORMAL_PRIORITY)
                  .addClass(this)
                  .addMethod(this);

          Code code = obj.getCode();
          if (code != null) bug.addSourceLineRange(clsContext, this, 0, code.getLength() - 1);
          bugReporter.reportBug(bug);

          break outer;
        }
      }
    }
  }
 /**
  * Filters the methods to be transformed.
  *
  * @param definition the definition
  * @param classMetaData the class meta-data
  * @param method the method to filter
  * @return boolean
  */
 private boolean methodFilter(
     final AspectWerkzDefinition definition,
     final ClassMetaData classMetaData,
     final MethodMetaData methodMetaData,
     final Method method) {
   if (method.isAbstract()
       || method.isNative()
       || method.getName().equals("<init>")
       || method.getName().equals("<clinit>")
       || method.getName().startsWith(TransformationUtil.ORIGINAL_METHOD_PREFIX)
       || method.getName().equals(TransformationUtil.GET_META_DATA_METHOD)
       || method.getName().equals(TransformationUtil.SET_META_DATA_METHOD)
       || method.getName().equals(TransformationUtil.CLASS_LOOKUP_METHOD)
       || method.getName().equals(TransformationUtil.GET_UUID_METHOD)) {
     return true;
   } else if (definition.hasExecutionPointcut(classMetaData, methodMetaData)) {
     return false;
   } else if (definition.hasThrowsPointcut(classMetaData, methodMetaData)) {
     return false;
   } else {
     return true;
   }
 }