docs: @Override
      public int compare(BugInstance lhs, BugInstance rhs) {
          // Attributes of BugInstance.
          // Compare abbreviation
          // Compare class and method annotations (ignoring line numbers).
          // Compare field annotations.
  
          int cmp;
  
          BugPattern lhsPattern = lhs.getBugPattern();
          BugPattern rhsPattern = rhs.getBugPattern();
  
          // Compare by abbrev instead of type. The specific bug type can
          // change
          // (e.g., "definitely null" to "null on simple path"). Also, we
          // often
          // change bug pattern types from one version of FindBugs to the
          // next.
          //
          // Source line and field name are still matched precisely, so this
          // shouldn't
          // cause loss of precision.
          if ((cmp = lhsPattern.getAbbrev().compareTo(rhsPattern.getAbbrev())) != 0) {
              return cmp;
          }
          if (isExactBugPatternMatch() && (cmp = lhsPattern.getType().compareTo(rhsPattern.getType())) != 0) {
              return cmp;
          }
  
          if (comparePriorities) {
              cmp = lhs.getPriority() - rhs.getPriority();
              if (cmp != 0) {
                  return cmp;
              }
          }
  
          Iterator<BugAnnotation> lhsIter = new FilteringAnnotationIterator(lhs.annotationIterator());
          Iterator<BugAnnotation> rhsIter = new FilteringAnnotationIterator(rhs.annotationIterator());
  
          while (lhsIter.hasNext() && rhsIter.hasNext()) {
              BugAnnotation lhsAnnotation = lhsIter.next();
              BugAnnotation rhsAnnotation = rhsIter.next();
              Class<? extends BugAnnotation> lhsClass;
              while (true) {
                  // Different annotation types obviously cannot be equal,
                  // so just compare by class name.
                  lhsClass = lhsAnnotation.getClass();
                  Class<? extends BugAnnotation> rhsClass = rhsAnnotation.getClass();
                  if (lhsClass == rhsClass) {
                      break;
                  }
                  if (lhsClass == LocalVariableAnnotation.class && !((LocalVariableAnnotation) lhsAnnotation).isSignificant()
                          && lhsIter.hasNext()) {
                      lhsAnnotation = lhsIter.next();
                  } else if (rhsClass == LocalVariableAnnotation.class && !((LocalVariableAnnotation) rhsAnnotation).isSignificant()
                          && rhsIter.hasNext()) {
                      rhsAnnotation = rhsIter.next();
                  } else {
                      return lhsClass.getName().compareTo(rhsClass.getName());
                  }
              }
  
              if (lhsClass == ClassAnnotation.class) {
                  // ClassAnnotations should have their class names rewritten to
                  // handle moved and renamed classes.
  
                  String lhsClassName = classNameRewriter.rewriteClassName(((ClassAnnotation) lhsAnnotation).getClassName());
                  String rhsClassName = classNameRewriter.rewriteClassName(((ClassAnnotation) rhsAnnotation).getClassName());
  
                  cmp = lhsClassName.compareTo(rhsClassName);
  
              } else if (lhsClass == MethodAnnotation.class) {
                  // Rewrite class names in MethodAnnotations
                  MethodAnnotation lhsMethod = ClassNameRewriterUtil.convertMethodAnnotation(classNameRewriter,
                          (MethodAnnotation) lhsAnnotation);
                  MethodAnnotation rhsMethod = ClassNameRewriterUtil.convertMethodAnnotation(classNameRewriter,
                          (MethodAnnotation) rhsAnnotation);
                  cmp = lhsMethod.compareTo(rhsMethod);
  
              } else if (lhsClass == FieldAnnotation.class) {
                  // Rewrite class names in FieldAnnotations
                  FieldAnnotation lhsField = ClassNameRewriterUtil.convertFieldAnnotation(classNameRewriter,
                          (FieldAnnotation) lhsAnnotation);
                  FieldAnnotation rhsField = ClassNameRewriterUtil.convertFieldAnnotation(classNameRewriter,
                          (FieldAnnotation) rhsAnnotation);
                  cmp = lhsField.compareTo(rhsField);
  
              } else if (lhsClass == StringAnnotation.class) {
                  String lhsString = ((StringAnnotation) lhsAnnotation).getValue();
                  String rhsString = ((StringAnnotation) rhsAnnotation).getValue();
                  cmp = lhsString.compareTo(rhsString);
  
              } else if (lhsClass == LocalVariableAnnotation.class) {
                  String lhsName = ((LocalVariableAnnotation) lhsAnnotation).getName();
                  String rhsName = ((LocalVariableAnnotation) rhsAnnotation).getName();
                  if ("?".equals(lhsName) || "?".equals(rhsName)) {
                      continue;
                  }
                  cmp = lhsName.compareTo(rhsName);
  
              } else if (lhsClass == TypeAnnotation.class) {
                  String lhsType = ((TypeAnnotation) lhsAnnotation).getTypeDescriptor();
                  String rhsType = ((TypeAnnotation) rhsAnnotation).getTypeDescriptor();
                  lhsType = ClassNameRewriterUtil.rewriteSignature(classNameRewriter, lhsType);
                  rhsType = ClassNameRewriterUtil.rewriteSignature(classNameRewriter, rhsType);
                  cmp = lhsType.compareTo(rhsType);
  
              } else if (lhsClass == IntAnnotation.class) {
                  int lhsValue = ((IntAnnotation) lhsAnnotation).getValue();
                  int rhsValue = ((IntAnnotation) rhsAnnotation).getValue();
                  cmp = lhsValue - rhsValue;
  
              } else if (isBoring(lhsAnnotation)) {
                  throw new IllegalStateException("Impossible");
              } else {
                  throw new IllegalStateException("Unknown annotation type: " + lhsClass.getName());
              }
              if (cmp != 0) {
                  return cmp;
              }
          }
  
          if (interestingNext(rhsIter)) {
              return -1;
          } else if (interestingNext(lhsIter)) {
              return 1;
          } else {
              return 0;
          }
      }