public void GenerateMethodInvocation(Method method)
        {
            var marshalers = new List <Marshaler>();
            var @params    = new List <string>();

            if (!method.IsStatic && !(method.IsConstructor || method.IsDestructor))
            {
                @params.Add("__object");
            }

            int paramIndex = 0;

            foreach (var param in method.Parameters.Where(m => !m.IsImplicit))
            {
                var marshal = new SwiftMarshalManagedToNative(Context)
                {
                    ArgName        = param.Name,
                    Parameter      = param,
                    ParameterIndex = paramIndex++
                };
                marshalers.Add(marshal);

                param.Visit(marshal);

                if (!string.IsNullOrWhiteSpace(marshal.Before))
                {
                    Write(marshal.Before);
                }

                @params.Add(marshal.Return);
            }

            var hasReturn = !method.ReturnType.Type.IsPrimitiveType(PrimitiveType.Void) &&
                            !(method.IsConstructor || method.IsDestructor);

            if (hasReturn)
            {
                TypePrinter.PushContext(TypePrinterContextKind.Native);
                var typeName = method.ReturnType.Visit(TypePrinter);
                TypePrinter.PopContext();
                Write($"let __ret : {typeName.Type} = ");
            }

            var effectiveMethod = method.CompleteDeclaration as Method ?? method;
            var nativeMethodId  = JavaNative.GetCMethodIdentifier(effectiveMethod);

            WriteLine($"{nativeMethodId}({string.Join(", ", @params)})");

            foreach (var marshal in marshalers)
            {
                if (!string.IsNullOrWhiteSpace(marshal.After))
                {
                    Write(marshal.After);
                }
            }

            if (hasReturn)
            {
                var marshal = new SwiftMarshalNativeToManaged(Context)
                {
                    ReturnType    = method.ReturnType,
                    ReturnVarName = "__ret"
                };

                method.ReturnType.Visit(marshal);

                if (marshal.Return.ToString().Length == 0)
                {
                    throw new NotSupportedException($"Cannot marshal return type {method.ReturnType}");
                }

                if (!string.IsNullOrWhiteSpace(marshal.Before))
                {
                    Write(marshal.Before);
                }

                WriteLine($"return {marshal.Return}");
            }
        }
        public void GenerateMethodInvocation(Method method)
        {
            var marshalers = new List <Marshaler>();
            var @params    = new List <string>();

            if (!method.IsStatic && !(method.IsConstructor || method.IsDestructor))
            {
                @params.Add("__object");
            }

            int paramIndex = 0;

            foreach (var param in method.Parameters.Where(m => !m.IsImplicit))
            {
                var marshal = new JavaMarshalManagedToNative(Context)
                {
                    ArgName        = param.Name,
                    Parameter      = param,
                    ParameterIndex = paramIndex++
                };
                marshalers.Add(marshal);

                param.Visit(marshal);

                if (!string.IsNullOrWhiteSpace(marshal.Before))
                {
                    Write(marshal.Before);
                }

                @params.Add(marshal.Return);
            }

            PrimitiveType primitive;

            method.ReturnType.Type.IsPrimitiveType(out primitive);

            var hasReturn = primitive != PrimitiveType.Void && !(method.IsConstructor || method.IsDestructor);

            if (hasReturn)
            {
                TypePrinter.PushContext(TypePrinterContextKind.Native);
                var typeName = method.ReturnType.Visit(TypePrinter);
                TypePrinter.PopContext();
                Write($"{typeName.Type} __ret = ");
            }

            if (method.IsConstructor)
            {
                Write("__object = ");
            }

            // Get the effective method for synthetized interface method implementations.
            var effectiveMethod = method.CompleteDeclaration as Method ?? method;
            var unit            = effectiveMethod.TranslationUnit;
            var package         = string.Join(".", GetPackageNames(unit));
            var nativeMethodId  = JavaNative.GetCMethodIdentifier(effectiveMethod);

            Write($"{package}.{JavaNative.GetNativeLibClassName(unit)}.INSTANCE.{nativeMethodId}(");

            Write(string.Join(", ", @params));
            WriteLine(");");

            WriteLine("mono.embeddinator.Runtime.checkExceptions();");

            foreach (var marshal in marshalers)
            {
                if (!string.IsNullOrWhiteSpace(marshal.After))
                {
                    Write(marshal.After);
                }
            }

            if (hasReturn)
            {
                var marshal = new JavaMarshalNativeToManaged(Context)
                {
                    ReturnType    = method.ReturnType,
                    ReturnVarName = "__ret"
                };

                method.ReturnType.Visit(marshal);

                if (marshal.Return.ToString().Length == 0)
                {
                    throw new System.Exception();
                }

                if (!string.IsNullOrWhiteSpace(marshal.Before))
                {
                    Write(marshal.Before);
                }

                WriteLine($"return {marshal.Return};");
            }
        }