class PolymorphicMethodRef extends SootMethodRefImpl {

  public static final String METHODHANDLE_SIGNATURE = "java.lang.invoke.MethodHandle";

  public static final String VARHANDLE_SIGNATURE = "java.lang.invoke.VarHandle";

  public static final String POLYMORPHIC_SIGNATURE = "java/lang/invoke/MethodHandle$PolymorphicSignature";

  /**
   * Check if the declaring class "has the rights" to declare polymorphic methods
   * {@see http://docs.oracle.com/javase/specs/jls/se11/html/jls-15.html#jls-15.12.4.4}
   * 
   * @param declaringClass
   *          the class to check
   * @return if the class is allowed according to the JVM Spec
   */
  public static boolean handlesClass(SootClass declaringClass) {
    return handlesClass(declaringClass.getName());
  }

  public static boolean handlesClass(String declaringClassName) {
    return PolymorphicMethodRef.METHODHANDLE_SIGNATURE.equals(declaringClassName)
        || PolymorphicMethodRef.VARHANDLE_SIGNATURE.equals(declaringClassName);
  }

  /**
   * Constructor.
   *
   * @param declaringClass
   *          the declaring class. Must not be {@code null}
   * @param name
   *          the method name. Must not be {@code null}
   * @param parameterTypes
   *          the types of parameters. May be {@code null}
   * @param returnType
   *          the type of return value. Must not be {@code null}
   * @param isStatic
   *          the static modifier value
   * @throws IllegalArgumentException
   *           is thrown when {@code declaringClass}, or {@code name}, or {@code returnType} is null
   */
  public PolymorphicMethodRef(SootClass declaringClass, String name, List<Type> parameterTypes, Type returnType,
      boolean isStatic) {
    super(declaringClass, name, parameterTypes, returnType, isStatic);
  }

  @Override
  public SootMethod resolve() {<FILL_FUNCTION_BODY>}

  private SootMethod addPolyMorphicMethod(SootMethod originalPolyMorphicMethod) {
    SootMethod newMethod
        = new SootMethod(getName(), getParameterTypes(), getReturnType(), originalPolyMorphicMethod.modifiers);
    getDeclaringClass().addMethod(newMethod);
    return newMethod;
  }
}

    SootMethod method = getDeclaringClass().getMethodUnsafe(getName(), getParameterTypes(), getReturnType());
    if (method != null) {
      return method;
    }

    // No method with matching parameter types or return types found for polymorphic methods,
    // we don't care about the return or parameter types. We just check if a method with the
    // name exists and has a polymorphic type signature.

    // Note(MB): We cannot use getMethodByName here since the method name is ambiguous after
    // adding the first method with same name and refined signature.
    for (SootMethod candidateMethod : getDeclaringClass().getMethods()) {
      if (candidateMethod.getName().equals(getName())) {
        Tag annotationsTag = candidateMethod.getTag(VisibilityAnnotationTag.NAME);
        if (annotationsTag != null) {
          for (AnnotationTag annotation : ((VisibilityAnnotationTag) annotationsTag).getAnnotations()) {
            // check the annotation's type
            if (('L' + POLYMORPHIC_SIGNATURE + ';').equals(annotation.getType())) {
              // The method is polymorphic, add a fitting method to the MethodHandle
              // or VarHandle class, as the JVM does on runtime.
              return addPolyMorphicMethod(candidateMethod);
            }
          }
        }
      }
    }

    return super.resolve();
  
<methods>public void <init>(soot.SootClass, java.lang.String, List<soot.Type>, soot.Type, boolean) ,public soot.SootClass declaringClass() ,public boolean equals(java.lang.Object) ,public soot.SootClass getDeclaringClass() ,public java.lang.String getName() ,public soot.Type getParameterType(int) ,public List<soot.Type> getParameterTypes() ,public soot.Type getReturnType() ,public java.lang.String getSignature() ,public soot.util.NumberedString getSubSignature() ,public int hashCode() ,public boolean isStatic() ,public java.lang.String name() ,public soot.Type parameterType(int) ,public List<soot.Type> parameterTypes() ,public soot.SootMethod resolve() ,public soot.Type returnType() ,public java.lang.String toString() ,public soot.SootMethod tryResolve() <variables>private final non-sealed soot.SootClass declaringClass,private final non-sealed boolean isStatic,private static final org.slf4j.Logger logger,private final non-sealed java.lang.String name,private final non-sealed List<soot.Type> parameterTypes,private soot.SootMethod resolveCache,private final non-sealed soot.Type returnType,private soot.util.NumberedString subsig