private void GenGlueVirtualMethod(GenerationInfo gen_info)
        {
            StreamWriter glue      = gen_info.GlueWriter;
            string       glue_name = String.Format("{0}sharp_{1}_base_{2}", container_type.NS.ToLower().Replace(".", "_"), container_type.Name.ToLower(), ClassFieldName);

            glue.WriteLine("{0} {1} ({2});\n", retval.CType, glue_name, GlueSignature);
            glue.WriteLine("{0}\n{1} ({2})", retval.CType, glue_name, GlueSignature);
            glue.WriteLine("{");
            glue.WriteLine("\t{0}Class *klass = ({0}Class *) get_threshold_class (G_OBJECT ({1}));", container_type.CName, parms[0].Name);
            glue.Write("\tif (klass->{0})\n\t\t", ClassFieldName);
            if (!IsVoid)
            {
                glue.Write("return ");
            }
            glue.Write("(* klass->{0}) (", ClassFieldName);
            for (int i = 0; i < parms.Count; i++)
            {
                glue.Write(parms[i].Name + (i == parms.Count - 1 ? "" : ", "));
            }
            glue.WriteLine(");");
            if (!IsVoid)
            {
                glue.WriteLine("\treturn " + DefaultGlueValue + ";");
            }
            glue.WriteLine("}");

            StreamWriter sw = gen_info.Writer;

            sw.WriteLine("\t\t[DllImport (\"{0}\", CallingConvention = CallingConvention.Cdecl)]", gen_info.GluelibName);
            sw.WriteLine("\t\tstatic extern {0} {1} ({2});\n", retval.MarshalType, glue_name, parms.ImportSignature);
            GenVMDeclaration(sw, null);
            sw.WriteLine("\t\t{");
            MethodBody body = new MethodBody(parms);

            body.Initialize(gen_info, false, false, String.Empty, false);
            sw.WriteLine("\t\t\t{0}{1} ({2});", IsVoid ? "" : retval.MarshalType + " __ret = ", glue_name, GlueCallString);
            body.Finish(sw, "");
            if (!IsVoid)
            {
                sw.WriteLine("\t\t\treturn {0};", retval.FromNative("__ret"));
                var postRef = retval.PostFromNative("__ret");
                if (postRef != string.Empty)
                {
                    sw.WriteLine("\t\t\t" + postRef);
                }
            }
            sw.WriteLine("\t\t}\n");
        }
        void GenInvoker(GenerationInfo gen_info, StreamWriter sw)
        {
            if (sig == null)
            {
                sig = new Signature(parms);
            }

            sw.WriteLine("\tinternal class " + Name + "Invoker {");
            sw.WriteLine();
            sw.WriteLine("\t\t" + Name + "Native native_cb;");
            sw.WriteLine("\t\tIntPtr __data;");
            sw.WriteLine("\t\tGLib.DestroyNotify __notify;");
            sw.WriteLine();
            sw.WriteLine("\t\t~" + Name + "Invoker ()");
            sw.WriteLine("\t\t{");
            sw.WriteLine("\t\t\tif (__notify == null)");
            sw.WriteLine("\t\t\t\treturn;");
            sw.WriteLine("\t\t\t__notify (__data);");
            sw.WriteLine("\t\t}");
            sw.WriteLine();
            sw.WriteLine("\t\tinternal " + Name + "Invoker (" + Name + "Native native_cb) : this (native_cb, IntPtr.Zero, null) {}");
            sw.WriteLine();
            sw.WriteLine("\t\tinternal " + Name + "Invoker (" + Name + "Native native_cb, IntPtr data) : this (native_cb, data, null) {}");
            sw.WriteLine();
            sw.WriteLine("\t\tinternal " + Name + "Invoker (" + Name + "Native native_cb, IntPtr data, GLib.DestroyNotify notify)");
            sw.WriteLine("\t\t{");
            sw.WriteLine("\t\t\tthis.native_cb = native_cb;");
            sw.WriteLine("\t\t\t__data = data;");
            sw.WriteLine("\t\t\t__notify = notify;");
            sw.WriteLine("\t\t}");
            sw.WriteLine();
            sw.WriteLine("\t\tinternal " + QualifiedName + " Handler {");
            sw.WriteLine("\t\t\tget {");
            sw.WriteLine("\t\t\t\treturn new " + QualifiedName + "(InvokeNative);");
            sw.WriteLine("\t\t\t}");
            sw.WriteLine("\t\t}");
            sw.WriteLine();
            sw.WriteLine("\t\t" + retval.CSType + " InvokeNative (" + sig + ")");
            sw.WriteLine("\t\t{");
            body.Initialize(gen_info, true);
            string call = "native_cb (" + InvokeString + ")";

            if (retval.IsVoid)
            {
                sw.WriteLine("\t\t\t" + call + ";");
            }
            else
            {
                sw.WriteLine("\t\t\t" + retval.CSType + " result = " + retval.FromNative(call) + ";");
                var postRef = retval.PostFromNative(call);
                if (postRef != string.Empty)
                {
                    sw.WriteLine("\t\t\t" + postRef);
                }
            }
            body.Finish(sw, String.Empty);
            if (!retval.IsVoid)
            {
                sw.WriteLine("\t\t\treturn result;");
            }
            sw.WriteLine("\t\t}");
            sw.WriteLine("\t}");
            sw.WriteLine();
        }
        public void GenerateBody(GenerationInfo gen_info, ClassBase implementor, string indent)
        {
            StreamWriter sw = gen_info.Writer;

            sw.WriteLine(" {");
            if (!IsStatic && implementor != null)
            {
                implementor.Prepare(sw, indent + "\t\t\t");
            }
            if (IsAccessor)
            {
                Body.InitAccessor(sw, Signature, indent);
            }
            Body.Initialize(gen_info, is_get, is_set, indent, false);

            if (HasWin32Utf8Variant)
            {
                if (!retval.IsVoid)
                {
                    sw.WriteLine(indent + "\t\t\t" + retval.MarshalType + " raw_ret;");
                }
                sw.WriteLine(indent + "\t\t\t" + "if (Environment.OSVersion.Platform == PlatformID.Win32NT ||");
                sw.WriteLine(indent + "\t\t\t" + "    Environment.OSVersion.Platform == PlatformID.Win32S ||");
                sw.WriteLine(indent + "\t\t\t" + "    Environment.OSVersion.Platform == PlatformID.Win32Windows ||");
                sw.WriteLine(indent + "\t\t\t" + "    Environment.OSVersion.Platform == PlatformID.WinCE)");
                if (retval.IsVoid)
                {
                    sw.WriteLine(indent + "\t\t\t\t" + CName + "_utf8" + call + ";");
                    sw.WriteLine(indent + "\t\t\t" + "else");
                    sw.WriteLine(indent + "\t\t\t\t" + CName + call + ";");
                }
                else
                {
                    sw.WriteLine(indent + "\t\t\t\traw_ret = " + CName + "_utf8" + call + ";");
                    sw.WriteLine(indent + "\t\t\t" + "else");
                    sw.WriteLine(indent + "\t\t\t\traw_ret = " + CName + call + ";");
                    sw.WriteLine(indent + "\t\t\t" + retval.CSType + " ret = " + retval.FromNative("raw_ret") + ";");
                    var postRef = retval.PostFromNative("raw_ret");
                    if (postRef != string.Empty)
                    {
                        sw.WriteLine(indent + "\t\t\t" + postRef);
                    }
                    sw.WriteLine();
                }
            }
            else
            {
                sw.Write(indent + "\t\t\t");
                if (retval.IsVoid)
                {
                    sw.WriteLine(CName + call + ";");
                }
                else if (!cacheValue)
                {
                    sw.WriteLine(retval.MarshalType + " raw_ret = " + CName + call + ";");
                    sw.WriteLine(indent + "\t\t\t" + retval.CSType + " ret = " + retval.FromNative("raw_ret") + ";");
                    var postRef = retval.PostFromNative("raw_ret");
                    if (postRef != string.Empty)
                    {
                        sw.WriteLine(indent + "\t\t\t" + postRef);
                    }
                }
            }

            if (!IsStatic && implementor != null)
            {
                implementor.Finish(sw, indent + "\t\t\t");
            }
            Body.Finish(sw, indent);
            Body.HandleException(sw, indent);

            if (is_get && Parameters.Count > 0)
            {
                sw.WriteLine(indent + "\t\t\treturn " + Parameters.AccessorName + ";");
            }
            else if (!retval.IsVoid)
            {
                sw.WriteLine(indent + "\t\t\treturn " + (cacheValue ? cacheName : "ret") + ";");
            }
            else if (IsAccessor)
            {
                Body.FinishAccessor(sw, Signature, indent);
            }

            sw.Write(indent + "\t\t}");
        }