@CheckForNull
  @Override
  public NullnessAnnotation getResolvedAnnotation(final Object o, boolean getMinimal) {

    Profiler profiler = Global.getAnalysisCache().getProfiler();
    profiler.start(this.getClass());
    try {
      if (o instanceof XMethodParameter) {
        XMethodParameter mp = (XMethodParameter) o;
        XMethod m = mp.getMethod();
        // TODO: Handle argument to equals specially: generate special
        // bug code for it
        int parameterNumber = mp.getParameterNumber();
        if (parameterNumber == 0) {
          if (m.getName().equals("equals")
              && m.getSignature().equals("(Ljava/lang/Object;)Z")
              && !m.isStatic()) return NullnessAnnotation.CHECK_FOR_NULL;
          else if (m.getName().equals("main")
              && m.getSignature().equals("([Ljava/lang/String;)V")
              && m.isStatic()
              && m.isPublic()) return NullnessAnnotation.NONNULL;
          else if (assertsFirstParameterIsNonnull(m)) return NullnessAnnotation.NONNULL;
          else if (m.getName().equals("compareTo")
              && m.getSignature().endsWith(";)Z")
              && !m.isStatic()) return NullnessAnnotation.NONNULL;
        }
      } else if (o instanceof XMethod) {
        XMethod m = (XMethod) o;
        String name = m.getName();
        String signature = m.getSignature();
        if (!m.isStatic()
            && (name.equals("clone") && signature.equals("()Ljava/lang/Object;")
                || name.equals("toString") && signature.equals("()Ljava/lang/String;")
                || m.isPrivate()
                    && name.equals("readResolve")
                    && signature.equals("()Ljava/lang/Object;"))) {
          NullnessAnnotation result = super.getDirectAnnotation(m);
          if (result != null) return result;
          return NullnessAnnotation.NONNULL;
        }

      } else if (o instanceof XField) {
        XField f = (XField) o;
        if (f.getName().startsWith("this$")) return NullnessAnnotation.NONNULL;
      }
      NullnessAnnotation result = super.getResolvedAnnotation(o, getMinimal);
      return result;
    } finally {
      profiler.end(this.getClass());
    }
  }
  public boolean parameterMustBeNonNull(XMethod m, int param) {
    if (param == 0) {
      if (m.getName().equals("equals")
          && m.getSignature().equals("(Ljava/lang/Object;)Z")
          && !m.isStatic()) return false;
      else if (m.getName().equals("main")
          && m.getSignature().equals("([Ljava/lang/String;)V")
          && m.isStatic()
          && m.isPublic()) return true;
      else if (assertsFirstParameterIsNonnull(m)) return true;
      else if (m.getName().equals("compareTo") && m.getSignature().endsWith(";)Z") && !m.isStatic())
        return true;
    }
    if (!anyAnnotations(NullnessAnnotation.NONNULL)) return false;
    XMethodParameter xmp = new XMethodParameter(m, param);
    NullnessAnnotation resolvedAnnotation = getResolvedAnnotation(xmp, true);

    return resolvedAnnotation == NullnessAnnotation.NONNULL;
  }
  /**
   * Constructor.
   *
   * @param method an XMethod specifying a specific method in a specific class
   * @throws ClassNotFoundException
   */
  public JavaClassAndMethod(XMethod method) throws ClassNotFoundException {

    this.javaClass = Repository.lookupClass(method.getClassName());
    for (Method m : javaClass.getMethods())
      if (m.getName().equals(method.getName())
          && m.getSignature().equals(method.getSignature())
          && m.isStatic() == method.isStatic()) {
        this.method = m;
        return;
      }
    throw new IllegalArgumentException("Can't find " + method);
  }
 public boolean choose(XMethod method) {
   return !method.isStatic();
 }