public @CheckForNull XMethod getXMethod(
      String cName, String mName, String sig, boolean isStatic) {
    ClassDescriptor classDesc =
        DescriptorFactory.instance().getClassDescriptorForDottedClassName(cName);
    ClassInfo xclass;

    // Get the XClass (really a ClassInfo object)
    try {
      xclass = (ClassInfo) Global.getAnalysisCache().getClassAnalysis(XClass.class, classDesc);
    } catch (MissingClassException e) {
      if (DEBUG) {
        System.out.println("  Class not found!");
      }
      //
      //	AnalysisContext.currentAnalysisContext().getLookupFailureCallback().reportMissingClass(e.getClassDescriptor());
      return null;
    } catch (CheckedAnalysisException e) {
      if (DEBUG) {
        System.out.println("  Class not found!");
      }
      //			AnalysisContext.logError("Error adding built-in nullness annotation", e);
      return null;
    }
    XMethod xmethod = xclass.findMethod(mName, sig, isStatic);

    if (xmethod == null) xmethod = XFactory.createXMethod(cName, mName, sig, isStatic);
    return xmethod;
  }
  private String findFullyQualifiedSourceFileName(IClassPath classPath, ClassDescriptor classDesc)
      throws IOException, CheckedAnalysisException {
    try {
      // Open and parse the class file to attempt
      // to discover the source file name.
      ICodeBaseEntry codeBaseEntry = classPath.lookupResource(classDesc.toResourceName());

      ClassParserUsingASM classParser =
          new ClassParserUsingASM(
              new ClassReader(codeBaseEntry.openResource()), classDesc, codeBaseEntry);

      ClassInfo.Builder classInfoBuilder = new ClassInfo.Builder();
      classParser.parse(classInfoBuilder);
      ClassInfo classInfo = classInfoBuilder.build();

      // Construct the fully-qualified source file name
      // based on the package name and source file name.
      String packageName = classDesc.getPackageName();
      String sourceFile = classInfo.getSource();

      if (!packageName.equals("")) {
        packageName = packageName.replace('.', '/');
        packageName += "/";
      }

      String fullyQualifiedSourceFile = packageName + sourceFile;

      return fullyQualifiedSourceFile;
    } catch (CheckedAnalysisException e) {
      errorLogger.logError("Could scan class " + classDesc.toDottedClassName(), e);
      throw e;
    } finally {
      progress.finishClass();
    }
  }
  /* (non-Javadoc)
   * @see edu.umd.cs.findbugs.ba.INullnessAnnotationDatabase#addDefaultAnnotation(java.lang.String, java.lang.String, edu.umd.cs.findbugs.ba.NullnessAnnotation)
   */
  public void addDefaultAnnotation(Target target, String c, NullnessAnnotation n) {
    if (DEBUG) {
      System.out.println("addDefaultAnnotation: target=" + target + ", c=" + c + ", n=" + n);
    }

    ClassDescriptor classDesc =
        DescriptorFactory.instance().getClassDescriptorForDottedClassName(c);
    ClassInfo xclass;

    // Get the XClass (really a ClassInfo object)
    try {
      xclass = (ClassInfo) Global.getAnalysisCache().getClassAnalysis(XClass.class, classDesc);
    } catch (MissingClassException e) {
      //
      //	AnalysisContext.currentAnalysisContext().getLookupFailureCallback().reportMissingClass(e.getClassDescriptor());
      return;
    } catch (CheckedAnalysisException e) {
      //			AnalysisContext.logError("Error adding built-in nullness annotation", e);
      return;
    }
    if (n == NullnessAnnotation.NONNULL && target == AnnotationDatabase.Target.PARAMETER) {
      xclass.addAnnotation(new AnnotationValue(PARAMETERS_ARE_NONNULL_BY_DEFAULT));
      return;
    } else if (n == NullnessAnnotation.NONNULL && target == AnnotationDatabase.Target.METHOD) {
      xclass.addAnnotation(new AnnotationValue(RETURN_VALUES_ARE_NONNULL_BY_DEFAULT));
      return;
    }
    // Get the default annotation type
    ClassDescriptor defaultAnnotationType;
    if (target == AnnotationDatabase.Target.ANY) {
      defaultAnnotationType = FindBugsDefaultAnnotations.DEFAULT_ANNOTATION;
    } else if (target == AnnotationDatabase.Target.FIELD) {
      defaultAnnotationType = FindBugsDefaultAnnotations.DEFAULT_ANNOTATION_FOR_FIELDS;
    } else if (target == AnnotationDatabase.Target.METHOD) {
      defaultAnnotationType = FindBugsDefaultAnnotations.DEFAULT_ANNOTATION_FOR_METHODS;
    } else if (target == AnnotationDatabase.Target.PARAMETER) {
      defaultAnnotationType = FindBugsDefaultAnnotations.DEFAULT_ANNOTATION_FOR_PARAMETERS;
    } else {
      throw new IllegalArgumentException("Unknown target for default annotation: " + target);
    }

    // Get the JSR-305 nullness annotation type
    ClassDescriptor nullnessAnnotationType = getNullnessAnnotationClassDescriptor(n);

    // Construct an AnnotationValue containing the default annotation
    AnnotationValue annotationValue = new AnnotationValue(defaultAnnotationType);
    AnnotationVisitor v = annotationValue.getAnnotationVisitor();
    v.visit("value", Type.getObjectType(nullnessAnnotationType.getClassName()));
    v.visitEnd();

    if (DEBUG) {
      System.out.println("Adding AnnotationValue " + annotationValue + " to class " + xclass);
    }

    // Destructively add the annotation to the ClassInfo object
    xclass.addAnnotation(annotationValue);
  }