static GList *
nautilus_python_object_get_property_pages (NautilusPropertyPageProvider *provider,
                                           GList                         *files) {
    NautilusPythonObject *object = (NautilusPythonObject*)provider;
    PyObject *py_files, *py_ret = NULL;
    GList *ret = NULL;
    PyGILState_STATE state = pyg_gil_state_ensure();
    
    debug_enter();

    CHECK_OBJECT(object);
    CHECK_METHOD_NAME(object->instance);

    CONVERT_LIST(py_files, files);
    
    py_ret = PyObject_CallMethod(object->instance, METHOD_PREFIX METHOD_NAME,
                                 "(N)", py_files);
    HANDLE_RETVAL(py_ret);

    HANDLE_LIST(py_ret, NautilusPropertyPage, "Nautilus.PropertyPage");
    
beach:
    Py_XDECREF(py_ret);
    pyg_gil_state_release(state);
    return ret;
}
static GList *
nautilus_python_object_get_columns (NautilusColumnProvider *provider) {
    NautilusPythonObject *object = (NautilusPythonObject*)provider;
    GList *ret = NULL;
    PyObject *py_ret = NULL;
    PyGILState_STATE state = pyg_gil_state_ensure();                                    \

    debug_enter();
        
    CHECK_OBJECT(object);
    CHECK_METHOD_NAME(object->instance);

    py_ret = PyObject_CallMethod(object->instance, METHOD_PREFIX METHOD_NAME,
                                 NULL);

    HANDLE_RETVAL(py_ret);

    HANDLE_LIST(py_ret, NautilusColumn, "Nautilus.Column");
    
beach:
    if (py_ret != NULL)
        Py_XDECREF(py_ret);
    pyg_gil_state_release(state);
    return ret;
}
static NemoOperationResult
nemo_python_object_update_file_info (NemoInfoProvider 		*provider,
										 NemoFile 				*file,
										 GClosure 					*update_complete,
										 NemoOperationHandle   **handle)
{
	NemoPythonObject *object = (NemoPythonObject*)provider;
    NemoOperationResult ret = NEMO_OPERATION_COMPLETE;
    PyObject *py_ret = NULL;
	PyGILState_STATE state = pyg_gil_state_ensure();
	PyObject *py_handle = nemo_python_boxed_new (_PyNemoOperationHandle_Type, *handle, FALSE);

  	debug_enter();

	CHECK_OBJECT(object);

	if (PyObject_HasAttrString(object->instance, "update_file_info_full"))
	{
		py_ret = PyObject_CallMethod(object->instance,
									 METHOD_PREFIX "update_file_info_full", "(NNNN)",
									 pygobject_new((GObject*)provider),
									 py_handle,
									 pyg_boxed_new(G_TYPE_CLOSURE, update_complete, TRUE, TRUE),
									 pygobject_new((GObject*)file));
	}
	else if (PyObject_HasAttrString(object->instance, "update_file_info"))
	{
		py_ret = PyObject_CallMethod(object->instance,
									 METHOD_PREFIX METHOD_NAME, "(N)",
									 pygobject_new((GObject*)file));
	}
	else
	{
		goto beach;
	}
	
	HANDLE_RETVAL(py_ret);

	if (!PyInt_Check(py_ret))
	{
		PyErr_SetString(PyExc_TypeError,
						METHOD_NAME " must return None or a int");
		goto beach;
	}

	ret = PyInt_AsLong(py_ret);
	
 beach:
 	free_pygobject_data(file, NULL);
	Py_XDECREF(py_ret);
	pyg_gil_state_release(state);
    return ret;
}
static GList *
nemo_python_object_get_file_items (NemoMenuProvider *provider,
									   GtkWidget 			*window,
									   GList 				*files)
{
	NemoPythonObject *object = (NemoPythonObject*)provider;
    GList *ret = NULL;
    PyObject *py_ret = NULL, *py_files;
	PyGILState_STATE state = pyg_gil_state_ensure();
	
  	debug_enter();

	CHECK_OBJECT(object);	

	if (PyObject_HasAttrString(object->instance, "get_file_items_full"))
	{
		CONVERT_LIST(py_files, files);
		py_ret = PyObject_CallMethod(object->instance, METHOD_PREFIX "get_file_items_full",
									 "(NNN)",
									 pygobject_new((GObject *)provider), 
									 pygobject_new((GObject *)window), 
									 py_files);
	}
	else if (PyObject_HasAttrString(object->instance, "get_file_items"))
	{
		CONVERT_LIST(py_files, files);
		py_ret = PyObject_CallMethod(object->instance, METHOD_PREFIX METHOD_NAME,
									 "(NN)", 
									 pygobject_new((GObject *)window), 
									 py_files);
	}
	else
	{
		goto beach;
	}

	HANDLE_RETVAL(py_ret);

	HANDLE_LIST(py_ret, NemoMenuItem, "Nemo.MenuItem");

 beach:
 	free_pygobject_data_list(files);
	Py_XDECREF(py_ret);
	pyg_gil_state_release(state);
    return ret;
}
static GList *
caja_python_object_get_background_items (CajaMenuProvider *provider,
											 GtkWidget 			  *window,
											 CajaFileInfo 	  *file)
{
	CajaPythonObject *object = (CajaPythonObject*)provider;
    GList *ret = NULL;
    PyObject *py_ret = NULL;
	PyGILState_STATE state = pyg_gil_state_ensure();
	
  	debug_enter();

	CHECK_OBJECT(object);

	if (PyObject_HasAttrString(object->instance, "get_background_items_full"))
	{
		py_ret = PyObject_CallMethod(object->instance, METHOD_PREFIX "get_background_items_full",
									 "(NNN)",
									 pygobject_new((GObject *)provider),
									 pygobject_new((GObject *)window),
									 pygobject_new((GObject *)file));
	}
	else if (PyObject_HasAttrString(object->instance, "get_background_items"))
	{
		py_ret = PyObject_CallMethod(object->instance, METHOD_PREFIX METHOD_NAME,
									 "(NN)",
									 pygobject_new((GObject *)window),
									 pygobject_new((GObject *)file));
	}
	else
	{
		goto beach;
	}

	HANDLE_RETVAL(py_ret);

	HANDLE_LIST(py_ret, CajaMenuItem, "Caja.MenuItem");
	
 beach:
	free_pygobject_data(file, NULL);
	Py_XDECREF(py_ret);
	pyg_gil_state_release(state);
    return ret;
}
static GtkWidget *
nemo_python_object_get_widget (NemoLocationWidgetProvider *provider,
								   const char 				 	  *uri,
								   GtkWidget 					  *window)
{
	NemoPythonObject *object = (NemoPythonObject*)provider;
	GtkWidget *ret = NULL;
	PyObject *py_ret = NULL;
	PyGObject *py_ret_gobj;
	PyObject *py_uri = NULL;
	PyGILState_STATE state = pyg_gil_state_ensure();

	debug_enter();

	CHECK_OBJECT(object);
	CHECK_METHOD_NAME(object->instance);

	py_uri = PyString_FromString(uri);

	py_ret = PyObject_CallMethod(object->instance, METHOD_PREFIX METHOD_NAME,
								 "(NN)", py_uri,
								 pygobject_new((GObject *)window));
	HANDLE_RETVAL(py_ret);

	py_ret_gobj = (PyGObject *)py_ret;
	if (!pygobject_check(py_ret_gobj, &PyGtkWidget_Type))
	{
		PyErr_SetString(PyExc_TypeError,
					    METHOD_NAME "should return a gtk.Widget");
		goto beach;
	}
	ret = (GtkWidget *)g_object_ref(py_ret_gobj->obj);

 beach:
	Py_XDECREF(py_ret);
	pyg_gil_state_release(state);
	return ret;
}
static CajaOperationResult
caja_python_object_update_file_info (CajaInfoProvider 		*provider,
										 CajaFile 				*file,
										 GClosure 					*update_complete,
										 CajaOperationHandle   **handle)
{
	CajaPythonObject *object = (CajaPythonObject*)provider;
    CajaOperationResult ret = CAJA_OPERATION_COMPLETE;
    PyObject *py_ret = NULL;
	PyGILState_STATE state = pyg_gil_state_ensure();
	static volatile gssize handle_generator = 1;

  	debug_enter();

	CHECK_OBJECT(object);

	*handle = NULL;

	if (PyObject_HasAttrString(object->instance, "update_file_info_full"))
	{
        PyObject *py_handle;
		void *h;

        /* Generate a new handle with a default value. */
        do {
            h = (CajaOperationHandle *) g_atomic_pointer_add (&handle_generator, 1);
        } while (!h);
        py_handle = caja_python_boxed_new (_PyCajaOperationHandle_Type,
                                           h, FALSE);


		py_ret = PyObject_CallMethod(object->instance,
									 METHOD_PREFIX "update_file_info_full", "(NNNN)",
									 pygobject_new((GObject*)provider),
									 py_handle,
									 pyg_boxed_new(G_TYPE_CLOSURE, update_complete, TRUE, TRUE),
									 pygobject_new((GObject*)file));
		*handle = (void *) ((PyGBoxed *) py_handle)->boxed;
	}
	else if (PyObject_HasAttrString(object->instance, "update_file_info"))
	{
		py_ret = PyObject_CallMethod(object->instance,
									 METHOD_PREFIX METHOD_NAME, "(N)",
									 pygobject_new((GObject*)file));
	}
	else
	{
		goto beach;
	}
	
	HANDLE_RETVAL(py_ret);

	if (!INT_CHECK(py_ret))
	{
		PyErr_SetString(PyExc_TypeError,
						METHOD_NAME " must return None or a int");
		goto beach;
	}

	ret = INT_ASLONG(py_ret);

    if (!*handle && ret == CAJA_OPERATION_IN_PROGRESS)
        ret = CAJA_OPERATION_FAILED;
	
 beach:
 	free_pygobject_data(file, NULL);
	Py_XDECREF(py_ret);
	pyg_gil_state_release(state);
    return ret;
}