public static @CheckForNull LocalVariableAnnotation findUniqueBestMatchingParameter(
     ClassContext classContext, Method method, String name, String signature) {
   LocalVariableAnnotation match = null;
   int localsThatAreParameters = PreorderVisitor.getNumberArguments(method.getSignature());
   int startIndex = 0;
   if (!method.isStatic()) startIndex = 1;
   SignatureParser parser = new SignatureParser(method.getSignature());
   Iterator<String> signatureIterator = parser.parameterSignatureIterator();
   int lowestCost = Integer.MAX_VALUE;
   for (int i = startIndex; i < localsThatAreParameters + startIndex; i++) {
     String sig = signatureIterator.next();
     if (signature.equals(sig)) {
       LocalVariableAnnotation potentialMatch =
           LocalVariableAnnotation.getLocalVariableAnnotation(method, i, 0, 0);
       if (!potentialMatch.isNamed()) continue;
       int distance = EditDistance.editDistance(name, potentialMatch.getName());
       if (distance < lowestCost) {
         match = potentialMatch;
         match.setDescription(DID_YOU_MEAN_ROLE);
         lowestCost = distance;
       } else if (distance == lowestCost) {
         // not unique best match
         match = null;
       }
       // signatures match
     }
   }
   if (lowestCost < 5) return match;
   return null;
 }
  public static @CheckForNull LocalVariableAnnotation findMatchingIgnoredParameter(
      ClassContext classContext, Method method, String name, String signature) {
    try {
      Dataflow<BitSet, LiveLocalStoreAnalysis> llsaDataflow =
          classContext.getLiveLocalStoreDataflow(method);
      CFG cfg;

      cfg = classContext.getCFG(method);
      LocalVariableAnnotation match = null;
      int lowestCost = Integer.MAX_VALUE;
      BitSet liveStoreSetAtEntry = llsaDataflow.getAnalysis().getResultFact(cfg.getEntry());
      int localsThatAreParameters = PreorderVisitor.getNumberArguments(method.getSignature());
      int startIndex = 0;
      if (!method.isStatic()) startIndex = 1;
      SignatureParser parser = new SignatureParser(method.getSignature());
      Iterator<String> signatureIterator = parser.parameterSignatureIterator();
      for (int i = startIndex; i < localsThatAreParameters + startIndex; i++) {
        String sig = signatureIterator.next();
        if (!liveStoreSetAtEntry.get(i) && signature.equals(sig)) {
          // parameter isn't live and signatures match
          LocalVariableAnnotation potentialMatch =
              LocalVariableAnnotation.getLocalVariableAnnotation(method, i, 0, 0);
          potentialMatch.setDescription(DID_YOU_MEAN_ROLE);
          if (!potentialMatch.isNamed()) return potentialMatch;
          int distance = EditDistance.editDistance(name, potentialMatch.getName());
          if (distance < lowestCost) {
            match = potentialMatch;
            match.setDescription(DID_YOU_MEAN_ROLE);
            lowestCost = distance;
          } else if (distance == lowestCost) {
            // not unique best match
            match = null;
          }
        }
      }
      return match;
    } catch (DataflowAnalysisException e) {
      AnalysisContext.logError("", e);
    } catch (CFGBuilderException e) {
      AnalysisContext.logError("", e);
    }
    return null;
  }
  public void visitClassContext(ClassContext classContext) {

    JavaClass jclass = classContext.getJavaClass();

    for (Method method : jclass.getMethods()) {
      XMethod xmethod = XFactory.createXMethod(classContext.getJavaClass(), method);
      ParameterProperty nonnullParameters =
          AnalysisContext.currentAnalysisContext()
              .getUnconditionalDerefParamDatabase()
              .getProperty(xmethod.getMethodDescriptor());
      if (nonnullParameters != null) {
        for (int p : nonnullParameters.iterable()) {
          TypeQualifierAnnotation directTypeQualifierAnnotation =
              TypeQualifierApplications.getDirectTypeQualifierAnnotation(
                  xmethod, p, nonnullTypeQualifierValue);
          if (directTypeQualifierAnnotation != null
              && directTypeQualifierAnnotation.when == When.UNKNOWN) {
            //
            // The LocalVariableAnnotation is constructed using the local variable
            // number of the parameter, not the parameter number.
            //
            int paramLocal = xmethod.isStatic() ? p : p + 1;

            reporter.reportBug(
                new BugInstance(
                        this,
                        "NP_PARAMETER_MUST_BE_NONNULL_BUT_MARKED_AS_NULLABLE",
                        NORMAL_PRIORITY)
                    .addClassAndMethod(jclass, method)
                    .add(
                        LocalVariableAnnotation.getParameterLocalVariableAnnotation(
                            method, paramLocal)));
          }
        }
      }
    }
  }