public static Set<ValueNumber> checkNonNullParams(
      Location location,
      ValueNumberFrame vnaFrame,
      ConstantPoolGen constantPool,
      @CheckForNull Method method,
      @CheckForNull IsNullValueFrame invFrame)
      throws DataflowAnalysisException {

    if (invFrame != null && !invFrame.isValid()) {
      return Collections.emptySet();
    }
    INullnessAnnotationDatabase database =
        AnalysisContext.currentAnalysisContext().getNullnessAnnotationDatabase();

    InvokeInstruction inv = (InvokeInstruction) location.getHandle().getInstruction();
    XMethod called = XFactory.createXMethod(inv, constantPool);
    SignatureParser sigParser = new SignatureParser(called.getSignature());
    int numParams = sigParser.getNumParameters();

    Set<ValueNumber> result = new HashSet<ValueNumber>();
    Iterator<String> parameterIterator = sigParser.parameterSignatureIterator();
    for (int i = 0; i < numParams; i++) {
      String parameterSignature = parameterIterator.next();
      char firstChar = parameterSignature.charAt(0);
      if (firstChar != 'L' && firstChar != '[') {
        continue;
      }
      int offset = sigParser.getSlotsFromTopOfStackForParameter(i);
      if (invFrame != null) {
        int slot = invFrame.getStackLocation(offset);
        if (!reportDereference(invFrame, slot)) {
          continue;
        }
      }
      if (database.parameterMustBeNonNull(called, i)) {
        int catchSizeNPE =
            Util.getSizeOfSurroundingTryBlock(
                method, "java/lang/NullPointerException", location.getHandle().getPosition());
        int catchSizeNFE =
            Util.getSizeOfSurroundingTryBlock(
                method, "java/lang/NumberFormatException", location.getHandle().getPosition());
        if (catchSizeNPE == Integer.MAX_VALUE
            && (!"java.lang.Integer".equals(called.getClassName())
                || catchSizeNFE == Integer.MAX_VALUE)) {
          // Get the corresponding value number
          ValueNumber vn = vnaFrame.getArgument(inv, constantPool, i, sigParser);
          result.add(vn);
        }
      }
    }
    return result;
  }
  public static Set<ValueNumber> checkUnconditionalDerefDatabase(
      Location location,
      ValueNumberFrame vnaFrame,
      ConstantPoolGen constantPool,
      @CheckForNull IsNullValueFrame invFrame,
      TypeDataflow typeDataflow)
      throws DataflowAnalysisException {
    if (invFrame != null && !invFrame.isValid()) {
      return Collections.emptySet();
    }

    InvokeInstruction inv = (InvokeInstruction) location.getHandle().getInstruction();

    SignatureParser sigParser = new SignatureParser(inv.getSignature(constantPool));
    int numParams = sigParser.getNumParameters();
    if (numParams == 0 || !sigParser.hasReferenceParameters()) {
      return Collections.emptySet();
    }
    ParameterNullnessPropertyDatabase database =
        AnalysisContext.currentAnalysisContext().getUnconditionalDerefParamDatabase();
    if (database == null) {
      if (DEBUG_CHECK_CALLS) {
        System.out.println("no database!");
      }
      return Collections.emptySet();
    }

    TypeFrame typeFrame = typeDataflow.getFactAtLocation(location);
    if (!typeFrame.isValid()) {
      if (DEBUG_CHECK_CALLS) {
        System.out.println("invalid type frame!");
      }
      return Collections.emptySet();
    }

    try {
      Set<XMethod> targetSet = Hierarchy2.resolveMethodCallTargets(inv, typeFrame, constantPool);

      if (targetSet.isEmpty()) {
        return Collections.emptySet();
      }

      if (DEBUG_CHECK_CALLS) {
        System.out.println("target set size: " + targetSet.size());
      }
      // Compute the intersection of all properties
      ParameterProperty derefParamSet = null;
      for (XMethod target : targetSet) {
        if (target.isStub()) {
          continue;
        }
        if (DEBUG_CHECK_CALLS) {
          System.out.print("Checking: " + target + ": ");
        }

        ParameterProperty targetDerefParamSet = database.getProperty(target.getMethodDescriptor());
        if (targetDerefParamSet == null) {
          // Hmm...no information for this target.
          // assume it doesn't dereference anything
          if (DEBUG_CHECK_CALLS) {
            System.out.println("==> no information, assume no guaranteed dereferences");
          }
          return Collections.emptySet();
        }

        if (DEBUG_CHECK_CALLS) {
          System.out.println("==> " + targetDerefParamSet);
        }
        if (derefParamSet == null) {
          derefParamSet = new ParameterProperty();
          derefParamSet.copyFrom(targetDerefParamSet);
        } else {
          derefParamSet.intersectWith(targetDerefParamSet);
        }
      }

      if (derefParamSet == null || derefParamSet.isEmpty()) {
        if (DEBUG) {
          System.out.println("** Nothing");
        }
        return Collections.emptySet();
      }
      if (DEBUG_CHECK_CALLS) {
        System.out.println(
            "** Summary of call @ " + location.getHandle().getPosition() + ": " + derefParamSet);
      }

      HashSet<ValueNumber> requiredToBeNonnull = new HashSet<ValueNumber>();
      for (int i = 0; i < numParams; i++) {
        if (!derefParamSet.hasProperty(i)) {
          continue;
        }
        int argSlot = vnaFrame.getStackLocation(sigParser.getSlotsFromTopOfStackForParameter(i));
        if (invFrame != null && !reportDereference(invFrame, argSlot)) {
          continue;
        }
        if (DEBUG_CHECK_CALLS) {
          System.out.println(
              "  dereference @ " + location.getHandle().getPosition() + " of parameter " + i);
        }

        requiredToBeNonnull.add(vnaFrame.getValue(argSlot));
      }
      return requiredToBeNonnull;

    } catch (ClassNotFoundException e) {
      AnalysisContext.reportMissingClass(e);
    }
    return Collections.emptySet();
  }