--- old/gnome-python/pygobject/examples/Makefile.am	2006-01-09 13:26:45.000000000 +0100
+++ gnome-python/pygobject/examples/Makefile.am	2006-04-14 22:56:27.000000000 +0200
@@ -1 +1,2 @@
-EXTRA_DIST = properties.py signal.py
+EXTRA_DIST = properties.py signal.py option.py
+
--- old/gnome-python/pygobject/examples/option.py	1970-01-01 01:00:00.000000000 +0100
+++ gnome-python/pygobject/examples/option.py	2006-04-14 23:14:31.000000000 +0200
@@ -0,0 +1,57 @@
+#!/usr/bin/env python
+# gnome-python/pygobject/examples/option.py
+
+import gobject
+import sys
+import os
+
+filename = None
+
+class TestController(object):
+    def __init__(self):
+        self.opts = gobject.OptionGroup("test", "Test Controller Options:", "Show all Test Controller options")
+        self.opts.set_parse_hooks(self.pre, self.post)
+        self.opts.set_error_hook(self.error)
+        
+        self.opts.add_entries([
+            ("string", "s", 0, gobject.OPTION_ARG_STRING, 'string', "Sets the string to STRING.", "STRING"),
+            ("list", "l", 0, gobject.OPTION_ARG_STRING_ARRAY, 'list', "Multiple string arguements", "STRING"),
+        ])
+        
+    def get_option_group(self):
+        return self.opts
+
+    def pre(self, group):
+        print "TestController.pre"
+        
+    def post(self, group):
+        print "TestController.post"
+        print "string", self.opts['string']
+        print "list", self.opts['list']
+        
+    def error(self, group):
+        print "TestController.error"
+
+if __name__ == '__main__':
+    controller = TestController()
+
+    try:
+        ctxt = gobject.OptionContext("- A simple GOptionContext and GOptionGroup example")
+
+        def setFilename(option_name, option_value, group):
+            filename = option_value
+        
+        ctxt.add_main_entries([
+            ("file", "f", 0, gobject.OPTION_ARG_CALLBACK, setFilename, "FILE must exist", "FILE"),
+            ("number", "n", 0, gobject.OPTION_ARG_INT, 'number', "Sets the integer to NUM", "NUM"),
+        ])
+
+        ctxt.add_group(controller.get_option_group())
+
+        ctxt.parse(sys.argv)
+        
+        print "Number", ctxt.get_main_group()['number']
+        print "Filename", filename
+    except gobject.GError, err:
+        print err
+        
--- old/gnome-python/pygobject/gobject/Makefile.am	2006-04-11 17:14:36.000000000 +0200
+++ gnome-python/pygobject/gobject/Makefile.am	2006-04-14 22:56:27.000000000 +0200
@@ -34,7 +34,9 @@ _gobject_la_SOURCES = \
 	pygpointer.c \
 	pygiochannel.c \
 	pygsource.c \
-	pygtype.c
+	pygtype.c \
+	pygoptioncontext.c \
+	pygoptiongroup.c
 
 if PLATFORM_WIN32
 _gobject_la_CFLAGS += -DPLATFORM_WIN32
--- old/gnome-python/pygobject/gobject/pygoptioncontext.c	1970-01-01 01:00:00.000000000 +0100
+++ gnome-python/pygobject/gobject/pygoptioncontext.c	2006-04-14 22:56:56.000000000 +0200
@@ -0,0 +1,313 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pygtk- Python bindings for the GTK toolkit.
+ * Copyright (C) 2006  Johannes Hölzl
+ *
+ *   pygoptioncontext.c: GOptionContext wrapper
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "pygobject-private.h"
+
+static int
+pyg_option_context_init(PyGOptionContext *self, 
+                        PyObject *args,
+                        PyObject *kwargs)
+{
+    char *parameter_string;
+    if (! PyArg_ParseTuple(args, "s:gobject.GOptionContext.__init__", &parameter_string))
+        return -1;
+    
+    self->context = g_option_context_new(parameter_string);
+    return 0;
+}
+
+static void
+pyg_option_context_dealloc(PyGOptionContext *self)
+{
+    Py_XDECREF(self->main_group);
+    self->main_group = NULL;
+    
+    if(self->context != NULL)
+    {
+        g_option_context_free(self->context);
+        self->context = NULL;
+    }
+
+    PyObject_Del(self);
+}
+
+static PyObject *
+pyg_option_context_parse(PyGOptionContext *self, PyObject *argv)
+{
+    PyObject *arg;
+    PyObject *new_argv;
+    gssize argv_length, pos;
+    char **argv_content, **original;
+    GError *error = NULL;
+    gboolean result;
+    
+    argv_length = PySequence_Size(argv);
+    if(argv_length == -1)
+    {
+        PyErr_SetString(PyExc_TypeError, 
+                        "GOptionContext.parse expects a list of strings.");
+        return NULL;
+    }
+    
+    argv_content = g_new(char*, PySequence_Size(argv) + 1);
+    argv_content[argv_length] = NULL;
+    for(pos = 0; pos < argv_length; pos++)
+    {
+        arg = PySequence_GetItem(argv, pos);
+        argv_content[pos] = g_strdup(PyString_AsString(arg));
+        if(argv_content[pos] == NULL)
+        {
+            g_strfreev(argv_content);
+            return NULL;
+        }
+    }
+    original = g_memdup(argv_content, sizeof(char*) * (PySequence_Size(argv) + 1));
+    
+    pyg_begin_allow_threads;
+    result = g_option_context_parse(self->context, &argv_length, &argv_content, &error);
+    pyg_end_allow_threads;
+
+    if(! result)
+    {
+        g_free(argv_content);
+        g_strfreev(original);
+        pyg_error_check(&error);
+        return NULL;
+    }
+    
+    new_argv = PyList_New(0);
+    for(pos = 0; pos < argv_length; pos++)
+    {
+        arg = PyString_FromString(argv_content[pos]);
+        PyList_Append(new_argv, arg);
+    }
+    
+    g_strfreev(original);
+    g_free(argv_content);
+    return new_argv;
+}
+
+static PyObject *
+pyg_option_context_set_help_enabled(PyGOptionContext *self,
+                                    PyObject *enabled)
+{
+    g_option_context_set_help_enabled(self->context, PyObject_IsTrue(enabled));
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+pyg_option_context_get_help_enabled(PyGOptionContext *self)
+{
+    return PyBool_FromLong(g_option_context_get_help_enabled(self->context));
+}
+
+static PyObject *
+pyg_option_context_set_ignore_unknown_options(PyGOptionContext *self,
+                                              PyObject *ignore)
+{
+    g_option_context_set_ignore_unknown_options(self->context, 
+                                                PyObject_IsTrue(ignore));
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+pyg_option_context_get_ignore_unknown_options(PyGOptionContext *self)
+{
+    return PyBool_FromLong(
+        g_option_context_get_ignore_unknown_options(self->context));
+}
+
+static PyObject *
+pyg_option_context_set_main_group(PyGOptionContext *self,
+                                  PyObject *group)
+{
+    GOptionGroup* g_group;
+    if(PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) {
+        PyErr_SetString(PyExc_TypeError, "GOptionContext.set_main_group expects a GOptionGroup.");
+        return NULL;
+    }
+    g_group = pyg_option_group_transfer_group((PyGOptionGroup*) group);
+    if(g_group == NULL)
+    {
+        PyErr_SetString(PyExc_RuntimeError, "Group is already in a OptionContext.");
+        return NULL;
+    }
+
+    g_option_context_set_main_group(self->context, g_group);
+    Py_IncRef(group);
+    self->main_group = (PyGOptionGroup*) group;
+    
+    Py_RETURN_NONE;
+}
+
+static PyObject *
+pyg_option_context_get_main_group(PyGOptionContext *self)
+{
+    if(self->main_group == NULL)
+        Py_RETURN_NONE;
+        
+    Py_INCREF(self->main_group);
+    return (PyObject*) self->main_group;
+}
+
+static PyObject *
+pyg_option_context_add_group(PyGOptionContext *self,
+                             PyObject *group)
+{
+    GOptionGroup* g_group;
+    if(PyObject_IsInstance(group, (PyObject*) &PyGOptionGroup_Type) != 1) {
+        PyErr_SetString(PyExc_TypeError, "GOptionContext.add_group expects a GOptionGroup.");
+        return NULL;
+    }
+    g_group = pyg_option_group_transfer_group((PyGOptionGroup*) group);
+    if(g_group == NULL)
+    {
+        PyErr_SetString(PyExc_RuntimeError, "Group is already in a OptionContext.");
+        return NULL;
+    }
+    g_option_context_add_group(self->context, g_group);
+    Py_IncRef(group);
+    
+    Py_RETURN_NONE;
+} 
+
+static PyObject*
+pyg_option_context_add_main_entries(PyGOptionContext *self, PyObject *args)
+{
+    PyObject *entries, *domain = NULL, *func_name;
+    
+    if(! PyArg_ParseTuple(args, "O|O:OptionContext.add_main_entries", &entries, &domain))
+        return NULL;
+    
+    if(self->main_group == NULL) {
+        self->main_group = (PyGOptionGroup*) PyObject_CallFunctionObjArgs(
+            (PyObject*) &PyGOptionGroup_Type, Py_None, Py_None, Py_None, NULL);
+        g_option_context_set_main_group(self->context, self->main_group->group); 
+    }
+
+    func_name = PyString_FromString("add_entries");
+    if(PyObject_CallMethodObjArgs((PyObject *) self->main_group, func_name, entries, NULL) == NULL)
+    {
+        Py_DECREF(func_name);
+        return NULL;
+    }
+        
+    Py_DECREF(func_name);
+
+    if(domain != NULL)
+    {
+        func_name = PyString_FromString("set_translation_domain");
+        if(PyObject_CallMethodObjArgs((PyObject *) self->main_group, func_name, domain, NULL) == NULL)
+        {
+            Py_DECREF(func_name);
+            return NULL;
+        }
+        
+        Py_DECREF(func_name);
+    }
+
+    Py_RETURN_NONE;
+    
+        
+}
+
+static int
+pyg_option_context_compare(PyGOptionContext *self, PyGOptionContext *v)
+{
+    if (self->context == v->context) return 0;
+    if (self->context > v->context) return -1;
+    return 1;
+}
+
+static PyMethodDef pyg_option_context_methods[] = {
+    { "parse", (PyCFunction)pyg_option_context_parse, METH_O },
+    { "set_help_enabled", (PyCFunction)pyg_option_context_set_help_enabled, METH_O },
+    { "get_help_enabled", (PyCFunction)pyg_option_context_get_help_enabled, METH_NOARGS },
+    { "set_ignore_unknown_options", (PyCFunction)pyg_option_context_set_ignore_unknown_options, METH_O },
+    { "get_ignore_unknown_options", (PyCFunction)pyg_option_context_get_ignore_unknown_options, METH_NOARGS },
+    { "add_main_entries", (PyCFunction)pyg_option_context_add_main_entries, METH_VARARGS },
+    { "set_main_group", (PyCFunction)pyg_option_context_set_main_group, METH_O },
+    { "get_main_group", (PyCFunction)pyg_option_context_get_main_group, METH_NOARGS },
+    { "add_group", (PyCFunction)pyg_option_context_add_group, METH_O },
+    { NULL, NULL, 0 },
+};
+
+PyTypeObject PyGOptionContext_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "gobject.OptionContext",
+    sizeof(PyGMainContext),
+    0,
+    /* methods */
+    (destructor)pyg_option_context_dealloc,
+    (printfunc)0,
+    (getattrfunc)0,
+    (setattrfunc)0,
+    (cmpfunc)pyg_option_context_compare,
+    (reprfunc)0,
+    0,
+    0,
+    0,
+    (hashfunc)0,
+    (ternaryfunc)0,
+    (reprfunc)0,
+    (getattrofunc)0,
+    (setattrofunc)0,
+    0,
+    Py_TPFLAGS_DEFAULT,
+    NULL,
+    (traverseproc)0,
+    (inquiry)0,
+    (richcmpfunc)0,
+    0,
+    (getiterfunc)0,
+    (iternextfunc)0,
+    pyg_option_context_methods,
+    0,
+    0,
+    NULL,
+    NULL,
+    (descrgetfunc)0,
+    (descrsetfunc)0,
+    0,
+    (initproc)pyg_option_context_init,
+};
+
+PyObject * 
+pyg_option_context_new (GOptionContext *context)
+{
+    PyGOptionContext *self;
+
+    self = (PyGOptionContext *)PyObject_NEW(PyGOptionContext,
+					    &PyGOptionContext_Type);
+    if (self == NULL)
+	return NULL;
+
+    self->context = context;
+    self->main_group = NULL;
+    
+    return (PyObject *)self;
+}
--- old/gnome-python/pygobject/gobject/pygoptiongroup.c	1970-01-01 01:00:00.000000000 +0100
+++ gnome-python/pygobject/gobject/pygoptiongroup.c	2006-04-15 00:02:49.000000000 +0200
@@ -0,0 +1,651 @@
+/* -*- Mode: C; c-basic-offset: 4 -*-
+ * pygtk- Python bindings for the GTK toolkit.
+ * Copyright (C) 2006  Johannes Hölzl
+ *
+ *   pygoptiongroup.c: GOptionContext and GOptionGroup wrapper
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ * USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include "pygobject-private.h"
+
+typedef struct {
+    GOptionArg arg;
+    union {
+        gboolean none;
+        gchar *string;
+        gint int_;
+        gchar **string_array;
+    } value;
+} ArgDescription;
+
+static void arg_description_free(ArgDescription *desc)
+{
+    switch(desc->arg)
+    {
+        case G_OPTION_ARG_NONE: break;
+
+        case G_OPTION_ARG_STRING:
+        case G_OPTION_ARG_FILENAME:
+            g_free(desc->value.string);
+            break;
+
+        case G_OPTION_ARG_INT: break;
+
+        case G_OPTION_ARG_CALLBACK: break;
+
+        case G_OPTION_ARG_STRING_ARRAY:
+        case G_OPTION_ARG_FILENAME_ARRAY:
+            g_free(desc->value.string_array);
+            break;
+    }
+    g_free(desc);
+}
+
+static gboolean 
+append_hash_table_cb(gchar *name,
+                     ArgDescription *desc,
+                     GHashTable *other)
+{
+    g_hash_table_insert(other, name, desc);
+    return TRUE;
+}
+
+static gboolean 
+arg_func(const gchar *option_name,
+         const gchar *value,
+         PyGOptionGroup *self,
+         GError *error)
+{
+   PyObject *obj, *cb;
+   cb = g_hash_table_lookup(self->arg_name_callback_map, option_name);
+   obj = PyObject_CallFunction(cb, "ssO", option_name, value, self);
+
+   if(obj == NULL)
+       return FALSE;
+
+   Py_DECREF(obj);
+   return TRUE;      
+}
+
+static gboolean
+parse_entries(PyObject *sequence, 
+              PyGOptionGroup *group)
+{
+    gssize entry_count, pos;
+    PyObject *tuple;
+    PyObject *arg_name;
+    ArgDescription *desc;
+    GHashTable *new_args, *new_cbs;
+    GOptionEntry *entries;
+    gchar *long_name, *short_name;
+    
+    entry_count = PySequence_Size(sequence);
+    if(entry_count == -1)
+    {
+        PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries expected a list of entries");
+        return FALSE;
+    }
+    
+    new_args = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                     g_free, (GDestroyNotify) arg_description_free);
+    new_cbs = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                    g_free, (GDestroyNotify) Py_DecRef);
+    entries = g_new0(GOptionEntry, entry_count + 1);
+    for(pos = 0; pos < entry_count; pos++)
+    {
+        tuple = PySequence_GetItem(sequence, pos);
+        if(! PyArg_ParseTuple(tuple, "sciiOss",
+            &(entries[pos].long_name),
+            &(entries[pos].short_name),
+            &(entries[pos].flags),
+            &(entries[pos].arg),
+            &(arg_name),
+            &(entries[pos].description),
+            &(entries[pos].arg_description)))
+        {
+            PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries expected a list of entries");
+            goto failed;
+        }
+
+        if(entries[pos].arg == G_OPTION_ARG_CALLBACK)
+        {
+            long_name = g_strdup_printf("--%s", entries[pos].long_name);
+            if(g_hash_table_lookup(group->arg_name_callback_map, long_name) != NULL ||
+               g_hash_table_lookup(new_cbs, long_name) != NULL)
+            {
+               g_free(long_name);
+               PyErr_SetString(PyExc_ValueError, "GOptionGroup.add_entries got an long_name which is already assigned to an entry in this group.");
+               goto failed;
+            }
+            g_hash_table_insert(new_cbs, long_name, arg_name);
+            Py_INCREF(arg_name);
+            
+            if(entries[pos].short_name != '\0')
+            {
+                short_name = g_strdup_printf("-%c", entries[pos].short_name);
+                if(g_hash_table_lookup(group->arg_name_callback_map, short_name) != NULL ||
+                   g_hash_table_lookup(new_cbs, short_name) != NULL)
+                {
+                   g_free(short_name);
+                   PyErr_SetString(PyExc_ValueError, "GOptionGroup.add_entries got an short_name which is already assigned to an entry in this group.");
+                   goto failed;
+                }
+                g_hash_table_insert(new_cbs, short_name, arg_name);
+                Py_INCREF(arg_name);
+            }
+            
+            
+            entries[pos].arg_data = arg_func;
+        }
+        else
+        {
+            desc = g_new0(ArgDescription, 1);
+            desc->arg = entries[pos].arg;
+            if(! PyString_Check(arg_name))
+            {
+               g_free(desc);
+               PyErr_SetString(PyExc_TypeError, "GOptionGroup.add_entries expects a string as arg_name.");
+               goto failed;
+            }
+            long_name = g_strdup(PyString_AsString(arg_name));
+            if(g_hash_table_lookup(group->arg_name_value_map, long_name) != NULL ||
+               g_hash_table_lookup(new_args, long_name)) {
+               g_free(long_name);
+               g_free(desc);
+               PyErr_SetString(PyExc_ValueError, "GOptionGroup.add_entries got an arg_name which is already assigned to an entry in this group.");
+               goto failed;
+            }
+         g_hash_table_insert(new_args, long_name, desc);
+             entries[pos].arg_data = &(desc->value);
+        }
+    }
+    
+    g_hash_table_foreach_steal(new_args, (GHRFunc) append_hash_table_cb, group->arg_name_value_map);
+    g_hash_table_destroy(new_args);
+
+    g_hash_table_foreach_steal(new_cbs, (GHRFunc) append_hash_table_cb, group->arg_name_callback_map);
+    g_hash_table_destroy(new_cbs);
+    
+    g_option_group_add_entries(group->group, entries);
+    
+    g_free(entries);
+    
+    return TRUE;
+    
+failed:
+    g_free(entries);
+    g_hash_table_destroy(new_args);
+    g_hash_table_destroy(new_cbs);
+    return FALSE;
+}
+
+static void destroy_g_group(PyGOptionGroup *self)
+{
+    GOptionGroup *group = self->group;
+    self->group = NULL;
+    if(group != NULL)
+    {
+        if(self->is_in_context)
+        {
+            Py_DECREF(self);
+        }
+           
+        if(self->arg_name_callback_map != NULL)
+        {
+            g_hash_table_destroy(self->arg_name_callback_map);
+            self->arg_name_callback_map = NULL;
+        }
+        
+        Py_XDECREF(self->pre_hook);
+        self->pre_hook = NULL;
+        
+        Py_XDECREF(self->post_hook);
+        self->post_hook = NULL;
+        
+        Py_XDECREF(self->hooks_arg);
+        self->hooks_arg = NULL;
+        
+        Py_XDECREF(self->error_hook);
+        self->error_hook = NULL;
+        
+        Py_XDECREF(self->translate_func);
+        self->translate_func = NULL;
+        
+        Py_XDECREF(self->translate_func_arg);
+        self->translate_func_arg = NULL;
+    }
+}
+
+static gboolean
+call_parse_func(PyGOptionGroup *self,
+                GOptionContext *context,
+                PyObject *func,
+                PyObject *arg,
+                GError **error)
+{
+   PyObject *obj;
+   if (func == NULL) return TRUE;
+   
+   if(arg != NULL)
+       obj = PyObject_CallFunction(func, "OO", self, arg);
+   else
+       obj = PyObject_CallFunction(func, "O", self);
+
+   if(obj == NULL)
+       return FALSE;
+      
+   Py_DECREF(obj);
+   return TRUE;
+}
+
+static gboolean
+check_if_owned(PyGOptionGroup *self)
+{
+    if(self->other_owner)
+    {
+        PyErr_SetString(PyExc_ValueError, "The GOptionGroup was not created by gobject.OptionGroup(), so operation is not possible.");
+        return TRUE;
+    }
+    return FALSE;
+}
+
+GOptionGroup *
+pyg_option_group_transfer_group(PyGOptionGroup *self)
+{
+    if(self->is_in_context) return NULL;
+    self->is_in_context = TRUE;
+    
+    /* Here we increase the reference count of the PyGOptionGroup, because now
+     * the GOptionContext holds an reference to us (it is the userdata passed
+     * to g_option_group_new().
+     *
+     * The GOptionGroup is freed with the GOptionContext.
+     *
+     * We set it here because if we would do this in the init method we would
+     * hold two references and the PyGOptionGroup would never be freed.
+     */
+    Py_INCREF(self);
+    
+    return self->group;
+}
+
+static PyObject *
+pyg_option_group_add_entries(PyGOptionGroup *self, PyObject *sequence)
+{
+    if(check_if_owned(self)) return NULL;
+    
+    if(! parse_entries(sequence, self))
+        return NULL;
+
+    Py_RETURN_NONE;
+}
+
+static gboolean
+pre_hook(GOptionContext *context,
+         GOptionGroup *group,
+         PyGOptionGroup *pyg,
+         GError **error)
+{
+    return call_parse_func(pyg, context, pyg->pre_hook, pyg->hooks_arg, error);
+}
+
+static gboolean
+post_hook(GOptionContext *context,
+          GOptionGroup *group,
+          PyGOptionGroup *pyg,
+          GError **error)
+{
+    return call_parse_func(pyg, context, pyg->post_hook, pyg->hooks_arg, error);
+}
+
+static void
+error_hook(GOptionContext *context, 
+           GOptionGroup *group,
+           PyGOptionGroup *pyg,
+           GError **error)
+{
+    call_parse_func(pyg, context, pyg->error_hook, pyg->error_hook_arg, error);
+}
+
+static int
+pyg_option_group_init(PyGOptionGroup *self, PyObject *args)
+{
+    char *name, *description, *help_description;
+    if (! PyArg_ParseTuple(args, "zzz:GOptionGroup.__init__", 
+                           &name, &description, &help_description))
+        return -1;
+    
+    self->group = g_option_group_new(name, description, help_description,
+                                     self, (GDestroyNotify) destroy_g_group);
+    g_option_group_set_parse_hooks(self->group, 
+                                   (GOptionParseFunc) pre_hook,
+                                   (GOptionParseFunc) post_hook);
+    g_option_group_set_error_hook(self->group, (GOptionErrorFunc) error_hook);
+    self->other_owner = FALSE;
+    self->is_in_context = FALSE;
+    self->arg_name_value_map = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, 
+                                                     (GDestroyNotify) arg_description_free);
+    self->arg_name_callback_map = g_hash_table_new_full(g_str_hash, g_str_equal,
+                                                        g_free, (GDestroyNotify) Py_DecRef);
+    return 0;
+}
+
+static void
+pyg_option_group_dealloc(PyGOptionGroup *self)
+{
+    if(! self->other_owner)
+    {
+        if(self->group != NULL)
+            g_option_group_free(self->group);
+    }
+
+    if(self->arg_name_value_map != NULL)    
+        g_hash_table_destroy(self->arg_name_value_map);
+    
+    PyObject_Del(self);
+}
+
+static PyObject *
+pyg_option_group_set_parse_hooks(PyGOptionGroup *self, PyObject *args)
+{
+    PyObject *pre, *post, *arg = NULL;
+    if(check_if_owned(self)) return NULL;
+    
+    if(! PyArg_ParseTuple(args, "OO|O:GOptionGroup.set_parse_hooks", &pre, &post, &arg))
+        return NULL;
+    
+    if(! (PyCallable_Check(pre) || pre == Py_None) || 
+       ! (PyCallable_Check(post) || post == Py_None))
+    {
+        PyErr_SetString(PyExc_TypeError, "gobject.GOptionGroup.set_parse_hooks expects two callables.");
+        return NULL;
+    }
+    
+    Py_XDECREF(self->hooks_arg);
+    self->hooks_arg = arg;
+    Py_XINCREF(self->hooks_arg);
+
+    Py_XDECREF(self->pre_hook);
+    if(pre != Py_None)
+    {
+        self->pre_hook = pre;
+        Py_INCREF(self->pre_hook);
+    }
+    else
+        self->pre_hook = NULL;
+
+    Py_XDECREF(self->post_hook);
+    if(post != Py_None)
+    {
+        self->post_hook = post;
+        Py_INCREF(self->post_hook);
+    }
+    else
+        self->post_hook = NULL;
+    
+    Py_RETURN_NONE;    
+}
+
+static PyObject *
+pyg_option_group_set_error_hook(PyGOptionGroup *self, PyObject *args)
+{
+    PyObject *error, *arg = NULL;
+    if(check_if_owned(self)) return NULL;
+
+    if(! PyArg_ParseTuple(args, "O|O:GOptionGroup.set_error_hook", &error, &arg))
+        return NULL;
+
+    if(! (PyCallable_Check(error) || error == Py_None))
+    {
+        PyErr_SetString(PyExc_TypeError, "gobject.GOptionGroup.set_error_hook expects a callable.");
+        return NULL;
+    }
+
+    Py_XDECREF(self->error_hook_arg);
+    self->error_hook_arg = arg;
+    Py_XINCREF(self->error_hook_arg);
+
+    Py_XDECREF(self->error_hook);
+    if(error == Py_None)
+    {
+        self->error_hook = error;
+        Py_INCREF(self->error_hook);
+    }
+    else
+        self->error_hook = NULL;
+
+    Py_RETURN_NONE;    
+}
+
+static gchar *
+translate_func(const gchar *str,
+               PyGOptionGroup *self)
+{
+   PyObject *obj;
+   gchar *result;
+   if(self->translate_func_arg != NULL)
+       obj = PyObject_CallFunction(self->translate_func, "sOO", str, self, self->translate_func_arg);
+   else
+       obj = PyObject_CallFunction(self->translate_func, "sO", str, self);
+
+   if(obj == NULL)
+       return NULL;
+   result = g_strdup(PyString_AsString(obj));
+   Py_DECREF(obj);
+   
+   return result;
+}
+
+static PyObject *
+pyg_option_group_set_translate_func(PyGOptionGroup *self, PyObject *args)
+{
+    PyObject *translate, *arg = NULL;
+    if(check_if_owned(self)) return NULL;
+
+    if(self->group == NULL)
+    {
+        PyErr_SetString(PyExc_RuntimeError, "The corresponding GOptionGroup was already freed, probably through the release of GOptionContext");
+        return NULL;
+    }
+    if(! PyArg_ParseTuple(args, "O|O:GOptionGroup.set_translate_func", &translate, &arg))
+        return NULL;
+
+    if(! (PyCallable_Check(translate) || translate == Py_None))
+    {
+        PyErr_SetString(PyExc_TypeError, "gobject.GOptionGroup.set_translate_func expects a callable.");
+        return NULL;
+    }
+
+
+    Py_XDECREF(self->translate_func_arg);
+    self->translate_func_arg = arg;
+    Py_XINCREF(self->translate_func_arg);
+
+    Py_XDECREF(self->translate_func);
+    if(translate == Py_None)
+    {
+        g_option_group_set_translate_func(self->group, NULL, NULL, NULL);
+    }
+    else
+    {
+        self->translate_func = translate;
+        Py_INCREF(self->translate_func);
+        g_option_group_set_translate_func(self->group, 
+                                          (GTranslateFunc) translate_func, 
+                                          self, NULL);
+    }
+    Py_RETURN_NONE;    
+}
+
+static PyObject *
+pyg_option_group_set_translation_domain(PyGOptionGroup *self, PyObject *args)
+{
+    char *domain;
+    if(check_if_owned(self)) return NULL;
+
+    if(self->group == NULL)
+    {
+        PyErr_SetString(PyExc_RuntimeError, "The corresponding GOptionGroup was already freed, probably through the release of GOptionContext");
+        return NULL;
+    }
+    if(! PyArg_ParseTuple(args, "s:GOptionGroup.set_translate_domain", &domain))
+        return NULL;
+    g_option_group_set_translation_domain(self->group, domain);
+    Py_RETURN_NONE;    
+}
+
+static PyObject *
+pyg_option_group_getitem(PyGOptionGroup *self, 
+                         PyObject *name)
+{
+    char *name_str;
+    ArgDescription *arg;
+    int pos;
+    PyObject *list, *string;
+    
+    name_str = PyString_AsString(name);
+    if(name_str == NULL) return NULL;
+    
+    arg = g_hash_table_lookup(self->arg_name_value_map, name_str);
+    if(arg == NULL)
+    {
+        PyErr_SetString(PyExc_KeyError, "arg_name not found in OptionGroup.");
+        return NULL;
+    }
+    
+    switch(arg->arg) {
+        case G_OPTION_ARG_NONE:
+            if(arg->value.none)
+                Py_RETURN_TRUE;
+            else
+                Py_RETURN_FALSE;
+
+        case G_OPTION_ARG_STRING:
+        case G_OPTION_ARG_FILENAME:
+            if (arg->value.string == NULL)
+                Py_RETURN_NONE;
+            else
+                return PyString_FromString(arg->value.string);
+
+        case G_OPTION_ARG_INT:
+            return PyInt_FromLong(arg->value.int_);
+
+        case G_OPTION_ARG_STRING_ARRAY:
+        case G_OPTION_ARG_FILENAME_ARRAY:
+            if (arg->value.string_array == NULL)
+                Py_RETURN_NONE;
+
+            list = PyList_New(0);
+            
+            for(pos = 0; arg->value.string_array[pos] != NULL; pos++)
+            {
+                string = PyString_FromString(arg->value.string_array[pos]);
+                PyList_Append(list, string);
+                Py_DECREF(string);
+            }
+            return list;
+        case G_OPTION_ARG_CALLBACK:
+        default:
+            g_assert_not_reached();
+    }   
+}
+
+static int
+pyg_option_group_compare(PyGOptionGroup *self, PyGOptionGroup *v)
+{
+    if (self->group == v->group) return 0;
+    if (self->group > v->group) return -1;
+    return 1;
+}
+
+static PyMethodDef pyg_option_group_methods[] = {
+    { "add_entries", (PyCFunction)pyg_option_group_add_entries, METH_O },
+    { "set_parse_hooks", (PyCFunction)pyg_option_group_set_parse_hooks, METH_VARARGS },
+    { "set_error_hook", (PyCFunction)pyg_option_group_set_error_hook, METH_VARARGS },
+    { "set_translate_func", (PyCFunction)pyg_option_group_set_translate_func, METH_VARARGS },
+    { "set_translation_domain", (PyCFunction)pyg_option_group_set_translation_domain, METH_VARARGS },
+    { NULL, NULL, 0 },
+};
+
+static PyMappingMethods pyg_option_group_mapping_methods = {
+    0,
+    (binaryfunc) pyg_option_group_getitem,
+    0,
+};
+
+PyTypeObject PyGOptionGroup_Type = {
+    PyObject_HEAD_INIT(NULL)
+    0,
+    "gobject.OptionGroup",
+    sizeof(PyGOptionGroup),
+    0,
+    /* methods */
+    (destructor)pyg_option_group_dealloc,
+    (printfunc)0,
+    (getattrfunc)0,
+    (setattrfunc)0,
+    (cmpfunc)pyg_option_group_compare,
+    (reprfunc)0,
+    0,
+    0,
+    &pyg_option_group_mapping_methods,
+    (hashfunc)0,
+    (ternaryfunc)0,
+    (reprfunc)0,
+    (getattrofunc)0,
+    (setattrofunc)0,
+    0,
+    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+    NULL,
+    (traverseproc)0,
+    (inquiry)0,
+    (richcmpfunc)0,
+    0,
+    (getiterfunc)0,
+    (iternextfunc)0,
+    pyg_option_group_methods,
+    0,
+    0,
+    NULL,
+    NULL,
+    (descrgetfunc)0,
+    (descrsetfunc)0,
+    0,
+    (initproc)pyg_option_group_init,
+};
+
+PyObject * 
+pyg_option_group_new (GOptionGroup *group)
+{
+    PyGOptionGroup *self;
+
+    self = (PyGOptionGroup *)PyObject_NEW(PyGOptionGroup,
+					  &PyGOptionGroup_Type);
+    if (self == NULL)
+	return NULL;
+
+    self->group = group;
+    self->other_owner = TRUE;
+    self->is_in_context = FALSE;
+        
+    return (PyObject *)self;
+}
+
--- old/gnome-python/pygobject/gobject/gobjectmodule.c	2006-04-12 00:58:37.000000000 +0200
+++ gnome-python/pygobject/gobject/gobjectmodule.c	2006-04-14 22:59:13.000000000 +0200
@@ -3101,6 +3101,9 @@ init_gobject(void)
     REGISTER_TYPE(d, PyGTimeout_Type, "Timeout");
     REGISTER_TYPE(d, PyGPollFD_Type, "PollFD");
 
+    REGISTER_TYPE(d, PyGOptionContext_Type, "OptionContext");
+    REGISTER_TYPE(d, PyGOptionGroup_Type, "OptionGroup");
+
     /* glib version */
     tuple = Py_BuildValue ("(iii)", glib_major_version, glib_minor_version,
 			   glib_micro_version);
@@ -3167,7 +3170,34 @@ init_gobject(void)
     addint(IO_FLAG_GET_MASK);
     addint(IO_FLAG_SET_MASK);
 
+ 
+    addint(OPTION_ERROR_UNKNOWN_OPTION);
+    addint(OPTION_ERROR_BAD_VALUE);
+    addint(OPTION_ERROR_FAILED);
+     
+    addint(OPTION_ARG_NONE);
+    addint(OPTION_ARG_STRING);
+    addint(OPTION_ARG_INT);
+    addint(OPTION_ARG_CALLBACK);
+    addint(OPTION_ARG_FILENAME);
+    addint(OPTION_ARG_STRING_ARRAY);
+    addint(OPTION_ARG_FILENAME_ARRAY);
+
+    addint(OPTION_FLAG_HIDDEN);
+    addint(OPTION_FLAG_IN_MAIN);
+    addint(OPTION_FLAG_REVERSE);
+    addint(OPTION_FLAG_NO_ARG);
+    addint(OPTION_FLAG_FILENAME);
+    addint(OPTION_FLAG_OPTIONAL_ARG);
+    /* addint(OPTION_FLAG_NOALAIS); */
+ 
+    addint(OPTION_ERROR_UNKNOWN_OPTION);
+    addint(OPTION_ERROR_BAD_VALUE);
+    addint(OPTION_ERROR_FAILED);
+ 
 #undef addint
+  
+    PyModule_AddStringConstant(m, "OPTION_REMAINING", G_OPTION_REMAINING);
 
     PyModule_AddIntConstant(m, "SPAWN_LEAVE_DESCRIPTORS_OPEN",
 			    G_SPAWN_LEAVE_DESCRIPTORS_OPEN);
--- old/gnome-python/pygobject/gobject/pygobject-private.h	2006-04-11 23:51:06.000000000 +0200
+++ gnome-python/pygobject/gobject/pygobject-private.h	2006-04-14 22:56:27.000000000 +0200
@@ -217,4 +217,28 @@ typedef struct
 } PyGPollFD;
 
 
+/* pygoption.c */
+extern PyTypeObject PyGOptionContext_Type;
+extern PyTypeObject PyGOptionGroup_Type;
+
+typedef struct {
+    PyObject_HEAD
+    GHashTable *arg_name_value_map, *arg_name_callback_map;
+    GOptionGroup *group;
+    gboolean other_owner, is_in_context;
+    PyObject *pre_hook, *post_hook, *hooks_arg,
+             *error_hook, *error_hook_arg,
+             *translate_func, *translate_func_arg;
+} PyGOptionGroup;
+
+typedef struct {
+    PyObject_HEAD
+    PyGOptionGroup *main_group;
+    GOptionContext *context;
+} PyGOptionContext;
+
+PyObject * pyg_option_context_new (GOptionContext * context);
+PyObject * pyg_option_group_new (GOptionGroup * group);
+GOptionGroup *pyg_option_group_transfer_group(PyGOptionGroup *self);
+
 #endif
