// Path: dex-reader-api/src/main/java/com/googlecode/d2j/Method.java
// public class Method {
//     /**
//      * name of the method.
//      */
//     private String name;
//     /**
//      * owner class of the method, in TypeDescriptor format.
//      */
//     private String owner;
//     /**
//      * parameter types of the method, in TypeDescriptor format.
//      */
//     private Proto proto;
// 
//     public Proto getProto() {
//         return proto;
//     }
// 
//     public Method(String owner, String name, String[] parameterTypes, String returnType) {
//         this.owner = owner;
//         this.name = name;
//         this.proto = new Proto(parameterTypes, returnType);
//     }
//     public Method(String owner, String name, Proto proto) {
//         this.owner = owner;
//         this.name = name;
//         this.proto = proto;
//     }
//     public String getDesc() {
//         return proto.getDesc();
//     }
// 
//     /**
//      * @return the name
//      */
//     public String getName() {
//         return name;
//     }
// 
//     /**
//      * @return the owner
//      */
//     public String getOwner() {
//         return owner;
//     }
// 
//     /**
//      * @return the parameterTypes
//      */
//     public String[] getParameterTypes() {
//         return proto.getParameterTypes();
//     }
// 
//     public String getReturnType() {
//         return proto.getReturnType();
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         Method method = (Method) o;
// 
//         if (name != null ? !name.equals(method.name) : method.name != null) return false;
//         if (owner != null ? !owner.equals(method.owner) : method.owner != null) return false;
//         return proto.equals(method.proto);
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = name != null ? name.hashCode() : 0;
//         result = 31 * result + (owner != null ? owner.hashCode() : 0);
//         result = 31 * result + proto.hashCode();
//         return result;
//     }
// 
//     /*
//          * (non-Javadoc)
//          *
//          * @see java.lang.Object#toString()
//          */
//     @Override
//     public String toString() {
//         return this.getOwner() + "->" + this.getName() + this.getDesc();
//     }
// }


import com.googlecode.d2j.Method;
import com.googlecode.d2j.Proto;
import com.googlecode.dex2jar.ir.LabelAndLocalMapper;
import com.googlecode.dex2jar.ir.Util;

    public Proto getProto() {
        return proto;
    }

    public InvokePolymorphicExpr(VT type, Value[] args, Proto proto, Method method) {
        super(type, args);
        this.proto = proto;
        this.method = method;
    }

    @Override
    public Value clone() {
        return new InvokePolymorphicExpr(vt, cloneOps(), proto, method);
    }

    @Override
    public Value clone(LabelAndLocalMapper mapper) {
        return new InvokePolymorphicExpr(vt, cloneOps(mapper), proto, method);
    }

    @Override
    public String toString0() {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        sb.append(ops[i++]).append('.').append(this.method.getName());
        String[] argTypes = getProto().getParameterTypes();
        sb.append('(');
        int j = 0;
        boolean first = true;
        for (; i < ops.length; i++) {

// Path: dex-reader-api/src/main/java/com/googlecode/d2j/Method.java
// public class Method {
//     /**
//      * name of the method.
//      */
//     private String name;
//     /**
//      * owner class of the method, in TypeDescriptor format.
//      */
//     private String owner;
//     /**
//      * parameter types of the method, in TypeDescriptor format.
//      */
//     private Proto proto;
// 
//     public Proto getProto() {
//         return proto;
//     }
// 
//     public Method(String owner, String name, String[] parameterTypes, String returnType) {
//         this.owner = owner;
//         this.name = name;
//         this.proto = new Proto(parameterTypes, returnType);
//     }
//     public Method(String owner, String name, Proto proto) {
//         this.owner = owner;
//         this.name = name;
//         this.proto = proto;
//     }
//     public String getDesc() {
//         return proto.getDesc();
//     }
// 
//     /**
//      * @return the name
//      */
//     public String getName() {
//         return name;
//     }
// 
//     /**
//      * @return the owner
//      */
//     public String getOwner() {
//         return owner;
//     }
// 
//     /**
//      * @return the parameterTypes
//      */
//     public String[] getParameterTypes() {
//         return proto.getParameterTypes();
//     }
// 
//     public String getReturnType() {
//         return proto.getReturnType();
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (o == null || getClass() != o.getClass()) return false;
// 
//         Method method = (Method) o;
// 
//         if (name != null ? !name.equals(method.name) : method.name != null) return false;
//         if (owner != null ? !owner.equals(method.owner) : method.owner != null) return false;
//         return proto.equals(method.proto);
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = name != null ? name.hashCode() : 0;
//         result = 31 * result + (owner != null ? owner.hashCode() : 0);
//         result = 31 * result + proto.hashCode();
//         return result;
//     }
// 
//     /*
//          * (non-Javadoc)
//          *
//          * @see java.lang.Object#toString()
//          */
//     @Override
//     public String toString() {
//         return this.getOwner() + "->" + this.getName() + this.getDesc();
//     }
// }


// Path: dex-ir/src/main/java/com/googlecode/dex2jar/ir/expr/InvokePolymorphicExpr.java
import com.googlecode.d2j.Method;
import com.googlecode.d2j.Proto;
import com.googlecode.dex2jar.ir.LabelAndLocalMapper;
import com.googlecode.dex2jar.ir.Util;

    public Proto getProto() {
        return proto;
    }

    public InvokePolymorphicExpr(VT type, Value[] args, Proto proto, Method method) {
        super(type, args);
        this.proto = proto;
        this.method = method;
    }

    @Override
    public Value clone() {
        return new InvokePolymorphicExpr(vt, cloneOps(), proto, method);
    }

    @Override
    public Value clone(LabelAndLocalMapper mapper) {
        return new InvokePolymorphicExpr(vt, cloneOps(mapper), proto, method);
    }

    @Override
    public String toString0() {
        StringBuilder sb = new StringBuilder();
        int i = 0;
        sb.append(ops[i++]).append('.').append(this.method.getName());
        String[] argTypes = getProto().getParameterTypes();
        sb.append('(');
        int j = 0;
        boolean first = true;
        for (; i < ops.length; i++) {

            if (first) {
