class BDynamicInvokeInst extends AbstractInvokeInst implements DynamicInvokeInst {

  protected final SootMethodRef bsmRef;
  private final List<Value> bsmArgs;
  protected int tag;

  public BDynamicInvokeInst(SootMethodRef bsmMethodRef, List<Value> bsmArgs, SootMethodRef methodRef, int tag) {
    super.methodRef = methodRef;
    this.bsmRef = bsmMethodRef;
    this.bsmArgs = bsmArgs;
    this.tag = tag;
  }

  @Override
  public Object clone() {
    return new BDynamicInvokeInst(bsmRef, bsmArgs, methodRef, tag);
  }

  @Override
  public int getInCount() {
    return methodRef.getParameterTypes().size();
  }

  @Override
  public int getOutCount() {
    return (methodRef.getReturnType() instanceof VoidType) ? 0 : 1;
  }

  @Override
  public SootMethodRef getBootstrapMethodRef() {
    return bsmRef;
  }

  @Override
  public List<Value> getBootstrapArgs() {
    return bsmArgs;
  }

  @Override
  public String getName() {
    return "dynamicinvoke";
  }

  @Override
  public void apply(Switch sw) {
    ((InstSwitch) sw).caseDynamicInvokeInst(this);
  }

  @Override
  public String toString() {
    StringBuilder buffer = new StringBuilder();

    buffer.append(Jimple.DYNAMICINVOKE + " \"");
    buffer.append(methodRef.getName()); // quoted method name (can be any UTF8 string)
    buffer.append("\" <");
    buffer.append(
        SootMethod.getSubSignature(""/* no method name here */, methodRef.getParameterTypes(), methodRef.getReturnType()));
    buffer.append('>');
    buffer.append(bsmRef.getSignature());
    buffer.append('(');

    for (Iterator<Value> it = bsmArgs.iterator(); it.hasNext();) {
      Value v = it.next();
      buffer.append(v.toString());
      if (it.hasNext()) {
        buffer.append(", ");
      }
    }
    buffer.append(')');

    return buffer.toString();
  }

  @Override
  public void toString(UnitPrinter up) {<FILL_FUNCTION_BODY>}

  @Override
  public int getHandleTag() {
    return tag;
  }
}

    up.literal(Jimple.DYNAMICINVOKE + " \"");
    up.literal(methodRef.getName());
    up.literal("\" <");
    up.literal(
        SootMethod.getSubSignature(""/* no method name here */, methodRef.getParameterTypes(), methodRef.getReturnType()));
    up.literal("> ");
    up.methodRef(bsmRef);
    up.literal("(");

    for (Iterator<Value> it = bsmArgs.iterator(); it.hasNext();) {
      Value v = it.next();
      v.toString(up);
      if (it.hasNext()) {
        up.literal(", ");
      }
    }
    up.literal(")");
  
<methods>public non-sealed void <init>() ,public boolean containsInvokeExpr() ,public int getInCount() ,public int getInMachineCount() ,public soot.SootMethod getMethod() ,public soot.SootMethodRef getMethodRef() ,public abstract java.lang.String getName() ,public int getOutCount() ,public int getOutMachineCount() ,public soot.Type getType() ,public java.lang.String toString() <variables>soot.SootMethodRef methodRef