class MethodHandle extends Constant {

  private static final long serialVersionUID = -7948291265532721191L;

  public static enum Kind {
    REF_GET_FIELD(Opcodes.H_GETFIELD, "REF_GET_FIELD"), REF_GET_FIELD_STATIC(Opcodes.H_GETSTATIC,
        "REF_GET_FIELD_STATIC"), REF_PUT_FIELD(Opcodes.H_PUTFIELD, "REF_PUT_FIELD"), REF_PUT_FIELD_STATIC(
            Opcodes.H_PUTSTATIC, "REF_PUT_FIELD_STATIC"), REF_INVOKE_VIRTUAL(Opcodes.H_INVOKEVIRTUAL,
                "REF_INVOKE_VIRTUAL"), REF_INVOKE_STATIC(Opcodes.H_INVOKESTATIC, "REF_INVOKE_STATIC"), REF_INVOKE_SPECIAL(
                    Opcodes.H_INVOKESPECIAL, "REF_INVOKE_SPECIAL"), REF_INVOKE_CONSTRUCTOR(Opcodes.H_NEWINVOKESPECIAL,
                        "REF_INVOKE_CONSTRUCTOR"), REF_INVOKE_INTERFACE(Opcodes.H_INVOKEINTERFACE, "REF_INVOKE_INTERFACE");

    private final int val;
    private final String valStr;

    private Kind(int val, String valStr) {
      this.val = val;
      this.valStr = valStr;
    }

    @Override
    public String toString() {
      return valStr;
    }

    public int getValue() {
      return val;
    }

    public static Kind getKind(int kind) {<FILL_FUNCTION_BODY>}

    public static Kind getKind(String kind) {
      for (Kind k : Kind.values()) {
        if (k.toString().equals(kind)) {
          return k;
        }
      }
      throw new RuntimeException("Error: No method handle kind for value '" + kind + "'.");
    }
  }

  protected final SootFieldRef fieldRef;
  protected final SootMethodRef methodRef;
  protected final int kind;

  private MethodHandle(SootMethodRef ref, int kind) {
    this.methodRef = ref;
    this.kind = kind;
    this.fieldRef = null;
  }

  private MethodHandle(SootFieldRef ref, int kind) {
    this.fieldRef = ref;
    this.kind = kind;
    this.methodRef = null;
  }

  public static MethodHandle v(SootMethodRef ref, int kind) {
    return new MethodHandle(ref, kind);
  }

  public static MethodHandle v(SootFieldRef ref, int kind) {
    return new MethodHandle(ref, kind);
  }

  @Override
  public String toString() {
    return "methodhandle: \"" + getKindString() + "\" "
        + (methodRef == null ? Objects.toString(fieldRef) : Objects.toString(methodRef));
  }

  @Override
  public Type getType() {
    if (Options.v().src_prec() == Options.src_prec_dotnet) {
      return isMethodRef() ? RefType.v(DotnetBasicTypes.SYSTEM_RUNTIMEMETHODHANDLE)
          : RefType.v(DotnetBasicTypes.SYSTEM_RUNTIMEFIELDHANDLE);
    }
    return RefType.v("java.lang.invoke.MethodHandle");
  }

  public SootMethodRef getMethodRef() {
    return methodRef;
  }

  public SootFieldRef getFieldRef() {
    return fieldRef;
  }

  public int getKind() {
    return kind;
  }

  public String getKindString() {
    return Kind.getKind(kind).toString();
  }

  public boolean isFieldRef() {
    return isFieldRef(kind);
  }

  public static boolean isFieldRef(int kind) {
    return kind == Kind.REF_GET_FIELD.getValue() || kind == Kind.REF_GET_FIELD_STATIC.getValue()
        || kind == Kind.REF_PUT_FIELD.getValue() || kind == Kind.REF_PUT_FIELD_STATIC.getValue();
  }

  public boolean isMethodRef() {
    return isMethodRef(kind);
  }

  public static boolean isMethodRef(int kind) {
    return kind == Kind.REF_INVOKE_VIRTUAL.getValue() || kind == Kind.REF_INVOKE_STATIC.getValue()
        || kind == Kind.REF_INVOKE_SPECIAL.getValue() || kind == Kind.REF_INVOKE_CONSTRUCTOR.getValue()
        || kind == Kind.REF_INVOKE_INTERFACE.getValue();
  }

  @Override
  public void apply(Switch sw) {
    ((ConstantSwitch) sw).caseMethodHandle(this);
  }

  @Override
  public int hashCode() {
    final int prime = 17;
    int result = 31;
    result = prime * result + Objects.hashCode(methodRef);
    result = prime * result + Objects.hashCode(fieldRef);
    result = prime * result + kind;
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null || this.getClass() != obj.getClass()) {
      return false;
    }
    MethodHandle other = (MethodHandle) obj;
    return Objects.equals(this.methodRef, other.methodRef) && Objects.equals(this.fieldRef, other.fieldRef);
  }
}

      for (Kind k : Kind.values()) {
        if (k.getValue() == kind) {
          return k;
        }
      }
      throw new RuntimeException("Error: No method handle kind for value '" + kind + "'.");
    
<methods>public non-sealed void <init>() ,public java.lang.Object clone() ,public void convertToBaf(soot.jimple.JimpleToBafContext, List<soot.Unit>) ,public int equivHashCode() ,public boolean equivTo(java.lang.Object) ,public final List<soot.ValueBox> getUseBoxes() ,public void toString(soot.UnitPrinter) <variables>