code: @Override
    Nullness visitMethodInvocation(
        MethodInvocationNode node, Updates thenUpdates, Updates elseUpdates, Updates bothUpdates) {
      ClassAndMethod callee = tryGetMethodSymbol(node.getTree(), Types.instance(context));
      if (callee != null && !callee.isStatic) {
        setNonnullIfTrackable(bothUpdates, node.getTarget().getReceiver());
      }
      setUnconditionalArgumentNullness(bothUpdates, node.getArguments(), callee);
      setConditionalArgumentNullness(
          thenUpdates,
          elseUpdates,
          node.getArguments(),
          callee,
          Types.instance(context),
          Symtab.instance(context));
      return returnValueNullness(node, callee);
    }
docs: Refines the receiver of a method invocation to type non-null after successful invocation, and
  refines the value of the expression as a whole to non-null if applicable (e.g., if the method
  returns a primitive type).
  
  <p>NOTE: This transfer makes the unsound assumption that fields reachable via the actual params
  of this method invocation are not mutated by the callee. To be sound with respect to escaping
  mutable references in general, we would have to set to top (i.e. NULLABLE) any tracked access
  path that could contain an alias of an actual parameter of this invocation.