class MethodInvokeUtils {

    public static int getArgumentCountRequiredForInvocation(AbstractInsnNode invokeNode) {
        Validate.notNull(invokeNode);

        if (invokeNode instanceof MethodInsnNode) {
            MethodInsnNode methodInsnNode = (MethodInsnNode) invokeNode;
            int extra;
            int paramCount;
            
            switch (methodInsnNode.getOpcode()) {
                case Opcodes.INVOKEVIRTUAL:
                case Opcodes.INVOKESPECIAL:
                case Opcodes.INVOKEINTERFACE:
                    extra = 1;
                    break;
                case Opcodes.INVOKESTATIC:
                    extra = 0;
                    break;
                default:
                    throw new IllegalArgumentException(); // unknown invocation type? probably badly generated instruction node
            }
            Type methodType = Type.getType(methodInsnNode.desc);
            paramCount = methodType.getArgumentTypes().length;
                    
            return paramCount + extra;
        } else if (invokeNode instanceof InvokeDynamicInsnNode) {
            InvokeDynamicInsnNode invokeDynamicInsnNode = (InvokeDynamicInsnNode) invokeNode;
            int paramCount;
            
            Type methodType = Type.getType(invokeDynamicInsnNode.desc);
            paramCount = methodType.getArgumentTypes().length;
            
            return paramCount;
        } else {
            throw new IllegalArgumentException();
        }
    }

    private  MethodInvokeUtils();

}