/**
  * Create statements for methods like getMethod() and getDeclaredMethod(), which return a single
  * method. This creates a return statement for each possible return value, each of which is a
  * {@link ConstantValue} for an {@link IMethod}.
  *
  * @param returnValues the possible return values for this method
  * @return the statements
  */
 private SSAInstruction[] getParticularMethodStatements(
     MethodReference ref,
     Collection<IMethod> returnValues,
     GetMethodContext context,
     Map<Integer, ConstantValue> constants) {
   ArrayList<SSAInstruction> statements = new ArrayList<SSAInstruction>();
   int nextLocal = ref.getNumberOfParameters() + 2;
   IClass cls = context.getType().getType();
   SSAInstructionFactory insts =
       context.getType().getType().getClassLoader().getInstructionFactory();
   if (cls != null) {
     for (IMethod m : returnValues) {
       int c = nextLocal++;
       constants.put(c, new ConstantValue(m));
       SSAReturnInstruction R = insts.ReturnInstruction(statements.size(), c, false);
       statements.add(R);
     }
   } else {
     // SJF: This is incorrect. TODO: fix and enable.
     // SSAThrowInstruction t = insts.ThrowInstruction(retValue);
     // statements.add(t);
   }
   SSAInstruction[] result = new SSAInstruction[statements.size()];
   Iterator<SSAInstruction> it = statements.iterator();
   for (int i = 0; i < result.length; i++) {
     result[i] = it.next();
   }
   return result;
 }
 @Override
 public Iterator<NewSiteReference> iterateNewSites(CGNode node) {
   if (node == null) {
     throw new IllegalArgumentException("node is null");
   }
   assert understands(node);
   GetMethodContext context = (GetMethodContext) node.getContext();
   TypeReference tr = context.getType().getTypeReference();
   if (tr != null) {
     return new NonNullSingletonIterator<NewSiteReference>(NewSiteReference.make(0, tr));
   }
   return EmptyIterator.instance();
 }
 /** Create statements for {@link Class#getDeclaredMethod(String, Class...)}. */
 private SSAInstruction[] makeGetDeclaredMethodStatements(
     GetMethodContext context, Map<Integer, ConstantValue> constants, Atom name) {
   IClass cls = context.getType().getType();
   if (cls == null) {
     return getParticularMethodStatements(GET_DECLARED_METHOD, null, context, constants);
   } else {
     return getParticularMethodStatements(
         GET_DECLARED_METHOD, getDeclaredNormalMethods(cls, name), context, constants);
   }
 }
 /**
  * @see
  *     com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter#getIR(com.ibm.wala.ipa.callgraph.CGNode)
  */
 @Override
 public IR getIR(CGNode node) {
   if (node == null) {
     throw new IllegalArgumentException("node is null");
   }
   assert understands(node);
   if (DEBUG) {
     System.err.println("generating IR for " + node);
   }
   IMethod method = node.getMethod();
   GetMethodContext context = (GetMethodContext) node.getContext();
   Map<Integer, ConstantValue> constants = HashMapFactory.make();
   if (method.getReference().equals(GET_METHOD)) {
     Atom name = Atom.findOrCreateAsciiAtom(context.getName());
     SSAInstruction instrs[] = makeGetMethodStatements(context, constants, name);
     return new SyntheticIR(
         method,
         context,
         new InducedCFG(instrs, method, context),
         instrs,
         SSAOptions.defaultOptions(),
         constants);
   }
   if (method.getReference().equals(GET_DECLARED_METHOD)) {
     Atom name = Atom.findOrCreateAsciiAtom(context.getName());
     SSAInstruction instrs[] = makeGetDeclaredMethodStatements(context, constants, name);
     return new SyntheticIR(
         method,
         context,
         new InducedCFG(instrs, method, context),
         instrs,
         SSAOptions.defaultOptions(),
         constants);
   }
   Assertions.UNREACHABLE("Unexpected method " + node);
   return null;
 }