gsubprocess: test environment a bit more
[platform/upstream/glib.git] / gio / tests / gdbus-test-codegen.c
index ea85a4b..62c17e0 100644 (file)
@@ -13,9 +13,7 @@
  * 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.
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
  *
  * Author: David Zeuthen <davidz@redhat.com>
  */
@@ -54,7 +52,7 @@ test_annotations (void)
   GDBusSignalInfo *signal;
   GDBusPropertyInfo *property;
 
-  iface = foo_bar_interface_info ();
+  iface = foo_igen_bar_interface_info ();
   g_assert (iface != NULL);
 
   /* see Makefile.am for where these annotations are injected */
@@ -87,20 +85,20 @@ test_annotations (void)
 /* ---------------------------------------------------------------------------------------------------- */
 
 static gboolean
-on_handle_hello_world (FooBar                 *object,
+on_handle_hello_world (FooiGenBar             *object,
                        GDBusMethodInvocation  *invocation,
                        const gchar            *greeting,
                        gpointer                user_data)
 {
   gchar *response;
-  response = g_strdup_printf ("Word! You said `%s'. I'm Stub, btw!", greeting);
-  foo_bar_complete_hello_world (object, invocation, response);
+  response = g_strdup_printf ("Word! You said '%s'. I'm Skeleton, btw!", greeting);
+  foo_igen_bar_complete_hello_world (object, invocation, response);
   g_free (response);
   return TRUE;
 }
 
 static gboolean
-on_handle_test_primitive_types (FooBar                *object,
+on_handle_test_primitive_types (FooiGenBar            *object,
                                 GDBusMethodInvocation *invocation,
                                 guchar                 val_byte,
                                 gboolean               val_boolean,
@@ -120,24 +118,24 @@ on_handle_test_primitive_types (FooBar                *object,
   gchar *s1;
   gchar *s2;
   gchar *s3;
-  s1 = g_strdup_printf ("Word! You said `%s'. Rock'n'roll!", val_string);
+  s1 = g_strdup_printf ("Word! You said '%s'. Rock'n'roll!", val_string);
   s2 = g_strdup_printf ("/modified%s", val_objpath);
   s3 = g_strdup_printf ("assgit%s", val_signature);
-  foo_bar_complete_test_primitive_types (object,
-                                         invocation,
-                                         10 + val_byte,
-                                         !val_boolean,
-                                         100 + val_int16,
-                                         1000 + val_uint16,
-                                         10000 + val_int32,
-                                         100000 + val_uint32,
-                                         1000000 + val_int64,
-                                         10000000 + val_uint64,
-                                         val_double / G_PI,
-                                         s1,
-                                         s2,
-                                         s3,
-                                         "bytestring!\xff");
+  foo_igen_bar_complete_test_primitive_types (object,
+                                              invocation,
+                                              10 + val_byte,
+                                              !val_boolean,
+                                              100 + val_int16,
+                                              1000 + val_uint16,
+                                              10000 + val_int32,
+                                              100000 + val_uint32,
+                                              1000000 + val_int64,
+                                              10000000 + val_uint64,
+                                              val_double / G_PI,
+                                              s1,
+                                              s2,
+                                              s3,
+                                              "bytestring!\xff");
   g_free (s1);
   g_free (s2);
   g_free (s3);
@@ -145,13 +143,13 @@ on_handle_test_primitive_types (FooBar                *object,
 }
 
 static gboolean
-on_handle_test_non_primitive_types (FooBar                *object,
+on_handle_test_non_primitive_types (FooiGenBar            *object,
                                     GDBusMethodInvocation *invocation,
                                     GVariant              *dict_s_to_s,
                                     GVariant              *dict_s_to_pairs,
                                     GVariant              *a_struct,
                                     const gchar* const    *array_of_strings,
-                                    GVariant              *array_of_objpaths,
+                                    const gchar* const    *array_of_objpaths,
                                     GVariant              *array_of_signatures,
                                     const gchar* const    *array_of_bytestrings,
                                     gpointer               user_data)
@@ -165,22 +163,22 @@ on_handle_test_non_primitive_types (FooBar                *object,
   s = g_strjoinv (", ", (gchar **) array_of_strings);
   g_string_append_printf (str, "array_of_strings: [%s] ", s);
   g_free (s);
-  s = g_variant_print (array_of_objpaths, TRUE);
-  g_string_append_printf (str, "array_of_objpaths: %s ", s);
+  s = g_strjoinv (", ", (gchar **) array_of_objpaths);
+  g_string_append_printf (str, "array_of_objpaths: [%s] ", s);
   g_free (s);
-  s = g_variant_print (array_of_objpaths, TRUE);
+  s = g_variant_print (array_of_signatures, TRUE);
   g_string_append_printf (str, "array_of_signatures: %s ", s);
   g_free (s);
   s = g_strjoinv (", ", (gchar **) array_of_bytestrings);
   g_string_append_printf (str, "array_of_bytestrings: [%s] ", s);
   g_free (s);
-  foo_bar_complete_test_non_primitive_types (object, invocation, str->str);
+  foo_igen_bar_complete_test_non_primitive_types (object, invocation, str->str);
   g_string_free (str, TRUE);
   return TRUE;
 }
 
 static gboolean
-on_handle_request_signal_emission (FooBar                 *object,
+on_handle_request_signal_emission (FooiGenBar             *object,
                                    GDBusMethodInvocation  *invocation,
                                    gint                    which_one,
                                    gpointer                user_data)
@@ -190,32 +188,52 @@ on_handle_request_signal_emission (FooBar                 *object,
       const gchar *a_strv[] = {"foo", "bar", NULL};
       const gchar *a_bytestring_array[] = {"foo\xff", "bar\xff", NULL};
       GVariant *a_variant = g_variant_new_parsed ("{'first': (42, 42), 'second': (43, 43)}");
-      foo_bar_emit_test_signal (object, 43, a_strv, a_bytestring_array, a_variant); /* consumes a_variant */
-      foo_bar_complete_request_signal_emission (object, invocation);
+      foo_igen_bar_emit_test_signal (object, 43, a_strv, a_bytestring_array, a_variant); /* consumes a_variant */
+      foo_igen_bar_complete_request_signal_emission (object, invocation);
     }
   return TRUE;
 }
 
 static gboolean
-on_handle_request_multi_property_mods (FooBar                 *object,
+on_handle_request_multi_property_mods (FooiGenBar             *object,
                                        GDBusMethodInvocation  *invocation,
                                        gpointer                user_data)
 {
-  foo_bar_set_y (object, foo_bar_get_y (object) + 1);
-  foo_bar_set_i (object, foo_bar_get_i (object) + 1);
-  foo_bar_set_y (object, foo_bar_get_y (object) + 1);
-  foo_bar_set_i (object, foo_bar_get_i (object) + 1);
-  g_dbus_interface_stub_flush (G_DBUS_INTERFACE_STUB (object));
-  foo_bar_set_y (object, foo_bar_get_y (object) + 1);
-  foo_bar_set_i (object, foo_bar_get_i (object) + 1);
-  foo_bar_complete_request_multi_property_mods (object, invocation);
+  foo_igen_bar_set_y (object, foo_igen_bar_get_y (object) + 1);
+  foo_igen_bar_set_i (object, foo_igen_bar_get_i (object) + 1);
+  foo_igen_bar_set_y (object, foo_igen_bar_get_y (object) + 1);
+  foo_igen_bar_set_i (object, foo_igen_bar_get_i (object) + 1);
+  g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (object));
+  foo_igen_bar_set_y (object, foo_igen_bar_get_y (object) + 1);
+  foo_igen_bar_set_i (object, foo_igen_bar_get_i (object) + 1);
+  foo_igen_bar_complete_request_multi_property_mods (object, invocation);
+  return TRUE;
+}
+
+static gboolean
+on_handle_property_cancellation (FooiGenBar             *object,
+                                 GDBusMethodInvocation  *invocation,
+                                 gpointer                user_data)
+{
+  guint n;
+  n = foo_igen_bar_get_n (object);
+  /* This queues up a PropertiesChange event */
+  foo_igen_bar_set_n (object, n + 1);
+  /* this modifies the queued up event */
+  foo_igen_bar_set_n (object, n);
+  /* this flushes all PropertiesChanges event (sends the D-Bus message right
+   * away, if any - there should not be any)
+   */
+  g_dbus_interface_skeleton_flush (G_DBUS_INTERFACE_SKELETON (object));
+  /* this makes us return the reply D-Bus method */
+  foo_igen_bar_complete_property_cancellation (object, invocation);
   return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 static gboolean
-on_handle_force_method (FooBat                 *object,
+on_handle_force_method (FooiGenBat             *object,
                         GDBusMethodInvocation  *invocation,
                         GVariant               *force_in_i,
                         GVariant               *force_in_s,
@@ -246,18 +264,18 @@ on_handle_force_method (FooBat                 *object,
   g_variant_ref_sink (ret_ay);
   g_variant_ref_sink (ret_struct);
 
-  foo_bat_emit_force_signal (object,
-                             ret_i,
-                             ret_s,
-                             ret_ay,
-                             ret_struct);
+  foo_igen_bat_emit_force_signal (object,
+                                  ret_i,
+                                  ret_s,
+                                  ret_ay,
+                                  ret_struct);
 
-  foo_bat_complete_force_method (object,
-                                 invocation,
-                                 ret_i,
-                                 ret_s,
-                                 ret_ay,
-                                 ret_struct);
+  foo_igen_bat_complete_force_method (object,
+                                      invocation,
+                                      ret_i,
+                                      ret_s,
+                                      ret_ay,
+                                      ret_struct);
 
   g_variant_unref (ret_i);
   g_variant_unref (ret_s);
@@ -271,9 +289,9 @@ on_handle_force_method (FooBat                 *object,
 /* ---------------------------------------------------------------------------------------------------- */
 
 static gboolean
-my_g_authorize_method_handler (GDBusInterfaceStub    *interface,
-                               GDBusMethodInvocation *invocation,
-                               gpointer               user_data)
+my_g_authorize_method_handler (GDBusInterfaceSkeleton *interface,
+                               GDBusMethodInvocation  *invocation,
+                               gpointer                user_data)
 {
   const gchar *method_name;
   gboolean authorized;
@@ -309,10 +327,10 @@ my_g_authorize_method_handler (GDBusInterfaceStub    *interface,
 }
 
 static gboolean
-my_object_authorize_method_handler (GDBusObjectStub       *object,
-                                    GDBusInterfaceStub    *interface,
-                                    GDBusMethodInvocation *invocation,
-                                    gpointer               user_data)
+my_object_authorize_method_handler (GDBusObjectSkeleton     *object,
+                                    GDBusInterfaceSkeleton  *interface,
+                                    GDBusMethodInvocation   *invocation,
+                                    gpointer                 user_data)
 {
   const gchar *method_name;
   gboolean authorized;
@@ -348,42 +366,42 @@ my_object_authorize_method_handler (GDBusObjectStub       *object,
 }
 
 static gboolean
-on_handle_check_not_authorized (FooAuthorize           *object,
+on_handle_check_not_authorized (FooiGenAuthorize       *object,
                                 GDBusMethodInvocation  *invocation,
                                 gpointer                user_data)
 {
-  foo_authorize_complete_check_not_authorized (object, invocation);
+  foo_igen_authorize_complete_check_not_authorized (object, invocation);
   return TRUE;
 }
 
 static gboolean
-on_handle_check_authorized (FooAuthorize           *object,
+on_handle_check_authorized (FooiGenAuthorize       *object,
                             GDBusMethodInvocation  *invocation,
                             gpointer                user_data)
 {
-  foo_authorize_complete_check_authorized (object, invocation);
+  foo_igen_authorize_complete_check_authorized (object, invocation);
   return TRUE;
 }
 
 static gboolean
-on_handle_check_not_authorized_from_object (FooAuthorize           *object,
+on_handle_check_not_authorized_from_object (FooiGenAuthorize       *object,
                                             GDBusMethodInvocation  *invocation,
                                             gpointer                user_data)
 {
-  foo_authorize_complete_check_not_authorized_from_object (object, invocation);
+  foo_igen_authorize_complete_check_not_authorized_from_object (object, invocation);
   return TRUE;
 }
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 static gboolean
-on_handle_get_self (FooMethodThreads       *object,
+on_handle_get_self (FooiGenMethodThreads   *object,
                     GDBusMethodInvocation  *invocation,
                     gpointer                user_data)
 {
   gchar *s;
   s = g_strdup_printf ("%p", g_thread_self ());
-  foo_method_threads_complete_get_self (object, invocation, s);
+  foo_igen_method_threads_complete_get_self (object, invocation, s);
   g_free (s);
   return TRUE;
 }
@@ -392,12 +410,22 @@ on_handle_get_self (FooMethodThreads       *object,
 
 static GThread *method_handler_thread = NULL;
 
-static FooBar *exported_bar_object = NULL;
-static FooBat *exported_bat_object = NULL;
-static FooAuthorize *exported_authorize_object = NULL;
-static GDBusObjectStub *authorize_enclosing_object = NULL;
-static FooMethodThreads *exported_thread_object_1 = NULL;
-static FooMethodThreads *exported_thread_object_2 = NULL;
+static FooiGenBar *exported_bar_object = NULL;
+static FooiGenBat *exported_bat_object = NULL;
+static FooiGenAuthorize *exported_authorize_object = NULL;
+static GDBusObjectSkeleton *authorize_enclosing_object = NULL;
+static FooiGenMethodThreads *exported_thread_object_1 = NULL;
+static FooiGenMethodThreads *exported_thread_object_2 = NULL;
+
+static void
+unexport_objects (void)
+{
+  g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_bar_object));
+  g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_bat_object));
+  g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_authorize_object));
+  g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1));
+  g_dbus_interface_skeleton_unexport (G_DBUS_INTERFACE_SKELETON (exported_thread_object_2));
+}
 
 static void
 on_bus_acquired (GDBusConnection *connection,
@@ -407,7 +435,7 @@ on_bus_acquired (GDBusConnection *connection,
   GError *error;
 
   /* Test that we can export an object using the generated
-   * FooBarStub subclass. Notes:
+   * FooiGenBarSkeleton subclass. Notes:
    *
    * 1. We handle methods by simply connecting to the appropriate
    * GObject signal.
@@ -417,23 +445,23 @@ on_bus_acquired (GDBusConnection *connection,
    *    C bindings at will)
    */
   error = NULL;
-  exported_bar_object = foo_bar_stub_new ();
-  foo_bar_set_ay (exported_bar_object, "ABCabc");
-  foo_bar_set_y (exported_bar_object, 42);
-  foo_bar_set_d (exported_bar_object, 43.0);
-  foo_bar_set_finally_normal_name (exported_bar_object, "There aint no place like home");
-  foo_bar_set_writeonly_property (exported_bar_object, "Mr. Burns");
-
-  /* The following works because it's on the Stub object - it will
+  exported_bar_object = foo_igen_bar_skeleton_new ();
+  foo_igen_bar_set_ay (exported_bar_object, "ABCabc");
+  foo_igen_bar_set_y (exported_bar_object, 42);
+  foo_igen_bar_set_d (exported_bar_object, 43.0);
+  foo_igen_bar_set_finally_normal_name (exported_bar_object, "There aint no place like home");
+  foo_igen_bar_set_writeonly_property (exported_bar_object, "Mr. Burns");
+
+  /* The following works because it's on the Skeleton object - it will
    * fail (at run-time) on a Proxy (see on_proxy_appeared() below)
    */
-  foo_bar_set_readonly_property (exported_bar_object, "blah");
-  g_assert_cmpstr (foo_bar_get_writeonly_property (exported_bar_object), ==, "Mr. Burns");
+  foo_igen_bar_set_readonly_property (exported_bar_object, "blah");
+  g_assert_cmpstr (foo_igen_bar_get_writeonly_property (exported_bar_object), ==, "Mr. Burns");
 
-  g_dbus_interface_stub_export (G_DBUS_INTERFACE_STUB (exported_bar_object),
-                                connection,
-                                "/bar",
-                                &error);
+  g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_bar_object),
+                                    connection,
+                                    "/bar",
+                                    &error);
   g_assert_no_error (error);
   g_signal_connect (exported_bar_object,
                     "handle-hello-world",
@@ -455,12 +483,16 @@ on_bus_acquired (GDBusConnection *connection,
                     "handle-request-multi-property-mods",
                     G_CALLBACK (on_handle_request_multi_property_mods),
                     NULL);
+  g_signal_connect (exported_bar_object,
+                    "handle-property-cancellation",
+                    G_CALLBACK (on_handle_property_cancellation),
+                    NULL);
 
-  exported_bat_object = foo_bat_stub_new ();
-  g_dbus_interface_stub_export (G_DBUS_INTERFACE_STUB (exported_bat_object),
-                                connection,
-                                "/bat",
-                                &error);
+  exported_bat_object = foo_igen_bat_skeleton_new ();
+  g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_bat_object),
+                                    connection,
+                                    "/bat",
+                                    &error);
   g_assert_no_error (error);
   g_signal_connect (exported_bat_object,
                     "handle-force-method",
@@ -473,18 +505,18 @@ on_bus_acquired (GDBusConnection *connection,
                 "force-struct", g_variant_new ("(i)", 4300),
                 NULL);
 
-  authorize_enclosing_object = g_dbus_object_stub_new ("/authorize");
+  authorize_enclosing_object = g_dbus_object_skeleton_new ("/authorize");
   g_signal_connect (authorize_enclosing_object,
                     "authorize-method",
                     G_CALLBACK (my_object_authorize_method_handler),
                     NULL);
-  exported_authorize_object = foo_authorize_stub_new ();
-  g_dbus_object_stub_add_interface (authorize_enclosing_object,
-                                    G_DBUS_INTERFACE_STUB (exported_authorize_object));
-  g_dbus_interface_stub_export (G_DBUS_INTERFACE_STUB (exported_authorize_object),
-                                connection,
-                                "/authorize",
-                                &error);
+  exported_authorize_object = foo_igen_authorize_skeleton_new ();
+  g_dbus_object_skeleton_add_interface (authorize_enclosing_object,
+                                        G_DBUS_INTERFACE_SKELETON (exported_authorize_object));
+  g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_authorize_object),
+                                    connection,
+                                    "/authorize",
+                                    &error);
   g_assert_no_error (error);
   g_signal_connect (exported_authorize_object,
                     "g-authorize-method",
@@ -504,31 +536,36 @@ on_bus_acquired (GDBusConnection *connection,
                     NULL);
 
 
-  /* only object 1 has the G_DBUS_INTERFACE_STUB_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD flag set */
-  exported_thread_object_1 = foo_method_threads_stub_new ();
-  g_dbus_interface_stub_set_flags (G_DBUS_INTERFACE_STUB (exported_thread_object_1),
-                                   G_DBUS_INTERFACE_STUB_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);
-  g_dbus_interface_stub_export (G_DBUS_INTERFACE_STUB (exported_thread_object_1),
-                                connection,
-                                "/method_threads_1",
-                                &error);
+  /* only object 1 has the G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD flag set */
+  exported_thread_object_1 = foo_igen_method_threads_skeleton_new ();
+  g_dbus_interface_skeleton_set_flags (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1),
+                                       G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);
+
+  g_assert (!g_dbus_interface_skeleton_has_connection (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1), connection));
+  g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1),
+                                    connection,
+                                    "/method_threads_1",
+                                    &error);
   g_assert_no_error (error);
   g_signal_connect (exported_thread_object_1,
                     "handle-get-self",
                     G_CALLBACK (on_handle_get_self),
                     NULL);
+  g_assert_cmpint (g_dbus_interface_skeleton_get_flags (G_DBUS_INTERFACE_SKELETON (exported_thread_object_1)), ==, G_DBUS_INTERFACE_SKELETON_FLAGS_HANDLE_METHOD_INVOCATIONS_IN_THREAD);
 
-  exported_thread_object_2 = foo_method_threads_stub_new ();
-  g_dbus_interface_stub_export (G_DBUS_INTERFACE_STUB (exported_thread_object_2),
-                                connection,
-                                "/method_threads_2",
-                                &error);
+  exported_thread_object_2 = foo_igen_method_threads_skeleton_new ();
+  g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON (exported_thread_object_2),
+                                    connection,
+                                    "/method_threads_2",
+                                    &error);
   g_assert_no_error (error);
   g_signal_connect (exported_thread_object_2,
                     "handle-get-self",
                     G_CALLBACK (on_handle_get_self),
                     NULL);
 
+  g_assert_cmpint (g_dbus_interface_skeleton_get_flags (G_DBUS_INTERFACE_SKELETON (exported_thread_object_2)), ==, G_DBUS_INTERFACE_SKELETON_FLAGS_NONE);
+
   method_handler_thread = g_thread_self ();
 }
 
@@ -541,10 +578,9 @@ on_name_acquired (GDBusConnection *connection,
 {
   GMainLoop *loop = user_data;
 
-  g_thread_create (check_proxies_in_thread,
-                   loop,
-                   TRUE,
-                   NULL);
+  g_thread_new ("check-proxies",
+                check_proxies_in_thread,
+                loop);
 }
 
 static void
@@ -595,19 +631,19 @@ on_g_properties_changed (GDBusProxy          *_proxy,
                          gpointer             user_data)
 {
   ClientData *data = user_data;
-  FooBar *proxy = FOO_BAR (_proxy);
+  FooiGenBar *proxy = FOO_IGEN_BAR (_proxy);
 
   g_assert_cmpint (g_variant_n_children (changed_properties), ==, 2);
 
   if (data->num_g_properties_changed == 0)
     {
-      g_assert_cmpint (data->initial_y, ==, foo_bar_get_y (proxy) - 2);
-      g_assert_cmpint (data->initial_i, ==, foo_bar_get_i (proxy) - 2);
+      g_assert_cmpint (data->initial_y, ==, foo_igen_bar_get_y (proxy) - 2);
+      g_assert_cmpint (data->initial_i, ==, foo_igen_bar_get_i (proxy) - 2);
     }
   else if (data->num_g_properties_changed == 1)
     {
-      g_assert_cmpint (data->initial_y, ==, foo_bar_get_y (proxy) - 3);
-      g_assert_cmpint (data->initial_i, ==, foo_bar_get_i (proxy) - 3);
+      g_assert_cmpint (data->initial_y, ==, foo_igen_bar_get_y (proxy) - 3);
+      g_assert_cmpint (data->initial_i, ==, foo_igen_bar_get_i (proxy) - 3);
     }
   else
     g_assert_not_reached ();
@@ -619,7 +655,7 @@ on_g_properties_changed (GDBusProxy          *_proxy,
 }
 
 static void
-on_test_signal (FooBar              *proxy,
+on_test_signal (FooiGenBar          *proxy,
                 gint                 val_int32,
                 const gchar* const  *array_of_strings,
                 const gchar* const  *array_of_bytestrings,
@@ -641,9 +677,30 @@ on_test_signal (FooBar              *proxy,
 }
 
 static void
-check_bar_proxy (FooBar    *proxy,
-                 GMainLoop *thread_loop)
+on_property_cancellation_cb (FooiGenBar    *proxy,
+                             GAsyncResult  *res,
+                             gpointer       user_data)
 {
+  ClientData *data = user_data;
+  gboolean ret;
+  GError *error = NULL;
+
+  error = NULL;
+  ret = foo_igen_bar_call_property_cancellation_finish (proxy, res, &error);
+  g_assert_no_error (error);
+  g_assert (ret);
+
+  g_main_loop_quit (data->thread_loop);
+}
+
+static void
+check_bar_proxy (FooiGenBar *proxy,
+                 GMainLoop  *thread_loop)
+{
+  const gchar *array_of_strings[3] = {"one", "two", NULL};
+  const gchar *array_of_strings_2[3] = {"one2", "two2", NULL};
+  const gchar *array_of_objpaths[3] = {"/one", "/one/two", NULL};
+  const gchar *array_of_bytestrings[3] = {"one\xff", "two\xff", NULL};
   guchar ret_val_byte;
   gboolean ret_val_boolean;
   gint16 ret_val_int16;
@@ -662,8 +719,8 @@ check_bar_proxy (FooBar    *proxy,
   ClientData *data;
   guchar val_y;
   gboolean val_b;
-  gint16 val_n;
-  guint16 val_q;
+  gint val_n;
+  guint val_q;
   gint val_i;
   guint val_u;
   gint64 val_x;
@@ -674,7 +731,7 @@ check_bar_proxy (FooBar    *proxy,
   gchar *val_g;
   gchar *val_ay;
   gchar **val_as;
-  GVariant *val_ao;
+  gchar **val_ao;
   GVariant *val_ag;
   gint32 val_unset_i;
   gdouble val_unset_d;
@@ -683,12 +740,15 @@ check_bar_proxy (FooBar    *proxy,
   gchar *val_unset_g;
   gchar *val_unset_ay;
   gchar **val_unset_as;
-  GVariant *val_unset_ao;
+  gchar **val_unset_ao;
   GVariant *val_unset_ag;
   GVariant *val_unset_struct;
   gchar *val_finally_normal_name;
   GVariant *v;
   gchar *s;
+  const gchar *const *read_as;
+  const gchar *const *read_as2;
+  const gchar *const *read_as3;
 
   data = g_new0 (ClientData, 1);
   data->thread_loop = thread_loop;
@@ -746,7 +806,7 @@ check_bar_proxy (FooBar    *proxy,
   g_assert_cmpstr (val_ay, ==, "ABCabc");
   g_free (val_ay);
   g_strfreev (val_as);
-  g_variant_unref (val_ao);
+  g_strfreev (val_ao);
   g_variant_unref (val_ag);
   g_free (val_finally_normal_name);
   /* check empty values */
@@ -760,7 +820,7 @@ check_bar_proxy (FooBar    *proxy,
   g_free (val_unset_g);
   g_assert_cmpstr (val_unset_ay, ==, "");
   g_assert (val_unset_as[0] == NULL);
-  g_assert (g_variant_is_of_type (val_unset_ao, G_VARIANT_TYPE ("ao")));
+  g_assert (val_unset_ao[0] == NULL);
   g_assert (g_variant_is_of_type (val_unset_ag, G_VARIANT_TYPE ("ag")));
   g_assert (g_variant_is_of_type (val_unset_struct, G_VARIANT_TYPE ("(idsogayasaoag)")));
   s = g_variant_print (val_unset_struct, TRUE);
@@ -768,7 +828,7 @@ check_bar_proxy (FooBar    *proxy,
   g_free (s);
   g_free (val_unset_ay);
   g_strfreev (val_unset_as);
-  g_variant_unref (val_unset_ao);
+  g_strfreev (val_unset_ao);
   g_variant_unref (val_unset_ag);
   g_variant_unref (val_unset_struct);
 
@@ -776,72 +836,71 @@ check_bar_proxy (FooBar    *proxy,
    * the org.fd.DBus.Properties.Set() method asynchronously. So we
    * have to wait for properties-changed...
    */
-  foo_bar_set_finally_normal_name (proxy, "foo!");
+  foo_igen_bar_set_finally_normal_name (proxy, "foo!");
   _g_assert_property_notify (proxy, "finally-normal-name");
-  g_assert_cmpstr (foo_bar_get_finally_normal_name (proxy), ==, "foo!");
+  g_assert_cmpstr (foo_igen_bar_get_finally_normal_name (proxy), ==, "foo!");
 
   /* Try setting properties that requires memory management. This
    * is to exercise the paths that frees the references.
    */
-  const gchar *array_of_strings[3] = {"one", "two", NULL};
-  const gchar *array_of_bytestrings[3] = {"one\xff", "two\xff", NULL};
+
   g_object_set (proxy,
                 "s", "a string",
                 "o", "/a/path",
                 "g", "asig",
                 "ay", g_variant_new_parsed ("[byte 0x65, 0x67]"),
                 "as", array_of_strings,
-                "ao", g_variant_new_parsed ("[@o '/one', '/one/two']"),
+                "ao", array_of_objpaths,
                 "ag", g_variant_new_parsed ("[@g 'ass', 'git']"),
                 NULL);
 
   error = NULL;
-  ret = foo_bar_call_test_primitive_types_sync (proxy,
-                                                10,
-                                                TRUE,
-                                                11,
-                                                12,
-                                                13,
-                                                14,
-                                                15,
-                                                16,
-                                                17,
-                                                "a string",
-                                                "/a/path",
-                                                "asig",
-                                                "bytestring\xff",
-                                                &ret_val_byte,
-                                                &ret_val_boolean,
-                                                &ret_val_int16,
-                                                &ret_val_uint16,
-                                                &ret_val_int32,
-                                                &ret_val_uint32,
-                                                &ret_val_int64,
-                                                &ret_val_uint64,
-                                                &ret_val_double,
-                                                &ret_val_string,
-                                                &ret_val_objpath,
-                                                &ret_val_signature,
-                                                &ret_val_bytestring,
-                                                NULL, /* GCancellable */
-                                                &error);
+  ret = foo_igen_bar_call_test_primitive_types_sync (proxy,
+                                                     10,
+                                                     TRUE,
+                                                     11,
+                                                     12,
+                                                     13,
+                                                     14,
+                                                     15,
+                                                     16,
+                                                     17,
+                                                     "a string",
+                                                     "/a/path",
+                                                     "asig",
+                                                     "bytestring\xff",
+                                                     &ret_val_byte,
+                                                     &ret_val_boolean,
+                                                     &ret_val_int16,
+                                                     &ret_val_uint16,
+                                                     &ret_val_int32,
+                                                     &ret_val_uint32,
+                                                     &ret_val_int64,
+                                                     &ret_val_uint64,
+                                                     &ret_val_double,
+                                                     &ret_val_string,
+                                                     &ret_val_objpath,
+                                                     &ret_val_signature,
+                                                     &ret_val_bytestring,
+                                                     NULL, /* GCancellable */
+                                                     &error);
   g_assert_no_error (error);
   g_assert (ret);
 
   error = NULL;
-  ret = foo_bar_call_test_non_primitive_types_sync (proxy,
-                                                    g_variant_new_parsed ("{'one': 'red',"
-                                                                          " 'two': 'blue'}"),
-                                                    g_variant_new_parsed ("{'first': (42, 42), "
-                                                                          "'second': (43, 43)}"),
-                                                    g_variant_new_parsed ("(42, 'foo', 'bar')"),
-                                                    array_of_strings,
-                                                    g_variant_new_parsed ("[@o '/one', '/one/two']"),
-                                                    g_variant_new_parsed ("[@g 'ass', 'git']"),
-                                                    array_of_bytestrings,
-                                                    &s,
-                                                    NULL, /* GCancellable */
-                                                    &error);
+  ret = foo_igen_bar_call_test_non_primitive_types_sync (proxy,
+                                                         g_variant_new_parsed ("{'one': 'red',"
+                                                                               " 'two': 'blue'}"),
+                                                         g_variant_new_parsed ("{'first': (42, 42), "
+                                                                               "'second': (43, 43)}"),
+                                                         g_variant_new_parsed ("(42, 'foo', 'bar')"),
+                                                         array_of_strings,
+                                                         array_of_objpaths,
+                                                         g_variant_new_parsed ("[@g 'ass', 'git']"),
+                                                         array_of_bytestrings,
+                                                         &s,
+                                                         NULL, /* GCancellable */
+                                                         &error);
 
   g_assert_no_error (error);
   g_assert (ret);
@@ -850,7 +909,7 @@ check_bar_proxy (FooBar    *proxy,
    * unimplemented methods.
    */
   error = NULL;
-  ret = foo_bar_call_unimplemented_method_sync (proxy, NULL /* GCancellable */, &error);
+  ret = foo_igen_bar_call_unimplemented_method_sync (proxy, NULL /* GCancellable */, &error);
   g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
   g_error_free (error);
   error = NULL;
@@ -861,7 +920,7 @@ check_bar_proxy (FooBar    *proxy,
                     G_CALLBACK (on_test_signal),
                     data);
   error = NULL;
-  ret = foo_bar_call_request_signal_emission_sync (proxy, 0, NULL, &error);
+  ret = foo_igen_bar_call_request_signal_emission_sync (proxy, 0, NULL, &error);
   g_assert_no_error (error);
   g_assert (ret);
 
@@ -873,9 +932,28 @@ check_bar_proxy (FooBar    *proxy,
    * the org.fd.DBus.Properties.Set() method asynchronously. So we
    * have to wait for properties-changed...
    */
-  foo_bar_set_finally_normal_name (proxy, "hey back!");
+  foo_igen_bar_set_finally_normal_name (proxy, "hey back!");
   _g_assert_property_notify (proxy, "finally-normal-name");
-  g_assert_cmpstr (foo_bar_get_finally_normal_name (proxy), ==, "hey back!");
+  g_assert_cmpstr (foo_igen_bar_get_finally_normal_name (proxy), ==, "hey back!");
+
+  /* Check that multiple calls to a strv getter works... and that
+   * updates on them works as well (See comment for "property vfuncs"
+   * in gio/gdbus-codegen/codegen.py for details)
+   */
+  read_as = foo_igen_bar_get_as (proxy);
+  read_as2 = foo_igen_bar_get_as (proxy);
+  g_assert_cmpint (g_strv_length ((gchar **) read_as), ==, 2);
+  g_assert_cmpstr (read_as[0], ==, "one");
+  g_assert_cmpstr (read_as[1], ==, "two");
+  g_assert (read_as == read_as2); /* this is more testing an implementation detail */
+  g_object_set (proxy,
+                "as", array_of_strings_2,
+                NULL);
+  _g_assert_property_notify (proxy, "as");
+  read_as3 = foo_igen_bar_get_as (proxy);
+  g_assert_cmpint (g_strv_length ((gchar **) read_as3), ==, 2);
+  g_assert_cmpstr (read_as3[0], ==, "one2");
+  g_assert_cmpstr (read_as3[1], ==, "two2");
 
   /* Check that grouping changes in idle works.
    *
@@ -884,19 +962,19 @@ check_bar_proxy (FooBar    *proxy,
    * properties.
    *
    * On the first reception, y and i should both be increased by
-   * two. On the the second reception, only by one. The signal handler
+   * two. On the second reception, only by one. The signal handler
    * checks this.
    *
    * This also checks that _drain_notify() works.
    */
-  data->initial_y = foo_bar_get_y (proxy);
-  data->initial_i = foo_bar_get_i (proxy);
+  data->initial_y = foo_igen_bar_get_y (proxy);
+  data->initial_i = foo_igen_bar_get_i (proxy);
   g_signal_connect (proxy,
                     "g-properties-changed",
                     G_CALLBACK (on_g_properties_changed),
                     data);
   error = NULL;
-  ret = foo_bar_call_request_multi_property_mods_sync (proxy, NULL, &error);
+  ret = foo_igen_bar_call_request_multi_property_mods_sync (proxy, NULL, &error);
   g_assert_no_error (error);
   g_assert (ret);
   g_main_loop_run (thread_loop);
@@ -915,11 +993,11 @@ check_bar_proxy (FooBar    *proxy,
                     "notify::u",
                     G_CALLBACK (on_notify_u),
                     data);
-  foo_bar_set_u (proxy, 1042);
+  foo_igen_bar_set_u (proxy, 1042);
   g_assert_cmpint (data->num_notify_u, ==, 1);
-  g_assert_cmpint (foo_bar_get_u (proxy), ==, 0);
+  g_assert_cmpint (foo_igen_bar_get_u (proxy), ==, 0);
   _g_assert_property_notify (proxy, "u");
-  g_assert_cmpint (foo_bar_get_u (proxy), ==, 1042);
+  g_assert_cmpint (foo_igen_bar_get_u (proxy), ==, 1042);
   g_assert_cmpint (data->num_notify_u, ==, 2);
 
   /* Now change u again to the same value.. this will cause a
@@ -935,7 +1013,7 @@ check_bar_proxy (FooBar    *proxy,
    * property and wait for that PropertiesChanged() message
    * to arrive.
    */
-  foo_bar_set_u (proxy, 1042);
+  foo_igen_bar_set_u (proxy, 1042);
   g_assert_cmpint (data->num_notify_u, ==, 3);
 
   g_assert_cmpint (data->num_notify_n, ==, 0);
@@ -943,16 +1021,32 @@ check_bar_proxy (FooBar    *proxy,
                     "notify::n",
                     G_CALLBACK (on_notify_n),
                     data);
-  foo_bar_set_n (proxy, 10042);
+  foo_igen_bar_set_n (proxy, 10042);
   g_assert_cmpint (data->num_notify_n, ==, 1);
-  g_assert_cmpint (foo_bar_get_n (proxy), ==, 0);
+  g_assert_cmpint (foo_igen_bar_get_n (proxy), ==, 0);
   _g_assert_property_notify (proxy, "n");
-  g_assert_cmpint (foo_bar_get_n (proxy), ==, 10042);
+  g_assert_cmpint (foo_igen_bar_get_n (proxy), ==, 10042);
   g_assert_cmpint (data->num_notify_n, ==, 2);
-
   /* Checks that u didn't change at all */
   g_assert_cmpint (data->num_notify_u, ==, 3);
 
+  /* Now we check that if the service does
+   *
+   *   guint n = foo_igen_bar_get_n (foo);
+   *   foo_igen_bar_set_n (foo, n + 1);
+   *   foo_igen_bar_set_n (foo, n);
+   *
+   *  then no PropertiesChanged() signal is emitted!
+   */
+  error = NULL;
+  foo_igen_bar_call_property_cancellation (proxy,
+                                           NULL, /* GCancellable */
+                                           (GAsyncReadyCallback) on_property_cancellation_cb,
+                                           data);
+  g_main_loop_run (thread_loop);
+  /* Checks that n didn't change at all */
+  g_assert_cmpint (data->num_notify_n, ==, 2);
+
   /* cleanup */
   g_free (data);
 }
@@ -960,12 +1054,12 @@ check_bar_proxy (FooBar    *proxy,
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-on_force_signal (FooBat    *proxy,
-                 GVariant  *force_i,
-                 GVariant  *force_s,
-                 GVariant  *force_ay,
-                 GVariant  *force_struct,
-                 gpointer   user_data)
+on_force_signal (FooiGenBat *proxy,
+                 GVariant   *force_i,
+                 GVariant   *force_s,
+                 GVariant   *force_ay,
+                 GVariant   *force_struct,
+                 gpointer    user_data)
 {
   gboolean *signal_received = user_data;
   gint val;
@@ -982,8 +1076,8 @@ on_force_signal (FooBat    *proxy,
 }
 
 static void
-check_bat_proxy (FooBat *proxy,
-                 GMainLoop *thread_loop)
+check_bat_proxy (FooiGenBat *proxy,
+                 GMainLoop  *thread_loop)
 {
   GError *error;
   GVariant *ret_i;
@@ -1022,17 +1116,17 @@ check_bat_proxy (FooBat *proxy,
                     &force_signal_received);
 
   error = NULL;
-  foo_bat_call_force_method_sync (proxy,
-                                  g_variant_new_int32 (42),
-                                  g_variant_new_string ("a string"),
-                                  g_variant_new_bytestring ("a bytestring\xff"),
-                                  g_variant_new ("(i)", 4200),
-                                  &ret_i,
-                                  &ret_s,
-                                  &ret_ay,
-                                  &ret_struct,
-                                  NULL, /* GCancellable* */
-                                  &error);
+  foo_igen_bat_call_force_method_sync (proxy,
+                                       g_variant_new_int32 (42),
+                                       g_variant_new_string ("a string"),
+                                       g_variant_new_bytestring ("a bytestring\xff"),
+                                       g_variant_new ("(i)", 4200),
+                                       &ret_i,
+                                       &ret_s,
+                                       &ret_ay,
+                                       &ret_struct,
+                                       NULL, /* GCancellable* */
+                                       &error);
   g_assert_no_error (error);
   g_assert_cmpint (g_variant_get_int32 (ret_i), ==, 42 + 10);
   g_assert_cmpstr (g_variant_get_string (ret_s, NULL), ==, "a string_foo");
@@ -1050,8 +1144,8 @@ check_bat_proxy (FooBat *proxy,
 /* ---------------------------------------------------------------------------------------------------- */
 
 static void
-check_authorize_proxy (FooAuthorize *proxy,
-                       GMainLoop *thread_loop)
+check_authorize_proxy (FooiGenAuthorize *proxy,
+                       GMainLoop        *thread_loop)
 {
   GError *error;
   gboolean ret;
@@ -1059,18 +1153,18 @@ check_authorize_proxy (FooAuthorize *proxy,
   /* Check that g-authorize-method works as intended */
 
   error = NULL;
-  ret = foo_authorize_call_check_not_authorized_sync (proxy, NULL, &error);
+  ret = foo_igen_authorize_call_check_not_authorized_sync (proxy, NULL, &error);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED);
   g_error_free (error);
   g_assert (!ret);
 
   error = NULL;
-  ret = foo_authorize_call_check_authorized_sync (proxy, NULL, &error);
+  ret = foo_igen_authorize_call_check_authorized_sync (proxy, NULL, &error);
   g_assert_no_error (error);
   g_assert (ret);
 
   error = NULL;
-  ret = foo_authorize_call_check_not_authorized_from_object_sync (proxy, NULL, &error);
+  ret = foo_igen_authorize_call_check_not_authorized_from_object_sync (proxy, NULL, &error);
   g_assert_error (error, G_IO_ERROR, G_IO_ERROR_PENDING);
   g_error_free (error);
   g_assert (!ret);
@@ -1079,7 +1173,7 @@ check_authorize_proxy (FooAuthorize *proxy,
 /* ---------------------------------------------------------------------------------------------------- */
 
 static GThread *
-get_self_via_proxy (FooMethodThreads *proxy_1)
+get_self_via_proxy (FooiGenMethodThreads *proxy_1)
 {
   GError *error;
   gchar *self_str;
@@ -1087,7 +1181,7 @@ get_self_via_proxy (FooMethodThreads *proxy_1)
   gpointer self;
 
   error = NULL;
-  ret = foo_method_threads_call_get_self_sync (proxy_1, &self_str, NULL, &error);
+  ret = foo_igen_method_threads_call_get_self_sync (proxy_1, &self_str, NULL, &error);
   g_assert_no_error (error);
   g_assert (ret);
 
@@ -1099,9 +1193,9 @@ get_self_via_proxy (FooMethodThreads *proxy_1)
 }
 
 static void
-check_thread_proxies (FooMethodThreads *proxy_1,
-                      FooMethodThreads *proxy_2,
-                      GMainLoop *thread_loop)
+check_thread_proxies (FooiGenMethodThreads *proxy_1,
+                      FooiGenMethodThreads *proxy_2,
+                      GMainLoop            *thread_loop)
 {
   /* proxy_1 is indeed using threads so should never get the handler thread */
   g_assert (get_self_via_proxy (proxy_1) != method_handler_thread);
@@ -1119,11 +1213,11 @@ check_proxies_in_thread (gpointer user_data)
   GMainContext *thread_context;
   GMainLoop *thread_loop;
   GError *error;
-  FooBar *bar_proxy;
-  FooBat *bat_proxy;
-  FooAuthorize *authorize_proxy;
-  FooMethodThreads *thread_proxy_1;
-  FooMethodThreads *thread_proxy_2;
+  FooiGenBar *bar_proxy;
+  FooiGenBat *bat_proxy;
+  FooiGenAuthorize *authorize_proxy;
+  FooiGenMethodThreads *thread_proxy_1;
+  FooiGenMethodThreads *thread_proxy_2;
 
   thread_context = g_main_context_new ();
   thread_loop = g_main_loop_new (thread_context, FALSE);
@@ -1131,52 +1225,52 @@ check_proxies_in_thread (gpointer user_data)
 
   /* Check the object */
   error = NULL;
-  bar_proxy = foo_bar_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
-                                              G_DBUS_PROXY_FLAGS_NONE,
-                                              "org.gtk.GDBus.BindingsTool.Test",
-                                              "/bar",
-                                              NULL, /* GCancellable* */
-                                              &error);
+  bar_proxy = foo_igen_bar_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                   G_DBUS_PROXY_FLAGS_NONE,
+                                                   "org.gtk.GDBus.BindingsTool.Test",
+                                                   "/bar",
+                                                   NULL, /* GCancellable* */
+                                                   &error);
   check_bar_proxy (bar_proxy, thread_loop);
   g_assert_no_error (error);
   g_object_unref (bar_proxy);
 
   error = NULL;
-  bat_proxy = foo_bat_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
-                                              G_DBUS_PROXY_FLAGS_NONE,
-                                              "org.gtk.GDBus.BindingsTool.Test",
-                                              "/bat",
-                                              NULL, /* GCancellable* */
-                                              &error);
+  bat_proxy = foo_igen_bat_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                   G_DBUS_PROXY_FLAGS_NONE,
+                                                   "org.gtk.GDBus.BindingsTool.Test",
+                                                   "/bat",
+                                                   NULL, /* GCancellable* */
+                                                   &error);
   check_bat_proxy (bat_proxy, thread_loop);
   g_assert_no_error (error);
   g_object_unref (bat_proxy);
 
   error = NULL;
-  authorize_proxy = foo_authorize_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
-                                                          G_DBUS_PROXY_FLAGS_NONE,
-                                                          "org.gtk.GDBus.BindingsTool.Test",
-                                                          "/authorize",
-                                                          NULL, /* GCancellable* */
-                                                          &error);
+  authorize_proxy = foo_igen_authorize_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                               G_DBUS_PROXY_FLAGS_NONE,
+                                                               "org.gtk.GDBus.BindingsTool.Test",
+                                                               "/authorize",
+                                                               NULL, /* GCancellable* */
+                                                               &error);
   check_authorize_proxy (authorize_proxy, thread_loop);
   g_assert_no_error (error);
   g_object_unref (authorize_proxy);
 
   error = NULL;
-  thread_proxy_1 = foo_method_threads_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
-                                                              G_DBUS_PROXY_FLAGS_NONE,
-                                                              "org.gtk.GDBus.BindingsTool.Test",
-                                                              "/method_threads_1",
-                                                              NULL, /* GCancellable* */
-                                                              &error);
+  thread_proxy_1 = foo_igen_method_threads_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                                   G_DBUS_PROXY_FLAGS_NONE,
+                                                                   "org.gtk.GDBus.BindingsTool.Test",
+                                                                   "/method_threads_1",
+                                                                   NULL, /* GCancellable* */
+                                                                   &error);
   g_assert_no_error (error);
-  thread_proxy_2 = foo_method_threads_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
-                                                              G_DBUS_PROXY_FLAGS_NONE,
-                                                              "org.gtk.GDBus.BindingsTool.Test",
-                                                              "/method_threads_2",
-                                                              NULL, /* GCancellable* */
-                                                              &error);
+  thread_proxy_2 = foo_igen_method_threads_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+                                                                   G_DBUS_PROXY_FLAGS_NONE,
+                                                                   "org.gtk.GDBus.BindingsTool.Test",
+                                                                   "/method_threads_2",
+                                                                   NULL, /* GCancellable* */
+                                                                   &error);
   g_assert_no_error (error);
   check_thread_proxies (thread_proxy_1, thread_proxy_2, thread_loop);
   g_object_unref (thread_proxy_1);
@@ -1561,41 +1655,28 @@ om_on_signal (GDBusConnection *connection,
       om_data->state = 104;
       g_main_loop_quit (om_data->loop);
       break;
+
+    case 200:
+      om_check_interfaces_added (signal_name, parameters, "/managed/first_1",
+                                 "com.acme.Coyote", NULL);
+      om_data->state = 201;
+      g_main_loop_quit (om_data->loop);
+      break;
     }
 }
 
 static GAsyncResult *om_res = NULL;
 
 static void
-om_pm_start_cb (GDBusObjectManagerClient *manager,
-                GAsyncResult      *res,
-                gpointer           user_data)
+om_pm_start_cb (FooiGenObjectManagerClient *manager,
+                GAsyncResult               *res,
+                gpointer                    user_data)
 {
   GMainLoop *loop = user_data;
   om_res = g_object_ref (res);
   g_main_loop_quit (loop);
 }
 
-static GType
-get_proxy_type (GDBusObjectManagerClient *manager,
-                const gchar       *object_path,
-                const gchar       *interface_name,
-                gpointer           user_data)
-{
-  GType type;
-
-  g_assert_cmpint (GPOINTER_TO_UINT (user_data), ==, 42);
-
-  type = G_TYPE_DBUS_PROXY;
-  /* only map Bar and Bat, not other interface types */
-  if (g_strcmp0 (interface_name, "org.project.Bar") == 0)
-    type = FOO_TYPE_BAR_PROXY;
-  else if (g_strcmp0 (interface_name, "org.project.Bat") == 0)
-    type = FOO_TYPE_BAT_PROXY;
-
-  return type;
-}
-
 static void
 on_interface_added (GDBusObject    *object,
                     GDBusInterface *interface,
@@ -1647,47 +1728,78 @@ on_object_proxy_removed (GDBusObjectManagerClient  *manager,
 }
 
 static void
+property_d_changed (GObject    *object,
+                   GParamSpec *pspec,
+                   gpointer    user_data)
+{
+  gboolean *changed = user_data;
+
+  *changed = TRUE;
+}
+
+static void
 om_check_property_and_signal_emission (GMainLoop  *loop,
-                                       FooBar     *stub,
-                                       FooBar     *proxy)
+                                       FooiGenBar *skeleton,
+                                       FooiGenBar *proxy)
 {
+  gboolean d_changed = FALSE;
+  guint handler;
+
   /* First PropertiesChanged */
-  g_assert_cmpint (foo_bar_get_i (stub), ==, 0);
-  g_assert_cmpint (foo_bar_get_i (proxy), ==, 0);
-  foo_bar_set_i (stub, 1);
+  g_assert_cmpint (foo_igen_bar_get_i (skeleton), ==, 0);
+  g_assert_cmpint (foo_igen_bar_get_i (proxy), ==, 0);
+  foo_igen_bar_set_i (skeleton, 1);
+  _g_assert_property_notify (proxy, "i");
+  g_assert_cmpint (foo_igen_bar_get_i (skeleton), ==, 1);
+  g_assert_cmpint (foo_igen_bar_get_i (proxy), ==, 1);
+
+  /* Double-check the gdouble case */
+  g_assert_cmpfloat (foo_igen_bar_get_d (skeleton), ==, 0.0);
+  g_assert_cmpfloat (foo_igen_bar_get_d (proxy), ==, 0.0);
+  foo_igen_bar_set_d (skeleton, 1.0);
+  _g_assert_property_notify (proxy, "d");
+
+  /* Verify that re-setting it to the same value doesn't cause a
+   * notify on the proxy, by taking advantage of the fact that
+   * notifications are serialized.
+   */
+  handler = g_signal_connect (proxy, "notify::d",
+                             G_CALLBACK (property_d_changed), &d_changed);
+  foo_igen_bar_set_d (skeleton, 1.0);
+  foo_igen_bar_set_i (skeleton, 2);
   _g_assert_property_notify (proxy, "i");
-  g_assert_cmpint (foo_bar_get_i (stub), ==, 1);
-  g_assert_cmpint (foo_bar_get_i (proxy), ==, 1);
+  g_assert (d_changed == FALSE);
+  g_signal_handler_disconnect (proxy, handler);
 
   /* Then just a regular signal */
-  foo_bar_emit_another_signal (stub, "word");
+  foo_igen_bar_emit_another_signal (skeleton, "word");
   _g_assert_signal_received (proxy, "another-signal");
 }
 
 static void
 check_object_manager (void)
 {
-  GDBusObjectStub *o;
-  GDBusObjectStub *o2;
-  GDBusInterfaceStub *i;
-  GDBusInterfaceStub *i2;
+  FooiGenObjectSkeleton *o = NULL;
+  FooiGenObjectSkeleton *o2 = NULL;
+  FooiGenObjectSkeleton *o3 = NULL;
+  GDBusInterfaceSkeleton *i;
   GDBusConnection *c;
-  GDBusObjectManagerServer *manager;
+  GDBusObjectManagerServer *manager = NULL;
   GDBusNodeInfo *info;
   GError *error;
   GMainLoop *loop;
-  OMData *om_data;
-  guint om_signal_id;
-  GDBusObjectManager *pm;
+  OMData *om_data = NULL;
+  guint om_signal_id = -1;
+  GDBusObjectManager *pm = NULL;
   GList *object_proxies;
   GList *proxies;
   GDBusObject *op;
   GDBusProxy *p;
-  FooBar *bar_stub;
-  FooBar *bar_p;
-  FooBar *bar_p2;
-  FooComAcmeCoyote *coyote_p;
-  guint old_ref_count;
+  FooiGenBar *bar_skeleton;
+  GDBusInterface *iface;
+  gchar *path, *name, *name_owner;
+  GDBusConnection *c2;
+  GDBusObjectManagerClientFlags flags;
 
   loop = g_main_loop_new (NULL, FALSE);
 
@@ -1720,19 +1832,28 @@ check_object_manager (void)
    * GDBusObjectManagerClient firing before om_on_signal().
    */
   error = NULL;
-  pm = g_dbus_object_manager_client_new_sync (c,
-                                              G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
-                                              g_dbus_connection_get_unique_name (c),
-                                              "/managed",
-                                              get_proxy_type,
-                                              GUINT_TO_POINTER (42),
-                                              NULL, /* GCancellable */
-                                              &error);
+  pm = foo_igen_object_manager_client_new_sync (c,
+                                                G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+                                                g_dbus_connection_get_unique_name (c),
+                                                "/managed",
+                                                NULL, /* GCancellable */
+                                                &error);
   g_assert_error (error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD);
   g_error_free (error);
   g_assert (pm == NULL);
 
-  manager = g_dbus_object_manager_server_new (c, "/managed");
+  manager = g_dbus_object_manager_server_new ("/managed");
+
+  g_assert (g_dbus_object_manager_server_get_connection (manager) == NULL);
+
+  g_dbus_object_manager_server_set_connection (manager, c);
+
+  g_assert_cmpstr (g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (manager)), ==, "/managed");
+  g_object_get (manager, "object-path", &path, "connection", &c2, NULL);
+  g_assert_cmpstr (path, ==, "/managed");
+  g_assert (c2 == c);
+  g_free (path);
+  g_clear_object (&c2);
 
   /* Check that the manager object is visible */
   info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed", loop);
@@ -1745,21 +1866,19 @@ check_object_manager (void)
   om_check_get_all (c, loop,
                     "(@a{oa{sa{sv}}} {},)");
 
-  /* Now try to create the the proxy manager again - this time it should work */
+  /* Now try to create the proxy manager again - this time it should work */
   error = NULL;
-  g_dbus_object_manager_client_new (c,
-                            G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
-                            g_dbus_connection_get_unique_name (c),
-                            "/managed",
-                            get_proxy_type,
-                            GUINT_TO_POINTER (42),
-                            NULL, /* GCancellable */
-                            (GAsyncReadyCallback) om_pm_start_cb,
-                            loop);
+  foo_igen_object_manager_client_new (c,
+                                      G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE,
+                                      g_dbus_connection_get_unique_name (c),
+                                      "/managed",
+                                      NULL, /* GCancellable */
+                                      (GAsyncReadyCallback) om_pm_start_cb,
+                                      loop);
   g_main_loop_run (loop);
   error = NULL;
-  pm = g_dbus_object_manager_client_new_finish (om_res, &error);
-  g_object_unref (om_res);
+  pm = foo_igen_object_manager_client_new_finish (om_res, &error);
+  g_clear_object (&om_res);
   g_assert_no_error (error);
   g_assert (pm != NULL);
   g_signal_connect (pm,
@@ -1770,6 +1889,25 @@ check_object_manager (void)
                     "object-removed",
                     G_CALLBACK (on_object_proxy_removed),
                     om_data);
+
+  g_assert_cmpstr (g_dbus_object_manager_get_object_path (G_DBUS_OBJECT_MANAGER (pm)), ==, "/managed");
+  g_object_get (pm,
+                "object-path", &path,
+                "connection", &c2,
+                "name", &name,
+                "name-owner", &name_owner,
+                "flags", &flags,
+                NULL);
+  g_assert_cmpstr (path, ==, "/managed");
+  g_assert_cmpstr (name, ==, g_dbus_connection_get_unique_name (c));
+  g_assert_cmpstr (name_owner, ==, g_dbus_connection_get_unique_name (c));
+  g_assert_cmpint (flags, ==, G_DBUS_OBJECT_MANAGER_CLIENT_FLAGS_NONE);
+  g_assert (c2 == c);
+  g_free (path);
+  g_clear_object (&c2);
+  g_free (name);
+  g_free (name_owner);
+
   /* ... check there are no object proxies yet */
   object_proxies = g_dbus_object_manager_get_objects (pm);
   g_assert (object_proxies == NULL);
@@ -1777,26 +1915,33 @@ check_object_manager (void)
   /* First, export an object with a single interface (also check that
    * g_dbus_interface_get_object() works and that the object isn't reffed)
    */
-  o = g_dbus_object_stub_new ("/managed/first");
-  i = G_DBUS_INTERFACE_STUB (foo_bar_stub_new ());
+  o = foo_igen_object_skeleton_new ("/managed/first");
+  i = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ());
   g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == NULL);
   g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1);
-  g_dbus_object_stub_add_interface (o, i);
+  foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i));
   g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1);
   g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == G_DBUS_OBJECT (o));
   g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1);
-  g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1);
-  g_dbus_object_stub_remove_interface (o, i);
+  foo_igen_object_skeleton_set_bar (o, NULL);
   g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == NULL);
   g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1);
-  g_dbus_object_stub_add_interface (o, i);
+  foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i));
   g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (i)) == G_DBUS_OBJECT (o));
   g_assert_cmpint (G_OBJECT (o)->ref_count, ==, 1);
-  g_dbus_object_manager_server_export (manager, o);
+
+  o2 = FOO_IGEN_OBJECT_SKELETON (g_dbus_interface_dup_object (G_DBUS_INTERFACE (i)));
+  g_assert (G_DBUS_OBJECT (o2) == G_DBUS_OBJECT (o));
+  g_assert_cmpint (G_OBJECT (o2)->ref_count, ==, 2);
+  g_clear_object (&o2);
+
+  g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (o));
 
   /* ... check we get the InterfacesAdded signal */
   om_data->state = 1;
+
   g_main_loop_run (om_data->loop);
+
   g_assert_cmpint (om_data->state, ==, 2);
   g_assert_cmpint (om_data->num_object_proxy_added_signals, ==, 1);
   g_assert_cmpint (om_data->num_object_proxy_removed_signals, ==, 0);
@@ -1808,8 +1953,20 @@ check_object_manager (void)
   g_assert (has_interface (info, "org.project.Bar"));
   g_dbus_node_info_unref (info);
 
+  /* Also check g_dbus_object_manager_get_interface */
+  iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (manager), "/managed/first", "org.project.Bar");
+  g_assert (iface != NULL);
+  g_clear_object (&iface);
+  iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (manager), "/managed/first", "org.project.Bat");
+  g_assert (iface == NULL);
+  iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (pm), "/managed/first", "org.project.Bar");
+  g_assert (iface != NULL);
+  g_clear_object (&iface);
+  iface = g_dbus_object_manager_get_interface (G_DBUS_OBJECT_MANAGER (pm), "/managed/first", "org.project.Bat");
+  g_assert (iface == NULL);
+
   /* Now, check adding the same interface replaces the existing one */
-  g_dbus_object_stub_add_interface (o, i);
+  foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i));
   /* ... check we get the InterfacesRemoved */
   om_data->state = 3;
   g_main_loop_run (om_data->loop);
@@ -1824,11 +1981,11 @@ check_object_manager (void)
   g_assert_cmpint (count_interfaces (info), ==, 4); /* Bar + Properties,Introspectable,Peer */
   g_assert (has_interface (info, "org.project.Bar"));
   g_dbus_node_info_unref (info);
-  g_object_unref (i);
+  g_clear_object (&i);
 
   /* check adding an interface of same type (but not same object) replaces the existing one */
-  i = G_DBUS_INTERFACE_STUB (foo_bar_stub_new ());
-  g_dbus_object_stub_add_interface (o, i);
+  i = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ());
+  foo_igen_object_skeleton_set_bar (o, FOO_IGEN_BAR (i));
   /* ... check we get the InterfacesRemoved and then InterfacesAdded */
   om_data->state = 7;
   g_main_loop_run (om_data->loop);
@@ -1842,12 +1999,12 @@ check_object_manager (void)
   g_assert_cmpint (count_interfaces (info), ==, 4); /* Bar + Properties,Introspectable,Peer */
   g_assert (has_interface (info, "org.project.Bar"));
   g_dbus_node_info_unref (info);
-  g_object_unref (i);
+  g_clear_object (&i);
 
   /* check adding an interface of another type doesn't replace the existing one */
-  i = G_DBUS_INTERFACE_STUB (foo_bat_stub_new ());
-  g_dbus_object_stub_add_interface (o, i);
-  g_object_unref (i);
+  i = G_DBUS_INTERFACE_SKELETON (foo_igen_bat_skeleton_new ());
+  foo_igen_object_skeleton_set_bat (o, FOO_IGEN_BAT (i));
+  g_clear_object (&i);
   /* ... check we get the InterfacesAdded */
   om_data->state = 11;
   g_main_loop_run (om_data->loop);
@@ -1864,7 +2021,7 @@ check_object_manager (void)
   g_dbus_node_info_unref (info);
 
   /* check we can remove an interface */
-  g_dbus_object_stub_remove_interface_by_name (o, "org.project.Bar");
+  foo_igen_object_skeleton_set_bar (o, NULL);
   /* ... check we get the InterfacesRemoved */
   om_data->state = 13;
   g_main_loop_run (om_data->loop);
@@ -1883,7 +2040,7 @@ check_object_manager (void)
    * (Note: if a signal was emitted we'd assert in the signal handler
    * because we're in state 14)
    */
-  g_dbus_object_stub_remove_interface_by_name (o, "org.project.Bar");
+  foo_igen_object_skeleton_set_bar (o, NULL);
   /* ... check introspection data */
   info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed/first", loop);
   g_assert_cmpint (count_interfaces (info), ==, 4); /* Bat + Properties,Introspectable,Peer */
@@ -1891,7 +2048,7 @@ check_object_manager (void)
   g_dbus_node_info_unref (info);
 
   /* remove the last interface */
-  g_dbus_object_stub_remove_interface_by_name (o, "org.project.Bat");
+  foo_igen_object_skeleton_set_bat (o, NULL);
   /* ... check we get the InterfacesRemoved */
   om_data->state = 15;
   g_main_loop_run (om_data->loop);
@@ -1906,9 +2063,9 @@ check_object_manager (void)
   g_dbus_node_info_unref (info);
 
   /* and add an interface again */
-  i = G_DBUS_INTERFACE_STUB (foo_com_acme_coyote_stub_new ());
-  g_dbus_object_stub_add_interface (o, i);
-  g_object_unref (i);
+  i = G_DBUS_INTERFACE_SKELETON (foo_igen_com_acme_coyote_skeleton_new ());
+  foo_igen_object_skeleton_set_com_acme_coyote (o, FOO_IGEN_COM_ACME_COYOTE (i));
+  g_clear_object (&i);
   /* ... check we get the InterfacesAdded */
   om_data->state = 17;
   g_main_loop_run (om_data->loop);
@@ -1930,16 +2087,16 @@ check_object_manager (void)
   /* -------------------------------------------------- */
 
   /* create a new object with two interfaces */
-  o2 = g_dbus_object_stub_new ("/managed/second");
-  i = G_DBUS_INTERFACE_STUB (foo_bar_stub_new ());
-  bar_stub = FOO_BAR (i); /* save for later test */
-  g_dbus_object_stub_add_interface (o2, i);
-  g_object_unref (i);
-  i = G_DBUS_INTERFACE_STUB (foo_bat_stub_new ());
-  g_dbus_object_stub_add_interface (o2, i);
-  g_object_unref (i);
+  o2 = foo_igen_object_skeleton_new ("/managed/second");
+  i = G_DBUS_INTERFACE_SKELETON (foo_igen_bar_skeleton_new ());
+  bar_skeleton = FOO_IGEN_BAR (i); /* save for later test */
+  foo_igen_object_skeleton_set_bar (o2, FOO_IGEN_BAR (i));
+  g_clear_object (&i);
+  i = G_DBUS_INTERFACE_SKELETON (foo_igen_bat_skeleton_new ());
+  foo_igen_object_skeleton_set_bat (o2, FOO_IGEN_BAT (i));
+  g_clear_object (&i);
   /* ... add it */
-  g_dbus_object_manager_server_export (manager, o2);
+  g_dbus_object_manager_server_export (manager, G_DBUS_OBJECT_SKELETON (o2));
   /* ... check we get the InterfacesAdded with _two_ interfaces */
   om_data->state = 101;
   g_main_loop_run (om_data->loop);
@@ -1957,106 +2114,66 @@ check_object_manager (void)
   om_check_get_all (c, loop,
                     "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': <byte 0x00>, 'b': <false>, 'n': <int16 0>, 'q': <uint16 0>, 'i': <0>, 'u': <uint32 0>, 'x': <int64 0>, 't': <uint64 0>, 'd': <0.0>, 's': <''>, 'o': <objectpath '/'>, 'g': <signature ''>, 'ay': <b''>, 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': <objectpath '/'>, 'unset_g': <signature ''>, 'unset_ay': <b''>, 'unset_as': <@as []>, 'unset_ao': <@ao []>, 'unset_ag': <@ag []>, 'unset_struct': <(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])>}, 'org.project.Bat': {'force_i': <0>, 'force_s': <''>, 'force_ay': <@ay []>, 'force_struct': <(0,)>}}},)");
 
-  /* check that the _GET_ and _PEEK_ macros work on the server side */
-  i = FOO_PEEK_BAR (o);
-  g_assert (i == NULL);
-  i = FOO_PEEK_COM_ACME_COYOTE (o);
-  g_assert (i != NULL);
-  g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (i), G_TYPE_DBUS_INTERFACE_STUB));
-  g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (i), FOO_TYPE_COM_ACME_COYOTE));
-  g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (i), FOO_TYPE_COM_ACME_COYOTE_STUB));
-  /* ... and that PEEK doesn't increase the ref_count but GET does */
-  g_assert_cmpint (G_OBJECT (i)->ref_count, ==, 2);
-  i2 = FOO_PEEK_COM_ACME_COYOTE (o);
-  g_assert (i == i2);
-  g_assert_cmpint (G_OBJECT (i)->ref_count, ==, 2);
-  i2 = FOO_GET_COM_ACME_COYOTE (o);
-  g_assert (i == i2);
-  g_assert_cmpint (G_OBJECT (i)->ref_count, ==, 3);
-  g_object_unref (i);
+  /* Set connection to NULL, causing everything to be unexported.. verify this.. and
+   * then set the connection back.. and then check things still work
+   */
+  g_dbus_object_manager_server_set_connection (manager, NULL);
+  info = introspect (c, g_dbus_connection_get_unique_name (c), "/managed", loop);
+  g_assert_cmpint (count_interfaces (info), ==, 0); /* nothing */
+  g_dbus_node_info_unref (info);
+
+  g_dbus_object_manager_server_set_connection (manager, c);
+  om_check_get_all (c, loop,
+                    "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/second': {'org.project.Bar': {'y': <byte 0x00>, 'b': <false>, 'n': <int16 0>, 'q': <uint16 0>, 'i': <0>, 'u': <uint32 0>, 'x': <int64 0>, 't': <uint64 0>, 'd': <0.0>, 's': <''>, 'o': <objectpath '/'>, 'g': <signature ''>, 'ay': <b''>, 'as': <@as []>, 'aay': <@aay []>, 'ao': <@ao []>, 'ag': <@ag []>, 'FinallyNormalName': <''>, 'ReadonlyProperty': <''>, 'unset_i': <0>, 'unset_d': <0.0>, 'unset_s': <''>, 'unset_o': <objectpath '/'>, 'unset_g': <signature ''>, 'unset_ay': <b''>, 'unset_as': <@as []>, 'unset_ao': <@ao []>, 'unset_ag': <@ag []>, 'unset_struct': <(0, 0.0, '', objectpath '/', signature '', @ay [], @as [], @ao [], @ag [])>}, 'org.project.Bat': {'force_i': <0>, 'force_s': <''>, 'force_ay': <@ay []>, 'force_struct': <(0,)>}}},)");
 
   /* Also check that the ObjectManagerClient returns these objects - and
-   * that they are of the right GType cf. what we requested via
-   * our ::get-proxy-type signal handler
+   * that they are of the right GType cf. what was requested via
+   * the generated ::get-proxy-type signal handler
    */
   object_proxies = g_dbus_object_manager_get_objects (pm);
   g_assert (g_list_length (object_proxies) == 2);
-  g_list_foreach (object_proxies, (GFunc) g_object_unref, NULL);
-  g_list_free (object_proxies);
+  g_list_free_full (object_proxies, g_object_unref);
   op = g_dbus_object_manager_get_object (pm, "/managed/first");
   g_assert (op != NULL);
+  g_assert (FOO_IGEN_IS_OBJECT_PROXY (op));
   g_assert_cmpstr (g_dbus_object_get_object_path (op), ==, "/managed/first");
   proxies = g_dbus_object_get_interfaces (op);
   g_assert (g_list_length (proxies) == 1);
-  g_list_foreach (proxies, (GFunc) g_object_unref, NULL);
-  g_list_free (proxies);
-  p = G_DBUS_PROXY (g_dbus_object_get_interface (op, "com.acme.Coyote"));
+  g_list_free_full (proxies, g_object_unref);
+  p = G_DBUS_PROXY (foo_igen_object_get_com_acme_coyote (FOO_IGEN_OBJECT (op)));
   g_assert (p != NULL);
-  g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, G_TYPE_DBUS_PROXY);
-  g_assert (!g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_TYPE_COM_ACME_COYOTE));
-  g_object_unref (p);
+  g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_IGEN_TYPE_COM_ACME_COYOTE_PROXY);
+  g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_IGEN_TYPE_COM_ACME_COYOTE));
+  g_clear_object (&p);
   p = (GDBusProxy *) g_dbus_object_get_interface (op, "org.project.NonExisting");
   g_assert (p == NULL);
-  g_object_unref (op);
+  g_clear_object (&op);
+
   /* -- */
   op = g_dbus_object_manager_get_object (pm, "/managed/second");
   g_assert (op != NULL);
+  g_assert (FOO_IGEN_IS_OBJECT_PROXY (op));
   g_assert_cmpstr (g_dbus_object_get_object_path (op), ==, "/managed/second");
   proxies = g_dbus_object_get_interfaces (op);
   g_assert (g_list_length (proxies) == 2);
-  g_list_foreach (proxies, (GFunc) g_object_unref, NULL);
-  g_list_free (proxies);
-  p = G_DBUS_PROXY (g_dbus_object_get_interface (op, "org.project.Bat"));
+  g_list_free_full (proxies, g_object_unref);
+  p = G_DBUS_PROXY (foo_igen_object_get_bat (FOO_IGEN_OBJECT (op)));
   g_assert (p != NULL);
-  g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_TYPE_BAT_PROXY);
-  g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_TYPE_BAT));
-  g_object_unref (p);
-  p = G_DBUS_PROXY (g_dbus_object_get_interface (op, "org.project.Bar"));
+  g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_IGEN_TYPE_BAT_PROXY);
+  g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_IGEN_TYPE_BAT));
+  g_clear_object (&p);
+  p = G_DBUS_PROXY (foo_igen_object_get_bar (FOO_IGEN_OBJECT (op)));
   g_assert (p != NULL);
-  g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_TYPE_BAR_PROXY);
-  g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_TYPE_BAR));
+  g_assert_cmpint (G_TYPE_FROM_INSTANCE (p), ==, FOO_IGEN_TYPE_BAR_PROXY);
+  g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (p), FOO_IGEN_TYPE_BAR));
   /* ... now that we have a Bar instance around, also check that we get signals
    *     and property changes...
    */
-  om_check_property_and_signal_emission (loop, bar_stub, FOO_BAR (p));
-  g_object_unref (p);
+  om_check_property_and_signal_emission (loop, bar_skeleton, FOO_IGEN_BAR (p));
+  g_clear_object (&p);
   p = (GDBusProxy *) g_dbus_object_get_interface (op, "org.project.NonExisting");
   g_assert (p == NULL);
-  g_object_unref (op);
-
-  /* -------------------------------------------------- */
-
-  /* check that the _GET_ and _PEEK_ macros work on the proxy side */
-  op = g_dbus_object_manager_get_object (pm, "/managed/second");
-  bar_p = FOO_GET_BAR (op);
-  old_ref_count = G_OBJECT (op)->ref_count;
-  g_assert (g_dbus_interface_get_object (G_DBUS_INTERFACE (bar_p)) == op);
-  g_assert_cmpint (old_ref_count, ==, G_OBJECT (op)->ref_count);
-  g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (bar_p), FOO_TYPE_BAR));
-  g_assert (g_type_is_a (G_TYPE_FROM_INSTANCE (bar_p), G_TYPE_DBUS_PROXY));
-  g_assert_cmpint (G_OBJECT (bar_p)->ref_count, ==, 2);
-  g_object_unref (bar_p);
-  bar_p2 = FOO_PEEK_BAR (op);
-  g_assert (bar_p2 == bar_p);
-  g_assert_cmpint (G_OBJECT (bar_p)->ref_count, ==, 1);
-  coyote_p = FOO_GET_COM_ACME_COYOTE (op);
-  g_assert (coyote_p == NULL);
-  coyote_p = FOO_PEEK_COM_ACME_COYOTE (op);
-  g_assert (coyote_p == NULL);
-  g_object_unref (op);
-
-  /* Also, check that we warn on stderr in case the get_proxy_type() function is
-   * wrong etc.
-   */
-  op = g_dbus_object_manager_get_object (pm, "/managed/first");
-  bar_p = FOO_GET_BAR (op);
-  g_assert (bar_p == NULL);
-  if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR))
-    {
-      coyote_p = FOO_GET_COM_ACME_COYOTE (op);
-    }
-  g_test_trap_assert_stderr ("*runtime check failed: (G_TYPE_CHECK_INSTANCE_TYPE (ret, type))*");
-  g_object_unref (op);
+  g_clear_object (&op);
 
   /* -------------------------------------------------- */
 
@@ -2079,23 +2196,52 @@ check_object_manager (void)
   /* Check GetManagedObjects() again */
   om_check_get_all (c, loop,
                     "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}},)");
+  /* -------------------------------------------------- */
 
-  //g_main_loop_run (loop); /* TODO: tmp */
+  /* Check that export_uniquely() works */
 
-  g_main_loop_unref (loop);
+  o3 = foo_igen_object_skeleton_new ("/managed/first");
+  i = G_DBUS_INTERFACE_SKELETON (foo_igen_com_acme_coyote_skeleton_new ());
+  foo_igen_com_acme_coyote_set_mood (FOO_IGEN_COM_ACME_COYOTE (i), "indifferent");
+  foo_igen_object_skeleton_set_com_acme_coyote (o3, FOO_IGEN_COM_ACME_COYOTE (i));
+  g_clear_object (&i);
+  g_dbus_object_manager_server_export_uniquely (manager, G_DBUS_OBJECT_SKELETON (o3));
+  /* ... check we get the InterfacesAdded signal */
+  om_data->state = 200;
+  g_main_loop_run (om_data->loop);
+  g_assert_cmpint (om_data->state, ==, 201);
 
-  g_dbus_connection_signal_unsubscribe (c, om_signal_id);
-  g_object_unref (o2);
-  g_object_unref (o);
-  g_object_unref (manager);
-  g_assert_cmpint (g_signal_handlers_disconnect_by_func (pm,
-                                                         G_CALLBACK (on_object_proxy_added),
-                                                         om_data), ==, 1);
-  g_assert_cmpint (g_signal_handlers_disconnect_by_func (pm,
-                                                         G_CALLBACK (on_object_proxy_removed),
-                                                         om_data), ==, 1);
-  g_object_unref (pm);
-  g_object_unref (c);
+  om_check_get_all (c, loop,
+                    "({objectpath '/managed/first': {'com.acme.Coyote': {'Mood': <''>}}, '/managed/first_1': {'com.acme.Coyote': {'Mood': <'indifferent'>}}},)");
+
+  //g_main_loop_run (loop); /* TODO: tmp */
+
+  /* Clean up objects */
+  g_assert (g_dbus_object_manager_server_unexport (manager, "/managed/first_1"));
+  //g_assert (g_dbus_object_manager_server_unexport (manager, "/managed/second"));
+  g_assert (g_dbus_object_manager_server_unexport (manager, "/managed/first"));
+  g_assert_cmpint (g_list_length (g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (manager))), ==, 0);
+
+  if (loop != NULL)
+    g_main_loop_unref (loop);
+
+  if (om_signal_id != -1)
+    g_dbus_connection_signal_unsubscribe (c, om_signal_id);
+  g_clear_object (&o3);
+  g_clear_object (&o2);
+  g_clear_object (&o);
+  g_clear_object (&manager);
+  if (pm != NULL)
+    {
+      g_assert_cmpint (g_signal_handlers_disconnect_by_func (pm,
+                                                             G_CALLBACK (on_object_proxy_added),
+                                                             om_data), ==, 1);
+      g_assert_cmpint (g_signal_handlers_disconnect_by_func (pm,
+                                                             G_CALLBACK (on_object_proxy_removed),
+                                                             om_data), ==, 1);
+      g_clear_object (&pm);
+    }
+  g_clear_object (&c);
 
   g_free (om_data);
 }
@@ -2126,6 +2272,8 @@ test_object_manager (void)
   /* uncomment to keep the service around (to e.g. introspect it) */
   /* g_main_loop_run (loop); */
 
+  unexport_objects ();
+
   g_bus_unown_name (id);
   g_main_loop_unref (loop);
 }
@@ -2137,16 +2285,22 @@ extern gpointer name_forcing_1;
 extern gpointer name_forcing_2;
 extern gpointer name_forcing_3;
 extern gpointer name_forcing_4;
-gpointer name_forcing_1 = foo_rocket123_get_gtype;
-gpointer name_forcing_2 = foo_rocket123_call_ignite_xyz;
-gpointer name_forcing_3 = foo_rocket123_emit_exploded_xyz;
-gpointer name_forcing_4 = foo_rocket123_get_speed_xyz;
+extern gpointer name_forcing_5;
+extern gpointer name_forcing_6;
+extern gpointer name_forcing_7;
+gpointer name_forcing_1 = foo_igen_rocket123_get_type;
+gpointer name_forcing_2 = foo_igen_rocket123_call_ignite_xyz;
+gpointer name_forcing_3 = foo_igen_rocket123_emit_exploded_xyz;
+gpointer name_forcing_4 = foo_igen_rocket123_get_speed_xyz;
+gpointer name_forcing_5 = foo_igen_test_ugly_case_interface_call_get_iscsi_servers;
+gpointer name_forcing_6 = foo_igen_test_ugly_case_interface_emit_servers_updated_now;
+gpointer name_forcing_7 = foo_igen_test_ugly_case_interface_get_ugly_name;
 
 /* ---------------------------------------------------------------------------------------------------- */
 
 /* See https://bugzilla.gnome.org/show_bug.cgi?id=647577#c5 for details */
 
-#define CHECK_FIELD(name, v1, v2) g_assert_cmpint (G_STRUCT_OFFSET (FooChangingInterface##v1##Iface, name), ==, G_STRUCT_OFFSET (FooChangingInterface##v2##Iface, name));
+#define CHECK_FIELD(name, v1, v2) g_assert_cmpint (G_STRUCT_OFFSET (FooiGenChangingInterface##v1##Iface, name), ==, G_STRUCT_OFFSET (FooiGenChangingInterface##v2##Iface, name));
 
 static void
 test_interface_stability (void)
@@ -2165,36 +2319,43 @@ test_interface_stability (void)
 
 /* ---------------------------------------------------------------------------------------------------- */
 
-int
-main (int   argc,
-      char *argv[])
+/* property naming
+ *
+ * - check that a property with name "Type" is mapped into g-name "type"
+ *   with C accessors get_type_ (to avoid clashing with the GType accessor)
+ *   and set_type_ (for symmetri)
+ *   (see https://bugzilla.gnome.org/show_bug.cgi?id=679473 for details)
+ *
+ * - (could add more tests here)
+ */
+
+static void
+test_property_naming (void)
 {
-  gint ret;
+  gpointer c_getter_name = foo_igen_naming_get_type_;
+  gpointer c_setter_name = foo_igen_naming_set_type_;
+  FooiGenNaming *skel;
 
-  g_type_init ();
-  g_test_init (&argc, &argv, NULL);
+  (void) c_getter_name;
+  (void) c_setter_name;
 
-  /* all the tests use a session bus with a well-known address that we can bring up and down
-   * using session_bus_up() and session_bus_down().
-   */
-  g_unsetenv ("DISPLAY");
-  g_setenv ("DBUS_SESSION_BUS_ADDRESS", session_bus_get_temporary_address (), TRUE);
+  skel = foo_igen_naming_skeleton_new ();
+  g_assert (g_object_class_find_property (G_OBJECT_GET_CLASS (skel), "type") != NULL);
+  g_object_unref (skel);
+}
 
-  session_bus_up ();
+/* ---------------------------------------------------------------------------------------------------- */
 
-  /* TODO: wait a bit for the bus to come up.. ideally session_bus_up() won't return
-   * until one can connect to the bus but that's not how things work right now
-   */
-  usleep (500 * 1000);
+int
+main (int   argc,
+      char *argv[])
+{
+  g_test_init (&argc, &argv, NULL);
 
   g_test_add_func ("/gdbus/codegen/annotations", test_annotations);
   g_test_add_func ("/gdbus/codegen/interface_stability", test_interface_stability);
   g_test_add_func ("/gdbus/codegen/object-manager", test_object_manager);
+  g_test_add_func ("/gdbus/codegen/property-naming", test_property_naming);
 
-  ret = g_test_run();
-
-  /* tear down bus */
-  session_bus_down ();
-
-  return ret;
+  return session_bus_run ();
 }